changeset 757:b98f5daab19e

More on tests, and not the right way to do it with end of resampled file
author Chris Cannam
date Fri, 08 Mar 2013 18:19:05 +0000
parents 02390a4c2abe
children babed5be1ae7
files data/fileio/CodedAudioFileReader.cpp data/fileio/CodedAudioFileReader.h data/fileio/test/AudioFileReaderTest.h
diffstat 3 files changed, 78 insertions(+), 17 deletions(-) [+]
line wrap: on
line diff
--- a/data/fileio/CodedAudioFileReader.cpp	Fri Mar 08 16:14:21 2013 +0000
+++ b/data/fileio/CodedAudioFileReader.cpp	Fri Mar 08 18:19:05 2013 +0000
@@ -39,7 +39,8 @@
     m_cacheWriteBufferIndex(0),
     m_cacheWriteBufferSize(16384),
     m_resampler(0),
-    m_resampleBuffer(0)
+    m_resampleBuffer(0),
+    m_fileFrameCount(0)
 {
     SVDEBUG << "CodedAudioFileReader::CodedAudioFileReader: rate " << targetRate << endl;
 
@@ -104,7 +105,7 @@
         SVDEBUG << "CodedAudioFileReader::initialiseDecodeCache: rate (from file) = " << m_fileRate << endl;
     }
     if (m_fileRate != m_sampleRate) {
-        std::cerr << "CodedAudioFileReader: resampling " << m_fileRate << " -> " <<  m_sampleRate << std::endl;
+        SVDEBUG << "CodedAudioFileReader: resampling " << m_fileRate << " -> " <<  m_sampleRate << endl;
         m_resampler = new Resampler(Resampler::FastestTolerable,
                                     m_channelCount,
                                     m_cacheWriteBufferSize);
@@ -297,10 +298,14 @@
     float max = 1.0;
     size_t count = sz * m_channelCount;
 
+    m_fileFrameCount += sz;
+
+    float ratio = 1.f;
+
     if (m_resampler && m_fileRate != 0) {
         
-        float ratio = float(m_sampleRate) / float(m_fileRate);
-
+        ratio = float(m_sampleRate) / float(m_fileRate);
+        
         if (ratio != 1.f) {
 
             size_t out = m_resampler->resampleInterleaved
@@ -344,6 +349,23 @@
         m_dataLock.unlock();
         break;
     }
+
+    if (final && m_resampler && ratio != 1.f) {
+        size_t equivFileFrames = m_frameCount / ratio;
+        if (equivFileFrames < m_fileFrameCount) {
+            size_t padFrames = m_fileFrameCount - equivFileFrames + 32;
+            size_t padSamples = padFrames * m_channelCount;
+            std::cerr << "frameCount = " << m_frameCount << ", equivFileFrames = " << equivFileFrames << ", m_fileFrameCount = " << m_fileFrameCount << ", padFrames= " << padFrames << ", padSamples = " << padSamples << std::endl;
+            float *padding = new float[padSamples];
+            for (int i = 0; i < padSamples; ++i) padding[i] = 0.f;
+
+            //!!! these are not file frames (ugh this is horrible)
+            m_fileFrameCount -= padFrames;
+
+            pushBuffer(padding, padFrames, true);
+            delete[] padding;
+        }
+    }
 }
 
 void
--- a/data/fileio/CodedAudioFileReader.h	Fri Mar 08 16:14:21 2013 +0000
+++ b/data/fileio/CodedAudioFileReader.h	Fri Mar 08 18:19:05 2013 +0000
@@ -85,6 +85,7 @@
 
     Resampler *m_resampler;
     float *m_resampleBuffer;
+    size_t m_fileFrameCount;
 };
 
 #endif
--- a/data/fileio/test/AudioFileReaderTest.h	Fri Mar 08 16:14:21 2013 +0000
+++ b/data/fileio/test/AudioFileReaderTest.h	Fri Mar 08 18:19:05 2013 +0000
@@ -63,16 +63,30 @@
     {
         QFETCH(QString, audiofile);
 
+        int readRate = 48000;
+
 	AudioFileReader *reader =
 	    AudioFileReaderFactory::createReader
-	    (audioDir + "/" + audiofile, 48000);
+	    (audioDir + "/" + audiofile, readRate);
+
+        QStringList fileAndExt = audiofile.split(".");
+        QStringList bits = fileAndExt[0].split("-");
+        QString extension = fileAndExt[1];
+        int nominalRate = bits[0].toInt();
+        int nominalChannels = bits[1].toInt();
+        int nominalDepth = 16;
+        if (bits.length() > 2) nominalDepth = bits[2].toInt();
 
 	if (!reader) {
-	    QSKIP(strOf(QString("File format for \"%1\" not supported, skipping").arg(audiofile)), SkipSingle);
+	    QSKIP("Unsupported file, skipping", SkipSingle);
 	}
 
+        QCOMPARE((int)reader->getChannelCount(), nominalChannels);
+        QCOMPARE((int)reader->getNativeRate(), nominalRate);
+        QCOMPARE((int)reader->getSampleRate(), readRate);
+
 	int channels = reader->getChannelCount();
-	AudioTestData tdata(48000, channels);
+	AudioTestData tdata(readRate, channels);
 	
 	float *reference = tdata.getInterleavedData();
 	int refsize = tdata.getFrameCount() * channels;
@@ -80,17 +94,33 @@
 	vector<float> test;
 	
 	// The reader should give us exactly the expected number of
-	// frames -- so we ask for one more, just to check we don't
-	// get it!
+	// 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);
 	int read = test.size() / channels;
-     
-	// need to resolve questions about frame count at end of
-	// resampled file before we can do this
-//!!!	QCOMPARE(read, tdata.getFrameCount());
 
-	float limit = 0.011;
+        if (extension == "mp3") {
+            // mp3s round up
+            QVERIFY(read >= tdata.getFrameCount());
+        } else {
+            QCOMPARE(read, tdata.getFrameCount());
+        }
+
+        // Our limits are pretty relaxed -- we're not testing decoder
+        // or resampler quality here, just whether the results are
+        // plainly wrong (e.g. at wrong samplerate or with an offset)
+
+	float limit = 0.01;
+        if (nominalDepth < 16) {
+            limit = 0.02;
+        }
+        if (extension == "ogg" || extension == "mp3" || extension == "aac") {
+            limit = 0.04;
+        }
+
+        int edgeSize = 100; 
+        float edgeLimit = limit * 10; // in first or final edgeSize frames
 
 	for (int c = 0; c < channels; ++c) {
 	    float maxdiff = 0.f;
@@ -100,9 +130,17 @@
 		float diff = fabsf(test[i * channels + c] -
 				   reference[i * channels + c]);
 		totdiff += diff;
-		if (diff > maxdiff) {
-		    maxdiff = diff;
-		    maxAt = i;
+                // in edge areas, record this only if it exceeds edgeLimit
+                if (i < edgeSize || i + edgeSize >= read) {
+                    if (diff > edgeLimit) {
+                        maxdiff = diff;
+                        maxAt = i;
+                    }
+                } else {
+                    if (diff > maxdiff) {
+                        maxdiff = diff;
+                        maxAt = i;
+                    }
 		}
 	    }
 	    float meandiff = totdiff / read;