comparison data/fileio/DecodingWavFileReader.cpp @ 823:f0558e69a074

Rename Resampling- to DecodingWavFileReader, and use it whenever we have an audio file that is not quickly seekable using libsndfile. Avoids very slow performance when analysing ogg files.
author Chris Cannam
date Wed, 17 Jul 2013 15:40:01 +0100
parents data/fileio/ResamplingWavFileReader.cpp@1424aa29ae95
children f3cda3280398 59e7fe1b1003
comparison
equal deleted inserted replaced
821:06c64a1c6785 823:f0558e69a074
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 DecodingWavFileReader::DecodingWavFileReader(FileSource source,
25 ResampleMode resampleMode,
26 CacheMode mode,
27 size_t targetRate,
28 ProgressReporter *reporter) :
29 CodedAudioFileReader(mode, targetRate),
30 m_source(source),
31 m_path(source.getLocalFilename()),
32 m_cancelled(false),
33 m_processed(0),
34 m_completion(0),
35 m_original(0),
36 m_reporter(reporter),
37 m_decodeThread(0)
38 {
39 m_channelCount = 0;
40 m_fileRate = 0;
41
42 SVDEBUG << "DecodingWavFileReader::DecodingWavFileReader(\""
43 << m_path << "\"): rate " << targetRate << endl;
44
45 Profiler profiler("DecodingWavFileReader::DecodingWavFileReader", true);
46
47 m_original = new WavFileReader(m_path);
48 if (!m_original->isOK()) {
49 m_error = m_original->getError();
50 return;
51 }
52
53 m_channelCount = m_original->getChannelCount();
54 m_fileRate = m_original->getSampleRate();
55
56 initialiseDecodeCache();
57
58 if (resampleMode == ResampleAtOnce) {
59
60 if (m_reporter) {
61 connect(m_reporter, SIGNAL(cancelled()), this, SLOT(cancelled()));
62 m_reporter->setMessage
63 (tr("Decoding %1...").arg(QFileInfo(m_path).fileName()));
64 }
65
66 size_t blockSize = 16384;
67 size_t total = m_original->getFrameCount();
68
69 SampleBlock block;
70
71 for (size_t i = 0; i < total; i += blockSize) {
72
73 size_t count = blockSize;
74 if (i + count > total) count = total - i;
75
76 m_original->getInterleavedFrames(i, count, block);
77 addBlock(block);
78
79 if (m_cancelled) break;
80 }
81
82 if (isDecodeCacheInitialised()) finishDecodeCache();
83 endSerialised();
84
85 if (m_reporter) m_reporter->setProgress(100);
86
87 delete m_original;
88 m_original = 0;
89
90 } else {
91
92 if (m_reporter) m_reporter->setProgress(100);
93
94 m_decodeThread = new DecodeThread(this);
95 m_decodeThread->start();
96 }
97 }
98
99 DecodingWavFileReader::~DecodingWavFileReader()
100 {
101 if (m_decodeThread) {
102 m_cancelled = true;
103 m_decodeThread->wait();
104 delete m_decodeThread;
105 }
106
107 delete m_original;
108 }
109
110 void
111 DecodingWavFileReader::cancelled()
112 {
113 m_cancelled = true;
114 }
115
116 void
117 DecodingWavFileReader::DecodeThread::run()
118 {
119 if (m_reader->m_cacheMode == CacheInTemporaryFile) {
120 m_reader->startSerialised("DecodingWavFileReader::Decode");
121 }
122
123 size_t blockSize = 16384;
124 size_t total = m_reader->m_original->getFrameCount();
125
126 SampleBlock block;
127
128 for (size_t i = 0; i < total; i += blockSize) {
129
130 size_t count = blockSize;
131 if (i + count > total) count = total - i;
132
133 m_reader->m_original->getInterleavedFrames(i, count, block);
134 m_reader->addBlock(block);
135
136 if (m_reader->m_cancelled) break;
137 }
138
139 if (m_reader->isDecodeCacheInitialised()) m_reader->finishDecodeCache();
140 m_reader->m_completion = 100;
141
142 m_reader->endSerialised();
143
144 delete m_reader->m_original;
145 m_reader->m_original = 0;
146 }
147
148 void
149 DecodingWavFileReader::addBlock(const SampleBlock &frames)
150 {
151 addSamplesToDecodeCache(frames);
152
153 m_processed += frames.size();
154
155 float ratio = float(m_sampleRate) / float(m_fileRate);
156
157 int progress = lrint((float(m_processed) * ratio * 100) /
158 float(m_original->getFrameCount()));
159
160 if (progress > 99) progress = 99;
161 m_completion = progress;
162
163 if (m_reporter) {
164 m_reporter->setProgress(progress);
165 }
166 }
167
168 void
169 DecodingWavFileReader::getSupportedExtensions(std::set<QString> &extensions)
170 {
171 WavFileReader::getSupportedExtensions(extensions);
172 }
173
174 bool
175 DecodingWavFileReader::supportsExtension(QString extension)
176 {
177 return WavFileReader::supportsExtension(extension);
178 }
179
180 bool
181 DecodingWavFileReader::supportsContentType(QString type)
182 {
183 return WavFileReader::supportsContentType(type);
184 }
185
186 bool
187 DecodingWavFileReader::supports(FileSource &source)
188 {
189 return WavFileReader::supports(source);
190 }
191
192