diff --git a/stepmania/src/RageSoundReader_FileReader.cpp b/stepmania/src/RageSoundReader_FileReader.cpp new file mode 100644 index 0000000000..8d47ee9451 --- /dev/null +++ b/stepmania/src/RageSoundReader_FileReader.cpp @@ -0,0 +1,93 @@ +#include "global.h" +#include "RageSoundReader_FileReader.h" +#include "RageUtil.h" +#include "RageLog.h" + +#include +#ifndef NO_WAV_SUPPORT +#include "RageSoundReader_WAV.h" +#endif + +#ifndef NO_MP3_SUPPORT +#include "RageSoundReader_MP3.h" +#endif + +#ifndef NO_VORBIS_SUPPORT +#include "RageSoundReader_Vorbisfile.h" +#endif + +SoundReader_FileReader *SoundReader_FileReader::TryOpenFile( CString filename, CString &error, CString format ) +{ + SoundReader_FileReader *Sample = NULL; + +#ifndef NO_WAV_SUPPORT + if( !format.CompareNoCase("wav") ) + Sample = new RageSoundReader_WAV; +#endif +#ifndef NO_MP3_SUPPORT + if( !format.CompareNoCase("mp3") ) + Sample = new RageSoundReader_MP3; +#endif + +#ifndef NO_VORBIS_SUPPORT + if( !format.CompareNoCase("ogg") ) + Sample = new RageSoundReader_Vorbisfile; +#endif + + if( !Sample ) + return NULL; + + OpenResult ret = Sample->Open(filename); + if( ret == OPEN_OK ) + return Sample; + + CString err = Sample->GetError(); + delete Sample; + + LOG->Trace( "Format %s failed: %s", format.c_str(), err.c_str() ); + + /* If OPEN_MATCH_BUT_FAIL, the error is important; otherwise it's probably + * just a "unknown file"-ish error. */ + if( ret == OPEN_MATCH_BUT_FAIL ) + { + if( error != "" ) + error += "; "; + error += ssprintf("%s: %s", format.c_str(), err.c_str() ); + } + + return NULL; +} + +SoundReader *SoundReader_FileReader::OpenFile( CString filename, CString &error ) +{ + set FileTypes; + FileTypes.insert("ogg"); + FileTypes.insert("mp3"); + FileTypes.insert("wav"); + + CString format = GetExtension(filename); + format.MakeLower(); + + error = ""; + + /* If the extension matches a format, try that first. */ + if( FileTypes.find(format) != FileTypes.end() ) + { + SoundReader_FileReader *NewSample = TryOpenFile( filename, error, format ); + if( NewSample ) + return NewSample; + FileTypes.erase( format ); + } + + for( set::iterator it = FileTypes.begin(); it != FileTypes.end(); ++it ) + { + SoundReader_FileReader *NewSample = TryOpenFile( filename, error, *it ); + if( NewSample ) + { + LOG->Warn("File \"%s\" is really %s", filename.c_str(), it->c_str()); + return NewSample; + } + } + + return NULL; +} diff --git a/stepmania/src/RageSoundReader_FileReader.h b/stepmania/src/RageSoundReader_FileReader.h index 1cf47203ef..ec5a3c00f9 100644 --- a/stepmania/src/RageSoundReader_FileReader.h +++ b/stepmania/src/RageSoundReader_FileReader.h @@ -6,7 +6,18 @@ class SoundReader_FileReader: public SoundReader { public: - virtual bool Open(CString filename) = 0; + /* Return OPEN_OK if the file is open and ready to go. Return OPEN_NO_MATCH + * if the file appears to be of a different type. Return OPEN_MATCH_BUT_FAIL if + * the file appears to be the correct type, but there was an error initializing + * the file. + * + * If the file can not be opened at all, or contains no data, return OPEN_MATCH_BUT_FAIL. */ + enum OpenResult { OPEN_OK, OPEN_NO_MATCH, OPEN_MATCH_BUT_FAIL }; + virtual OpenResult Open(CString filename) = 0; + + static SoundReader *OpenFile( CString filename, CString &error ); +private: + static SoundReader_FileReader *TryOpenFile( CString filename, CString &error, CString format ); }; #endif