Skip to content
Snippets Groups Projects
Select Git revision
  • 01a43cb1f397d90ba4379968134f0cec723ca7ed
  • master default protected
  • develop protected
  • feature/triangulation-qhull
  • jst
  • ti_lab_build
  • features/splines_and_piecewise_polynomials
  • ma_2018/erraji
  • fabian
  • ITABase_v2025a
  • ITABase_v2024a
  • VA_v2023b
  • VA_v2023a
  • VA_v2022a
  • before_cmake_rework
  • v2021.a
  • v2020.a
  • v2019.a
  • v2018.b
  • v2018.a
  • v2017.d
  • v2017.c
  • v2017.b
  • v2017.a
  • v2016.a
25 results

ITABufferedAudioFileWriter.cpp

Blame
  • Jonas Stienen's avatar
    Dipl.-Ing. Jonas Stienen authored
    Switching from unsigned int to all in. Max WAV file size now 2GB instead of 4GB.
    Fixing painful implicit conversion of ITADomain and ITAQuantization (was simple enum) to enum classes (can not be converted implicitly, i.e. by false function call).
    5f5744c1
    History
    Code owners
    Assign users and groups as approvers for specific file changes. Learn more.
    ITABufferedAudioFileWriter.cpp 3.20 KiB
    #include <ITABufferedAudioFileWriter.h>
    
    #include <ITAException.h>
    #include <ITASampleFrame.h>
    
    #include <algorithm>
    #include <list>
    #include <algorithm>
    #include <math.h>
    
    
    class ITABufferedAudiofileWriterImpl : public ITABufferedAudiofileWriter
    {
    public:
    	inline ITABufferedAudiofileWriterImpl( const std::string& sFilePath,
    		const ITAAudiofileProperties& props,
    		double dInitialBufferSizeSeconds,
    		double dGrowBufferSizeSeconds )
    		: m_pWriter( NULL )
    	{
    		// Zunächst versuchen den regulären (ungepufferten) Schreiber aufzusetzen
    		m_pWriter = ITAAudiofileWriter::create( sFilePath, props );
    
    		// Initialen Chunk anlegen
    		m_iInitialBufferSizeSamples = (int) ceil( dInitialBufferSizeSeconds*props.dSampleRate );
    		m_iGrowBufferSizeSamples = (int)  ceil( dGrowBufferSizeSeconds*props.dSampleRate );
    
    		m_lpChunks.push_back( new Chunk( (int) props.iChannels, m_iInitialBufferSizeSamples ) );
    	}
    
    	inline virtual ~ITABufferedAudiofileWriterImpl()
    	{
    		// Alle Chunks schreiben und freigeben
    		for (std::list<Chunk*>::iterator it=m_lpChunks.begin(); it!=m_lpChunks.end(); ++it) {
    			Chunk* pChunk = (*it);
    			
    			if (m_pWriter && (pChunk->m_iTail > 0))
    				m_pWriter->write(pChunk->m_iTail, pChunk->m_vpfData);
    
    			delete pChunk;
    		}
    
    		// Schreiber freigeben
    		delete m_pWriter;
    	}
    
    	inline virtual void write( int iLength, std::vector<const float*> vpfSource )
    	{
    		// Korrekte Anzahl Kanäle
    		int iChannels = m_lpChunks.back()->m_sfSamples.channels();
    		if ((int) vpfSource.size() != iChannels)
    			ITA_EXCEPT1(INVALID_PARAMETER, "Wrong number of channels in source data");
    
    		if( iLength == 0 ) return;
    		
    		int iWritten = 0;
    		int iTotal = iLength;
    		int iRemain = iTotal;
    		
    		while (iWritten < iTotal) {
    			Chunk* pTailChunk = m_lpChunks.back();
    			
    			// Soviel in diesen Chunk schreiben wie möglich
    			int iChunkRemain = pTailChunk->m_sfSamples.length() - pTailChunk->m_iTail;
    			int iCount = std::min( iRemain, iChunkRemain );
    
    			for (int i=0; i<iChannels; i++)
    				pTailChunk->m_sfSamples[i].write( vpfSource[i], iCount, pTailChunk->m_iTail );
    			pTailChunk->m_iTail += iCount;
    
    			iWritten += iCount;
    			iRemain = iTotal - iWritten;
    
    			// Neuen Chunk anlegen, falls noch Daten zu schreiben ...
    			if (iRemain > 0) {
    				m_lpChunks.push_back( new Chunk( iChannels, m_iGrowBufferSizeSamples) );
    			}
    		}
    	}
    
    private:
    	// Interner Speicherblock für Samples
    	class Chunk
    	{
    	public:
    		ITASampleFrame m_sfSamples;
    		std::vector<float*> m_vpfData; // Zugriffszeiger auf Kanaldaten (für den Writer)
    		int m_iTail;
    
    		inline Chunk( int iChannels, int iCapacity )
    		: m_sfSamples( iChannels, iCapacity, false )
    		, m_vpfData(iChannels)
    		, m_iTail(0)
    		{
    			for( int i=0; i<iChannels; i++ )
    				m_vpfData[i] = m_sfSamples[i].GetData();
    		}
    	};
    
    	ITAAudiofileWriter* m_pWriter;
    	std::list<Chunk*> m_lpChunks;
    	int m_iInitialBufferSizeSamples;
    	int m_iGrowBufferSizeSamples;
    };
    
    
    ITABufferedAudiofileWriter* ITABufferedAudiofileWriter::create(const std::string& sFilePath,
    													           const ITAAudiofileProperties& props,
    													           double dInitialBufferSizeSeconds,
    													           double dGrowBufferSizeSeconds)
    {
    	return new ITABufferedAudiofileWriterImpl( sFilePath, props, dInitialBufferSizeSeconds, dGrowBufferSizeSeconds );
    }