annotate data/fileio/AudioFileReaderFactory.cpp @ 548:1469caaa8e67

* Finer locking in fft caches; fix displayed bin ranges in spectrogram
author Chris Cannam
date Thu, 05 Feb 2009 12:05:28 +0000
parents 5746c559af15
children 029dd9e5cc29 1c8898816fd0
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@386 76 // std::cerr << "AudioFileReaderFactory::createReader(\"" << source.getLocation().toStdString() << "\"): Requested rate: " << targetRate << std::endl;
Chris@386 77
Chris@386 78 if (!source.isOK() || !source.isAvailable()) {
Chris@386 79 std::cerr << "AudioFileReaderFactory::createReader(\"" << source.getLocation().toStdString() << "\": Source unavailable" << std::endl;
Chris@386 80 return 0;
Chris@386 81 }
Chris@386 82
Chris@386 83 AudioFileReader *reader = 0;
Chris@386 84
Chris@386 85 // Try to construct a preferred reader based on the extension or
Chris@386 86 // MIME type.
Chris@386 87
Chris@386 88 if (WavFileReader::supports(source)) {
Chris@386 89
Chris@386 90 reader = new WavFileReader(source);
Chris@386 91
Chris@386 92 if (targetRate != 0 &&
Chris@386 93 reader->isOK() &&
Chris@386 94 reader->getSampleRate() != targetRate) {
Chris@386 95
Chris@386 96 std::cerr << "AudioFileReaderFactory::createReader: WAV file rate: " << reader->getSampleRate() << ", creating resampling reader" << std::endl;
Chris@386 97
Chris@386 98 delete reader;
Chris@386 99 reader = new ResamplingWavFileReader
Chris@386 100 (source,
Chris@386 101 threading ?
Chris@386 102 ResamplingWavFileReader::ResampleThreaded :
Chris@386 103 ResamplingWavFileReader::ResampleAtOnce,
Chris@386 104 ResamplingWavFileReader::CacheInTemporaryFile,
Chris@392 105 targetRate,
Chris@392 106 reporter);
Chris@440 107 if (!reader->isOK()) {
Chris@440 108 delete reader;
Chris@440 109 reader = 0;
Chris@440 110 }
Chris@386 111 }
Chris@386 112 }
Chris@386 113
Chris@386 114 #ifdef HAVE_OGGZ
Chris@386 115 #ifdef HAVE_FISHSOUND
Chris@386 116 if (!reader) {
Chris@386 117 if (OggVorbisFileReader::supports(source)) {
Chris@386 118 reader = new OggVorbisFileReader
Chris@386 119 (source,
Chris@386 120 threading ?
Chris@386 121 OggVorbisFileReader::DecodeThreaded :
Chris@386 122 OggVorbisFileReader::DecodeAtOnce,
Chris@386 123 OggVorbisFileReader::CacheInTemporaryFile,
Chris@392 124 targetRate,
Chris@392 125 reporter);
Chris@440 126 if (!reader->isOK()) {
Chris@440 127 delete reader;
Chris@440 128 reader = 0;
Chris@440 129 }
Chris@386 130 }
Chris@386 131 }
Chris@386 132 #endif
Chris@386 133 #endif
Chris@386 134
Chris@386 135 #ifdef HAVE_MAD
Chris@386 136 if (!reader) {
Chris@386 137 if (MP3FileReader::supports(source)) {
Chris@386 138 reader = new MP3FileReader
Chris@386 139 (source,
Chris@386 140 threading ?
Chris@386 141 MP3FileReader::DecodeThreaded :
Chris@386 142 MP3FileReader::DecodeAtOnce,
Chris@386 143 MP3FileReader::CacheInTemporaryFile,
Chris@392 144 targetRate,
Chris@392 145 reporter);
Chris@440 146 if (!reader->isOK()) {
Chris@440 147 delete reader;
Chris@440 148 reader = 0;
Chris@440 149 }
Chris@386 150 }
Chris@386 151 }
Chris@386 152 #endif
Chris@386 153
Chris@386 154 #ifdef HAVE_QUICKTIME
Chris@386 155 if (!reader) {
Chris@386 156 if (QuickTimeFileReader::supports(source)) {
Chris@386 157 reader = new QuickTimeFileReader
Chris@386 158 (source,
Chris@386 159 threading ?
Chris@386 160 QuickTimeFileReader::DecodeThreaded :
Chris@386 161 QuickTimeFileReader::DecodeAtOnce,
Chris@386 162 QuickTimeFileReader::CacheInTemporaryFile,
Chris@392 163 targetRate,
Chris@392 164 reporter);
Chris@440 165 if (!reader->isOK()) {
Chris@440 166 delete reader;
Chris@440 167 reader = 0;
Chris@440 168 }
Chris@440 169 }
Chris@440 170 }
Chris@440 171 #endif
Chris@440 172
Chris@440 173 // If none of the readers claimed to support this file extension,
Chris@440 174 // perhaps the extension is missing or misleading. Try again,
Chris@440 175 // ignoring it. We have to be confident that the reader won't
Chris@440 176 // open just any old text file or whatever and pretend it's
Chris@440 177 // succeeded
Chris@440 178
Chris@440 179 if (!reader) {
Chris@440 180
Chris@440 181 reader = new WavFileReader(source);
Chris@440 182
Chris@440 183 if (targetRate != 0 &&
Chris@440 184 reader->isOK() &&
Chris@440 185 reader->getSampleRate() != targetRate) {
Chris@440 186
Chris@440 187 std::cerr << "AudioFileReaderFactory::createReader: WAV file rate: " << reader->getSampleRate() << ", creating resampling reader" << std::endl;
Chris@440 188
Chris@440 189 delete reader;
Chris@440 190 reader = new ResamplingWavFileReader
Chris@440 191 (source,
Chris@440 192 threading ?
Chris@440 193 ResamplingWavFileReader::ResampleThreaded :
Chris@440 194 ResamplingWavFileReader::ResampleAtOnce,
Chris@440 195 ResamplingWavFileReader::CacheInTemporaryFile,
Chris@440 196 targetRate,
Chris@440 197 reporter);
Chris@440 198 }
Chris@440 199
Chris@440 200 if (!reader->isOK()) {
Chris@440 201 delete reader;
Chris@440 202 reader = 0;
Chris@440 203 }
Chris@440 204 }
Chris@440 205
Chris@440 206 #ifdef HAVE_OGGZ
Chris@440 207 #ifdef HAVE_FISHSOUND
Chris@440 208 if (!reader) {
Chris@440 209 reader = new OggVorbisFileReader
Chris@440 210 (source,
Chris@440 211 threading ?
Chris@440 212 OggVorbisFileReader::DecodeThreaded :
Chris@440 213 OggVorbisFileReader::DecodeAtOnce,
Chris@440 214 OggVorbisFileReader::CacheInTemporaryFile,
Chris@440 215 targetRate,
Chris@440 216 reporter);
Chris@440 217
Chris@440 218 if (!reader->isOK()) {
Chris@440 219 delete reader;
Chris@440 220 reader = 0;
Chris@440 221 }
Chris@440 222 }
Chris@440 223 #endif
Chris@440 224 #endif
Chris@440 225
Chris@440 226 #ifdef HAVE_MAD
Chris@440 227 if (!reader) {
Chris@440 228 reader = new MP3FileReader
Chris@440 229 (source,
Chris@440 230 threading ?
Chris@440 231 MP3FileReader::DecodeThreaded :
Chris@440 232 MP3FileReader::DecodeAtOnce,
Chris@440 233 MP3FileReader::CacheInTemporaryFile,
Chris@440 234 targetRate,
Chris@440 235 reporter);
Chris@440 236
Chris@440 237 if (!reader->isOK()) {
Chris@440 238 delete reader;
Chris@440 239 reader = 0;
Chris@440 240 }
Chris@440 241 }
Chris@440 242 #endif
Chris@440 243
Chris@440 244 #ifdef HAVE_QUICKTIME
Chris@440 245 if (!reader) {
Chris@440 246 reader = new QuickTimeFileReader
Chris@440 247 (source,
Chris@440 248 threading ?
Chris@440 249 QuickTimeFileReader::DecodeThreaded :
Chris@440 250 QuickTimeFileReader::DecodeAtOnce,
Chris@440 251 QuickTimeFileReader::CacheInTemporaryFile,
Chris@440 252 targetRate,
Chris@440 253 reporter);
Chris@440 254
Chris@440 255 if (!reader->isOK()) {
Chris@440 256 delete reader;
Chris@440 257 reader = 0;
Chris@386 258 }
Chris@386 259 }
Chris@386 260 #endif
Chris@386 261
Chris@386 262 if (reader) {
Chris@386 263 if (reader->isOK()) {
Chris@386 264 // std::cerr << "AudioFileReaderFactory: Reader is OK" << std::endl;
Chris@386 265 return reader;
Chris@386 266 }
Chris@386 267 std::cerr << "AudioFileReaderFactory: Preferred reader for "
Chris@386 268 << "url \"" << source.getLocation().toStdString()
Chris@386 269 << "\" (content type \""
Chris@386 270 << source.getContentType().toStdString() << "\") failed";
Chris@386 271
Chris@386 272 if (reader->getError() != "") {
Chris@386 273 std::cerr << ": \"" << reader->getError().toStdString() << "\"";
Chris@386 274 }
Chris@386 275 std::cerr << std::endl;
Chris@386 276 delete reader;
Chris@386 277 reader = 0;
Chris@386 278 }
Chris@386 279
Chris@386 280 std::cerr << "AudioFileReaderFactory: No reader" << std::endl;
Chris@386 281 return reader;
Chris@386 282 }
Chris@386 283