Chris@235: /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*-  vi:set ts=8 sts=4 sw=4: */
Chris@235: 
Chris@235: /*
Chris@235:     Sonic Visualiser
Chris@235:     An audio file viewer and annotation editor.
Chris@235:     Centre for Digital Music, Queen Mary, University of London.
Chris@235:     This file copyright 2006 Chris Cannam and QMUL.
Chris@235:     
Chris@235:     This program is free software; you can redistribute it and/or
Chris@235:     modify it under the terms of the GNU General Public License as
Chris@235:     published by the Free Software Foundation; either version 2 of the
Chris@235:     License, or (at your option) any later version.  See the file
Chris@235:     COPYING included with this distribution for more information.
Chris@235: */
Chris@235: 
Chris@235: #include "AudioFileReaderFactory.h"
Chris@235: 
Chris@235: #include "WavFileReader.h"
Chris@235: #include "OggVorbisFileReader.h"
Chris@235: #include "MP3FileReader.h"
Chris@235: 
Chris@235: #include <QString>
Chris@241: #include <QFileInfo>
Chris@235: #include <iostream>
Chris@235: 
Chris@235: QString
Chris@235: AudioFileReaderFactory::getKnownExtensions()
Chris@235: {
Chris@235:     std::set<QString> extensions;
Chris@235: 
Chris@235:     WavFileReader::getSupportedExtensions(extensions);
Chris@235: #ifdef HAVE_MAD
Chris@235:     MP3FileReader::getSupportedExtensions(extensions);
Chris@235: #endif
Chris@235: #ifdef HAVE_OGGZ
Chris@235: #ifdef HAVE_FISHSOUND
Chris@235:     OggVorbisFileReader::getSupportedExtensions(extensions);
Chris@235: #endif
Chris@235: #endif
Chris@235: 
Chris@235:     QString rv;
Chris@235:     for (std::set<QString>::const_iterator i = extensions.begin();
Chris@235:          i != extensions.end(); ++i) {
Chris@235:         if (i != extensions.begin()) rv += " ";
Chris@235:         rv += "*." + *i;
Chris@235:     }
Chris@235: 
Chris@235:     return rv;
Chris@235: }
Chris@235: 
Chris@235: AudioFileReader *
Chris@235: AudioFileReaderFactory::createReader(QString path)
Chris@235: {
Chris@235:     QString err;
Chris@235: 
Chris@235:     AudioFileReader *reader = 0;
Chris@235: 
Chris@241:     // First try to construct a preferred reader based on the
Chris@241:     // extension.  If we can't identify one or it fails to load the
Chris@241:     // file, fall back to trying all readers in no particular order.
Chris@241: 
Chris@241:     QString ext = QFileInfo(path).suffix().toLower();
Chris@241:     std::set<QString> extensions;
Chris@241: 
Chris@241:     WavFileReader::getSupportedExtensions(extensions);
Chris@241:     if (extensions.find(ext) != extensions.end()) {
Chris@241:         reader = new WavFileReader(path);
Chris@241:     }
Chris@241:     
Chris@241: #ifdef HAVE_MAD
Chris@241:     if (!reader) {
Chris@241:         extensions.clear();
Chris@241:         MP3FileReader::getSupportedExtensions(extensions);
Chris@241:         if (extensions.find(ext) != extensions.end()) {
Chris@241:             reader = new MP3FileReader
Chris@263:                 (path,
Chris@265:                  MP3FileReader::DecodeThreaded,
Chris@263:                  MP3FileReader::CacheInTemporaryFile);
Chris@241:         }
Chris@241:     }
Chris@241: #endif
Chris@241: #ifdef HAVE_OGGZ
Chris@241: #ifdef HAVE_FISHSOUND
Chris@241:     if (!reader) {
Chris@241:         extensions.clear();
Chris@241:         OggVorbisFileReader::getSupportedExtensions(extensions);
Chris@241:         if (extensions.find(ext) != extensions.end()) {
Chris@241:             reader = new OggVorbisFileReader
Chris@263:                 (path, 
Chris@265:                  OggVorbisFileReader::DecodeThreaded,
Chris@263:                  OggVorbisFileReader::CacheInTemporaryFile);
Chris@241:         }
Chris@241:     }
Chris@241: #endif
Chris@241: #endif
Chris@241: 
Chris@241:     if (reader) {
Chris@241:         if (reader->isOK()) return reader;
Chris@241:         if (reader->getError() != "") {
Chris@241:             std::cerr << "AudioFileReaderFactory: Preferred reader for "
Chris@241:                       << "extension \"" << ext.toStdString() << "\" failed: \""
Chris@241:                       << reader->getError().toStdString() << "\"" << std::endl;
Chris@241:         } else {
Chris@241:             std::cerr << "AudioFileReaderFactory: Preferred reader for "
Chris@241:                       << "extension \"" << ext.toStdString() << "\" failed"
Chris@241:                       << std::endl;
Chris@241:         }            
Chris@241:         delete reader;
Chris@241:         reader = 0;
Chris@241:     }
Chris@241: 
Chris@235:     reader = new WavFileReader(path);
Chris@235:     if (reader->isOK()) return reader;
Chris@241:     if (reader->getError() != "") {
Chris@241: 	std::cerr << "AudioFileReaderFactory: WAV file reader error: \""
Chris@241:                   << reader->getError().toStdString() << "\"" << std::endl;
Chris@241:     } else {
Chris@241: 	std::cerr << "AudioFileReaderFactory: WAV file reader failed"
Chris@241:                   << std::endl;
Chris@241:     }        
Chris@235:     delete reader;
Chris@235: 
Chris@235: #ifdef HAVE_OGGZ
Chris@235: #ifdef HAVE_FISHSOUND
Chris@241:     reader = new OggVorbisFileReader
Chris@263:         (path,
Chris@265:          OggVorbisFileReader::DecodeThreaded,
Chris@263:          OggVorbisFileReader::CacheInTemporaryFile);
Chris@235:     if (reader->isOK()) return reader;
Chris@241:     if (reader->getError() != "") {
Chris@241: 	std::cerr << "AudioFileReaderFactory: Ogg file reader error: \""
Chris@241:                   << reader->getError().toStdString() << "\"" << std::endl;
Chris@241:     } else {
Chris@241: 	std::cerr << "AudioFileReaderFactory: Ogg file reader failed"
Chris@241:                   << std::endl;
Chris@241:     }        
Chris@235:     delete reader;
Chris@235: #endif
Chris@235: #endif
Chris@235:  
Chris@235: #ifdef HAVE_MAD
Chris@241:     reader = new MP3FileReader
Chris@263:         (path,
Chris@265:          MP3FileReader::DecodeThreaded,
Chris@263:          MP3FileReader::CacheInTemporaryFile);
Chris@235:     if (reader->isOK()) return reader;
Chris@241:     if (reader->getError() != "") {
Chris@241: 	std::cerr << "AudioFileReaderFactory: MP3 file reader error: \""
Chris@241:                   << reader->getError().toStdString() << "\"" << std::endl;
Chris@241:     } else {
Chris@241: 	std::cerr << "AudioFileReaderFactory: MP3 file reader failed"
Chris@241:                   << std::endl;
Chris@241:     }        
Chris@235:     delete reader;
Chris@235: #endif
Chris@235: 
Chris@235:     return 0;
Chris@235: }
Chris@235: