Mercurial > hg > svcore
changeset 1307:c84629395040 mp3-gapless
Handle trimming the padding from end as well
author | Chris Cannam |
---|---|
date | Tue, 29 Nov 2016 13:34:51 +0000 |
parents | b325e91505b5 |
children | 80c77916fe85 |
files | data/fileio/CodedAudioFileReader.cpp data/fileio/CodedAudioFileReader.h data/fileio/MP3FileReader.cpp |
diffstat | 3 files changed, 48 insertions(+), 15 deletions(-) [+] |
line wrap: on
line diff
--- a/data/fileio/CodedAudioFileReader.cpp Tue Nov 29 12:06:49 2016 +0000 +++ b/data/fileio/CodedAudioFileReader.cpp Tue Nov 29 13:34:51 2016 +0000 @@ -41,7 +41,7 @@ m_cacheFileReader(0), m_cacheWriteBuffer(0), m_cacheWriteBufferIndex(0), - m_cacheWriteBufferSize(16384), + m_cacheWriteBufferSize(65536), m_resampler(0), m_resampleBuffer(0), m_fileFrameCount(0), @@ -96,7 +96,7 @@ } void -CodedAudioFileReader::setSamplesToTrim(sv_frame_t fromStart, sv_frame_t fromEnd) +CodedAudioFileReader::setFramesToTrim(sv_frame_t fromStart, sv_frame_t fromEnd) { m_trimFromStart = fromStart; m_trimFromEnd = fromEnd; @@ -127,6 +127,11 @@ SVDEBUG << "CodedAudioFileReader::initialiseDecodeCache: file rate = " << m_fileRate << endl; + if (m_channelCount == 0) { + SVCERR << "CodedAudioFileReader::initialiseDecodeCache: No channel count set!" << endl; + throw std::logic_error("No channel count set"); + } + if (m_fileRate == 0) { SVDEBUG << "CodedAudioFileReader::initialiseDecodeCache: ERROR: File sample rate unknown (bug in subclass implementation?)" << endl; throw FileOperationFailed("(coded file)", "File sample rate unknown (bug in subclass implementation?)"); @@ -221,6 +226,11 @@ m_data.clear(); } + if (m_trimFromEnd >= (m_cacheWriteBufferSize * m_channelCount)) { + SVCERR << "WARNING: CodedAudioFileReader::setSamplesToTrim: Can't handle trimming more frames from end (" << m_trimFromEnd << ") than can be stored in cache-write buffer (" << (m_cacheWriteBufferSize * m_channelCount) << "), won't trim anything from the end after all"; + m_trimFromEnd = 0; + } + m_initialised = true; } @@ -351,12 +361,35 @@ if (final || (m_cacheWriteBufferIndex == m_cacheWriteBufferSize * m_channelCount)) { + + if (m_trimFromEnd > 0) { - pushBuffer(m_cacheWriteBuffer, - m_cacheWriteBufferIndex / m_channelCount, - final); - - m_cacheWriteBufferIndex = 0; + sv_frame_t framesToPush = + (m_cacheWriteBufferIndex / m_channelCount) - m_trimFromEnd; + + if (framesToPush <= 0 && !final) { + // This won't do, the buffer is full so we have to push + // something. Should have checked for this earlier + throw std::logic_error("Buffer full but nothing to push"); + } + + pushBuffer(m_cacheWriteBuffer, framesToPush, final); + + m_cacheWriteBufferIndex -= framesToPush * m_channelCount; + + for (sv_frame_t i = 0; i < m_cacheWriteBufferIndex; ++i) { + m_cacheWriteBuffer[i] = + m_cacheWriteBuffer[framesToPush * m_channelCount + i]; + } + + } else { + + pushBuffer(m_cacheWriteBuffer, + m_cacheWriteBufferIndex / m_channelCount, + final); + + m_cacheWriteBufferIndex = 0; + } if (m_cacheFileReader) { m_cacheFileReader->updateFrameCount(); @@ -466,7 +499,7 @@ sv_frame_t padSamples = padFrames * m_channelCount; - SVDEBUG << "pushBufferResampling: frameCount = " << m_frameCount << ", equivFileFrames = " << double(m_frameCount) / ratio << ", m_fileFrameCount = " << m_fileFrameCount << ", padFrames = " << padFrames << ", padSamples = " << padSamples << endl; + SVDEBUG << "CodedAudioFileReader::pushBufferResampling: frameCount = " << m_frameCount << ", equivFileFrames = " << double(m_frameCount) / ratio << ", m_fileFrameCount = " << m_fileFrameCount << ", padFrames = " << padFrames << ", padSamples = " << padSamples << endl; float *padding = new float[padSamples]; for (sv_frame_t i = 0; i < padSamples; ++i) padding[i] = 0.f;
--- a/data/fileio/CodedAudioFileReader.h Tue Nov 29 12:06:49 2016 +0000 +++ b/data/fileio/CodedAudioFileReader.h Tue Nov 29 13:34:51 2016 +0000 @@ -63,7 +63,7 @@ void initialiseDecodeCache(); // samplerate, channels must have been set // compensation for encoder delays: - void setSamplesToTrim(sv_frame_t fromStart, sv_frame_t fromEnd); + void setFramesToTrim(sv_frame_t fromStart, sv_frame_t fromEnd); // may throw InsufficientDiscSpace: void addSamplesToDecodeCache(float **samples, sv_frame_t nframes); @@ -102,7 +102,7 @@ SNDFILE *m_cacheFileWritePtr; WavFileReader *m_cacheFileReader; float *m_cacheWriteBuffer; - sv_frame_t m_cacheWriteBufferIndex; + sv_frame_t m_cacheWriteBufferIndex; // samples sv_frame_t m_cacheWriteBufferSize; // frames Resampler *m_resampler;
--- a/data/fileio/MP3FileReader.cpp Tue Nov 29 12:06:49 2016 +0000 +++ b/data/fileio/MP3FileReader.cpp Tue Nov 29 13:34:51 2016 +0000 @@ -72,7 +72,7 @@ m_reporter = reporter; if (m_gaplessMode == Gapless) { - CodedAudioFileReader::setSamplesToTrim(DEFAULT_DECODER_DELAY, 0); + CodedAudioFileReader::setFramesToTrim(DEFAULT_DECODER_DELAY, 0); } struct stat stat; @@ -375,7 +375,7 @@ return data->reader->filter(stream, frame); } -static string toMagic(uint32_t fourcc) +static string toMagic(unsigned long fourcc) { string magic("...."); for (int i = 0; i < 4; ++i) { @@ -437,8 +437,8 @@ (void)mad_bit_read(&ptr, 8); } - uint32_t delay = mad_bit_read(&ptr, 12); - uint32_t padding = mad_bit_read(&ptr, 12); + auto delay = mad_bit_read(&ptr, 12); + auto padding = mad_bit_read(&ptr, 12); sv_frame_t delayToDrop = DEFAULT_DECODER_DELAY + delay; sv_frame_t paddingToDrop = padding - DEFAULT_DECODER_DELAY; @@ -451,7 +451,7 @@ << " samples from start and " << paddingToDrop << " from end" << endl; - CodedAudioFileReader::setSamplesToTrim(delayToDrop, paddingToDrop); + CodedAudioFileReader::setFramesToTrim(delayToDrop, paddingToDrop); } else { SVDEBUG << "MP3FileReader: Xing frame has no LAME metadata" << endl;