Chris@297: /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ Chris@297: Chris@297: /* Chris@297: Sonic Visualiser Chris@297: An audio file viewer and annotation editor. Chris@297: Centre for Digital Music, Queen Mary, University of London. Chris@297: This file copyright 2007 QMUL. Chris@297: Chris@297: This program is free software; you can redistribute it and/or Chris@297: modify it under the terms of the GNU General Public License as Chris@297: published by the Free Software Foundation; either version 2 of the Chris@297: License, or (at your option) any later version. See the file Chris@297: COPYING included with this distribution for more information. Chris@297: */ Chris@297: Chris@823: #include "DecodingWavFileReader.h" Chris@297: Chris@297: #include "WavFileReader.h" Chris@297: #include "base/Profiler.h" Chris@392: #include "base/ProgressReporter.h" Chris@297: Chris@297: #include Chris@297: Chris@823: DecodingWavFileReader::DecodingWavFileReader(FileSource source, Chris@297: ResampleMode resampleMode, Chris@297: CacheMode mode, Chris@392: size_t targetRate, Chris@392: ProgressReporter *reporter) : Chris@297: CodedAudioFileReader(mode, targetRate), Chris@316: m_source(source), Chris@316: m_path(source.getLocalFilename()), Chris@297: m_cancelled(false), Chris@297: m_processed(0), Chris@297: m_completion(0), Chris@297: m_original(0), Chris@392: m_reporter(reporter), Chris@297: m_decodeThread(0) Chris@297: { Chris@297: m_channelCount = 0; Chris@297: m_fileRate = 0; Chris@297: Chris@823: SVDEBUG << "DecodingWavFileReader::DecodingWavFileReader(\"" Chris@687: << m_path << "\"): rate " << targetRate << endl; Chris@297: Chris@823: Profiler profiler("DecodingWavFileReader::DecodingWavFileReader", true); Chris@297: Chris@316: m_original = new WavFileReader(m_path); Chris@297: if (!m_original->isOK()) { Chris@297: m_error = m_original->getError(); Chris@297: return; Chris@297: } Chris@297: Chris@297: m_channelCount = m_original->getChannelCount(); Chris@297: m_fileRate = m_original->getSampleRate(); Chris@297: Chris@297: initialiseDecodeCache(); Chris@297: Chris@297: if (resampleMode == ResampleAtOnce) { Chris@297: Chris@392: if (m_reporter) { Chris@392: connect(m_reporter, SIGNAL(cancelled()), this, SLOT(cancelled())); Chris@392: m_reporter->setMessage Chris@823: (tr("Decoding %1...").arg(QFileInfo(m_path).fileName())); Chris@327: } Chris@297: Chris@297: size_t blockSize = 16384; Chris@297: size_t total = m_original->getFrameCount(); Chris@297: Chris@297: SampleBlock block; Chris@297: Chris@297: for (size_t i = 0; i < total; i += blockSize) { Chris@297: Chris@297: size_t count = blockSize; Chris@297: if (i + count > total) count = total - i; Chris@297: Chris@297: m_original->getInterleavedFrames(i, count, block); Chris@297: addBlock(block); Chris@297: Chris@297: if (m_cancelled) break; Chris@297: } Chris@297: Chris@297: if (isDecodeCacheInitialised()) finishDecodeCache(); Chris@398: endSerialised(); Chris@297: Chris@403: if (m_reporter) m_reporter->setProgress(100); Chris@403: Chris@297: delete m_original; Chris@297: m_original = 0; Chris@297: Chris@392: } else { Chris@297: Chris@392: if (m_reporter) m_reporter->setProgress(100); Chris@297: Chris@297: m_decodeThread = new DecodeThread(this); Chris@297: m_decodeThread->start(); Chris@297: } Chris@297: } Chris@297: Chris@823: DecodingWavFileReader::~DecodingWavFileReader() Chris@297: { Chris@297: if (m_decodeThread) { Chris@297: m_cancelled = true; Chris@297: m_decodeThread->wait(); Chris@297: delete m_decodeThread; Chris@297: } Chris@297: Chris@297: delete m_original; Chris@297: } Chris@297: Chris@297: void Chris@823: DecodingWavFileReader::cancelled() Chris@392: { Chris@392: m_cancelled = true; Chris@392: } Chris@392: Chris@392: void Chris@823: DecodingWavFileReader::DecodeThread::run() Chris@297: { Chris@297: if (m_reader->m_cacheMode == CacheInTemporaryFile) { Chris@823: m_reader->startSerialised("DecodingWavFileReader::Decode"); Chris@297: } Chris@297: Chris@297: size_t blockSize = 16384; Chris@297: size_t total = m_reader->m_original->getFrameCount(); Chris@297: Chris@297: SampleBlock block; Chris@297: Chris@297: for (size_t i = 0; i < total; i += blockSize) { Chris@297: Chris@297: size_t count = blockSize; Chris@297: if (i + count > total) count = total - i; Chris@297: Chris@297: m_reader->m_original->getInterleavedFrames(i, count, block); Chris@297: m_reader->addBlock(block); Chris@297: Chris@297: if (m_reader->m_cancelled) break; Chris@297: } Chris@297: Chris@297: if (m_reader->isDecodeCacheInitialised()) m_reader->finishDecodeCache(); Chris@297: m_reader->m_completion = 100; Chris@297: Chris@297: m_reader->endSerialised(); Chris@297: Chris@297: delete m_reader->m_original; Chris@297: m_reader->m_original = 0; Chris@297: } Chris@297: Chris@297: void Chris@823: DecodingWavFileReader::addBlock(const SampleBlock &frames) Chris@297: { Chris@297: addSamplesToDecodeCache(frames); Chris@297: Chris@297: m_processed += frames.size(); Chris@297: Chris@403: float ratio = float(m_sampleRate) / float(m_fileRate); Chris@403: Chris@403: int progress = lrint((float(m_processed) * ratio * 100) / Chris@297: float(m_original->getFrameCount())); Chris@297: Chris@297: if (progress > 99) progress = 99; Chris@297: m_completion = progress; Chris@297: Chris@392: if (m_reporter) { Chris@392: m_reporter->setProgress(progress); Chris@297: } Chris@297: } Chris@297: Chris@297: void Chris@823: DecodingWavFileReader::getSupportedExtensions(std::set &extensions) Chris@297: { Chris@297: WavFileReader::getSupportedExtensions(extensions); Chris@297: } Chris@297: Chris@316: bool Chris@823: DecodingWavFileReader::supportsExtension(QString extension) Chris@316: { Chris@316: return WavFileReader::supportsExtension(extension); Chris@316: } Chris@297: Chris@316: bool Chris@823: DecodingWavFileReader::supportsContentType(QString type) Chris@316: { Chris@316: return WavFileReader::supportsContentType(type); Chris@316: } Chris@316: Chris@316: bool Chris@823: DecodingWavFileReader::supports(FileSource &source) Chris@316: { Chris@316: return WavFileReader::supports(source); Chris@316: } Chris@316: Chris@316: