src/audio/sound_file.cpp

Go to the documentation of this file.
00001 //  SuperTux
00002 //  Copyright (C) 2006 Matthias Braun <matze@braunis.de>
00003 //
00004 //  This program is free software: you can redistribute it and/or modify
00005 //  it under the terms of the GNU General Public License as published by
00006 //  the Free Software Foundation, either version 3 of the License, or
00007 //  (at your option) any later version.
00008 //
00009 //  This program is distributed in the hope that it will be useful,
00010 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012 //  GNU General Public License for more details.
00013 //
00014 //  You should have received a copy of the GNU General Public License
00015 //  along with this program.  If not, see <http://www.gnu.org/licenses/>.
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 /* EOF */

Generated on Mon Jun 9 03:38:16 2014 for SuperTux by  doxygen 1.5.1