annotate data/fileio/ResamplingWavFileReader.cpp @ 316:3a6725f285d6

* Make RemoteFile far more pervasive, and use it for local files as well so that we can handle both transparently. Make it shallow copy with reference counting, so it can be used by value without having to worry about the cache file lifetime. Use RemoteFile for MainWindow file-open functions, etc
author Chris Cannam
date Thu, 18 Oct 2007 15:31:20 +0000
parents c022976d18e8
children c324d410b096
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@297 16 #include "ResamplingWavFileReader.h"
Chris@297 17
Chris@297 18 #include "WavFileReader.h"
Chris@297 19 #include "base/Profiler.h"
Chris@297 20
Chris@297 21 #include <QProgressDialog>
Chris@297 22 #include <QFileInfo>
Chris@297 23 #include <QApplication>
Chris@297 24
Chris@316 25 ResamplingWavFileReader::ResamplingWavFileReader(RemoteFile source,
Chris@297 26 ResampleMode resampleMode,
Chris@297 27 CacheMode mode,
Chris@297 28 size_t targetRate) :
Chris@297 29 CodedAudioFileReader(mode, targetRate),
Chris@316 30 m_source(source),
Chris@316 31 m_path(source.getLocalFilename()),
Chris@297 32 m_cancelled(false),
Chris@297 33 m_processed(0),
Chris@297 34 m_completion(0),
Chris@297 35 m_original(0),
Chris@297 36 m_progress(0),
Chris@297 37 m_decodeThread(0)
Chris@297 38 {
Chris@297 39 m_channelCount = 0;
Chris@297 40 m_fileRate = 0;
Chris@297 41
Chris@297 42 std::cerr << "ResamplingWavFileReader::ResamplingWavFileReader(\""
Chris@316 43 << m_path.toStdString() << "\"): rate " << targetRate << std::endl;
Chris@297 44
Chris@297 45 Profiler profiler("ResamplingWavFileReader::ResamplingWavFileReader", true);
Chris@297 46
Chris@316 47 m_original = new WavFileReader(m_path);
Chris@297 48 if (!m_original->isOK()) {
Chris@297 49 m_error = m_original->getError();
Chris@297 50 return;
Chris@297 51 }
Chris@297 52
Chris@297 53 m_channelCount = m_original->getChannelCount();
Chris@297 54 m_fileRate = m_original->getSampleRate();
Chris@297 55
Chris@297 56 initialiseDecodeCache();
Chris@297 57
Chris@297 58 if (resampleMode == ResampleAtOnce) {
Chris@297 59
Chris@297 60 m_progress = new QProgressDialog
Chris@316 61 (QObject::tr("Resampling %1...").arg(QFileInfo(m_path).fileName()),
Chris@297 62 QObject::tr("Stop"), 0, 100);
Chris@297 63 m_progress->hide();
Chris@297 64
Chris@297 65 size_t blockSize = 16384;
Chris@297 66 size_t total = m_original->getFrameCount();
Chris@297 67
Chris@297 68 SampleBlock block;
Chris@297 69
Chris@297 70 for (size_t i = 0; i < total; i += blockSize) {
Chris@297 71
Chris@297 72 size_t count = blockSize;
Chris@297 73 if (i + count > total) count = total - i;
Chris@297 74
Chris@297 75 m_original->getInterleavedFrames(i, count, block);
Chris@297 76 addBlock(block);
Chris@297 77
Chris@297 78 if (m_cancelled) break;
Chris@297 79 }
Chris@297 80
Chris@297 81 if (isDecodeCacheInitialised()) finishDecodeCache();
Chris@297 82
Chris@297 83 delete m_original;
Chris@297 84 m_original = 0;
Chris@297 85
Chris@297 86 delete m_progress;
Chris@297 87 m_progress = 0;
Chris@297 88
Chris@297 89 } else {
Chris@297 90
Chris@297 91 m_decodeThread = new DecodeThread(this);
Chris@297 92 m_decodeThread->start();
Chris@297 93 }
Chris@297 94 }
Chris@297 95
Chris@297 96 ResamplingWavFileReader::~ResamplingWavFileReader()
Chris@297 97 {
Chris@297 98 if (m_decodeThread) {
Chris@297 99 m_cancelled = true;
Chris@297 100 m_decodeThread->wait();
Chris@297 101 delete m_decodeThread;
Chris@297 102 }
Chris@297 103
Chris@297 104 delete m_original;
Chris@297 105 }
Chris@297 106
Chris@297 107 void
Chris@297 108 ResamplingWavFileReader::DecodeThread::run()
Chris@297 109 {
Chris@297 110 if (m_reader->m_cacheMode == CacheInTemporaryFile) {
Chris@297 111 m_reader->startSerialised("ResamplingWavFileReader::Decode");
Chris@297 112 }
Chris@297 113
Chris@297 114 size_t blockSize = 16384;
Chris@297 115 size_t total = m_reader->m_original->getFrameCount();
Chris@297 116
Chris@297 117 SampleBlock block;
Chris@297 118
Chris@297 119 for (size_t i = 0; i < total; i += blockSize) {
Chris@297 120
Chris@297 121 size_t count = blockSize;
Chris@297 122 if (i + count > total) count = total - i;
Chris@297 123
Chris@297 124 m_reader->m_original->getInterleavedFrames(i, count, block);
Chris@297 125 m_reader->addBlock(block);
Chris@297 126
Chris@297 127 if (m_reader->m_cancelled) break;
Chris@297 128 }
Chris@297 129
Chris@297 130 if (m_reader->isDecodeCacheInitialised()) m_reader->finishDecodeCache();
Chris@297 131 m_reader->m_completion = 100;
Chris@297 132
Chris@297 133 m_reader->endSerialised();
Chris@297 134
Chris@297 135 delete m_reader->m_original;
Chris@297 136 m_reader->m_original = 0;
Chris@297 137 }
Chris@297 138
Chris@297 139 void
Chris@297 140 ResamplingWavFileReader::addBlock(const SampleBlock &frames)
Chris@297 141 {
Chris@297 142 addSamplesToDecodeCache(frames);
Chris@297 143
Chris@297 144 m_processed += frames.size();
Chris@297 145
Chris@297 146 int progress = lrint((float(m_processed) * 100) /
Chris@297 147 float(m_original->getFrameCount()));
Chris@297 148
Chris@297 149 if (progress > 99) progress = 99;
Chris@297 150 m_completion = progress;
Chris@297 151
Chris@297 152 if (m_progress) {
Chris@297 153 if (progress > m_progress->value()) {
Chris@297 154 m_progress->setValue(progress);
Chris@297 155 m_progress->show();
Chris@297 156 m_progress->raise();
Chris@297 157 qApp->processEvents();
Chris@297 158 if (m_progress->wasCanceled()) {
Chris@297 159 m_cancelled = true;
Chris@297 160 }
Chris@297 161 }
Chris@297 162 }
Chris@297 163 }
Chris@297 164
Chris@297 165 void
Chris@297 166 ResamplingWavFileReader::getSupportedExtensions(std::set<QString> &extensions)
Chris@297 167 {
Chris@297 168 WavFileReader::getSupportedExtensions(extensions);
Chris@297 169 }
Chris@297 170
Chris@316 171 bool
Chris@316 172 ResamplingWavFileReader::supportsExtension(QString extension)
Chris@316 173 {
Chris@316 174 return WavFileReader::supportsExtension(extension);
Chris@316 175 }
Chris@297 176
Chris@316 177 bool
Chris@316 178 ResamplingWavFileReader::supportsContentType(QString type)
Chris@316 179 {
Chris@316 180 return WavFileReader::supportsContentType(type);
Chris@316 181 }
Chris@316 182
Chris@316 183 bool
Chris@316 184 ResamplingWavFileReader::supports(RemoteFile &source)
Chris@316 185 {
Chris@316 186 return WavFileReader::supports(source);
Chris@316 187 }
Chris@316 188
Chris@316 189