Merged changes from branches/supertux-milestone2-grumbel/ to trunk/supertux/
[supertux.git] / src / audio / sound_manager.hpp
1 //  SuperTux
2 //  Copyright (C) 2006 Matthias Braun <matze@braunis.de>
3 //
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.
8 //
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.
13 //
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/>.
16
17 #ifndef HEADER_SUPERTUX_AUDIO_SOUND_MANAGER_HPP
18 #define HEADER_SUPERTUX_AUDIO_SOUND_MANAGER_HPP
19
20 #include <map>
21 #include <string>
22 #include <vector>
23
24 #include <al.h>
25 #include <alc.h>
26
27 #include "math/vector.hpp"
28
29 class SoundFile;
30 class SoundSource;
31 class StreamSoundSource;
32 class OpenALSoundSource;
33
34 class SoundManager
35 {
36 public:
37   SoundManager();
38   virtual ~SoundManager();
39
40   void enable_sound(bool sound_enabled);
41   /**
42    * Creates a new sound source object which plays the specified soundfile.
43    * You are responsible for deleting the sound source later (this will stop the
44    * sound).
45    * This function never throws exceptions, but might return a DummySoundSource
46    */
47   SoundSource* create_sound_source(const std::string& filename);
48   /**
49    * Convenience function to simply play a sound at a given position.
50    */
51   void play(const std::string& name, const Vector& pos = Vector(-1, -1));
52   /**
53    * Adds the source to the list of managed sources (= the source gets deleted
54    * when it finished playing)
55    */
56   void manage_source(SoundSource* source);
57   /// preloads a sound, so that you don't get a lag later when playing it
58   void preload(const std::string& name);
59
60   void set_listener_position(const Vector& position);
61   void set_listener_velocity(const Vector& velocity);
62
63   void enable_music(bool music_enabled);
64   void play_music(const std::string& filename, bool fade = false);
65   void stop_music(float fadetime = 0);
66
67   bool is_music_enabled() { return music_enabled; }
68   bool is_sound_enabled() { return sound_enabled; }
69
70   bool is_audio_enabled() {
71     return device != 0 && context != 0;
72   }
73
74   void update();
75
76   /*
77    * Tell soundmanager to call update() for stream_sound_source.
78    */
79   void register_for_update( StreamSoundSource* sss );
80   /*
81    * Unsubscribe from updates for stream_sound_source.
82    */
83   void remove_from_update( StreamSoundSource* sss );
84
85 private:
86   friend class OpenALSoundSource;
87   friend class StreamSoundSource;
88
89   /** creates a new sound source, might throw exceptions, never returns NULL */
90   OpenALSoundSource* intern_create_sound_source(const std::string& filename);
91   static ALuint load_file_into_buffer(SoundFile* file);
92   static ALenum get_sample_format(SoundFile* file);
93
94   void print_openal_version();
95   void check_alc_error(const char* message);
96   static void check_al_error(const char* message);
97
98   ALCdevice* device;
99   ALCcontext* context;
100   bool sound_enabled;
101
102   typedef std::map<std::string, ALuint> SoundBuffers;
103   SoundBuffers buffers;
104   typedef std::vector<OpenALSoundSource*> SoundSources;
105   SoundSources sources;
106
107   typedef std::vector<StreamSoundSource*> StreamSoundSources;
108   StreamSoundSources update_list;
109
110   StreamSoundSource* music_source;
111
112   bool music_enabled;
113   std::string current_music;
114
115 private:
116   SoundManager(const SoundManager&);
117   SoundManager& operator=(const SoundManager&);
118 };
119
120 extern SoundManager* sound_manager;
121
122 #endif
123
124 /* EOF */