annotate data/fileio/ResamplingWavFileReader.cpp @ 360:ac300d385ab2

* Various fixes to object lifetime management, particularly in the spectrum layer and for notification of main model deletion. The main purpose of this is to improve the behaviour of the spectrum, but I think it may also help with #1840922 Various crashes in Layer Summary window.
author Chris Cannam
date Wed, 23 Jan 2008 15:43:27 +0000
parents 1d656dcda8ef
children 183ee2a55fc7
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@317 25 ResamplingWavFileReader::ResamplingWavFileReader(FileSource 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@327 60 if (dynamic_cast<QApplication *>(QCoreApplication::instance())) {
Chris@327 61 m_progress = new QProgressDialog
Chris@327 62 (QObject::tr("Resampling %1...").arg(QFileInfo(m_path).fileName()),
Chris@327 63 QObject::tr("Stop"), 0, 100);
Chris@327 64 m_progress->hide();
Chris@327 65 }
Chris@297 66
Chris@297 67 size_t blockSize = 16384;
Chris@297 68 size_t total = m_original->getFrameCount();
Chris@297 69
Chris@297 70 SampleBlock block;
Chris@297 71
Chris@297 72 for (size_t i = 0; i < total; i += blockSize) {
Chris@297 73
Chris@297 74 size_t 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@297 84
Chris@297 85 delete m_original;
Chris@297 86 m_original = 0;
Chris@297 87
Chris@297 88 delete m_progress;
Chris@297 89 m_progress = 0;
Chris@297 90
Chris@297 91 } else {
Chris@297 92
Chris@297 93 m_decodeThread = new DecodeThread(this);
Chris@297 94 m_decodeThread->start();
Chris@297 95 }
Chris@297 96 }
Chris@297 97
Chris@297 98 ResamplingWavFileReader::~ResamplingWavFileReader()
Chris@297 99 {
Chris@297 100 if (m_decodeThread) {
Chris@297 101 m_cancelled = true;
Chris@297 102 m_decodeThread->wait();
Chris@297 103 delete m_decodeThread;
Chris@297 104 }
Chris@297 105
Chris@297 106 delete m_original;
Chris@297 107 }
Chris@297 108
Chris@297 109 void
Chris@297 110 ResamplingWavFileReader::DecodeThread::run()
Chris@297 111 {
Chris@297 112 if (m_reader->m_cacheMode == CacheInTemporaryFile) {
Chris@297 113 m_reader->startSerialised("ResamplingWavFileReader::Decode");
Chris@297 114 }
Chris@297 115
Chris@297 116 size_t blockSize = 16384;
Chris@297 117 size_t total = m_reader->m_original->getFrameCount();
Chris@297 118
Chris@297 119 SampleBlock block;
Chris@297 120
Chris@297 121 for (size_t i = 0; i < total; i += blockSize) {
Chris@297 122
Chris@297 123 size_t count = blockSize;
Chris@297 124 if (i + count > total) count = total - i;
Chris@297 125
Chris@297 126 m_reader->m_original->getInterleavedFrames(i, count, block);
Chris@297 127 m_reader->addBlock(block);
Chris@297 128
Chris@297 129 if (m_reader->m_cancelled) break;
Chris@297 130 }
Chris@297 131
Chris@297 132 if (m_reader->isDecodeCacheInitialised()) m_reader->finishDecodeCache();
Chris@297 133 m_reader->m_completion = 100;
Chris@297 134
Chris@297 135 m_reader->endSerialised();
Chris@297 136
Chris@297 137 delete m_reader->m_original;
Chris@297 138 m_reader->m_original = 0;
Chris@297 139 }
Chris@297 140
Chris@297 141 void
Chris@297 142 ResamplingWavFileReader::addBlock(const SampleBlock &frames)
Chris@297 143 {
Chris@297 144 addSamplesToDecodeCache(frames);
Chris@297 145
Chris@297 146 m_processed += frames.size();
Chris@297 147
Chris@297 148 int progress = lrint((float(m_processed) * 100) /
Chris@297 149 float(m_original->getFrameCount()));
Chris@297 150
Chris@297 151 if (progress > 99) progress = 99;
Chris@297 152 m_completion = progress;
Chris@297 153
Chris@297 154 if (m_progress) {
Chris@297 155 if (progress > m_progress->value()) {
Chris@297 156 m_progress->setValue(progress);
Chris@297 157 m_progress->show();
Chris@297 158 m_progress->raise();
Chris@297 159 qApp->processEvents();
Chris@297 160 if (m_progress->wasCanceled()) {
Chris@297 161 m_cancelled = true;
Chris@297 162 }
Chris@297 163 }
Chris@297 164 }
Chris@297 165 }
Chris@297 166
Chris@297 167 void
Chris@297 168 ResamplingWavFileReader::getSupportedExtensions(std::set<QString> &extensions)
Chris@297 169 {
Chris@297 170 WavFileReader::getSupportedExtensions(extensions);
Chris@297 171 }
Chris@297 172
Chris@316 173 bool
Chris@316 174 ResamplingWavFileReader::supportsExtension(QString extension)
Chris@316 175 {
Chris@316 176 return WavFileReader::supportsExtension(extension);
Chris@316 177 }
Chris@297 178
Chris@316 179 bool
Chris@316 180 ResamplingWavFileReader::supportsContentType(QString type)
Chris@316 181 {
Chris@316 182 return WavFileReader::supportsContentType(type);
Chris@316 183 }
Chris@316 184
Chris@316 185 bool
Chris@317 186 ResamplingWavFileReader::supports(FileSource &source)
Chris@316 187 {
Chris@316 188 return WavFileReader::supports(source);
Chris@316 189 }
Chris@316 190
Chris@316 191