2 /// Sound effect management class
4 /// Provides a sound manager class to keep track of multiple sounds and manage
5 /// playing them with different effects and timings.
7 // Sound manager initially written by David Findlay
8 // <david_j_findlay@yahoo.com.au> 2001
10 // C++-ified by Curtis Olson, started March 2001.
11 // Modified for the new SoundSystem by Erik Hofman, October 2009
13 // Copyright (C) 2001 Curtis L. Olson - http://www.flightgear.org/~curt
14 // Copyright (C) 2009 Erik Hofman <erik@ehofman.com>
16 // This library is free software; you can redistribute it and/or
17 // modify it under the terms of the GNU Library General Public
18 // License as published by the Free Software Foundation; either
19 // version 2 of the License, or (at your option) any later version.
21 // This library is distributed in the hope that it will be useful,
22 // but WITHOUT ANY WARRANTY; without even the implied warranty of
23 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
24 // Library General Public License for more details.
26 // You should have received a copy of the GNU Library General Public
27 // License along with this library; if not, write to the Free Software
28 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
30 #ifndef _SG_SOUNDMGR_OPENAL_HXX
31 #define _SG_SOUNDMGR_OPENAL_HXX 1
36 #include <memory> // for std::auto_ptr
38 #include <simgear/compiler.h>
39 #include <simgear/structure/subsystem_mgr.hxx>
40 #include <simgear/math/SGMath.hxx>
47 * Manage a collection of SGSampleGroup instances
49 class SGSoundMgr : public SGSubsystem
57 void update(double dt);
66 * Select a specific sound device.
67 * Requires a init/reinit call before sound is actually switched.
69 inline void select_device(const char* devname) {_device_name = devname;}
72 * Test is the sound manager is in a working condition.
73 * @return true is the sound manager is working
75 bool is_working() const;
78 * Set the sound manager to a working condition.
83 * Test is the sound manager is in an active and working condition.
84 * @return true is the sound manager is active
86 inline bool is_active() const { return _active; }
89 * Register a sample group to the sound manager.
90 * @param sgrp Pointer to a sample group to add
91 * @param refname Reference name of the sample group
92 * @return true if successful, false otherwise
94 bool add( SGSampleGroup *sgrp, const std::string& refname );
97 * Remove a sample group from the sound manager.
98 * @param refname Reference name of the sample group to remove
99 * @return true if successful, false otherwise
101 bool remove( const std::string& refname );
104 * Test if a specified sample group is registered at the sound manager
105 * @param refname Reference name of the sample group test for
106 * @return true if the specified sample group exists
108 bool exists( const std::string& refname );
111 * Find a specified sample group in the sound manager
113 * @param refname Reference name of the sample group to find
114 * @param create If the group should be create if it does not exist
115 * @return A pointer to the SGSampleGroup
117 SGSampleGroup *find( const std::string& refname, bool create = false );
120 * Set the Cartesian position of the sound manager.
122 * @param pos OpenAL listener position
124 void set_position( const SGVec3d& pos, const SGGeod& pos_geod );
126 void set_position_offset( const SGVec3d& pos ) {
127 _offset_pos = pos; _changed = true;
131 * Get the position of the sound manager.
132 * This is in the same coordinate system as OpenGL; y=up, z=back, x=right
134 * @return OpenAL listener position
136 const SGVec3d& get_position() const;
139 * Set the velocity vector (in meters per second) of the sound manager
140 * This is the horizontal local frame; x=north, y=east, z=down
142 * @param vel 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.
152 * @return Velocity vector of the OpenAL listener
154 inline SGVec3f get_velocity() { return toVec3f(_velocity); }
157 * Set the orientation of the sound manager
159 * @param ori Quaternation containing the orientation information
161 void set_orientation( const SGQuatd& ori );
164 * Get the orientation of the sound manager
166 * @return Quaternation containing the orientation information
168 const SGQuatd& get_orientation() const;
171 * Get the direction vector of the sound manager
172 * This is in the same coordinate system as OpenGL; y=up, z=back, x=right.
174 * @return Look-at direction of the OpenAL listener
176 SGVec3f get_direction() const;
179 NO_SOURCE = (unsigned int)-1,
180 NO_BUFFER = (unsigned int)-1,
181 FAILED_BUFFER = (unsigned int)-2
185 * Set the master volume.
187 * @param vol Volume (must be between 0.0 and 1.0)
189 void set_volume( float vol );
192 * Get the master volume.
194 * @return Volume (must be between 0.0 and 1.0)
196 inline float get_volume() { return _volume; }
199 * Get a free OpenAL source-id
201 * @return NO_SOURCE if no source is available
203 unsigned int request_source();
206 * Free an OpenAL source-id for future use
208 * @param source OpenAL source-id to free
210 void release_source( unsigned int source );
213 * Get a free OpenAL buffer-id
214 * The buffer-id will be assigned to the sample by calling this function.
216 * @param sample Pointer to an audio sample to assign the buffer-id to
217 * @return NO_BUFFER if loading of the buffer failed.
219 unsigned int request_buffer(SGSoundSample *sample);
222 * Free an OpenAL buffer-id for this sample
224 * @param sample Pointer to an audio sample for which to free the buffer
226 void release_buffer( SGSoundSample *sample );
229 * Test if the position of the sound manager has changed.
230 * The value will be set to false upon the next call to update_late()
232 * @return true if the position has changed
234 inline bool has_changed() { return _changed; }
237 * Some implementations seem to need the velocity multiplied by a
238 * factor of 100 to make them distinct. I've not found if this is
239 * a problem in the implementation or in out code. Until then
240 * this function is used to detect the problematic implementations.
242 inline bool bad_doppler_effect() { return _bad_doppler; }
245 * Load a sample file and return it's configuration and data.
247 * @param samplepath Path to the file to load
248 * @param data Pointer to a variable that points to the allocated data
249 * @param format Pointer to a vairable that gets the OpenAL format
250 * @param size Pointer to a vairable that gets the sample size in bytes
251 * @param freq Pointer to a vairable that gets the sample frequency in Herz
252 * @return true if succesful, false on error
254 bool load( const std::string &samplepath,
261 * Get a list of available playback devices.
263 std::vector<const char*> get_available_devices();
266 * Get the current OpenAL vendor or rendering backend.
268 const std::string& get_vendor() { return _vendor; }
269 const std::string& get_renderer() { return _renderer; }
272 class SoundManagerPrivate;
273 /// private implementation object
274 std::auto_ptr<SoundManagerPrivate> d;
280 // Position of the listener.
284 // Velocity of the listener.
288 std::string _renderer;
290 std::string _device_name;
292 bool testForALError(std::string s);
293 bool testForALCError(std::string s);
294 bool testForError(void *p, std::string s);
296 void update_sample_config( SGSampleGroup *sound );
300 #endif // _SG_SOUNDMGR_OPENAL_HXX