svcore  1.9
DecodingWavFileReader.cpp
Go to the documentation of this file.
00001 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*-  vi:set ts=8 sts=4 sw=4: */
00002 
00003 /*
00004     Sonic Visualiser
00005     An audio file viewer and annotation editor.
00006     Centre for Digital Music, Queen Mary, University of London.
00007     This file copyright 2007 QMUL.
00008     
00009     This program is free software; you can redistribute it and/or
00010     modify it under the terms of the GNU General Public License as
00011     published by the Free Software Foundation; either version 2 of the
00012     License, or (at your option) any later version.  See the file
00013     COPYING included with this distribution for more information.
00014 */
00015 
00016 #include "DecodingWavFileReader.h"
00017 
00018 #include "WavFileReader.h"
00019 #include "base/Profiler.h"
00020 #include "base/ProgressReporter.h"
00021 
00022 #include <QFileInfo>
00023 
00024 DecodingWavFileReader::DecodingWavFileReader(FileSource source,
00025                                              ResampleMode resampleMode,
00026                                              CacheMode mode,
00027                                              int targetRate,
00028                                              bool normalised,
00029                                              ProgressReporter *reporter) :
00030     CodedAudioFileReader(mode, targetRate, normalised),
00031     m_source(source),
00032     m_path(source.getLocalFilename()),
00033     m_cancelled(false),
00034     m_processed(0),
00035     m_completion(0),
00036     m_original(0),
00037     m_reporter(reporter),
00038     m_decodeThread(0)
00039 {
00040     m_channelCount = 0;
00041     m_fileRate = 0;
00042 
00043     SVDEBUG << "DecodingWavFileReader::DecodingWavFileReader(\""
00044               << m_path << "\"): rate " << targetRate << endl;
00045 
00046     Profiler profiler("DecodingWavFileReader::DecodingWavFileReader", true);
00047 
00048     m_original = new WavFileReader(m_path);
00049     if (!m_original->isOK()) {
00050         m_error = m_original->getError();
00051         return;
00052     }
00053 
00054     m_channelCount = m_original->getChannelCount();
00055     m_fileRate = m_original->getSampleRate();
00056 
00057     initialiseDecodeCache();
00058 
00059     if (resampleMode == ResampleAtOnce) {
00060 
00061         if (m_reporter) {
00062             connect(m_reporter, SIGNAL(cancelled()), this, SLOT(cancelled()));
00063             m_reporter->setMessage
00064                 (tr("Decoding %1...").arg(QFileInfo(m_path).fileName()));
00065         }
00066 
00067         int blockSize = 16384;
00068         int total = m_original->getFrameCount();
00069 
00070         SampleBlock block;
00071 
00072         for (int i = 0; i < total; i += blockSize) {
00073 
00074             int count = blockSize;
00075             if (i + count > total) count = total - i;
00076 
00077             m_original->getInterleavedFrames(i, count, block);
00078             addBlock(block);
00079 
00080             if (m_cancelled) break;
00081         }
00082 
00083         if (isDecodeCacheInitialised()) finishDecodeCache();
00084         endSerialised();
00085 
00086         if (m_reporter) m_reporter->setProgress(100);
00087 
00088         delete m_original;
00089         m_original = 0;
00090 
00091     } else {
00092 
00093         if (m_reporter) m_reporter->setProgress(100);
00094 
00095         m_decodeThread = new DecodeThread(this);
00096         m_decodeThread->start();
00097     }
00098 }
00099 
00100 DecodingWavFileReader::~DecodingWavFileReader()
00101 {
00102     if (m_decodeThread) {
00103         m_cancelled = true;
00104         m_decodeThread->wait();
00105         delete m_decodeThread;
00106     }
00107     
00108     delete m_original;
00109 }
00110 
00111 void
00112 DecodingWavFileReader::cancelled()
00113 {
00114     m_cancelled = true;
00115 }
00116 
00117 void
00118 DecodingWavFileReader::DecodeThread::run()
00119 {
00120     if (m_reader->m_cacheMode == CacheInTemporaryFile) {
00121         m_reader->startSerialised("DecodingWavFileReader::Decode");
00122     }
00123 
00124     int blockSize = 16384;
00125     int total = m_reader->m_original->getFrameCount();
00126     
00127     SampleBlock block;
00128     
00129     for (int i = 0; i < total; i += blockSize) {
00130         
00131         int count = blockSize;
00132         if (i + count > total) count = total - i;
00133         
00134         m_reader->m_original->getInterleavedFrames(i, count, block);
00135         m_reader->addBlock(block);
00136 
00137         if (m_reader->m_cancelled) break;
00138     }
00139     
00140     if (m_reader->isDecodeCacheInitialised()) m_reader->finishDecodeCache();
00141     m_reader->m_completion = 100;
00142 
00143     m_reader->endSerialised();
00144 
00145     delete m_reader->m_original;
00146     m_reader->m_original = 0;
00147 } 
00148 
00149 void
00150 DecodingWavFileReader::addBlock(const SampleBlock &frames)
00151 {
00152     addSamplesToDecodeCache(frames);
00153 
00154     m_processed += frames.size();
00155 
00156     float ratio = float(m_sampleRate) / float(m_fileRate);
00157 
00158     int progress = lrint((float(m_processed) * ratio * 100) /
00159                          float(m_original->getFrameCount()));
00160 
00161     if (progress > 99) progress = 99;
00162     m_completion = progress;
00163     
00164     if (m_reporter) {
00165         m_reporter->setProgress(progress);
00166     }
00167 }
00168 
00169 void
00170 DecodingWavFileReader::getSupportedExtensions(std::set<QString> &extensions)
00171 {
00172     WavFileReader::getSupportedExtensions(extensions);
00173 }
00174 
00175 bool
00176 DecodingWavFileReader::supportsExtension(QString extension)
00177 {
00178     return WavFileReader::supportsExtension(extension);
00179 }
00180 
00181 bool
00182 DecodingWavFileReader::supportsContentType(QString type)
00183 {
00184     return WavFileReader::supportsContentType(type);
00185 }
00186 
00187 bool
00188 DecodingWavFileReader::supports(FileSource &source)
00189 {
00190     return WavFileReader::supports(source);
00191 }
00192 
00193