# HG changeset patch # User Chris Cannam # Date 1362778546 0 # Node ID a43acbe3988f0e4603135023c046bc8098b028aa # Parent babed5be1ae741411bd8aee43fd793952ae633f8 More refinement in audiofile read tests and implementation diff -r babed5be1ae7 -r a43acbe3988f data/fileio/CodedAudioFileReader.cpp --- a/data/fileio/CodedAudioFileReader.cpp Fri Mar 08 20:05:49 2013 +0000 +++ b/data/fileio/CodedAudioFileReader.cpp Fri Mar 08 21:35:46 2013 +0000 @@ -270,11 +270,11 @@ return; } - if (m_cacheWriteBufferIndex > 0) { +// if (m_cacheWriteBufferIndex > 0) { pushBuffer(m_cacheWriteBuffer, m_cacheWriteBufferIndex / m_channelCount, true); - } +// } delete[] m_cacheWriteBuffer; m_cacheWriteBuffer = 0; @@ -349,14 +349,19 @@ CodedAudioFileReader::pushBufferResampling(float *buffer, size_t sz, float ratio, bool final) { - size_t out = m_resampler->resampleInterleaved - (buffer, - m_resampleBuffer, - sz, - ratio, - false); + SVDEBUG << "pushBufferResampling: ratio = " << ratio << ", sz = " << sz << ", final = " << final << endl; - pushBufferNonResampling(m_resampleBuffer, out); + if (sz > 0) { + + size_t out = m_resampler->resampleInterleaved + (buffer, + m_resampleBuffer, + sz, + ratio, + false); + + pushBufferNonResampling(m_resampleBuffer, out); + } if (final) { @@ -367,18 +372,22 @@ size_t padSamples = padFrames * m_channelCount; - std::cerr << "frameCount = " << m_frameCount << ", equivFileFrames = " << m_frameCount / ratio << ", m_fileFrameCount = " << m_fileFrameCount << ", padFrames= " << padFrames << ", padSamples = " << padSamples << std::endl; + SVDEBUG << "frameCount = " << m_frameCount << ", equivFileFrames = " << m_frameCount / ratio << ", m_fileFrameCount = " << m_fileFrameCount << ", padFrames= " << padFrames << ", padSamples = " << padSamples << endl; float *padding = new float[padSamples]; for (int i = 0; i < padSamples; ++i) padding[i] = 0.f; - out = m_resampler->resampleInterleaved + size_t out = m_resampler->resampleInterleaved (padding, m_resampleBuffer, padFrames, ratio, true); + if (m_frameCount + out > int(m_fileFrameCount * ratio)) { + out = int(m_fileFrameCount * ratio) - m_frameCount; + } + pushBufferNonResampling(m_resampleBuffer, out); delete[] padding; } diff -r babed5be1ae7 -r a43acbe3988f data/fileio/CoreAudioFileReader.cpp --- a/data/fileio/CoreAudioFileReader.cpp Fri Mar 08 20:05:49 2013 +0000 +++ b/data/fileio/CoreAudioFileReader.cpp Fri Mar 08 21:35:46 2013 +0000 @@ -74,7 +74,7 @@ Profiler profiler("CoreAudioFileReader::CoreAudioFileReader", true); - std::cerr << "CoreAudioFileReader: path is \"" << m_path.toStdString() << "\"" << std::endl; + SVDEBUG << "CoreAudioFileReader: path is \"" << m_path.toStdString() << "\"" << endl; QByteArray ba = m_path.toLocal8Bit(); @@ -120,9 +120,7 @@ m_channelCount = m_d->asbd.mChannelsPerFrame; m_fileRate = m_d->asbd.mSampleRate; - std::cerr << "CoreAudioReadStream: " << m_channelCount << " channels, " << m_sampleRate << " Hz" << std::endl; - - m_d->asbd.mSampleRate = getSampleRate(); + std::cerr << "CoreAudioReadStream: " << m_channelCount << " channels, " << m_fileRate << " Hz" << std::endl; m_d->asbd.mFormatID = kAudioFormatLinearPCM; m_d->asbd.mFormatFlags = diff -r babed5be1ae7 -r a43acbe3988f data/fileio/test/AudioFileReaderTest.h --- a/data/fileio/test/AudioFileReaderTest.h Fri Mar 08 20:05:49 2013 +0000 +++ b/data/fileio/test/AudioFileReaderTest.h Fri Mar 08 21:35:46 2013 +0000 @@ -89,22 +89,24 @@ AudioTestData tdata(readRate, channels); float *reference = tdata.getInterleavedData(); - int refsize = tdata.getFrameCount() * channels; + int refFrames = tdata.getFrameCount(); + int refsize = refFrames * channels; vector test; // The reader should give us exactly the expected number of - // frames, except for mp3 files -- so we ask for one more, - // just to check we don't get it! - reader->getInterleavedFrames - (0, tdata.getFrameCount() + 1, test); + // frames, except for mp3/aac files. We ask for quite a lot + // more, though, so we can (a) check that we only get the + // expected number back (if this is not mp3/aac) or (b) take + // into account silence at beginning and end (if it is). + reader->getInterleavedFrames(0, refFrames + 5000, test); int read = test.size() / channels; - if (extension == "mp3") { - // mp3s round up - QVERIFY(read >= tdata.getFrameCount()); + if (extension == "mp3" || extension == "aac" || extension == "m4a") { + // mp3s and aacs can have silence at start and end + QVERIFY(read >= refFrames); } else { - QCOMPARE(read, tdata.getFrameCount()); + QCOMPARE(read, refFrames); } // Our limits are pretty relaxed -- we're not testing decoder @@ -112,26 +114,58 @@ // plainly wrong (e.g. at wrong samplerate or with an offset) float limit = 0.01; + float edgeLimit = limit * 10; // in first or final edgeSize frames + int edgeSize = 100; + if (nominalDepth < 16) { limit = 0.02; } - if (extension == "ogg" || extension == "mp3" || extension == "aac") { - limit = 0.04; + if (extension == "ogg" || extension == "mp3" || + extension == "aac" || extension == "m4a") { + limit = 0.2; + edgeLimit = limit * 3; } - int edgeSize = 100; - float edgeLimit = limit * 10; // in first or final edgeSize frames + // And we ignore completely the last few frames when upsampling + int discard = 1 + readRate / nominalRate; + + int offset = 0; + + if (extension == "aac" || extension == "m4a") { + // our m4a file appears to have a fixed offset of 1024 (at + // file sample rate) + offset = (1024 / float(nominalRate)) * readRate; + } + + if (extension == "mp3") { + // while mp3s appear to vary + for (int i = 0; i < read; ++i) { + bool any = false; + float thresh = 0.01; + for (int c = 0; c < channels; ++c) { + if (fabsf(test[i * channels + c]) > thresh) { + any = true; + break; + } + } + if (any) { + offset = i; + break; + } + } +// std::cerr << "offset = " << offset << std::endl; + } for (int c = 0; c < channels; ++c) { float maxdiff = 0.f; int maxAt = 0; float totdiff = 0.f; - for (int i = 0; i < read; ++i) { - float diff = fabsf(test[i * channels + c] - + for (int i = 0; i < read - offset - discard && i < refFrames; ++i) { + float diff = fabsf(test[(i + offset) * channels + c] - reference[i * channels + c]); totdiff += diff; // in edge areas, record this only if it exceeds edgeLimit - if (i < edgeSize || i + edgeSize >= read) { + if (i < edgeSize || i + edgeSize >= read - offset) { if (diff > edgeLimit) { maxdiff = diff; maxAt = i; @@ -146,8 +180,12 @@ float meandiff = totdiff / read; // cerr << "meandiff on channel " << c << ": " << meandiff << endl; // cerr << "maxdiff on channel " << c << ": " << maxdiff << " at " << maxAt << endl; + if (meandiff >= limit) { + cerr << "ERROR: for audiofile " << audiofile << ": mean diff = " << meandiff << " for channel " << c << endl; + QVERIFY(meandiff < limit); + } if (maxdiff >= limit) { - cerr << "ERROR: for audiofile " << audiofile << ": maxdiff = " << maxdiff << " at frame " << maxAt << " of " << read << " on channel " << c << " (mean diff = " << meandiff << ")" << endl; + cerr << "ERROR: for audiofile " << audiofile << ": max diff = " << maxdiff << " at frame " << maxAt << " of " << read << " on channel " << c << " (mean diff = " << meandiff << ")" << endl; QVERIFY(maxdiff < limit); } } diff -r babed5be1ae7 -r a43acbe3988f data/fileio/test/testfiles/32000-1.aac Binary file data/fileio/test/testfiles/32000-1.aac has changed diff -r babed5be1ae7 -r a43acbe3988f data/fileio/test/testfiles/32000-1.m4a Binary file data/fileio/test/testfiles/32000-1.m4a has changed diff -r babed5be1ae7 -r a43acbe3988f data/fileio/test/testfiles/44100-2.aac Binary file data/fileio/test/testfiles/44100-2.aac has changed diff -r babed5be1ae7 -r a43acbe3988f data/fileio/test/testfiles/44100-2.m4a Binary file data/fileio/test/testfiles/44100-2.m4a has changed