1 // soundmgr.hxx -- Sound effect management class
3 // Sound manager initially written by David Findlay
4 // <david_j_findlay@yahoo.com.au> 2001
6 // C++-ified by Curtis Olson, started March 2001.
7 // Modified for the new SoundSystem by Erik Hofman, October 2009
9 // Copyright (C) 2001 Curtis L. Olson - http://www.flightgear.org/~curt
10 // Copyright (C) 2009 Erik Hofman <erik@ehofman.com>
12 // This program is free software; you can redistribute it and/or
13 // modify it under the terms of the GNU General Public License as
14 // published by the Free Software Foundation; either version 2 of the
15 // License, or (at your option) any later version.
17 // This program is distributed in the hope that it will be useful, but
18 // WITHOUT ANY WARRANTY; without even the implied warranty of
19 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 // General Public License for more details.
22 // You should have received a copy of the GNU General Public License
23 // along with this program; if not, write to the Free Software Foundation,
24 // Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
30 * Provides a sound manager class to keep track of
31 * multiple sounds and manage playing them with different effects and
35 #ifndef _SG_SOUNDMGR_OPENAL_HXX
36 #define _SG_SOUNDMGR_OPENAL_HXX 1
41 #include <memory> // for std::auto_ptr
43 #include <simgear/compiler.h>
44 #include <simgear/structure/subsystem_mgr.hxx>
45 #include <simgear/math/SGMath.hxx>
52 * Manage a collection of SGSampleGroup instances
54 class SGSoundMgr : public SGSubsystem
62 void update(double dt);
71 * Select a specific sound device.
72 * Requires a init/reinit call before sound is actually switched.
74 inline void select_device(const char* devname) {_device_name = devname;}
77 * Test is the sound manager is in a working condition.
78 * @return true is the sound manager is working
80 bool is_working() const;
83 * Set the sound manager to a working condition.
88 * Test is the sound manager is in an active and working condition.
89 * @return true is the sound manager is active
91 inline bool is_active() const { return _active; }
94 * Register a sample group to the sound manager.
95 * @param sgrp Pointer to a sample group to add
96 * @param refname Reference name of the sample group
97 * @return true if successful, false otherwise
99 bool add( SGSampleGroup *sgrp, const std::string& refname );
102 * Remove a sample group from the sound manager.
103 * @param refname Reference name of the sample group to remove
104 * @return true if successful, false otherwise
106 bool remove( const std::string& refname );
109 * Test if a specified sample group is registered at the sound manager
110 * @param refname Reference name of the sample group test for
111 * @return true if the specified sample group exists
113 bool exists( const std::string& refname );
116 * Find a specified sample group in the sound manager
117 * @param refname Reference name of the sample group to find
118 * @return A pointer to the SGSampleGroup
120 SGSampleGroup *find( const std::string& refname, bool create = false );
123 * Set the Cartesian position of the sound manager.
124 * @param pos OpenAL listener position
126 void set_position( const SGVec3d& pos, const SGGeod& pos_geod );
128 void set_position_offset( const SGVec3d& pos ) {
129 _offset_pos = pos; _changed = true;
133 * Get the position of the sound manager.
134 * This is in the same coordinate system as OpenGL; y=up, z=back, x=right
135 * @return OpenAL listener position
137 const SGVec3d& get_position() const;
140 * Set the velocity vector (in meters per second) of the sound manager
141 * This is the horizontal local frame; x=north, y=east, z=down
142 * @param Velocity vector
144 void set_velocity( const SGVec3d& vel ) {
145 _velocity = vel; _changed = true;
149 * Get the velocity vector of the sound manager
150 * This is in the same coordinate system as OpenGL; y=up, z=back, x=right.
151 * @return Velocity vector of the OpenAL listener
153 inline SGVec3f get_velocity() { return toVec3f(_velocity); }
156 * Set the orientation of the sound manager
157 * @param ori Quaternation containing the orientation information
159 void set_orientation( const SGQuatd& ori );
162 * Get the orientation of the sound manager
163 * @return Quaternation containing the orientation information
165 const SGQuatd& get_orientation() const;
168 * Get the direction vector of the sound manager
169 * This is in the same coordinate system as OpenGL; y=up, z=back, x=right.
170 * @return Look-at direction of the OpenAL listener
172 SGVec3f get_direction() const;
175 NO_SOURCE = (unsigned int)-1,
176 NO_BUFFER = (unsigned int)-1,
177 FAILED_BUFFER = (unsigned int)-2
181 * Set the master volume.
182 * @param vol Volume (must be between 0.0 and 1.0)
184 void set_volume( float vol );
187 * Get the master volume.
188 * @return Volume (must be between 0.0 and 1.0)
190 inline float get_volume() { return _volume; }
193 * Get a free OpenAL source-id
194 * @return NO_SOURCE if no source is available
196 unsigned int request_source();
199 * Free an OpenAL source-id for future use
200 * @param source OpenAL source-id to free
202 void release_source( unsigned int source );
205 * Get a free OpenAL buffer-id
206 * The buffer-id will be assigned to the sample by calling this function.
207 * @param sample Pointer to an audio sample to assign the buffer-id to
208 * @return NO_BUFFER if loading of the buffer failed.
210 unsigned int request_buffer(SGSoundSample *sample);
213 * Free an OpenAL buffer-id for this sample
214 * @param sample Pointer to an audio sample for which to free the buffer
216 void release_buffer( SGSoundSample *sample );
219 * Test if the position of the sound manager has changed.
220 * The value will be set to false upon the next call to update_late()
221 * @return true if the position has changed
223 inline bool has_changed() { return _changed; }
226 * Some implementations seem to need the velocity multiplied by a
227 * factor of 100 to make them distinct. I've not found if this is
228 * a problem in the implementation or in out code. Until then
229 * this function is used to detect the problematic implementations.
231 inline bool bad_doppler_effect() { return _bad_doppler; }
234 * Load a sample file and return it's configuration and data.
235 * @param samplepath Path to the file to load
236 * @param data Pointer to a variable that points to the allocated data
237 * @param format Pointer to a vairable that gets the OpenAL format
238 * @param size Pointer to a vairable that gets the sample size in bytes
239 * @param freq Pointer to a vairable that gets the sample frequency in Herz
240 * @return true if succesful, false on error
242 bool load(const std::string &samplepath, void **data, int *format,
243 size_t *size, int *freq );
246 * Get a list of available playback devices.
248 std::vector<const char*> get_available_devices();
251 * Get the current OpenAL vendor or rendering backend.
253 const std::string& get_vendor() { return _vendor; }
254 const std::string& get_renderer() { return _renderer; }
257 class SoundManagerPrivate;
258 /// private implementation object
259 std::auto_ptr<SoundManagerPrivate> d;
265 // Position of the listener.
269 // Velocity of the listener.
273 std::string _renderer;
275 std::string _device_name;
277 bool testForALError(std::string s);
278 bool testForALCError(std::string s);
279 bool testForError(void *p, std::string s);
281 void update_sample_config( SGSampleGroup *sound );
285 #endif // _SG_SOUNDMGR_OPENAL_HXX