annotate data/fileio/DecodingWavFileReader.cpp @ 1008:d9e0e59a1581

When using an aggregate model to pass data to a transform, zero-pad the shorter input to the duration of the longer rather than truncating the longer. (This is better behaviour for e.g. MATCH, and in any case the code was previously truncating incorrectly and ending up with garbage data at the end.)
author Chris Cannam
date Fri, 14 Nov 2014 13:51:33 +0000
parents d03b3d956358
children cc27f35aa75c
rev   line source
Chris@297 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
Chris@297 2
Chris@297 3 /*
Chris@297 4 Sonic Visualiser
Chris@297 5 An audio file viewer and annotation editor.
Chris@297 6 Centre for Digital Music, Queen Mary, University of London.
Chris@297 7 This file copyright 2007 QMUL.
Chris@297 8
Chris@297 9 This program is free software; you can redistribute it and/or
Chris@297 10 modify it under the terms of the GNU General Public License as
Chris@297 11 published by the Free Software Foundation; either version 2 of the
Chris@297 12 License, or (at your option) any later version. See the file
Chris@297 13 COPYING included with this distribution for more information.
Chris@297 14 */
Chris@297 15
Chris@823 16 #include "DecodingWavFileReader.h"
Chris@297 17
Chris@297 18 #include "WavFileReader.h"
Chris@297 19 #include "base/Profiler.h"
Chris@392 20 #include "base/ProgressReporter.h"
Chris@297 21
Chris@297 22 #include <QFileInfo>
Chris@297 23
Chris@823 24 DecodingWavFileReader::DecodingWavFileReader(FileSource source,
Chris@920 25 ResampleMode resampleMode,
Chris@920 26 CacheMode mode,
Chris@933 27 int targetRate,
Chris@920 28 bool normalised,
Chris@920 29 ProgressReporter *reporter) :
Chris@920 30 CodedAudioFileReader(mode, targetRate, normalised),
Chris@316 31 m_source(source),
Chris@316 32 m_path(source.getLocalFilename()),
Chris@297 33 m_cancelled(false),
Chris@297 34 m_processed(0),
Chris@297 35 m_completion(0),
Chris@297 36 m_original(0),
Chris@392 37 m_reporter(reporter),
Chris@297 38 m_decodeThread(0)
Chris@297 39 {
Chris@297 40 m_channelCount = 0;
Chris@297 41 m_fileRate = 0;
Chris@297 42
Chris@823 43 SVDEBUG << "DecodingWavFileReader::DecodingWavFileReader(\""
Chris@687 44 << m_path << "\"): rate " << targetRate << endl;
Chris@297 45
Chris@823 46 Profiler profiler("DecodingWavFileReader::DecodingWavFileReader", true);
Chris@297 47
Chris@316 48 m_original = new WavFileReader(m_path);
Chris@297 49 if (!m_original->isOK()) {
Chris@297 50 m_error = m_original->getError();
Chris@297 51 return;
Chris@297 52 }
Chris@297 53
Chris@297 54 m_channelCount = m_original->getChannelCount();
Chris@297 55 m_fileRate = m_original->getSampleRate();
Chris@297 56
Chris@297 57 initialiseDecodeCache();
Chris@297 58
Chris@297 59 if (resampleMode == ResampleAtOnce) {
Chris@297 60
Chris@392 61 if (m_reporter) {
Chris@392 62 connect(m_reporter, SIGNAL(cancelled()), this, SLOT(cancelled()));
Chris@392 63 m_reporter->setMessage
Chris@823 64 (tr("Decoding %1...").arg(QFileInfo(m_path).fileName()));
Chris@327 65 }
Chris@297 66
Chris@929 67 int blockSize = 16384;
Chris@929 68 int total = m_original->getFrameCount();
Chris@297 69
Chris@297 70 SampleBlock block;
Chris@297 71
Chris@929 72 for (int i = 0; i < total; i += blockSize) {
Chris@297 73
Chris@929 74 int count = blockSize;
Chris@297 75 if (i + count > total) count = total - i;
Chris@297 76
Chris@297 77 m_original->getInterleavedFrames(i, count, block);
Chris@297 78 addBlock(block);
Chris@297 79
Chris@297 80 if (m_cancelled) break;
Chris@297 81 }
Chris@297 82
Chris@297 83 if (isDecodeCacheInitialised()) finishDecodeCache();
Chris@398 84 endSerialised();
Chris@297 85
Chris@403 86 if (m_reporter) m_reporter->setProgress(100);
Chris@403 87
Chris@297 88 delete m_original;
Chris@297 89 m_original = 0;
Chris@297 90
Chris@392 91 } else {
Chris@297 92
Chris@392 93 if (m_reporter) m_reporter->setProgress(100);
Chris@297 94
Chris@297 95 m_decodeThread = new DecodeThread(this);
Chris@297 96 m_decodeThread->start();
Chris@297 97 }
Chris@297 98 }
Chris@297 99
Chris@823 100 DecodingWavFileReader::~DecodingWavFileReader()
Chris@297 101 {
Chris@297 102 if (m_decodeThread) {
Chris@297 103 m_cancelled = true;
Chris@297 104 m_decodeThread->wait();
Chris@297 105 delete m_decodeThread;
Chris@297 106 }
Chris@297 107
Chris@297 108 delete m_original;
Chris@297 109 }
Chris@297 110
Chris@297 111 void
Chris@823 112 DecodingWavFileReader::cancelled()
Chris@392 113 {
Chris@392 114 m_cancelled = true;
Chris@392 115 }
Chris@392 116
Chris@392 117 void
Chris@823 118 DecodingWavFileReader::DecodeThread::run()
Chris@297 119 {
Chris@297 120 if (m_reader->m_cacheMode == CacheInTemporaryFile) {
Chris@823 121 m_reader->startSerialised("DecodingWavFileReader::Decode");
Chris@297 122 }
Chris@297 123
Chris@929 124 int blockSize = 16384;
Chris@929 125 int total = m_reader->m_original->getFrameCount();
Chris@297 126
Chris@297 127 SampleBlock block;
Chris@297 128
Chris@929 129 for (int i = 0; i < total; i += blockSize) {
Chris@297 130
Chris@929 131 int count = blockSize;
Chris@297 132 if (i + count > total) count = total - i;
Chris@297 133
Chris@297 134 m_reader->m_original->getInterleavedFrames(i, count, block);
Chris@297 135 m_reader->addBlock(block);
Chris@297 136
Chris@297 137 if (m_reader->m_cancelled) break;
Chris@297 138 }
Chris@297 139
Chris@297 140 if (m_reader->isDecodeCacheInitialised()) m_reader->finishDecodeCache();
Chris@297 141 m_reader->m_completion = 100;
Chris@297 142
Chris@297 143 m_reader->endSerialised();
Chris@297 144
Chris@297 145 delete m_reader->m_original;
Chris@297 146 m_reader->m_original = 0;
Chris@297 147 }
Chris@297 148
Chris@297 149 void
Chris@823 150 DecodingWavFileReader::addBlock(const SampleBlock &frames)
Chris@297 151 {
Chris@297 152 addSamplesToDecodeCache(frames);
Chris@297 153
Chris@297 154 m_processed += frames.size();
Chris@297 155
Chris@403 156 float ratio = float(m_sampleRate) / float(m_fileRate);
Chris@403 157
Chris@403 158 int progress = lrint((float(m_processed) * ratio * 100) /
Chris@297 159 float(m_original->getFrameCount()));
Chris@297 160
Chris@297 161 if (progress > 99) progress = 99;
Chris@297 162 m_completion = progress;
Chris@297 163
Chris@392 164 if (m_reporter) {
Chris@392 165 m_reporter->setProgress(progress);
Chris@297 166 }
Chris@297 167 }
Chris@297 168
Chris@297 169 void
Chris@823 170 DecodingWavFileReader::getSupportedExtensions(std::set<QString> &extensions)
Chris@297 171 {
Chris@297 172 WavFileReader::getSupportedExtensions(extensions);
Chris@297 173 }
Chris@297 174
Chris@316 175 bool
Chris@823 176 DecodingWavFileReader::supportsExtension(QString extension)
Chris@316 177 {
Chris@316 178 return WavFileReader::supportsExtension(extension);
Chris@316 179 }
Chris@297 180
Chris@316 181 bool
Chris@823 182 DecodingWavFileReader::supportsContentType(QString type)
Chris@316 183 {
Chris@316 184 return WavFileReader::supportsContentType(type);
Chris@316 185 }
Chris@316 186
Chris@316 187 bool
Chris@823 188 DecodingWavFileReader::supports(FileSource &source)
Chris@316 189 {
Chris@316 190 return WavFileReader::supports(source);
Chris@316 191 }
Chris@316 192
Chris@316 193