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 <memory>
22#include <string>
23#include <vector>
24
25#include <al.h>
26#include <alc.h>
27
28#include "math/vector.hpp"
29#include "util/currenton.hpp"
30
31class SoundFile;
32class SoundSource;
33class StreamSoundSource;
34class OpenALSoundSource;
35
36class SoundManager final : public Currenton<SoundManager>
37{
38 friend class OpenALSoundSource;
39 friend class StreamSoundSource;
40
41private:
42 static ALuint load_file_into_buffer(SoundFile& file);
43 static ALenum get_sample_format(const SoundFile& file);
44
45 static void print_openal_version();
46 static void check_al_error(const char* message);
47
48public:
49 SoundManager();
50 virtual ~SoundManager();
51
52 void enable_sound(bool sound_enabled);
53
54 /** Creates a new sound source object which plays the specified
55 soundfile. You are responsible for deleting the sound source
56 later (this will stop the sound).
57 This function never throws exceptions, but might return a DummySoundSource */
58 std::unique_ptr<SoundSource> create_sound_source(const std::string& filename);
59
60 /** Convenience functions to simply play a sound at a given position. */
61 void play(const std::string& name, const Vector& pos = Vector(-1, -1),
62 const float gain = 0.5f);
63 void play(const std::string& name, const float gain)
64 {
65 play(name, Vector(-1, -1), gain);
66 }
67
68
69 /** Adds the source to the list of managed sources (= the source gets deleted
70 when it finished playing) */
71 void manage_source(std::unique_ptr<SoundSource> source);
72
73 /** preloads a sound, so that you don't get a lag later when playing it */
74 void preload(const std::string& name);
75
76 void set_listener_position(const Vector& position);
77 void set_listener_velocity(const Vector& velocity);
78 void set_listener_orientation(const Vector& at, const Vector& up);
79
80 void enable_music(bool music_enabled);
81 void play_music(const std::string& filename, bool fade = false);
82 void pause_music(float fadetime = 0);
83 void resume_music(float fadetime = 0);
84 void stop_music(float fadetime = 0);
85 void set_music_volume(int volume);
86
87 void pause_sounds();
88 void resume_sounds();
89 void stop_sounds();
90 void set_sound_volume(int volume);
91
92 bool is_music_enabled() const { return m_music_enabled; }
93 bool is_sound_enabled() const { return m_sound_enabled; }
94
95 bool is_audio_enabled() const { return m_device != nullptr && m_context != nullptr; }
96 std::string get_current_music() const { return m_current_music; }
97 void update();
98
99 /** Tell soundmanager to call update() for stream_sound_source. */
100 void register_for_update(StreamSoundSource* sss);
101
102 /** Unsubscribe from updates for stream_sound_source. */
103 void remove_from_update(StreamSoundSource* sss);
104
105private:
106 /** creates a new sound source, might throw exceptions, never returns nullptr */
107 std::unique_ptr<OpenALSoundSource> intern_create_sound_source(const std::string& filename);
108
109 void check_alc_error(const char* message) const;
110
111private:
112 ALCdevice* m_device;
113 ALCcontext* m_context;
114 bool m_sound_enabled;
115 int m_sound_volume;
116
117 std::map<std::string, ALuint> m_buffers;
118 std::vector<std::unique_ptr<OpenALSoundSource> > m_sources;
119
120 std::vector<StreamSoundSource*> m_update_list;
121
122 std::unique_ptr<StreamSoundSource> m_music_source;
123
124 bool m_music_enabled;
125 int m_music_volume;
126 std::string m_current_music;
127
128private:
129 SoundManager(const SoundManager&) = delete;
130 SoundManager& operator=(const SoundManager&) = delete;
131};
132
133#endif
134
135/* EOF */
136