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@1096: using namespace std; Chris@1096: Chris@823: DecodingWavFileReader::DecodingWavFileReader(FileSource source, Chris@1097: DecodeMode decodeMode, Chris@920: CacheMode mode, Chris@1040: sv_samplerate_t targetRate, Chris@920: bool normalised, Chris@920: ProgressReporter *reporter) : Chris@920: CodedAudioFileReader(mode, targetRate, normalised), 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@1582: m_original(nullptr), Chris@392: m_reporter(reporter), Chris@1582: m_decodeThread(nullptr) Chris@297: { Chris@1279: SVDEBUG << "DecodingWavFileReader: local path: \"" << m_path Chris@1279: << "\", decode mode: " << decodeMode << " (" Chris@1279: << (decodeMode == DecodeAtOnce ? "DecodeAtOnce" : "DecodeThreaded") Chris@1279: << ")" << endl; Chris@1279: Chris@297: m_channelCount = 0; Chris@297: m_fileRate = 0; Chris@297: Chris@1295: Profiler profiler("DecodingWavFileReader::DecodingWavFileReader"); 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@1592: m_title = m_original->getTitle(); Chris@1592: m_maker = m_original->getMaker(); Chris@1592: Chris@297: initialiseDecodeCache(); Chris@297: Chris@1097: if (decodeMode == DecodeAtOnce) { 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@1038: sv_frame_t blockSize = 16384; Chris@1038: sv_frame_t total = m_original->getFrameCount(); Chris@297: Chris@1326: floatvec_t block; Chris@297: Chris@1038: for (sv_frame_t i = 0; i < total; i += blockSize) { Chris@297: Chris@1038: sv_frame_t count = blockSize; Chris@297: if (i + count > total) count = total - i; Chris@297: Chris@1041: block = m_original->getInterleavedFrames(i, count); 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@1582: m_original = nullptr; 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@1038: sv_frame_t blockSize = 16384; Chris@1038: sv_frame_t total = m_reader->m_original->getFrameCount(); Chris@297: Chris@1326: floatvec_t block; Chris@297: Chris@1038: for (sv_frame_t i = 0; i < total; i += blockSize) { Chris@297: Chris@1038: sv_frame_t count = blockSize; Chris@297: if (i + count > total) count = total - i; Chris@297: Chris@1041: block = m_reader->m_original->getInterleavedFrames(i, count); 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@1582: m_reader->m_original = nullptr; Chris@297: } Chris@297: Chris@297: void Chris@1326: DecodingWavFileReader::addBlock(const floatvec_t &frames) Chris@297: { Chris@297: addSamplesToDecodeCache(frames); Chris@297: Chris@297: m_processed += frames.size(); Chris@297: Chris@1038: double ratio = double(m_sampleRate) / double(m_fileRate); Chris@403: Chris@1038: int progress = int(lrint((double(m_processed) * ratio * 100) / Chris@1038: double(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@1096: DecodingWavFileReader::getSupportedExtensions(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: