#include #include #include #include #include #include #include class ITABufferedAudiofileWriterImpl : public ITABufferedAudiofileWriter { public: inline ITABufferedAudiofileWriterImpl(std::string sFilename, const ITAAudiofileProperties& props, double dInitialBufferSizeSeconds, double dGrowBufferSizeSeconds) : m_pWriter(NULL) { // Zunächst versuchen den regulären (ungepufferten) Schreiber aufzusetzen m_pWriter = ITAAudiofileWriter::create(sFilename, 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.uiChannels, m_iInitialBufferSizeSamples ) ); } inline virtual ~ITABufferedAudiofileWriterImpl() { // Alle Chunks schreiben und freigeben for (std::list::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( unsigned int uiLength, std::vector 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 (uiLength == 0) return; int iWritten = 0; int iTotal = (int) uiLength; 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; im_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 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 m_lpChunks; int m_iInitialBufferSizeSamples; int m_iGrowBufferSizeSamples; }; ITABufferedAudiofileWriter* ITABufferedAudiofileWriter::create(const std::string& sFilename, const ITAAudiofileProperties& props, double dInitialBufferSizeSeconds, double dGrowBufferSizeSeconds) { return new ITABufferedAudiofileWriterImpl(sFilename, props, dInitialBufferSizeSeconds, dGrowBufferSizeSeconds); }