svcore
1.9
|
00001 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ 00002 00003 /* 00004 Sonic Visualiser 00005 An audio file viewer and annotation editor. 00006 Centre for Digital Music, Queen Mary, University of London. 00007 This file copyright 2006 Chris Cannam and QMUL. 00008 00009 This program is free software; you can redistribute it and/or 00010 modify it under the terms of the GNU General Public License as 00011 published by the Free Software Foundation; either version 2 of the 00012 License, or (at your option) any later version. See the file 00013 COPYING included with this distribution for more information. 00014 */ 00015 00016 #include "AudioFileReaderFactory.h" 00017 00018 #include "WavFileReader.h" 00019 #include "DecodingWavFileReader.h" 00020 #include "OggVorbisFileReader.h" 00021 #include "MP3FileReader.h" 00022 #include "QuickTimeFileReader.h" 00023 #include "CoreAudioFileReader.h" 00024 00025 #include <QString> 00026 #include <QFileInfo> 00027 #include <iostream> 00028 00029 QString 00030 AudioFileReaderFactory::getKnownExtensions() 00031 { 00032 std::set<QString> extensions; 00033 00034 WavFileReader::getSupportedExtensions(extensions); 00035 #ifdef HAVE_MAD 00036 MP3FileReader::getSupportedExtensions(extensions); 00037 #endif 00038 #ifdef HAVE_OGGZ 00039 #ifdef HAVE_FISHSOUND 00040 OggVorbisFileReader::getSupportedExtensions(extensions); 00041 #endif 00042 #endif 00043 #ifdef HAVE_QUICKTIME 00044 QuickTimeFileReader::getSupportedExtensions(extensions); 00045 #endif 00046 #ifdef HAVE_COREAUDIO 00047 CoreAudioFileReader::getSupportedExtensions(extensions); 00048 #endif 00049 00050 QString rv; 00051 for (std::set<QString>::const_iterator i = extensions.begin(); 00052 i != extensions.end(); ++i) { 00053 if (i != extensions.begin()) rv += " "; 00054 rv += "*." + *i; 00055 } 00056 00057 return rv; 00058 } 00059 00060 AudioFileReader * 00061 AudioFileReaderFactory::createReader(FileSource source, 00062 int targetRate, 00063 bool normalised, 00064 ProgressReporter *reporter) 00065 { 00066 return create(source, targetRate, normalised, false, reporter); 00067 } 00068 00069 AudioFileReader * 00070 AudioFileReaderFactory::createThreadingReader(FileSource source, 00071 int targetRate, 00072 bool normalised, 00073 ProgressReporter *reporter) 00074 { 00075 return create(source, targetRate, normalised, true, reporter); 00076 } 00077 00078 AudioFileReader * 00079 AudioFileReaderFactory::create(FileSource source, 00080 int targetRate, 00081 bool normalised, 00082 bool threading, 00083 ProgressReporter *reporter) 00084 { 00085 QString err; 00086 00087 SVDEBUG << "AudioFileReaderFactory::createReader(\"" << source.getLocation() << "\"): Requested rate: " << targetRate << endl; 00088 00089 if (!source.isOK()) { 00090 cerr << "AudioFileReaderFactory::createReader(\"" << source.getLocation() << "\": Failed to retrieve source (transmission error?): " << source.getErrorString() << endl; 00091 return 0; 00092 } 00093 00094 if (!source.isAvailable()) { 00095 SVDEBUG << "AudioFileReaderFactory::createReader(\"" << source.getLocation() << "\": Source not found" << endl; 00096 return 0; 00097 } 00098 00099 AudioFileReader *reader = 0; 00100 00101 // Try to construct a preferred reader based on the extension or 00102 // MIME type. 00103 00104 if (WavFileReader::supports(source)) { 00105 00106 reader = new WavFileReader(source); 00107 00108 int fileRate = reader->getSampleRate(); 00109 00110 if (reader->isOK() && 00111 (!reader->isQuicklySeekable() || 00112 normalised || 00113 (targetRate != 0 && fileRate != targetRate))) { 00114 00115 SVDEBUG << "AudioFileReaderFactory::createReader: WAV file rate: " << reader->getSampleRate() << ", normalised " << normalised << ", seekable " << reader->isQuicklySeekable() << ", creating decoding reader" << endl; 00116 00117 delete reader; 00118 reader = new DecodingWavFileReader 00119 (source, 00120 threading ? 00121 DecodingWavFileReader::ResampleThreaded : 00122 DecodingWavFileReader::ResampleAtOnce, 00123 DecodingWavFileReader::CacheInTemporaryFile, 00124 targetRate ? targetRate : fileRate, 00125 normalised, 00126 reporter); 00127 if (!reader->isOK()) { 00128 delete reader; 00129 reader = 0; 00130 } 00131 } 00132 } 00133 00134 #ifdef HAVE_OGGZ 00135 #ifdef HAVE_FISHSOUND 00136 if (!reader) { 00137 if (OggVorbisFileReader::supports(source)) { 00138 reader = new OggVorbisFileReader 00139 (source, 00140 threading ? 00141 OggVorbisFileReader::DecodeThreaded : 00142 OggVorbisFileReader::DecodeAtOnce, 00143 OggVorbisFileReader::CacheInTemporaryFile, 00144 targetRate, 00145 normalised, 00146 reporter); 00147 if (!reader->isOK()) { 00148 delete reader; 00149 reader = 0; 00150 } 00151 } 00152 } 00153 #endif 00154 #endif 00155 00156 #ifdef HAVE_MAD 00157 if (!reader) { 00158 if (MP3FileReader::supports(source)) { 00159 reader = new MP3FileReader 00160 (source, 00161 threading ? 00162 MP3FileReader::DecodeThreaded : 00163 MP3FileReader::DecodeAtOnce, 00164 MP3FileReader::CacheInTemporaryFile, 00165 targetRate, 00166 normalised, 00167 reporter); 00168 if (!reader->isOK()) { 00169 delete reader; 00170 reader = 0; 00171 } 00172 } 00173 } 00174 #endif 00175 00176 #ifdef HAVE_QUICKTIME 00177 if (!reader) { 00178 if (QuickTimeFileReader::supports(source)) { 00179 reader = new QuickTimeFileReader 00180 (source, 00181 threading ? 00182 QuickTimeFileReader::DecodeThreaded : 00183 QuickTimeFileReader::DecodeAtOnce, 00184 QuickTimeFileReader::CacheInTemporaryFile, 00185 targetRate, 00186 normalised, 00187 reporter); 00188 if (!reader->isOK()) { 00189 delete reader; 00190 reader = 0; 00191 } 00192 } 00193 } 00194 #endif 00195 00196 #ifdef HAVE_COREAUDIO 00197 if (!reader) { 00198 if (CoreAudioFileReader::supports(source)) { 00199 reader = new CoreAudioFileReader 00200 (source, 00201 threading ? 00202 CoreAudioFileReader::DecodeThreaded : 00203 CoreAudioFileReader::DecodeAtOnce, 00204 CoreAudioFileReader::CacheInTemporaryFile, 00205 targetRate, 00206 normalised, 00207 reporter); 00208 if (!reader->isOK()) { 00209 delete reader; 00210 reader = 0; 00211 } 00212 } 00213 } 00214 #endif 00215 00216 00217 // If none of the readers claimed to support this file extension, 00218 // perhaps the extension is missing or misleading. Try again, 00219 // ignoring it. We have to be confident that the reader won't 00220 // open just any old text file or whatever and pretend it's 00221 // succeeded 00222 00223 if (!reader) { 00224 00225 reader = new WavFileReader(source); 00226 00227 int fileRate = reader->getSampleRate(); 00228 00229 if (reader->isOK() && 00230 (!reader->isQuicklySeekable() || 00231 normalised || 00232 (targetRate != 0 && fileRate != targetRate))) { 00233 00234 SVDEBUG << "AudioFileReaderFactory::createReader: WAV file rate: " << reader->getSampleRate() << ", normalised " << normalised << ", seekable " << reader->isQuicklySeekable() << ", creating decoding reader" << endl; 00235 00236 delete reader; 00237 reader = new DecodingWavFileReader 00238 (source, 00239 threading ? 00240 DecodingWavFileReader::ResampleThreaded : 00241 DecodingWavFileReader::ResampleAtOnce, 00242 DecodingWavFileReader::CacheInTemporaryFile, 00243 targetRate ? targetRate : fileRate, 00244 normalised, 00245 reporter); 00246 } 00247 00248 if (!reader->isOK()) { 00249 delete reader; 00250 reader = 0; 00251 } 00252 } 00253 00254 #ifdef HAVE_OGGZ 00255 #ifdef HAVE_FISHSOUND 00256 if (!reader) { 00257 reader = new OggVorbisFileReader 00258 (source, 00259 threading ? 00260 OggVorbisFileReader::DecodeThreaded : 00261 OggVorbisFileReader::DecodeAtOnce, 00262 OggVorbisFileReader::CacheInTemporaryFile, 00263 targetRate, 00264 reporter); 00265 00266 if (!reader->isOK()) { 00267 delete reader; 00268 reader = 0; 00269 } 00270 } 00271 #endif 00272 #endif 00273 00274 #ifdef HAVE_MAD 00275 if (!reader) { 00276 reader = new MP3FileReader 00277 (source, 00278 threading ? 00279 MP3FileReader::DecodeThreaded : 00280 MP3FileReader::DecodeAtOnce, 00281 MP3FileReader::CacheInTemporaryFile, 00282 targetRate, 00283 reporter); 00284 00285 if (!reader->isOK()) { 00286 delete reader; 00287 reader = 0; 00288 } 00289 } 00290 #endif 00291 00292 #ifdef HAVE_QUICKTIME 00293 if (!reader) { 00294 reader = new QuickTimeFileReader 00295 (source, 00296 threading ? 00297 QuickTimeFileReader::DecodeThreaded : 00298 QuickTimeFileReader::DecodeAtOnce, 00299 QuickTimeFileReader::CacheInTemporaryFile, 00300 targetRate, 00301 reporter); 00302 00303 if (!reader->isOK()) { 00304 delete reader; 00305 reader = 0; 00306 } 00307 } 00308 #endif 00309 00310 #ifdef HAVE_COREAUDIO 00311 if (!reader) { 00312 reader = new CoreAudioFileReader 00313 (source, 00314 threading ? 00315 CoreAudioFileReader::DecodeThreaded : 00316 CoreAudioFileReader::DecodeAtOnce, 00317 CoreAudioFileReader::CacheInTemporaryFile, 00318 targetRate, 00319 reporter); 00320 00321 if (!reader->isOK()) { 00322 delete reader; 00323 reader = 0; 00324 } 00325 } 00326 #endif 00327 00328 if (reader) { 00329 if (reader->isOK()) { 00330 SVDEBUG << "AudioFileReaderFactory: Reader is OK" << endl; 00331 return reader; 00332 } 00333 cerr << "AudioFileReaderFactory: Preferred reader for " 00334 << "url \"" << source.getLocation() 00335 << "\" (content type \"" 00336 << source.getContentType() << "\") failed"; 00337 00338 if (reader->getError() != "") { 00339 cerr << ": \"" << reader->getError() << "\""; 00340 } 00341 cerr << endl; 00342 delete reader; 00343 reader = 0; 00344 } 00345 00346 cerr << "AudioFileReaderFactory: No reader" << endl; 00347 return reader; 00348 } 00349