2 // Copyright (C) 2006 Matthias Braun <matze@braunis.de>
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
14 // You should have received a copy of the GNU General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
17 /** Used SDL_mixer and glest source as reference */
19 #include "audio/sound_file.hpp"
27 #include "audio/sound_error.hpp"
28 #include "audio/ogg_sound_file.hpp"
29 #include "audio/wav_sound_file.hpp"
30 #include "lisp/parser.hpp"
31 #include "util/reader.hpp"
32 #include "util/file_system.hpp"
33 #include "util/log.hpp"
35 SoundFile* load_music_file(const std::string& filename)
37 lisp::Parser parser(false);
38 const lisp::Lisp* root = parser.parse(filename);
39 const lisp::Lisp* music = root->get_lisp("supertux-music");
41 throw SoundError("file is not a supertux-music file.");
43 std::string raw_music_file;
47 music->get("file", raw_music_file);
48 music->get("loop-begin", loop_begin);
49 music->get("loop-at", loop_at);
52 throw SoundError("can't loop from negative value");
55 std::string basedir = FileSystem::dirname(filename);
56 raw_music_file = FileSystem::normalize(basedir + raw_music_file);
58 PHYSFS_file* file = PHYSFS_openRead(raw_music_file.c_str());
60 std::stringstream msg;
61 msg << "Couldn't open '" << raw_music_file << "': " << PHYSFS_getLastError();
62 throw SoundError(msg.str());
65 return new OggSoundFile(file, loop_begin, loop_at);
68 SoundFile* load_sound_file(const std::string& filename)
70 if(filename.length() > 6
71 && filename.compare(filename.length()-6, 6, ".music") == 0) {
72 return load_music_file(filename);
75 PHYSFS_file* file = PHYSFS_openRead(filename.c_str());
77 std::stringstream msg;
78 msg << "Couldn't open '" << filename << "': " << PHYSFS_getLastError() << ", using dummy sound file.";
79 throw SoundError(msg.str());
84 if(PHYSFS_read(file, magic, sizeof(magic), 1) != 1)
85 throw SoundError("Couldn't read magic, file too short");
87 if(strncmp(magic, "RIFF", 4) == 0)
88 return new WavSoundFile(file);
89 else if(strncmp(magic, "OggS", 4) == 0)
90 return new OggSoundFile(file, 0, -1);
92 throw SoundError("Unknown file format");
93 } catch(std::exception& e) {
94 std::stringstream msg;
95 msg << "Couldn't read '" << filename << "': " << e.what();
96 throw SoundError(msg.str());