annotate data/fileio/AudioFileReaderFactory.cpp @ 386:e6d11871e4c9

* Fix bug that was causing decoded audio files (mp3s, oggs) to come up some of the time with zero sample rate
author Chris Cannam
date Sat, 01 Mar 2008 16:17:44 +0000
parents 1d656dcda8ef
children 183ee2a55fc7
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@386 57 AudioFileReaderFactory::createReader(FileSource source, size_t targetRate)
Chris@386 58 {
Chris@386 59 return create(source, targetRate, false);
Chris@386 60 }
Chris@386 61
Chris@386 62 AudioFileReader *
Chris@386 63 AudioFileReaderFactory::createThreadingReader(FileSource source, size_t targetRate)
Chris@386 64 {
Chris@386 65 return create(source, targetRate, true);
Chris@386 66 }
Chris@386 67
Chris@386 68 AudioFileReader *
Chris@386 69 AudioFileReaderFactory::create(FileSource source, size_t targetRate, bool threading)
Chris@386 70 {
Chris@386 71 QString err;
Chris@386 72
Chris@386 73 // std::cerr << "AudioFileReaderFactory::createReader(\"" << source.getLocation().toStdString() << "\"): Requested rate: " << targetRate << std::endl;
Chris@386 74
Chris@386 75 if (!source.isOK() || !source.isAvailable()) {
Chris@386 76 std::cerr << "AudioFileReaderFactory::createReader(\"" << source.getLocation().toStdString() << "\": Source unavailable" << std::endl;
Chris@386 77 return 0;
Chris@386 78 }
Chris@386 79
Chris@386 80 AudioFileReader *reader = 0;
Chris@386 81
Chris@386 82 // Try to construct a preferred reader based on the extension or
Chris@386 83 // MIME type.
Chris@386 84
Chris@386 85 if (WavFileReader::supports(source)) {
Chris@386 86
Chris@386 87 reader = new WavFileReader(source);
Chris@386 88
Chris@386 89 if (targetRate != 0 &&
Chris@386 90 reader->isOK() &&
Chris@386 91 reader->getSampleRate() != targetRate) {
Chris@386 92
Chris@386 93 std::cerr << "AudioFileReaderFactory::createReader: WAV file rate: " << reader->getSampleRate() << ", creating resampling reader" << std::endl;
Chris@386 94
Chris@386 95 delete reader;
Chris@386 96 reader = new ResamplingWavFileReader
Chris@386 97 (source,
Chris@386 98 threading ?
Chris@386 99 ResamplingWavFileReader::ResampleThreaded :
Chris@386 100 ResamplingWavFileReader::ResampleAtOnce,
Chris@386 101 ResamplingWavFileReader::CacheInTemporaryFile,
Chris@386 102 targetRate);
Chris@386 103 }
Chris@386 104 }
Chris@386 105
Chris@386 106 #ifdef HAVE_OGGZ
Chris@386 107 #ifdef HAVE_FISHSOUND
Chris@386 108 if (!reader) {
Chris@386 109 if (OggVorbisFileReader::supports(source)) {
Chris@386 110 reader = new OggVorbisFileReader
Chris@386 111 (source,
Chris@386 112 threading ?
Chris@386 113 OggVorbisFileReader::DecodeThreaded :
Chris@386 114 OggVorbisFileReader::DecodeAtOnce,
Chris@386 115 OggVorbisFileReader::CacheInTemporaryFile,
Chris@386 116 targetRate);
Chris@386 117 }
Chris@386 118 }
Chris@386 119 #endif
Chris@386 120 #endif
Chris@386 121
Chris@386 122 #ifdef HAVE_MAD
Chris@386 123 if (!reader) {
Chris@386 124 if (MP3FileReader::supports(source)) {
Chris@386 125 reader = new MP3FileReader
Chris@386 126 (source,
Chris@386 127 threading ?
Chris@386 128 MP3FileReader::DecodeThreaded :
Chris@386 129 MP3FileReader::DecodeAtOnce,
Chris@386 130 MP3FileReader::CacheInTemporaryFile,
Chris@386 131 targetRate);
Chris@386 132 }
Chris@386 133 }
Chris@386 134 #endif
Chris@386 135
Chris@386 136 #ifdef HAVE_QUICKTIME
Chris@386 137 if (!reader) {
Chris@386 138 if (QuickTimeFileReader::supports(source)) {
Chris@386 139 reader = new QuickTimeFileReader
Chris@386 140 (source,
Chris@386 141 threading ?
Chris@386 142 QuickTimeFileReader::DecodeThreaded :
Chris@386 143 QuickTimeFileReader::DecodeAtOnce,
Chris@386 144 QuickTimeFileReader::CacheInTemporaryFile,
Chris@386 145 targetRate);
Chris@386 146 }
Chris@386 147 }
Chris@386 148 #endif
Chris@386 149
Chris@386 150 if (reader) {
Chris@386 151 if (reader->isOK()) {
Chris@386 152 // std::cerr << "AudioFileReaderFactory: Reader is OK" << std::endl;
Chris@386 153 return reader;
Chris@386 154 }
Chris@386 155 std::cerr << "AudioFileReaderFactory: Preferred reader for "
Chris@386 156 << "url \"" << source.getLocation().toStdString()
Chris@386 157 << "\" (content type \""
Chris@386 158 << source.getContentType().toStdString() << "\") failed";
Chris@386 159
Chris@386 160 if (reader->getError() != "") {
Chris@386 161 std::cerr << ": \"" << reader->getError().toStdString() << "\"";
Chris@386 162 }
Chris@386 163 std::cerr << std::endl;
Chris@386 164 delete reader;
Chris@386 165 reader = 0;
Chris@386 166 }
Chris@386 167
Chris@386 168 std::cerr << "AudioFileReaderFactory: No reader" << std::endl;
Chris@386 169 return reader;
Chris@386 170 }
Chris@386 171