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