comparison data/fileio/test/AudioFileReaderTest.h @ 759:a43acbe3988f

More refinement in audiofile read tests and implementation
author Chris Cannam
date Fri, 08 Mar 2013 21:35:46 +0000
parents b98f5daab19e
children 2b3a8ae04597
comparison
equal deleted inserted replaced
758:babed5be1ae7 759:a43acbe3988f
87 87
88 int channels = reader->getChannelCount(); 88 int channels = reader->getChannelCount();
89 AudioTestData tdata(readRate, channels); 89 AudioTestData tdata(readRate, channels);
90 90
91 float *reference = tdata.getInterleavedData(); 91 float *reference = tdata.getInterleavedData();
92 int refsize = tdata.getFrameCount() * channels; 92 int refFrames = tdata.getFrameCount();
93 int refsize = refFrames * channels;
93 94
94 vector<float> test; 95 vector<float> test;
95 96
96 // The reader should give us exactly the expected number of 97 // The reader should give us exactly the expected number of
97 // frames, except for mp3 files -- so we ask for one more, 98 // frames, except for mp3/aac files. We ask for quite a lot
98 // just to check we don't get it! 99 // more, though, so we can (a) check that we only get the
99 reader->getInterleavedFrames 100 // expected number back (if this is not mp3/aac) or (b) take
100 (0, tdata.getFrameCount() + 1, test); 101 // into account silence at beginning and end (if it is).
102 reader->getInterleavedFrames(0, refFrames + 5000, test);
101 int read = test.size() / channels; 103 int read = test.size() / channels;
102 104
103 if (extension == "mp3") { 105 if (extension == "mp3" || extension == "aac" || extension == "m4a") {
104 // mp3s round up 106 // mp3s and aacs can have silence at start and end
105 QVERIFY(read >= tdata.getFrameCount()); 107 QVERIFY(read >= refFrames);
106 } else { 108 } else {
107 QCOMPARE(read, tdata.getFrameCount()); 109 QCOMPARE(read, refFrames);
108 } 110 }
109 111
110 // Our limits are pretty relaxed -- we're not testing decoder 112 // Our limits are pretty relaxed -- we're not testing decoder
111 // or resampler quality here, just whether the results are 113 // or resampler quality here, just whether the results are
112 // plainly wrong (e.g. at wrong samplerate or with an offset) 114 // plainly wrong (e.g. at wrong samplerate or with an offset)
113 115
114 float limit = 0.01; 116 float limit = 0.01;
117 float edgeLimit = limit * 10; // in first or final edgeSize frames
118 int edgeSize = 100;
119
115 if (nominalDepth < 16) { 120 if (nominalDepth < 16) {
116 limit = 0.02; 121 limit = 0.02;
117 } 122 }
118 if (extension == "ogg" || extension == "mp3" || extension == "aac") { 123 if (extension == "ogg" || extension == "mp3" ||
119 limit = 0.04; 124 extension == "aac" || extension == "m4a") {
125 limit = 0.2;
126 edgeLimit = limit * 3;
120 } 127 }
121 128
122 int edgeSize = 100; 129 // And we ignore completely the last few frames when upsampling
123 float edgeLimit = limit * 10; // in first or final edgeSize frames 130 int discard = 1 + readRate / nominalRate;
131
132 int offset = 0;
133
134 if (extension == "aac" || extension == "m4a") {
135 // our m4a file appears to have a fixed offset of 1024 (at
136 // file sample rate)
137 offset = (1024 / float(nominalRate)) * readRate;
138 }
139
140 if (extension == "mp3") {
141 // while mp3s appear to vary
142 for (int i = 0; i < read; ++i) {
143 bool any = false;
144 float thresh = 0.01;
145 for (int c = 0; c < channels; ++c) {
146 if (fabsf(test[i * channels + c]) > thresh) {
147 any = true;
148 break;
149 }
150 }
151 if (any) {
152 offset = i;
153 break;
154 }
155 }
156 // std::cerr << "offset = " << offset << std::endl;
157 }
124 158
125 for (int c = 0; c < channels; ++c) { 159 for (int c = 0; c < channels; ++c) {
126 float maxdiff = 0.f; 160 float maxdiff = 0.f;
127 int maxAt = 0; 161 int maxAt = 0;
128 float totdiff = 0.f; 162 float totdiff = 0.f;
129 for (int i = 0; i < read; ++i) { 163 for (int i = 0; i < read - offset - discard && i < refFrames; ++i) {
130 float diff = fabsf(test[i * channels + c] - 164 float diff = fabsf(test[(i + offset) * channels + c] -
131 reference[i * channels + c]); 165 reference[i * channels + c]);
132 totdiff += diff; 166 totdiff += diff;
133 // in edge areas, record this only if it exceeds edgeLimit 167 // in edge areas, record this only if it exceeds edgeLimit
134 if (i < edgeSize || i + edgeSize >= read) { 168 if (i < edgeSize || i + edgeSize >= read - offset) {
135 if (diff > edgeLimit) { 169 if (diff > edgeLimit) {
136 maxdiff = diff; 170 maxdiff = diff;
137 maxAt = i; 171 maxAt = i;
138 } 172 }
139 } else { 173 } else {
144 } 178 }
145 } 179 }
146 float meandiff = totdiff / read; 180 float meandiff = totdiff / read;
147 // cerr << "meandiff on channel " << c << ": " << meandiff << endl; 181 // cerr << "meandiff on channel " << c << ": " << meandiff << endl;
148 // cerr << "maxdiff on channel " << c << ": " << maxdiff << " at " << maxAt << endl; 182 // cerr << "maxdiff on channel " << c << ": " << maxdiff << " at " << maxAt << endl;
183 if (meandiff >= limit) {
184 cerr << "ERROR: for audiofile " << audiofile << ": mean diff = " << meandiff << " for channel " << c << endl;
185 QVERIFY(meandiff < limit);
186 }
149 if (maxdiff >= limit) { 187 if (maxdiff >= limit) {
150 cerr << "ERROR: for audiofile " << audiofile << ": maxdiff = " << maxdiff << " at frame " << maxAt << " of " << read << " on channel " << c << " (mean diff = " << meandiff << ")" << endl; 188 cerr << "ERROR: for audiofile " << audiofile << ": max diff = " << maxdiff << " at frame " << maxAt << " of " << read << " on channel " << c << " (mean diff = " << meandiff << ")" << endl;
151 QVERIFY(maxdiff < limit); 189 QVERIFY(maxdiff < limit);
152 } 190 }
153 } 191 }
154 } 192 }
155 }; 193 };