annotate data/fileio/test/AudioFileWriterTest.h @ 1699:ad33d6c10738 single-point

Merge from default branch
author Chris Cannam
date Fri, 03 May 2019 13:44:45 +0100
parents 87ae75da6527
children
rev   line source
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