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) {