Skip to content
Snippets Groups Projects
Select Git revision
  • 9492f270e96479aad3e340829504b9b7e6243b8c
  • main default protected
2 results

ExperimentsRandomTestsVarSystemFixedAcceptanceRatioFixedTestSize.java

Blame
  • 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 );
    }