annotate data/fileio/AudioFileReaderFactory.cpp @ 706:579b2da21e7a

Make FileSource capable of handling resource files. Without this, we failed to open the silent resource file used as a placeholder in templates and thus failed to replace it with the proper file after loading the template -- the consequence was that (although the right audio file ended up being shown as the main model) any derived models were not regenerated
author Chris Cannam
date Fri, 07 Oct 2011 17:04:09 +0100
parents 1424aa29ae95
children c10cb8782576
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@386 19 #include "ResamplingWavFileReader.h"
Chris@386 20 #include "OggVorbisFileReader.h"
Chris@386 21 #include "MP3FileReader.h"
Chris@386 22 #include "QuickTimeFileReader.h"
Chris@386 23
Chris@386 24 #include <QString>
Chris@386 25 #include <QFileInfo>
Chris@386 26 #include <iostream>
Chris@386 27
Chris@386 28 QString
Chris@386 29 AudioFileReaderFactory::getKnownExtensions()
Chris@386 30 {
Chris@386 31 std::set<QString> extensions;
Chris@386 32
Chris@386 33 WavFileReader::getSupportedExtensions(extensions);
Chris@386 34 #ifdef HAVE_MAD
Chris@386 35 MP3FileReader::getSupportedExtensions(extensions);
Chris@386 36 #endif
Chris@386 37 #ifdef HAVE_OGGZ
Chris@386 38 #ifdef HAVE_FISHSOUND
Chris@386 39 OggVorbisFileReader::getSupportedExtensions(extensions);
Chris@386 40 #endif
Chris@386 41 #endif
Chris@386 42 #ifdef HAVE_QUICKTIME
Chris@386 43 QuickTimeFileReader::getSupportedExtensions(extensions);
Chris@386 44 #endif
Chris@386 45
Chris@386 46 QString rv;
Chris@386 47 for (std::set<QString>::const_iterator i = extensions.begin();
Chris@386 48 i != extensions.end(); ++i) {
Chris@386 49 if (i != extensions.begin()) rv += " ";
Chris@386 50 rv += "*." + *i;
Chris@386 51 }
Chris@386 52
Chris@386 53 return rv;
Chris@386 54 }
Chris@386 55
Chris@386 56 AudioFileReader *
Chris@392 57 AudioFileReaderFactory::createReader(FileSource source, size_t targetRate,
Chris@392 58 ProgressReporter *reporter)
Chris@386 59 {
Chris@392 60 return create(source, targetRate, false, reporter);
Chris@386 61 }
Chris@386 62
Chris@386 63 AudioFileReader *
Chris@392 64 AudioFileReaderFactory::createThreadingReader(FileSource source, size_t targetRate,
Chris@392 65 ProgressReporter *reporter)
Chris@386 66 {
Chris@392 67 return create(source, targetRate, true, reporter);
Chris@386 68 }
Chris@386 69
Chris@386 70 AudioFileReader *
Chris@392 71 AudioFileReaderFactory::create(FileSource source, size_t targetRate, bool threading,
Chris@392 72 ProgressReporter *reporter)
Chris@386 73 {
Chris@386 74 QString err;
Chris@386 75
Chris@690 76 // SVDEBUG << "AudioFileReaderFactory::createReader(\"" << source.getLocation() << "\"): Requested rate: " << targetRate << endl;
Chris@386 77
Chris@667 78 if (!source.isOK()) {
Chris@686 79 std::cerr << "AudioFileReaderFactory::createReader(\"" << source.getLocation() << "\": Failed to retrieve source (transmission error?): " << source.getErrorString() << std::endl;
Chris@667 80 return 0;
Chris@667 81 }
Chris@667 82
Chris@667 83 if (!source.isAvailable()) {
Chris@690 84 SVDEBUG << "AudioFileReaderFactory::createReader(\"" << source.getLocation() << "\": Source not found" << endl;
Chris@386 85 return 0;
Chris@386 86 }
Chris@386 87
Chris@386 88 AudioFileReader *reader = 0;
Chris@386 89
Chris@386 90 // Try to construct a preferred reader based on the extension or
Chris@386 91 // MIME type.
Chris@386 92
Chris@386 93 if (WavFileReader::supports(source)) {
Chris@386 94
Chris@386 95 reader = new WavFileReader(source);
Chris@386 96
Chris@386 97 if (targetRate != 0 &&
Chris@386 98 reader->isOK() &&
Chris@386 99 reader->getSampleRate() != targetRate) {
Chris@386 100
Chris@690 101 SVDEBUG << "AudioFileReaderFactory::createReader: WAV file rate: " << reader->getSampleRate() << ", creating resampling reader" << endl;
Chris@386 102
Chris@386 103 delete reader;
Chris@386 104 reader = new ResamplingWavFileReader
Chris@386 105 (source,
Chris@386 106 threading ?
Chris@386 107 ResamplingWavFileReader::ResampleThreaded :
Chris@386 108 ResamplingWavFileReader::ResampleAtOnce,
Chris@386 109 ResamplingWavFileReader::CacheInTemporaryFile,
Chris@392 110 targetRate,
Chris@392 111 reporter);
Chris@440 112 if (!reader->isOK()) {
Chris@440 113 delete reader;
Chris@440 114 reader = 0;
Chris@440 115 }
Chris@386 116 }
Chris@386 117 }
Chris@386 118
Chris@386 119 #ifdef HAVE_OGGZ
Chris@386 120 #ifdef HAVE_FISHSOUND
Chris@386 121 if (!reader) {
Chris@386 122 if (OggVorbisFileReader::supports(source)) {
Chris@386 123 reader = new OggVorbisFileReader
Chris@386 124 (source,
Chris@386 125 threading ?
Chris@386 126 OggVorbisFileReader::DecodeThreaded :
Chris@386 127 OggVorbisFileReader::DecodeAtOnce,
Chris@386 128 OggVorbisFileReader::CacheInTemporaryFile,
Chris@392 129 targetRate,
Chris@392 130 reporter);
Chris@440 131 if (!reader->isOK()) {
Chris@440 132 delete reader;
Chris@440 133 reader = 0;
Chris@440 134 }
Chris@386 135 }
Chris@386 136 }
Chris@386 137 #endif
Chris@386 138 #endif
Chris@386 139
Chris@386 140 #ifdef HAVE_MAD
Chris@386 141 if (!reader) {
Chris@386 142 if (MP3FileReader::supports(source)) {
Chris@386 143 reader = new MP3FileReader
Chris@386 144 (source,
Chris@386 145 threading ?
Chris@386 146 MP3FileReader::DecodeThreaded :
Chris@386 147 MP3FileReader::DecodeAtOnce,
Chris@386 148 MP3FileReader::CacheInTemporaryFile,
Chris@392 149 targetRate,
Chris@392 150 reporter);
Chris@440 151 if (!reader->isOK()) {
Chris@440 152 delete reader;
Chris@440 153 reader = 0;
Chris@440 154 }
Chris@386 155 }
Chris@386 156 }
Chris@386 157 #endif
Chris@386 158
Chris@386 159 #ifdef HAVE_QUICKTIME
Chris@386 160 if (!reader) {
Chris@386 161 if (QuickTimeFileReader::supports(source)) {
Chris@386 162 reader = new QuickTimeFileReader
Chris@386 163 (source,
Chris@386 164 threading ?
Chris@386 165 QuickTimeFileReader::DecodeThreaded :
Chris@386 166 QuickTimeFileReader::DecodeAtOnce,
Chris@386 167 QuickTimeFileReader::CacheInTemporaryFile,
Chris@392 168 targetRate,
Chris@392 169 reporter);
Chris@440 170 if (!reader->isOK()) {
Chris@440 171 delete reader;
Chris@440 172 reader = 0;
Chris@440 173 }
Chris@440 174 }
Chris@440 175 }
Chris@440 176 #endif
Chris@440 177
Chris@440 178 // If none of the readers claimed to support this file extension,
Chris@440 179 // perhaps the extension is missing or misleading. Try again,
Chris@440 180 // ignoring it. We have to be confident that the reader won't
Chris@440 181 // open just any old text file or whatever and pretend it's
Chris@440 182 // succeeded
Chris@440 183
Chris@440 184 if (!reader) {
Chris@440 185
Chris@440 186 reader = new WavFileReader(source);
Chris@440 187
Chris@440 188 if (targetRate != 0 &&
Chris@440 189 reader->isOK() &&
Chris@440 190 reader->getSampleRate() != targetRate) {
Chris@440 191
Chris@690 192 SVDEBUG << "AudioFileReaderFactory::createReader: WAV file rate: " << reader->getSampleRate() << ", creating resampling reader" << endl;
Chris@440 193
Chris@440 194 delete reader;
Chris@440 195 reader = new ResamplingWavFileReader
Chris@440 196 (source,
Chris@440 197 threading ?
Chris@440 198 ResamplingWavFileReader::ResampleThreaded :
Chris@440 199 ResamplingWavFileReader::ResampleAtOnce,
Chris@440 200 ResamplingWavFileReader::CacheInTemporaryFile,
Chris@440 201 targetRate,
Chris@440 202 reporter);
Chris@440 203 }
Chris@440 204
Chris@440 205 if (!reader->isOK()) {
Chris@440 206 delete reader;
Chris@440 207 reader = 0;
Chris@440 208 }
Chris@440 209 }
Chris@440 210
Chris@440 211 #ifdef HAVE_OGGZ
Chris@440 212 #ifdef HAVE_FISHSOUND
Chris@440 213 if (!reader) {
Chris@440 214 reader = new OggVorbisFileReader
Chris@440 215 (source,
Chris@440 216 threading ?
Chris@440 217 OggVorbisFileReader::DecodeThreaded :
Chris@440 218 OggVorbisFileReader::DecodeAtOnce,
Chris@440 219 OggVorbisFileReader::CacheInTemporaryFile,
Chris@440 220 targetRate,
Chris@440 221 reporter);
Chris@440 222
Chris@440 223 if (!reader->isOK()) {
Chris@440 224 delete reader;
Chris@440 225 reader = 0;
Chris@440 226 }
Chris@440 227 }
Chris@440 228 #endif
Chris@440 229 #endif
Chris@440 230
Chris@440 231 #ifdef HAVE_MAD
Chris@440 232 if (!reader) {
Chris@440 233 reader = new MP3FileReader
Chris@440 234 (source,
Chris@440 235 threading ?
Chris@440 236 MP3FileReader::DecodeThreaded :
Chris@440 237 MP3FileReader::DecodeAtOnce,
Chris@440 238 MP3FileReader::CacheInTemporaryFile,
Chris@440 239 targetRate,
Chris@440 240 reporter);
Chris@440 241
Chris@440 242 if (!reader->isOK()) {
Chris@440 243 delete reader;
Chris@440 244 reader = 0;
Chris@440 245 }
Chris@440 246 }
Chris@440 247 #endif
Chris@440 248
Chris@440 249 #ifdef HAVE_QUICKTIME
Chris@440 250 if (!reader) {
Chris@440 251 reader = new QuickTimeFileReader
Chris@440 252 (source,
Chris@440 253 threading ?
Chris@440 254 QuickTimeFileReader::DecodeThreaded :
Chris@440 255 QuickTimeFileReader::DecodeAtOnce,
Chris@440 256 QuickTimeFileReader::CacheInTemporaryFile,
Chris@440 257 targetRate,
Chris@440 258 reporter);
Chris@440 259
Chris@440 260 if (!reader->isOK()) {
Chris@440 261 delete reader;
Chris@440 262 reader = 0;
Chris@386 263 }
Chris@386 264 }
Chris@386 265 #endif
Chris@386 266
Chris@386 267 if (reader) {
Chris@386 268 if (reader->isOK()) {
Chris@386 269 // std::cerr << "AudioFileReaderFactory: Reader is OK" << std::endl;
Chris@386 270 return reader;
Chris@386 271 }
Chris@386 272 std::cerr << "AudioFileReaderFactory: Preferred reader for "
Chris@386 273 << "url \"" << source.getLocation().toStdString()
Chris@386 274 << "\" (content type \""
Chris@686 275 << source.getContentType() << "\") failed";
Chris@386 276
Chris@386 277 if (reader->getError() != "") {
Chris@686 278 std::cerr << ": \"" << reader->getError() << "\"";
Chris@386 279 }
Chris@386 280 std::cerr << std::endl;
Chris@386 281 delete reader;
Chris@386 282 reader = 0;
Chris@386 283 }
Chris@386 284
Chris@386 285 std::cerr << "AudioFileReaderFactory: No reader" << std::endl;
Chris@386 286 return reader;
Chris@386 287 }
Chris@386 288