Mercurial > hg > svcore
comparison data/fileio/test/EncodingTest.h @ 1359:1c9bbbb6116a 3.0-integration
Use W64 instead of WAV for decoded files; use Ogg reader in preference to WAV one for Ogg files (WAV reader works, via libsndfile, but doesn't load metadata); fix Ogg reader to use QFile open instead of non-Win32-compatible API; add more encoder tests, audio writer test, midi reader test
author | Chris Cannam |
---|---|
date | Tue, 10 Jan 2017 10:58:25 +0000 |
parents | 281a8c9d4886 |
children | 8eddb528ef0c |
comparison
equal
deleted
inserted
replaced
1358:b7be05d57f0a | 1359:1c9bbbb6116a |
---|---|
18 // Quick tests for filename encodings and encoding of ID3 data. Not a | 18 // Quick tests for filename encodings and encoding of ID3 data. Not a |
19 // test of audio codecs. | 19 // test of audio codecs. |
20 | 20 |
21 #include "../AudioFileReaderFactory.h" | 21 #include "../AudioFileReaderFactory.h" |
22 #include "../AudioFileReader.h" | 22 #include "../AudioFileReader.h" |
23 #include "../WavFileWriter.h" | |
23 | 24 |
24 #include <cmath> | 25 #include <cmath> |
25 | 26 |
26 #include <QObject> | 27 #include <QObject> |
27 #include <QtTest> | 28 #include <QtTest> |
34 const char utf8_name_cdp_1[] = "Caf\303\251 de Paris"; | 35 const char utf8_name_cdp_1[] = "Caf\303\251 de Paris"; |
35 const char utf8_name_cdp_2[] = "Caf\303\251 de \351\207\215\345\272\206"; | 36 const char utf8_name_cdp_2[] = "Caf\303\251 de \351\207\215\345\272\206"; |
36 const char utf8_name_tsprk[] = "T\303\253mple of Sp\303\266rks"; | 37 const char utf8_name_tsprk[] = "T\303\253mple of Sp\303\266rks"; |
37 const char utf8_name_sprkt[] = "\343\202\271\343\203\235\343\203\274\343\202\257\343\201\256\345\257\272\351\231\242"; | 38 const char utf8_name_sprkt[] = "\343\202\271\343\203\235\343\203\274\343\202\257\343\201\256\345\257\272\351\231\242"; |
38 | 39 |
40 // Mapping between filename and expected title metadata field | |
39 static const char *mapping[][2] = { | 41 static const char *mapping[][2] = { |
40 { "id3v2-iso-8859-1", utf8_name_cdp_1 }, | 42 { "id3v2-iso-8859-1", utf8_name_cdp_1 }, |
41 { "id3v2-ucs-2", utf8_name_cdp_2 }, | 43 { "id3v2-ucs-2", utf8_name_cdp_2 }, |
42 { utf8_name_tsprk, utf8_name_tsprk }, | 44 { utf8_name_tsprk, utf8_name_tsprk }, |
43 { utf8_name_sprkt, utf8_name_sprkt }, | 45 { utf8_name_sprkt, utf8_name_sprkt }, |
49 Q_OBJECT | 51 Q_OBJECT |
50 | 52 |
51 private: | 53 private: |
52 QString testDirBase; | 54 QString testDirBase; |
53 QString encodingDir; | 55 QString encodingDir; |
56 QString outDir; | |
54 | 57 |
55 public: | 58 public: |
56 EncodingTest(QString base) { | 59 EncodingTest(QString base) { |
57 if (base == "") { | 60 if (base == "") { |
58 base = "svcore/data/fileio/test"; | 61 base = "svcore/data/fileio/test"; |
59 } | 62 } |
60 testDirBase = base; | 63 testDirBase = base; |
61 encodingDir = base + "/encodings"; | 64 encodingDir = base + "/encodings"; |
65 outDir = base + "/outfiles"; | |
62 } | 66 } |
63 | 67 |
64 private: | 68 private: |
65 const char *strOf(QString s) { | 69 const char *strOf(QString s) { |
66 return strdup(s.toLocal8Bit().data()); | 70 return strdup(s.toLocal8Bit().data()); |
71 } | |
72 | |
73 void addAudioFiles() { | |
74 QTest::addColumn<QString>("audiofile"); | |
75 QStringList files = QDir(encodingDir).entryList(QDir::Files); | |
76 foreach (QString filename, files) { | |
77 QTest::newRow(strOf(filename)) << filename; | |
78 } | |
67 } | 79 } |
68 | 80 |
69 private slots: | 81 private slots: |
70 void init() | 82 void init() |
71 { | 83 { |
72 if (!QDir(encodingDir).exists()) { | 84 if (!QDir(encodingDir).exists()) { |
73 cerr << "ERROR: Audio encoding file directory \"" << encodingDir << "\" does not exist" << endl; | 85 cerr << "ERROR: Audio encoding file directory \"" << encodingDir << "\" does not exist" << endl; |
74 QVERIFY2(QDir(encodingDir).exists(), "Audio encoding file directory not found"); | 86 QVERIFY2(QDir(encodingDir).exists(), "Audio encoding file directory not found"); |
75 } | 87 } |
76 } | 88 if (!QDir(outDir).exists() && !QDir().mkpath(outDir)) { |
77 | 89 cerr << "ERROR: Audio out directory \"" << outDir << "\" does not exist and could not be created" << endl; |
78 void read_data() | 90 QVERIFY2(QDir(outDir).exists(), "Audio out directory not found and could not be created"); |
79 { | 91 } |
80 QTest::addColumn<QString>("audiofile"); | 92 } |
81 QStringList files = QDir(encodingDir).entryList(QDir::Files); | 93 |
82 foreach (QString filename, files) { | 94 void readAudio_data() { |
83 QTest::newRow(strOf(filename)) << filename; | 95 addAudioFiles(); |
84 } | 96 } |
85 } | 97 |
86 | 98 void readAudio() { |
87 void read() | 99 |
88 { | 100 // Ensure that we can open all the files |
101 | |
89 QFETCH(QString, audiofile); | 102 QFETCH(QString, audiofile); |
90 | 103 |
91 AudioFileReaderFactory::Parameters params; | 104 AudioFileReaderFactory::Parameters params; |
92 AudioFileReader *reader = | 105 AudioFileReader *reader = |
93 AudioFileReaderFactory::createReader | 106 AudioFileReaderFactory::createReader |
94 (encodingDir + "/" + audiofile, params); | 107 (encodingDir + "/" + audiofile, params); |
95 | 108 |
96 QVERIFY(reader != nullptr); | 109 QVERIFY(reader != nullptr); |
110 } | |
111 | |
112 void readMetadata_data() { | |
113 addAudioFiles(); | |
114 } | |
115 | |
116 void readMetadata() { | |
117 | |
118 // All files other than WAVs should have title metadata; check | |
119 // that the title matches whatever is in our mapping structure | |
120 // defined at the top | |
121 | |
122 QFETCH(QString, audiofile); | |
123 | |
124 AudioFileReaderFactory::Parameters params; | |
125 AudioFileReader *reader = | |
126 AudioFileReaderFactory::createReader | |
127 (encodingDir + "/" + audiofile, params); | |
128 | |
129 QVERIFY(reader != nullptr); | |
97 | 130 |
98 QStringList fileAndExt = audiofile.split("."); | 131 QStringList fileAndExt = audiofile.split("."); |
99 QString file = fileAndExt[0]; | 132 QString file = fileAndExt[0]; |
100 QString extension = fileAndExt[1]; | 133 QString extension = fileAndExt[1]; |
101 | 134 |
102 if (extension == "mp3") { | 135 if (extension != "wav") { |
103 | 136 |
137 auto blah = reader->getInterleavedFrames(0, 10); | |
138 | |
104 QString title = reader->getTitle(); | 139 QString title = reader->getTitle(); |
105 QVERIFY(title != QString()); | 140 QVERIFY(title != QString()); |
106 | 141 |
107 bool found = false; | 142 bool found = false; |
108 for (int m = 0; m < mappingCount; ++m) { | 143 for (int m = 0; m < mappingCount; ++m) { |
126 break; | 161 break; |
127 } | 162 } |
128 } | 163 } |
129 | 164 |
130 if (!found) { | 165 if (!found) { |
166 // Note that this can happen legitimately on Windows, | |
167 // where (for annoying VCS-related reasons) the test | |
168 // files may have a different filename encoding from | |
169 // the expected UTF-16. We check this properly in | |
170 // readWriteAudio below, by saving out the file to a | |
171 // name matching the metadata | |
131 cerr << "Couldn't find filename \"" | 172 cerr << "Couldn't find filename \"" |
132 << file << "\" in title mapping array" << endl; | 173 << file << "\" in title mapping array" << endl; |
133 QSKIP("Couldn't find filename in title mapping array"); | 174 QSKIP("Couldn't find filename in title mapping array"); |
134 } | 175 } |
135 } | 176 } |
136 } | 177 } |
178 | |
179 void readWriteAudio_data() { | |
180 addAudioFiles(); | |
181 } | |
182 | |
183 void readWriteAudio() | |
184 { | |
185 // For those files that have title metadata (i.e. all of them | |
186 // except the WAVs), read the title metadata and write a wav | |
187 // file (of arbitrary content) whose name matches that. Then | |
188 // check that we can re-read it. This is intended to exercise | |
189 // systems on which the original test filename is miscoded (as | |
190 // can happen on Windows). | |
191 | |
192 QFETCH(QString, audiofile); | |
193 | |
194 QStringList fileAndExt = audiofile.split("."); | |
195 QString file = fileAndExt[0]; | |
196 QString extension = fileAndExt[1]; | |
197 | |
198 if (extension == "wav") { | |
199 return; | |
200 } | |
201 | |
202 AudioFileReaderFactory::Parameters params; | |
203 AudioFileReader *reader = | |
204 AudioFileReaderFactory::createReader | |
205 (encodingDir + "/" + audiofile, params); | |
206 QVERIFY(reader != nullptr); | |
207 | |
208 QString title = reader->getTitle(); | |
209 QVERIFY(title != QString()); | |
210 | |
211 for (int useTemporary = 0; useTemporary <= 1; ++useTemporary) { | |
212 | |
213 QString outfile = outDir + "/" + file + ".wav"; | |
214 WavFileWriter writer(outfile, | |
215 reader->getSampleRate(), | |
216 1, | |
217 useTemporary ? | |
218 WavFileWriter::WriteToTemporary : | |
219 WavFileWriter::WriteToTarget); | |
220 | |
221 QVERIFY(writer.isOK()); | |
222 | |
223 floatvec_t data { 0.0, 1.0, 0.0, -1.0, 0.0, 1.0, 0.0, -1.0 }; | |
224 const float *samples = data.data(); | |
225 bool ok = writer.writeSamples(&samples, 8); | |
226 QVERIFY(ok); | |
227 | |
228 ok = writer.close(); | |
229 QVERIFY(ok); | |
230 | |
231 AudioFileReader *rereader = | |
232 AudioFileReaderFactory::createReader(outfile, params); | |
233 QVERIFY(rereader != nullptr); | |
234 | |
235 floatvec_t readFrames = rereader->getInterleavedFrames(0, 8); | |
236 QCOMPARE(readFrames, data); | |
237 | |
238 delete rereader; | |
239 } | |
240 | |
241 delete reader; | |
242 } | |
137 }; | 243 }; |
138 | 244 |
139 #endif | 245 #endif |