DecodingWavFileReader.cpp
Go to the documentation of this file.
1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
2 
3 /*
4  Sonic Visualiser
5  An audio file viewer and annotation editor.
6  Centre for Digital Music, Queen Mary, University of London.
7  This file copyright 2007 QMUL.
8 
9  This program is free software; you can redistribute it and/or
10  modify it under the terms of the GNU General Public License as
11  published by the Free Software Foundation; either version 2 of the
12  License, or (at your option) any later version. See the file
13  COPYING included with this distribution for more information.
14 */
15 
16 #include "DecodingWavFileReader.h"
17 
18 #include "WavFileReader.h"
19 #include "base/Profiler.h"
20 #include "base/ProgressReporter.h"
21 
22 #include <QFileInfo>
23 
24 using namespace std;
25 
27  DecodeMode decodeMode,
28  CacheMode mode,
29  sv_samplerate_t targetRate,
30  bool normalised,
31  ProgressReporter *reporter) :
32  CodedAudioFileReader(mode, targetRate, normalised),
33  m_source(source),
34  m_path(source.getLocalFilename()),
35  m_cancelled(false),
36  m_processed(0),
37  m_completion(0),
38  m_original(nullptr),
39  m_reporter(reporter),
40  m_decodeThread(nullptr)
41 {
42  SVDEBUG << "DecodingWavFileReader: local path: \"" << m_path
43  << "\", decode mode: " << decodeMode << " ("
44  << (decodeMode == DecodeAtOnce ? "DecodeAtOnce" : "DecodeThreaded")
45  << ")" << endl;
46 
47  m_channelCount = 0;
48  m_fileRate = 0;
49 
50  Profiler profiler("DecodingWavFileReader::DecodingWavFileReader");
51 
53  if (!m_original->isOK()) {
55  return;
56  }
57 
58  m_channelCount = m_original->getChannelCount();
60 
63 
65 
66  if (decodeMode == DecodeAtOnce) {
67 
68  if (m_reporter) {
69  connect(m_reporter, SIGNAL(cancelled()), this, SLOT(cancelled()));
71  (tr("Decoding %1...").arg(QFileInfo(m_path).fileName()));
72  }
73 
74  sv_frame_t blockSize = 16384;
76 
77  floatvec_t block;
78 
79  for (sv_frame_t i = 0; i < total; i += blockSize) {
80 
81  sv_frame_t count = blockSize;
82  if (i + count > total) count = total - i;
83 
84  block = m_original->getInterleavedFrames(i, count);
85  addBlock(block);
86 
87  if (m_cancelled) break;
88  }
89 
91  endSerialised();
92 
94 
95  delete m_original;
96  m_original = nullptr;
97 
98  } else {
99 
100  if (m_reporter) m_reporter->setProgress(100);
101 
102  m_decodeThread = new DecodeThread(this);
104  }
105 }
106 
108 {
109  if (m_decodeThread) {
110  m_cancelled = true;
111  m_decodeThread->wait();
112  delete m_decodeThread;
113  }
114 
115  delete m_original;
116 }
117 
118 void
120 {
121  m_cancelled = true;
122 }
123 
124 void
126 {
127  if (m_reader->m_cacheMode == CacheInTemporaryFile) {
128  m_reader->startSerialised("DecodingWavFileReader::Decode",
129  &m_reader->m_cancelled);
130  if (m_reader->m_cancelled) {
131  return;
132  }
133  }
134 
135  sv_frame_t blockSize = 16384;
136  sv_frame_t total = m_reader->m_original->getFrameCount();
137 
138  floatvec_t block;
139 
140  for (sv_frame_t i = 0; i < total; i += blockSize) {
141 
142  sv_frame_t count = blockSize;
143  if (i + count > total) count = total - i;
144 
145  block = m_reader->m_original->getInterleavedFrames(i, count);
146  m_reader->addBlock(block);
147 
148  if (m_reader->m_cancelled) break;
149  }
150 
151  if (m_reader->isDecodeCacheInitialised()) m_reader->finishDecodeCache();
152  m_reader->m_completion = 100;
153 
154  m_reader->endSerialised();
155 
156  delete m_reader->m_original;
157  m_reader->m_original = nullptr;
158 }
159 
160 void
162 {
163  addSamplesToDecodeCache(frames);
164 
165  m_processed += frames.size();
166 
167  double ratio = double(m_sampleRate) / double(m_fileRate);
168 
169  int progress = int(lrint((double(m_processed) * ratio * 100) /
170  double(m_original->getFrameCount())));
171 
172  if (progress > 99) progress = 99;
174 
175  if (m_reporter) {
176  m_reporter->setProgress(progress);
177  }
178 }
179 
180 void
182 {
184 }
185 
186 bool
188 {
189  return WavFileReader::supportsExtension(extension);
190 }
191 
192 bool
194 {
196 }
197 
198 bool
200 {
201  return WavFileReader::supports(source);
202 }
203 
204 
double sv_samplerate_t
Sample rate.
Definition: BaseTypes.h:51
int64_t sv_frame_t
Frame index, the unit of our time axis.
Definition: BaseTypes.h:31
static bool supportsContentType(QString type)
Reader for audio files using libsndfile.
Definition: WavFileReader.h:41
static bool supports(FileSource &source)
void start()
Definition: Thread.cpp:34
static bool supportsExtension(QString ext)
void addBlock(const floatvec_t &frames)
static bool supportsContentType(QString type)
static bool supports(FileSource &source)
std::vector< float, breakfastquay::StlAllocator< float > > floatvec_t
Definition: BaseTypes.h:53
static void getSupportedExtensions(std::set< QString > &extensions)
FileSource is a class used to refer to the contents of a file that may be either local or at a remote...
Definition: FileSource.h:59
static void getSupportedExtensions(std::set< QString > &extensions)
void addSamplesToDecodeCache(float **samples, sv_frame_t nframes)
QString getError() const override
If isOK() is false, return an error string.
Definition: WavFileReader.h:52
virtual void setProgress(int percentage)=0
#define SVDEBUG
Definition: Debug.h:106
bool isOK() const
Return true if the file was opened successfully and no error has subsequently occurred.
DecodingWavFileReader(FileSource source, DecodeMode decodeMode, CacheMode cacheMode, sv_samplerate_t targetRate=0, bool normalised=false, ProgressReporter *reporter=0)
std::atomic< bool > m_cancelled
QString getTitle() const override
Return the title of the work in the audio file, if known.
Definition: WavFileReader.h:54
ProgressReporter * m_reporter
virtual void setMessage(QString text)=0
sv_frame_t getFrameCount() const
Return the number of audio sample frames (i.e.
floatvec_t getInterleavedFrames(sv_frame_t start, sv_frame_t count) const override
Must be safe to call from multiple threads with different arguments on the same object at the same ti...
sv_samplerate_t m_sampleRate
bool isDecodeCacheInitialised() const
QString getMaker() const override
Return the "maker" of the work in the audio file, if known.
Definition: WavFileReader.h:55
static bool supportsExtension(QString ext)
sv_samplerate_t getSampleRate() const
Return the samplerate at which the file is being read.
int getChannelCount() const
Return the number of channels in the file.
Profile point instance class.
Definition: Profiler.h:93