annotate data/fileio/AudioFileReaderFactory.cpp @ 998:e25dc8d57565

Add descriptions for writers; add housekeeping options to Sonic Annotator to list writers and formats
author Chris Cannam
date Mon, 13 Oct 2014 14:44:51 +0100
parents d03b3d956358
children a1cd5abcb38b
rev   line source
Chris@386 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
Chris@386 2
Chris@386 3 /*
Chris@386 4 Sonic Visualiser
Chris@386 5 An audio file viewer and annotation editor.
Chris@386 6 Centre for Digital Music, Queen Mary, University of London.
Chris@386 7 This file copyright 2006 Chris Cannam and QMUL.
Chris@386 8
Chris@386 9 This program is free software; you can redistribute it and/or
Chris@386 10 modify it under the terms of the GNU General Public License as
Chris@386 11 published by the Free Software Foundation; either version 2 of the
Chris@386 12 License, or (at your option) any later version. See the file
Chris@386 13 COPYING included with this distribution for more information.
Chris@386 14 */
Chris@386 15
Chris@386 16 #include "AudioFileReaderFactory.h"
Chris@386 17
Chris@386 18 #include "WavFileReader.h"
Chris@823 19 #include "DecodingWavFileReader.h"
Chris@386 20 #include "OggVorbisFileReader.h"
Chris@386 21 #include "MP3FileReader.h"
Chris@386 22 #include "QuickTimeFileReader.h"
luisf@665 23 #include "CoreAudioFileReader.h"
Chris@386 24
Chris@386 25 #include <QString>
Chris@386 26 #include <QFileInfo>
Chris@386 27 #include <iostream>
Chris@386 28
Chris@386 29 QString
Chris@386 30 AudioFileReaderFactory::getKnownExtensions()
Chris@386 31 {
Chris@386 32 std::set<QString> extensions;
Chris@386 33
Chris@386 34 WavFileReader::getSupportedExtensions(extensions);
Chris@386 35 #ifdef HAVE_MAD
Chris@386 36 MP3FileReader::getSupportedExtensions(extensions);
Chris@386 37 #endif
Chris@386 38 #ifdef HAVE_OGGZ
Chris@386 39 #ifdef HAVE_FISHSOUND
Chris@386 40 OggVorbisFileReader::getSupportedExtensions(extensions);
Chris@386 41 #endif
Chris@386 42 #endif
Chris@386 43 #ifdef HAVE_QUICKTIME
Chris@386 44 QuickTimeFileReader::getSupportedExtensions(extensions);
Chris@386 45 #endif
luisf@665 46 #ifdef HAVE_COREAUDIO
luisf@665 47 CoreAudioFileReader::getSupportedExtensions(extensions);
luisf@665 48 #endif
Chris@386 49
Chris@386 50 QString rv;
Chris@386 51 for (std::set<QString>::const_iterator i = extensions.begin();
Chris@386 52 i != extensions.end(); ++i) {
Chris@386 53 if (i != extensions.begin()) rv += " ";
Chris@386 54 rv += "*." + *i;
Chris@386 55 }
Chris@386 56
Chris@386 57 return rv;
Chris@386 58 }
Chris@386 59
Chris@386 60 AudioFileReader *
Chris@920 61 AudioFileReaderFactory::createReader(FileSource source,
Chris@933 62 int targetRate,
Chris@920 63 bool normalised,
Chris@392 64 ProgressReporter *reporter)
Chris@386 65 {
Chris@920 66 return create(source, targetRate, normalised, false, reporter);
Chris@386 67 }
Chris@386 68
Chris@386 69 AudioFileReader *
Chris@920 70 AudioFileReaderFactory::createThreadingReader(FileSource source,
Chris@933 71 int targetRate,
Chris@920 72 bool normalised,
Chris@392 73 ProgressReporter *reporter)
Chris@386 74 {
Chris@920 75 return create(source, targetRate, normalised, true, reporter);
Chris@386 76 }
Chris@386 77
Chris@386 78 AudioFileReader *
Chris@920 79 AudioFileReaderFactory::create(FileSource source,
Chris@933 80 int targetRate,
Chris@920 81 bool normalised,
Chris@920 82 bool threading,
Chris@392 83 ProgressReporter *reporter)
Chris@386 84 {
Chris@386 85 QString err;
Chris@386 86
Chris@742 87 SVDEBUG << "AudioFileReaderFactory::createReader(\"" << source.getLocation() << "\"): Requested rate: " << targetRate << endl;
Chris@386 88
Chris@667 89 if (!source.isOK()) {
Chris@843 90 cerr << "AudioFileReaderFactory::createReader(\"" << source.getLocation() << "\": Failed to retrieve source (transmission error?): " << source.getErrorString() << endl;
Chris@667 91 return 0;
Chris@667 92 }
Chris@667 93
Chris@667 94 if (!source.isAvailable()) {
Chris@690 95 SVDEBUG << "AudioFileReaderFactory::createReader(\"" << source.getLocation() << "\": Source not found" << endl;
Chris@386 96 return 0;
Chris@386 97 }
Chris@386 98
Chris@386 99 AudioFileReader *reader = 0;
Chris@386 100
Chris@386 101 // Try to construct a preferred reader based on the extension or
Chris@386 102 // MIME type.
Chris@386 103
Chris@386 104 if (WavFileReader::supports(source)) {
Chris@386 105
Chris@386 106 reader = new WavFileReader(source);
Chris@386 107
Chris@823 108 int fileRate = reader->getSampleRate();
Chris@386 109
Chris@823 110 if (reader->isOK() &&
Chris@823 111 (!reader->isQuicklySeekable() ||
Chris@920 112 normalised ||
Chris@823 113 (targetRate != 0 && fileRate != targetRate))) {
Chris@823 114
Chris@920 115 SVDEBUG << "AudioFileReaderFactory::createReader: WAV file rate: " << reader->getSampleRate() << ", normalised " << normalised << ", seekable " << reader->isQuicklySeekable() << ", creating decoding reader" << endl;
Chris@386 116
Chris@386 117 delete reader;
Chris@823 118 reader = new DecodingWavFileReader
Chris@386 119 (source,
Chris@386 120 threading ?
Chris@823 121 DecodingWavFileReader::ResampleThreaded :
Chris@823 122 DecodingWavFileReader::ResampleAtOnce,
Chris@823 123 DecodingWavFileReader::CacheInTemporaryFile,
Chris@823 124 targetRate ? targetRate : fileRate,
Chris@920 125 normalised,
Chris@392 126 reporter);
Chris@440 127 if (!reader->isOK()) {
Chris@440 128 delete reader;
Chris@440 129 reader = 0;
Chris@440 130 }
Chris@386 131 }
Chris@386 132 }
Chris@386 133
Chris@386 134 #ifdef HAVE_OGGZ
Chris@386 135 #ifdef HAVE_FISHSOUND
Chris@386 136 if (!reader) {
Chris@386 137 if (OggVorbisFileReader::supports(source)) {
Chris@386 138 reader = new OggVorbisFileReader
Chris@386 139 (source,
Chris@386 140 threading ?
Chris@386 141 OggVorbisFileReader::DecodeThreaded :
Chris@386 142 OggVorbisFileReader::DecodeAtOnce,
Chris@386 143 OggVorbisFileReader::CacheInTemporaryFile,
Chris@392 144 targetRate,
Chris@920 145 normalised,
Chris@392 146 reporter);
Chris@440 147 if (!reader->isOK()) {
Chris@440 148 delete reader;
Chris@440 149 reader = 0;
Chris@440 150 }
Chris@386 151 }
Chris@386 152 }
Chris@386 153 #endif
Chris@386 154 #endif
Chris@386 155
Chris@386 156 #ifdef HAVE_MAD
Chris@386 157 if (!reader) {
Chris@386 158 if (MP3FileReader::supports(source)) {
Chris@386 159 reader = new MP3FileReader
Chris@386 160 (source,
Chris@386 161 threading ?
Chris@386 162 MP3FileReader::DecodeThreaded :
Chris@386 163 MP3FileReader::DecodeAtOnce,
Chris@386 164 MP3FileReader::CacheInTemporaryFile,
Chris@392 165 targetRate,
Chris@920 166 normalised,
Chris@392 167 reporter);
Chris@440 168 if (!reader->isOK()) {
Chris@440 169 delete reader;
Chris@440 170 reader = 0;
Chris@440 171 }
Chris@386 172 }
Chris@386 173 }
Chris@386 174 #endif
Chris@386 175
Chris@386 176 #ifdef HAVE_QUICKTIME
Chris@386 177 if (!reader) {
Chris@386 178 if (QuickTimeFileReader::supports(source)) {
Chris@386 179 reader = new QuickTimeFileReader
Chris@386 180 (source,
Chris@386 181 threading ?
Chris@386 182 QuickTimeFileReader::DecodeThreaded :
Chris@386 183 QuickTimeFileReader::DecodeAtOnce,
Chris@386 184 QuickTimeFileReader::CacheInTemporaryFile,
Chris@392 185 targetRate,
Chris@920 186 normalised,
Chris@392 187 reporter);
Chris@440 188 if (!reader->isOK()) {
Chris@440 189 delete reader;
Chris@440 190 reader = 0;
Chris@440 191 }
Chris@440 192 }
Chris@440 193 }
Chris@440 194 #endif
Chris@440 195
luisf@665 196 #ifdef HAVE_COREAUDIO
luisf@665 197 if (!reader) {
luisf@665 198 if (CoreAudioFileReader::supports(source)) {
luisf@665 199 reader = new CoreAudioFileReader
luisf@665 200 (source,
luisf@665 201 threading ?
luisf@665 202 CoreAudioFileReader::DecodeThreaded :
luisf@665 203 CoreAudioFileReader::DecodeAtOnce,
luisf@665 204 CoreAudioFileReader::CacheInTemporaryFile,
luisf@665 205 targetRate,
Chris@920 206 normalised,
luisf@665 207 reporter);
luisf@665 208 if (!reader->isOK()) {
luisf@665 209 delete reader;
luisf@665 210 reader = 0;
luisf@665 211 }
luisf@665 212 }
luisf@665 213 }
luisf@665 214 #endif
luisf@665 215
luisf@665 216
Chris@440 217 // If none of the readers claimed to support this file extension,
Chris@440 218 // perhaps the extension is missing or misleading. Try again,
Chris@440 219 // ignoring it. We have to be confident that the reader won't
Chris@440 220 // open just any old text file or whatever and pretend it's
Chris@440 221 // succeeded
Chris@440 222
Chris@440 223 if (!reader) {
Chris@440 224
Chris@440 225 reader = new WavFileReader(source);
Chris@440 226
Chris@823 227 int fileRate = reader->getSampleRate();
Chris@440 228
Chris@823 229 if (reader->isOK() &&
Chris@823 230 (!reader->isQuicklySeekable() ||
Chris@920 231 normalised ||
Chris@823 232 (targetRate != 0 && fileRate != targetRate))) {
Chris@823 233
Chris@920 234 SVDEBUG << "AudioFileReaderFactory::createReader: WAV file rate: " << reader->getSampleRate() << ", normalised " << normalised << ", seekable " << reader->isQuicklySeekable() << ", creating decoding reader" << endl;
Chris@440 235
Chris@440 236 delete reader;
Chris@823 237 reader = new DecodingWavFileReader
Chris@440 238 (source,
Chris@440 239 threading ?
Chris@823 240 DecodingWavFileReader::ResampleThreaded :
Chris@823 241 DecodingWavFileReader::ResampleAtOnce,
Chris@823 242 DecodingWavFileReader::CacheInTemporaryFile,
Chris@823 243 targetRate ? targetRate : fileRate,
Chris@920 244 normalised,
Chris@440 245 reporter);
Chris@440 246 }
Chris@440 247
Chris@440 248 if (!reader->isOK()) {
Chris@440 249 delete reader;
Chris@440 250 reader = 0;
Chris@440 251 }
Chris@440 252 }
Chris@440 253
Chris@440 254 #ifdef HAVE_OGGZ
Chris@440 255 #ifdef HAVE_FISHSOUND
Chris@440 256 if (!reader) {
Chris@440 257 reader = new OggVorbisFileReader
Chris@440 258 (source,
Chris@440 259 threading ?
Chris@440 260 OggVorbisFileReader::DecodeThreaded :
Chris@440 261 OggVorbisFileReader::DecodeAtOnce,
Chris@440 262 OggVorbisFileReader::CacheInTemporaryFile,
Chris@440 263 targetRate,
Chris@440 264 reporter);
Chris@440 265
Chris@440 266 if (!reader->isOK()) {
Chris@440 267 delete reader;
Chris@440 268 reader = 0;
Chris@440 269 }
Chris@440 270 }
Chris@440 271 #endif
Chris@440 272 #endif
Chris@440 273
Chris@440 274 #ifdef HAVE_MAD
Chris@440 275 if (!reader) {
Chris@440 276 reader = new MP3FileReader
Chris@440 277 (source,
Chris@440 278 threading ?
Chris@440 279 MP3FileReader::DecodeThreaded :
Chris@440 280 MP3FileReader::DecodeAtOnce,
Chris@440 281 MP3FileReader::CacheInTemporaryFile,
Chris@440 282 targetRate,
Chris@440 283 reporter);
Chris@440 284
Chris@440 285 if (!reader->isOK()) {
Chris@440 286 delete reader;
Chris@440 287 reader = 0;
Chris@440 288 }
Chris@440 289 }
Chris@440 290 #endif
Chris@440 291
Chris@440 292 #ifdef HAVE_QUICKTIME
Chris@440 293 if (!reader) {
Chris@440 294 reader = new QuickTimeFileReader
Chris@440 295 (source,
Chris@440 296 threading ?
Chris@440 297 QuickTimeFileReader::DecodeThreaded :
Chris@440 298 QuickTimeFileReader::DecodeAtOnce,
Chris@440 299 QuickTimeFileReader::CacheInTemporaryFile,
Chris@440 300 targetRate,
Chris@440 301 reporter);
Chris@440 302
Chris@440 303 if (!reader->isOK()) {
Chris@440 304 delete reader;
Chris@440 305 reader = 0;
Chris@386 306 }
Chris@386 307 }
Chris@386 308 #endif
Chris@386 309
luisf@665 310 #ifdef HAVE_COREAUDIO
luisf@665 311 if (!reader) {
luisf@665 312 reader = new CoreAudioFileReader
luisf@665 313 (source,
luisf@665 314 threading ?
luisf@665 315 CoreAudioFileReader::DecodeThreaded :
luisf@665 316 CoreAudioFileReader::DecodeAtOnce,
luisf@665 317 CoreAudioFileReader::CacheInTemporaryFile,
luisf@665 318 targetRate,
luisf@665 319 reporter);
luisf@665 320
luisf@665 321 if (!reader->isOK()) {
luisf@665 322 delete reader;
luisf@665 323 reader = 0;
luisf@665 324 }
luisf@665 325 }
luisf@665 326 #endif
luisf@665 327
Chris@386 328 if (reader) {
Chris@386 329 if (reader->isOK()) {
Chris@756 330 SVDEBUG << "AudioFileReaderFactory: Reader is OK" << endl;
Chris@386 331 return reader;
Chris@386 332 }
Chris@843 333 cerr << "AudioFileReaderFactory: Preferred reader for "
Chris@844 334 << "url \"" << source.getLocation()
Chris@386 335 << "\" (content type \""
Chris@686 336 << source.getContentType() << "\") failed";
Chris@386 337
Chris@386 338 if (reader->getError() != "") {
Chris@843 339 cerr << ": \"" << reader->getError() << "\"";
Chris@386 340 }
Chris@843 341 cerr << endl;
Chris@386 342 delete reader;
Chris@386 343 reader = 0;
Chris@386 344 }
Chris@386 345
Chris@843 346 cerr << "AudioFileReaderFactory: No reader" << endl;
Chris@386 347 return reader;
Chris@386 348 }
Chris@386 349