comparison data/fileio/AudioFileReaderFactory.cpp @ 1126:39019ce29178 tony-2.0-integration

Merge through to branch for Tony 2.0
author Chris Cannam
date Thu, 20 Aug 2015 14:54:21 +0100
parents cd156ede1395
children 6877f4200912
comparison
equal deleted inserted replaced
1119:e22bfe8ca248 1126:39019ce29178
19 #include "DecodingWavFileReader.h" 19 #include "DecodingWavFileReader.h"
20 #include "OggVorbisFileReader.h" 20 #include "OggVorbisFileReader.h"
21 #include "MP3FileReader.h" 21 #include "MP3FileReader.h"
22 #include "QuickTimeFileReader.h" 22 #include "QuickTimeFileReader.h"
23 #include "CoreAudioFileReader.h" 23 #include "CoreAudioFileReader.h"
24 #include "AudioFileSizeEstimator.h"
25
26 #include "base/StorageAdviser.h"
24 27
25 #include <QString> 28 #include <QString>
26 #include <QFileInfo> 29 #include <QFileInfo>
27 #include <iostream> 30 #include <iostream>
28 31
96 return 0; 99 return 0;
97 } 100 }
98 101
99 AudioFileReader *reader = 0; 102 AudioFileReader *reader = 0;
100 103
104 sv_frame_t estimatedSamples =
105 AudioFileSizeEstimator::estimate(source, targetRate);
106
107 CodedAudioFileReader::CacheMode cacheMode =
108 CodedAudioFileReader::CacheInTemporaryFile;
109
110 if (estimatedSamples > 0) {
111 size_t kb = (estimatedSamples * sizeof(float)) / 1024;
112 StorageAdviser::Recommendation rec =
113 StorageAdviser::recommend(StorageAdviser::SpeedCritical, kb, kb);
114 if (rec == StorageAdviser::UseMemory ||
115 rec == StorageAdviser::PreferMemory) {
116 cacheMode = CodedAudioFileReader::CacheInMemory;
117 }
118 }
119
120 CodedAudioFileReader::DecodeMode decodeMode =
121 (threading ?
122 CodedAudioFileReader::DecodeThreaded :
123 CodedAudioFileReader::DecodeAtOnce);
124
101 // Try to construct a preferred reader based on the extension or 125 // Try to construct a preferred reader based on the extension or
102 // MIME type. 126 // MIME type.
127
128 #define CHECK(reader) if (!reader->isOK()) { delete reader; reader = 0; }
103 129
104 if (WavFileReader::supports(source)) { 130 if (WavFileReader::supports(source)) {
105 131
106 reader = new WavFileReader(source); 132 reader = new WavFileReader(source);
107 133
108 sv_samplerate_t fileRate = reader->getSampleRate(); 134 sv_samplerate_t fileRate = reader->getSampleRate();
109 135
110 if (reader->isOK() && 136 if (reader->isOK() &&
111 (!reader->isQuicklySeekable() || 137 (!reader->isQuicklySeekable() ||
112 normalised || 138 normalised ||
139 (cacheMode == CodedAudioFileReader::CacheInMemory) ||
113 (targetRate != 0 && fileRate != targetRate))) { 140 (targetRate != 0 && fileRate != targetRate))) {
114 141
115 SVDEBUG << "AudioFileReaderFactory::createReader: WAV file rate: " << reader->getSampleRate() << ", normalised " << normalised << ", seekable " << reader->isQuicklySeekable() << ", creating decoding reader" << endl; 142 SVDEBUG << "AudioFileReaderFactory::createReader: WAV file rate: " << reader->getSampleRate() << ", normalised " << normalised << ", seekable " << reader->isQuicklySeekable() << ", in memory " << (cacheMode == CodedAudioFileReader::CacheInMemory) << ", creating decoding reader" << endl;
116 143
117 delete reader; 144 delete reader;
118 reader = new DecodingWavFileReader 145 reader = new DecodingWavFileReader
119 (source, 146 (source,
120 threading ? 147 decodeMode, cacheMode,
121 DecodingWavFileReader::ResampleThreaded :
122 DecodingWavFileReader::ResampleAtOnce,
123 DecodingWavFileReader::CacheInTemporaryFile,
124 targetRate ? targetRate : fileRate, 148 targetRate ? targetRate : fileRate,
125 normalised, 149 normalised,
126 reporter); 150 reporter);
127 if (!reader->isOK()) { 151 CHECK(reader);
128 delete reader;
129 reader = 0;
130 }
131 } 152 }
132 } 153 }
133 154
134 #ifdef HAVE_OGGZ 155 #ifdef HAVE_OGGZ
135 #ifdef HAVE_FISHSOUND 156 #ifdef HAVE_FISHSOUND
136 if (!reader) { 157 if (!reader && OggVorbisFileReader::supports(source)) {
137 if (OggVorbisFileReader::supports(source)) { 158 reader = new OggVorbisFileReader
138 reader = new OggVorbisFileReader 159 (source, decodeMode, cacheMode, targetRate, normalised, reporter);
139 (source, 160 CHECK(reader);
140 threading ?
141 OggVorbisFileReader::DecodeThreaded :
142 OggVorbisFileReader::DecodeAtOnce,
143 OggVorbisFileReader::CacheInTemporaryFile,
144 targetRate,
145 normalised,
146 reporter);
147 if (!reader->isOK()) {
148 delete reader;
149 reader = 0;
150 }
151 }
152 } 161 }
153 #endif 162 #endif
154 #endif 163 #endif
155 164
156 #ifdef HAVE_MAD 165 #ifdef HAVE_MAD
157 if (!reader) { 166 if (!reader && MP3FileReader::supports(source)) {
158 if (MP3FileReader::supports(source)) { 167 reader = new MP3FileReader
159 reader = new MP3FileReader 168 (source, decodeMode, cacheMode, targetRate, normalised, reporter);
160 (source, 169 CHECK(reader);
161 threading ?
162 MP3FileReader::DecodeThreaded :
163 MP3FileReader::DecodeAtOnce,
164 MP3FileReader::CacheInTemporaryFile,
165 targetRate,
166 normalised,
167 reporter);
168 if (!reader->isOK()) {
169 delete reader;
170 reader = 0;
171 }
172 }
173 } 170 }
174 #endif 171 #endif
175 172
176 #ifdef HAVE_QUICKTIME 173 #ifdef HAVE_QUICKTIME
177 if (!reader) { 174 if (!reader && QuickTimeFileReader::supports(source)) {
178 if (QuickTimeFileReader::supports(source)) { 175 reader = new QuickTimeFileReader
179 reader = new QuickTimeFileReader 176 (source, decodeMode, cacheMode, targetRate, normalised, reporter);
180 (source, 177 CHECK(reader);
181 threading ?
182 QuickTimeFileReader::DecodeThreaded :
183 QuickTimeFileReader::DecodeAtOnce,
184 QuickTimeFileReader::CacheInTemporaryFile,
185 targetRate,
186 normalised,
187 reporter);
188 if (!reader->isOK()) {
189 delete reader;
190 reader = 0;
191 }
192 }
193 } 178 }
194 #endif 179 #endif
195 180
196 #ifdef HAVE_COREAUDIO 181 #ifdef HAVE_COREAUDIO
197 if (!reader) { 182 if (!reader && CoreAudioFileReader::supports(source)) {
198 if (CoreAudioFileReader::supports(source)) { 183 reader = new CoreAudioFileReader
199 reader = new CoreAudioFileReader 184 (source, decodeMode, cacheMode, targetRate, normalised, reporter);
200 (source, 185 CHECK(reader);
201 threading ? 186 }
202 CoreAudioFileReader::DecodeThreaded : 187 #endif
203 CoreAudioFileReader::DecodeAtOnce, 188
204 CoreAudioFileReader::CacheInTemporaryFile, 189 if (reader) {
205 targetRate, 190 // The happy case: a reader recognised the file extension &
206 normalised, 191 // succeeded in opening the file
207 reporter); 192 return reader;
208 if (!reader->isOK()) { 193 }
209 delete reader; 194
210 reader = 0;
211 }
212 }
213 }
214 #endif
215
216
217 // If none of the readers claimed to support this file extension, 195 // If none of the readers claimed to support this file extension,
218 // perhaps the extension is missing or misleading. Try again, 196 // perhaps the extension is missing or misleading. Try again,
219 // ignoring it. We have to be confident that the reader won't 197 // ignoring it. We have to be confident that the reader won't
220 // open just any old text file or whatever and pretend it's 198 // open just any old text file or whatever and pretend it's
221 // succeeded 199 // succeeded
222 200
223 if (!reader) { 201 reader = new WavFileReader(source);
224 202
225 reader = new WavFileReader(source); 203 sv_samplerate_t fileRate = reader->getSampleRate();
226 204
227 sv_samplerate_t fileRate = reader->getSampleRate(); 205 if (reader->isOK() &&
228 206 (!reader->isQuicklySeekable() ||
229 if (reader->isOK() && 207 normalised ||
230 (!reader->isQuicklySeekable() || 208 (cacheMode == CodedAudioFileReader::CacheInMemory) ||
231 normalised || 209 (targetRate != 0 && fileRate != targetRate))) {
232 (targetRate != 0 && fileRate != targetRate))) { 210
233 211 SVDEBUG << "AudioFileReaderFactory::createReader: WAV file rate: " << reader->getSampleRate() << ", normalised " << normalised << ", seekable " << reader->isQuicklySeekable() << ", in memory " << (cacheMode == CodedAudioFileReader::CacheInMemory) << ", creating decoding reader" << endl;
234 SVDEBUG << "AudioFileReaderFactory::createReader: WAV file rate: " << reader->getSampleRate() << ", normalised " << normalised << ", seekable " << reader->isQuicklySeekable() << ", creating decoding reader" << endl; 212
235 213 delete reader;
236 delete reader; 214 reader = new DecodingWavFileReader
237 reader = new DecodingWavFileReader 215 (source,
238 (source, 216 decodeMode, cacheMode,
239 threading ? 217 targetRate ? targetRate : fileRate,
240 DecodingWavFileReader::ResampleThreaded : 218 normalised,
241 DecodingWavFileReader::ResampleAtOnce, 219 reporter);
242 DecodingWavFileReader::CacheInTemporaryFile, 220 }
243 targetRate ? targetRate : fileRate, 221
244 normalised, 222 CHECK(reader);
245 reporter);
246 }
247
248 if (!reader->isOK()) {
249 delete reader;
250 reader = 0;
251 }
252 }
253 223
254 #ifdef HAVE_OGGZ 224 #ifdef HAVE_OGGZ
255 #ifdef HAVE_FISHSOUND 225 #ifdef HAVE_FISHSOUND
256 if (!reader) { 226 if (!reader) {
257 reader = new OggVorbisFileReader 227 reader = new OggVorbisFileReader
258 (source, 228 (source, decodeMode, cacheMode, targetRate, normalised, reporter);
259 threading ? 229 CHECK(reader);
260 OggVorbisFileReader::DecodeThreaded :
261 OggVorbisFileReader::DecodeAtOnce,
262 OggVorbisFileReader::CacheInTemporaryFile,
263 targetRate,
264 reporter);
265
266 if (!reader->isOK()) {
267 delete reader;
268 reader = 0;
269 }
270 } 230 }
271 #endif 231 #endif
272 #endif 232 #endif
273 233
274 #ifdef HAVE_MAD 234 #ifdef HAVE_MAD
275 if (!reader) { 235 if (!reader) {
276 reader = new MP3FileReader 236 reader = new MP3FileReader
277 (source, 237 (source, decodeMode, cacheMode, targetRate, normalised, reporter);
278 threading ? 238 CHECK(reader);
279 MP3FileReader::DecodeThreaded :
280 MP3FileReader::DecodeAtOnce,
281 MP3FileReader::CacheInTemporaryFile,
282 targetRate,
283 reporter);
284
285 if (!reader->isOK()) {
286 delete reader;
287 reader = 0;
288 }
289 } 239 }
290 #endif 240 #endif
291 241
292 #ifdef HAVE_QUICKTIME 242 #ifdef HAVE_QUICKTIME
293 if (!reader) { 243 if (!reader) {
294 reader = new QuickTimeFileReader 244 reader = new QuickTimeFileReader
295 (source, 245 (source, decodeMode, cacheMode, targetRate, normalised, reporter);
296 threading ? 246 CHECK(reader);
297 QuickTimeFileReader::DecodeThreaded :
298 QuickTimeFileReader::DecodeAtOnce,
299 QuickTimeFileReader::CacheInTemporaryFile,
300 targetRate,
301 reporter);
302
303 if (!reader->isOK()) {
304 delete reader;
305 reader = 0;
306 }
307 } 247 }
308 #endif 248 #endif
309 249
310 #ifdef HAVE_COREAUDIO 250 #ifdef HAVE_COREAUDIO
311 if (!reader) { 251 if (!reader) {
312 reader = new CoreAudioFileReader 252 reader = new CoreAudioFileReader
313 (source, 253 (source, decodeMode, cacheMode, targetRate, normalised, reporter);
314 threading ? 254 CHECK(reader);
315 CoreAudioFileReader::DecodeThreaded : 255 }
316 CoreAudioFileReader::DecodeAtOnce, 256 #endif
317 CoreAudioFileReader::CacheInTemporaryFile, 257
318 targetRate, 258 if (!reader) {
319 reporter); 259 cerr << "AudioFileReaderFactory::Failed to create a reader for "
320 260 << "url \"" << source.getLocation()
321 if (!reader->isOK()) { 261 << "\" (content type \""
322 delete reader; 262 << source.getContentType() << "\")" << endl;
323 reader = 0; 263 return nullptr;
324 } 264 }
325 } 265
326 #endif
327
328 if (reader) {
329 if (reader->isOK()) {
330 SVDEBUG << "AudioFileReaderFactory: Reader is OK" << endl;
331 return reader;
332 }
333 cerr << "AudioFileReaderFactory: Preferred reader for "
334 << "url \"" << source.getLocation()
335 << "\" (content type \""
336 << source.getContentType() << "\") failed";
337
338 if (reader->getError() != "") {
339 cerr << ": \"" << reader->getError() << "\"";
340 }
341 cerr << endl;
342 delete reader;
343 reader = 0;
344 }
345
346 cerr << "AudioFileReaderFactory: No reader" << endl;
347 return reader; 266 return reader;
348 } 267 }
349 268