Mercurial > hg > svcore
comparison data/fileio/test/AudioFileReaderTest.h @ 1296:fc9cef5e988d 3.0-integration
Improve mp3 offset detection, add test for truncated decode
| author | Chris Cannam | 
|---|---|
| date | Fri, 25 Nov 2016 11:33:34 +0000 | 
| parents | abfc498c52bc | 
| children | 80c77916fe85 | 
   comparison
  equal
  deleted
  inserted
  replaced
| 1295:4704e834d0f9 | 1296:fc9cef5e988d | 
|---|---|
| 121 if (nominalDepth < 16) { | 121 if (nominalDepth < 16) { | 
| 122 limit = 0.02; | 122 limit = 0.02; | 
| 123 } | 123 } | 
| 124 if (extension == "ogg" || extension == "mp3" || | 124 if (extension == "ogg" || extension == "mp3" || | 
| 125 extension == "aac" || extension == "m4a") { | 125 extension == "aac" || extension == "m4a") { | 
| 126 limit = 0.2; | 126 limit = 0.1; | 
| 127 edgeLimit = limit * 3; | 127 edgeLimit = limit * 3; | 
| 128 } | 128 } | 
| 129 | 129 | 
| 130 // And we ignore completely the last few frames when upsampling | 130 // And we ignore completely the last few frames when upsampling | 
| 131 int discard = 1 + int(round(readRate / nominalRate)); | 131 int discard = 1 + int(round(readRate / nominalRate)); | 
| 137 // file sample rate) | 137 // file sample rate) | 
| 138 offset = int(round((1024 / nominalRate) * readRate)); | 138 offset = int(round((1024 / nominalRate) * readRate)); | 
| 139 } | 139 } | 
| 140 | 140 | 
| 141 if (extension == "mp3") { | 141 if (extension == "mp3") { | 
| 142 // while mp3s appear to vary | 142 // ...while mp3s appear to vary. What we're looking for is | 
| 143 for (int i = 0; i < read; ++i) { | 143 // the first peak of the sinusoid in the first channel | 
| 144 bool any = false; | 144 // (since we may have only the one channel). This should | 
| 145 double thresh = 0.01; | 145 // appear at 0.4ms (see AudioTestData.h) | 
| 146 for (int c = 0; c < channels; ++c) { | 146 int expectedPeak = int(0.0004 * readRate); | 
| 147 if (fabs(test[i * channels + c]) > thresh) { | 147 // std::cerr << "expectedPeak = " << expectedPeak << std::endl; | 
| 148 any = true; | 148 for (int i = 1; i < read; ++i) { | 
| 149 break; | 149 if (test[i * channels] > 0.8 && | 
| 150 } | 150 test[(i+1) * channels] < test[i * channels]) { | 
| 151 } | 151 offset = i - expectedPeak - 1; | 
| 152 if (any) { | 152 // std::cerr << "actual peak = " << i-1 << std::endl; | 
| 153 offset = i; | |
| 154 break; | 153 break; | 
| 155 } | 154 } | 
| 156 } | 155 } | 
| 157 // std::cerr << "offset = " << offset << std::endl; | 156 // std::cerr << "offset = " << offset << std::endl; | 
| 158 } | 157 } | 
| 159 | 158 | 
| 160 for (int c = 0; c < channels; ++c) { | 159 for (int c = 0; c < channels; ++c) { | 
| 161 float maxdiff = 0.f; | 160 float maxdiff = 0.f; | 
| 162 int maxAt = 0; | 161 int maxAt = 0; | 
| 163 float totdiff = 0.f; | 162 float totdiff = 0.f; | 
| 164 for (int i = 0; i < read - offset - discard && i < refFrames; ++i) { | 163 for (int i = 0; i < refFrames; ++i) { | 
| 165 float diff = fabsf(test[(i + offset) * channels + c] - | 164 int ix = i + offset; | 
| 165 if (ix >= read) { | |
| 166 cerr << "ERROR: audiofile " << audiofile << " reads truncated (read-rate reference frames " << i << " onward are lost)" << endl; | |
| 167 QVERIFY(ix < read); | |
| 168 } | |
| 169 if (ix + discard >= read) { | |
| 170 // we forgive the very edge samples when | |
| 171 // resampling (discard > 0) | |
| 172 continue; | |
| 173 } | |
| 174 float diff = fabsf(test[(ix) * channels + c] - | |
| 166 reference[i * channels + c]); | 175 reference[i * channels + c]); | 
| 167 totdiff += diff; | 176 totdiff += diff; | 
| 168 // in edge areas, record this only if it exceeds edgeLimit | 177 // in edge areas, record this only if it exceeds edgeLimit | 
| 169 if (i < edgeSize || i + edgeSize >= read - offset) { | 178 if (i < edgeSize || i + edgeSize >= read - offset) { | 
| 170 if (diff > edgeLimit && diff > maxdiff) { | 179 if (diff > edgeLimit && diff > maxdiff) { | 
