Mercurial > hg > svcore
comparison data/fileio/test/EncodingTest.h @ 1527:710e6250a401 zoom
Merge from default branch
author | Chris Cannam |
---|---|
date | Mon, 17 Sep 2018 13:51:14 +0100 |
parents | 87ae75da6527 |
children | 0773b34d987f |
comparison
equal
deleted
inserted
replaced
1324:d4a28d1479a8 | 1527:710e6250a401 |
---|---|
1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ | |
2 | |
3 /* | |
4 Sonic Visualiser | |
5 An audio file viewer and annotation editor. | |
6 Centre for Digital Music, Queen Mary, University of London. | |
7 | |
8 This program is free software; you can redistribute it and/or | |
9 modify it under the terms of the GNU General Public License as | |
10 published by the Free Software Foundation; either version 2 of the | |
11 License, or (at your option) any later version. See the file | |
12 COPYING included with this distribution for more information. | |
13 */ | |
14 | |
15 #ifndef TEST_AUDIO_ENCODINGS_H | |
16 #define TEST_AUDIO_ENCODINGS_H | |
17 | |
18 // Quick tests for filename encodings and encoding of ID3 data. Not a | |
19 // test of audio codecs. | |
20 | |
21 #include "../AudioFileReaderFactory.h" | |
22 #include "../AudioFileReader.h" | |
23 #include "../WavFileWriter.h" | |
24 | |
25 #include <cmath> | |
26 | |
27 #include <QObject> | |
28 #include <QtTest> | |
29 #include <QDir> | |
30 | |
31 #include <iostream> | |
32 | |
33 using namespace std; | |
34 | |
35 const char utf8_name_cdp_1[] = "Caf\303\251 de Paris"; | |
36 const char utf8_name_cdp_2[] = "Caf\303\251 de \351\207\215\345\272\206"; | |
37 const char utf8_name_tsprk[] = "T\303\253mple of Sp\303\266rks"; | |
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"; | |
39 | |
40 // Mapping between filename and expected title metadata field | |
41 static const char *mapping[][2] = { | |
42 { "id3v2-iso-8859-1", utf8_name_cdp_1 }, | |
43 { "id3v2-ucs-2", utf8_name_cdp_2 }, | |
44 { utf8_name_tsprk, utf8_name_tsprk }, | |
45 { utf8_name_sprkt, utf8_name_sprkt }, | |
46 }; | |
47 static const int mappingCount = 4; | |
48 | |
49 class EncodingTest : public QObject | |
50 { | |
51 Q_OBJECT | |
52 | |
53 private: | |
54 QString testDirBase; | |
55 QString encodingDir; | |
56 QString outDir; | |
57 | |
58 public: | |
59 EncodingTest(QString base) { | |
60 if (base == "") { | |
61 base = "svcore/data/fileio/test"; | |
62 } | |
63 testDirBase = base; | |
64 encodingDir = base + "/encodings"; | |
65 outDir = base + "/outfiles"; | |
66 } | |
67 | |
68 private: | |
69 const char *strOf(QString s) { | |
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 } | |
79 } | |
80 | |
81 private slots: | |
82 void init() | |
83 { | |
84 if (!QDir(encodingDir).exists()) { | |
85 SVCERR << "ERROR: Audio encoding file directory \"" << encodingDir << "\" does not exist" << endl; | |
86 QVERIFY2(QDir(encodingDir).exists(), "Audio encoding file directory not found"); | |
87 } | |
88 if (!QDir(outDir).exists() && !QDir().mkpath(outDir)) { | |
89 SVCERR << "ERROR: Audio out directory \"" << outDir << "\" does not exist and could not be created" << endl; | |
90 QVERIFY2(QDir(outDir).exists(), "Audio out directory not found and could not be created"); | |
91 } | |
92 } | |
93 | |
94 void readAudio_data() { | |
95 addAudioFiles(); | |
96 } | |
97 | |
98 void readAudio() { | |
99 | |
100 // Ensure that we can open all the files | |
101 | |
102 QFETCH(QString, audiofile); | |
103 | |
104 AudioFileReaderFactory::Parameters params; | |
105 AudioFileReader *reader = | |
106 AudioFileReaderFactory::createReader | |
107 (encodingDir + "/" + audiofile, params); | |
108 | |
109 QVERIFY(reader != nullptr); | |
110 | |
111 delete reader; | |
112 } | |
113 | |
114 void readMetadata_data() { | |
115 addAudioFiles(); | |
116 } | |
117 | |
118 void readMetadata() { | |
119 | |
120 // All files other than WAVs should have title metadata; check | |
121 // that the title matches whatever is in our mapping structure | |
122 // defined at the top | |
123 | |
124 QFETCH(QString, audiofile); | |
125 | |
126 AudioFileReaderFactory::Parameters params; | |
127 AudioFileReader *reader = | |
128 AudioFileReaderFactory::createReader | |
129 (encodingDir + "/" + audiofile, params); | |
130 | |
131 QVERIFY(reader != nullptr); | |
132 | |
133 QStringList fileAndExt = audiofile.split("."); | |
134 QString file = fileAndExt[0]; | |
135 QString extension = fileAndExt[1]; | |
136 | |
137 if (extension == "wav") { | |
138 | |
139 // Nothing | |
140 | |
141 delete reader; | |
142 | |
143 } else { | |
144 | |
145 #if (!defined (HAVE_OGGZ) || !defined(HAVE_FISHSOUND)) | |
146 if (extension == "ogg") { | |
147 QSKIP("Lack native Ogg Vorbis reader, so won't be getting metadata"); | |
148 } | |
149 #endif | |
150 | |
151 auto blah = reader->getInterleavedFrames(0, 10); | |
152 | |
153 QString title = reader->getTitle(); | |
154 QVERIFY(title != QString()); | |
155 | |
156 delete reader; | |
157 | |
158 bool found = false; | |
159 for (int m = 0; m < mappingCount; ++m) { | |
160 if (file == QString::fromUtf8(mapping[m][0])) { | |
161 found = true; | |
162 QString expected = QString::fromUtf8(mapping[m][1]); | |
163 if (title != expected) { | |
164 SVCERR << "Title does not match expected: codepoints are" << endl; | |
165 SVCERR << "Title (" << title.length() << "ch): "; | |
166 for (int i = 0; i < title.length(); ++i) { | |
167 SVCERR << title[i].unicode() << " "; | |
168 } | |
169 SVCERR << endl; | |
170 SVCERR << "Expected (" << expected.length() << "ch): "; | |
171 for (int i = 0; i < expected.length(); ++i) { | |
172 SVCERR << expected[i].unicode() << " "; | |
173 } | |
174 SVCERR << endl; | |
175 } | |
176 QCOMPARE(title, expected); | |
177 break; | |
178 } | |
179 } | |
180 | |
181 if (!found) { | |
182 // Note that this can happen legitimately on Windows, | |
183 // where (for annoying VCS-related reasons) the test | |
184 // files may have a different filename encoding from | |
185 // the expected UTF-16. We check this properly in | |
186 // readWriteAudio below, by saving out the file to a | |
187 // name matching the metadata | |
188 SVCERR << "Couldn't find filename \"" | |
189 << file << "\" in title mapping array" << endl; | |
190 QSKIP("Couldn't find filename in title mapping array"); | |
191 } | |
192 } | |
193 } | |
194 | |
195 void readWriteAudio_data() { | |
196 addAudioFiles(); | |
197 } | |
198 | |
199 void readWriteAudio() | |
200 { | |
201 // For those files that have title metadata (i.e. all of them | |
202 // except the WAVs), read the title metadata and write a wav | |
203 // file (of arbitrary content) whose name matches that. Then | |
204 // check that we can re-read it. This is intended to exercise | |
205 // systems on which the original test filename is miscoded (as | |
206 // can happen on Windows). | |
207 | |
208 QFETCH(QString, audiofile); | |
209 | |
210 QStringList fileAndExt = audiofile.split("."); | |
211 QString file = fileAndExt[0]; | |
212 QString extension = fileAndExt[1]; | |
213 | |
214 if (extension == "wav") { | |
215 return; | |
216 } | |
217 | |
218 #if (!defined (HAVE_OGGZ) || !defined(HAVE_FISHSOUND)) | |
219 if (extension == "ogg") { | |
220 QSKIP("Lack native Ogg Vorbis reader, so won't be getting metadata"); | |
221 } | |
222 #endif | |
223 | |
224 AudioFileReaderFactory::Parameters params; | |
225 AudioFileReader *reader = | |
226 AudioFileReaderFactory::createReader | |
227 (encodingDir + "/" + audiofile, params); | |
228 QVERIFY(reader != nullptr); | |
229 | |
230 QString title = reader->getTitle(); | |
231 QVERIFY(title != QString()); | |
232 | |
233 for (int useTemporary = 0; useTemporary <= 1; ++useTemporary) { | |
234 | |
235 QString outfile = outDir + "/" + file + ".wav"; | |
236 WavFileWriter writer(outfile, | |
237 reader->getSampleRate(), | |
238 1, | |
239 useTemporary ? | |
240 WavFileWriter::WriteToTemporary : | |
241 WavFileWriter::WriteToTarget); | |
242 | |
243 QVERIFY(writer.isOK()); | |
244 | |
245 floatvec_t data { 0.0, 1.0, 0.0, -1.0, 0.0, 1.0, 0.0, -1.0 }; | |
246 const float *samples = data.data(); | |
247 bool ok = writer.writeSamples(&samples, 8); | |
248 QVERIFY(ok); | |
249 | |
250 ok = writer.close(); | |
251 QVERIFY(ok); | |
252 | |
253 AudioFileReader *rereader = | |
254 AudioFileReaderFactory::createReader(outfile, params); | |
255 QVERIFY(rereader != nullptr); | |
256 | |
257 floatvec_t readFrames = rereader->getInterleavedFrames(0, 8); | |
258 QCOMPARE(readFrames, data); | |
259 | |
260 delete rereader; | |
261 } | |
262 | |
263 delete reader; | |
264 } | |
265 }; | |
266 | |
267 #endif |