Chris@1359
|
1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
|
Chris@1359
|
2
|
Chris@1359
|
3 /*
|
Chris@1359
|
4 Sonic Visualiser
|
Chris@1359
|
5 An audio file viewer and annotation editor.
|
Chris@1359
|
6 Centre for Digital Music, Queen Mary, University of London.
|
Chris@1359
|
7
|
Chris@1359
|
8 This program is free software; you can redistribute it and/or
|
Chris@1359
|
9 modify it under the terms of the GNU General Public License as
|
Chris@1359
|
10 published by the Free Software Foundation; either version 2 of the
|
Chris@1359
|
11 License, or (at your option) any later version. See the file
|
Chris@1359
|
12 COPYING included with this distribution for more information.
|
Chris@1359
|
13 */
|
Chris@1359
|
14
|
Chris@1359
|
15 #ifndef TEST_AUDIO_FILE_WRITER_H
|
Chris@1359
|
16 #define TEST_AUDIO_FILE_WRITER_H
|
Chris@1359
|
17
|
Chris@1359
|
18 #include "../AudioFileReaderFactory.h"
|
Chris@1359
|
19 #include "../AudioFileReader.h"
|
Chris@1359
|
20 #include "../WavFileWriter.h"
|
Chris@1359
|
21
|
Chris@1359
|
22 #include "AudioTestData.h"
|
Chris@1359
|
23
|
Chris@1359
|
24 #include "bqvec/VectorOps.h"
|
Chris@1359
|
25 #include "bqvec/Allocators.h"
|
Chris@1359
|
26
|
Chris@1359
|
27 #include <cmath>
|
Chris@1359
|
28
|
Chris@1359
|
29 #include <QObject>
|
Chris@1359
|
30 #include <QtTest>
|
Chris@1359
|
31 #include <QDir>
|
Chris@1359
|
32
|
Chris@1359
|
33 #include <iostream>
|
Chris@1359
|
34
|
Chris@1359
|
35 using namespace std;
|
Chris@1359
|
36 using namespace breakfastquay;
|
Chris@1359
|
37
|
Chris@1359
|
38 class AudioFileWriterTest : public QObject
|
Chris@1359
|
39 {
|
Chris@1359
|
40 Q_OBJECT
|
Chris@1359
|
41
|
Chris@1359
|
42 private:
|
Chris@1359
|
43 QString testDirBase;
|
Chris@1359
|
44 QString outDir;
|
Chris@1359
|
45
|
Chris@1359
|
46 static const int rate = 44100;
|
Chris@1359
|
47
|
Chris@1359
|
48 public:
|
Chris@1359
|
49 AudioFileWriterTest(QString base) {
|
Chris@1359
|
50 if (base == "") {
|
Chris@1359
|
51 base = "svcore/data/fileio/test";
|
Chris@1359
|
52 }
|
Chris@1359
|
53 testDirBase = base;
|
Chris@1359
|
54 outDir = base + "/outfiles";
|
Chris@1359
|
55 }
|
Chris@1359
|
56
|
Chris@1359
|
57 const char *strOf(QString s) {
|
Chris@1359
|
58 return strdup(s.toLocal8Bit().data());
|
Chris@1359
|
59 }
|
Chris@1359
|
60
|
Chris@1359
|
61 QString testName(bool direct, int channels) {
|
Chris@1359
|
62 return QString("%1 %2 %3")
|
Chris@1359
|
63 .arg(channels)
|
Chris@1359
|
64 .arg(channels > 1 ? "channels" : "channel")
|
Chris@1359
|
65 .arg(direct ? "direct" : "via temporary");
|
Chris@1359
|
66 }
|
Chris@1359
|
67
|
Chris@1359
|
68 private slots:
|
Chris@1359
|
69 void init()
|
Chris@1359
|
70 {
|
Chris@1359
|
71 if (!QDir(outDir).exists() && !QDir().mkpath(outDir)) {
|
Chris@1428
|
72 SVCERR << "ERROR: Audio out directory \"" << outDir << "\" does not exist and could not be created" << endl;
|
Chris@1359
|
73 QVERIFY2(QDir(outDir).exists(), "Audio out directory not found and could not be created");
|
Chris@1359
|
74 }
|
Chris@1359
|
75 }
|
Chris@1359
|
76
|
Chris@1359
|
77 void write_data()
|
Chris@1359
|
78 {
|
Chris@1359
|
79 QTest::addColumn<bool>("direct");
|
Chris@1359
|
80 QTest::addColumn<int>("channels");
|
Chris@1359
|
81 for (int direct = 0; direct <= 1; ++direct) {
|
Chris@1359
|
82 for (int channels = 1; channels < 8; ++channels) {
|
Chris@1359
|
83 if (channels == 1 || channels == 2 ||
|
Chris@1359
|
84 channels == 5 || channels == 8) {
|
Chris@1359
|
85 QString desc = testName(direct, channels);
|
Chris@1359
|
86 QTest::newRow(strOf(desc)) << (bool)direct << channels;
|
Chris@1359
|
87 }
|
Chris@1359
|
88 }
|
Chris@1359
|
89 }
|
Chris@1359
|
90 }
|
Chris@1359
|
91
|
Chris@1359
|
92 void write()
|
Chris@1359
|
93 {
|
Chris@1359
|
94 QFETCH(bool, direct);
|
Chris@1359
|
95 QFETCH(int, channels);
|
Chris@1359
|
96
|
Chris@1359
|
97 QString outfile = QString("%1/out-%2ch-%3.wav")
|
Chris@1359
|
98 .arg(outDir).arg(channels).arg(direct ? "direct" : "via-temporary");
|
Chris@1359
|
99
|
Chris@1359
|
100 WavFileWriter writer(outfile,
|
Chris@1359
|
101 rate,
|
Chris@1359
|
102 channels,
|
Chris@1359
|
103 direct ?
|
Chris@1359
|
104 WavFileWriter::WriteToTarget :
|
Chris@1359
|
105 WavFileWriter::WriteToTemporary);
|
Chris@1359
|
106 QVERIFY(writer.isOK());
|
Chris@1359
|
107
|
Chris@1359
|
108 AudioTestData data(rate, channels);
|
Chris@1359
|
109 data.generate();
|
Chris@1359
|
110
|
Chris@1359
|
111 sv_frame_t frameCount = data.getFrameCount();
|
Chris@1359
|
112 float *interleaved = data.getInterleavedData();
|
Chris@1359
|
113 float **nonInterleaved = allocate_channels<float>(channels, frameCount);
|
Chris@1359
|
114 v_deinterleave(nonInterleaved, interleaved, channels, int(frameCount));
|
Chris@1359
|
115 bool ok = writer.writeSamples(nonInterleaved, frameCount);
|
Chris@1359
|
116 deallocate_channels(nonInterleaved, channels);
|
Chris@1359
|
117 QVERIFY(ok);
|
Chris@1359
|
118
|
Chris@1359
|
119 ok = writer.close();
|
Chris@1359
|
120 QVERIFY(ok);
|
Chris@1359
|
121
|
Chris@1359
|
122 AudioFileReaderFactory::Parameters params;
|
Chris@1359
|
123 AudioFileReader *rereader =
|
Chris@1359
|
124 AudioFileReaderFactory::createReader(outfile, params);
|
Chris@1359
|
125 QVERIFY(rereader != nullptr);
|
Chris@1359
|
126
|
Chris@1359
|
127 floatvec_t readFrames = rereader->getInterleavedFrames(0, frameCount);
|
Chris@1359
|
128 floatvec_t expected(interleaved, interleaved + frameCount * channels);
|
Chris@1359
|
129 QCOMPARE(readFrames, expected);
|
Chris@1359
|
130
|
Chris@1359
|
131 delete rereader;
|
Chris@1359
|
132 }
|
Chris@1359
|
133 };
|
Chris@1359
|
134
|
Chris@1359
|
135 #endif
|