00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00019 #include "audio/sound_file.hpp"
00020
00021 #include <config.h>
00022
00023 #include <stdint.h>
00024 #include <sstream>
00025 #include <physfs.h>
00026
00027 #include "audio/sound_error.hpp"
00028 #include "audio/ogg_sound_file.hpp"
00029 #include "audio/wav_sound_file.hpp"
00030 #include "lisp/parser.hpp"
00031 #include "util/reader.hpp"
00032 #include "util/file_system.hpp"
00033 #include "util/log.hpp"
00034
00035 SoundFile* load_music_file(const std::string& filename)
00036 {
00037 lisp::Parser parser(false);
00038 const lisp::Lisp* root = parser.parse(filename);
00039 const lisp::Lisp* music = root->get_lisp("supertux-music");
00040 if(music == NULL)
00041 throw SoundError("file is not a supertux-music file.");
00042
00043 std::string raw_music_file;
00044 float loop_begin = 0;
00045 float loop_at = -1;
00046
00047 music->get("file", raw_music_file);
00048 music->get("loop-begin", loop_begin);
00049 music->get("loop-at", loop_at);
00050
00051 if(loop_begin < 0) {
00052 throw SoundError("can't loop from negative value");
00053 }
00054
00055 std::string basedir = FileSystem::dirname(filename);
00056 raw_music_file = FileSystem::normalize(basedir + raw_music_file);
00057
00058 PHYSFS_file* file = PHYSFS_openRead(raw_music_file.c_str());
00059 if(!file) {
00060 std::stringstream msg;
00061 msg << "Couldn't open '" << raw_music_file << "': " << PHYSFS_getLastError();
00062 throw SoundError(msg.str());
00063 }
00064
00065 return new OggSoundFile(file, loop_begin, loop_at);
00066 }
00067
00068 SoundFile* load_sound_file(const std::string& filename)
00069 {
00070 if(filename.length() > 6
00071 && filename.compare(filename.length()-6, 6, ".music") == 0) {
00072 return load_music_file(filename);
00073 }
00074
00075 PHYSFS_file* file = PHYSFS_openRead(filename.c_str());
00076 if(!file) {
00077 std::stringstream msg;
00078 msg << "Couldn't open '" << filename << "': " << PHYSFS_getLastError() << ", using dummy sound file.";
00079 throw SoundError(msg.str());
00080 }
00081
00082 try {
00083 char magic[4];
00084 if(PHYSFS_read(file, magic, sizeof(magic), 1) != 1)
00085 throw SoundError("Couldn't read magic, file too short");
00086 PHYSFS_seek(file, 0);
00087 if(strncmp(magic, "RIFF", 4) == 0)
00088 return new WavSoundFile(file);
00089 else if(strncmp(magic, "OggS", 4) == 0)
00090 return new OggSoundFile(file, 0, -1);
00091 else
00092 throw SoundError("Unknown file format");
00093 } catch(std::exception& e) {
00094 std::stringstream msg;
00095 msg << "Couldn't read '" << filename << "': " << e.what();
00096 throw SoundError(msg.str());
00097 }
00098 }
00099
00100