1 // sample_openal.hxx -- Audio sample encapsulation class
3 // Written by Curtis Olson, started April 2004.
4 // Modified to match the new SoundSystem by Erik Hofman, October 2009
6 // Copyright (C) 2004 Curtis L. Olson - http://www.flightgear.org/~curt
7 // Copyright (C) 2009 Erik Hofman <erik@ehofman.com>
9 // This program is free software; you can redistribute it and/or
10 // modify it under the terms of the GNU General Public License as
11 // published by the Free Software Foundation; either version 2 of the
12 // License, or (at your option) any later version.
14 // This program is distributed in the hope that it will be useful, but
15 // WITHOUT ANY WARRANTY; without even the implied warranty of
16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 // General Public License for more details.
19 // You should have received a copy of the GNU General Public License
20 // along with this program; if not, write to the Free Software Foundation,
21 // Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
26 * \file audio sample.hxx
27 * Provides a audio sample encapsulation
30 #ifndef _SG_SAMPLE_HXX
31 #define _SG_SAMPLE_HXX 1
33 #include <simgear/math/SGMath.hxx>
34 #include <simgear/props/props.hxx>
42 SG_SAMPLE_16BITS = 16,
44 SG_SAMPLE_UNCOMPRESSED = 0,
45 SG_SAMPLE_COMPRESSED = 256,
47 SG_SAMPLE_MONO8 = (SG_SAMPLE_MONO|SG_SAMPLE_8BITS),
48 SG_SAMPLE_MONO16 = (SG_SAMPLE_MONO|SG_SAMPLE_16BITS),
49 SG_SAMPLE_MULAW = (SG_SAMPLE_MONO|SG_SAMPLE_8BITS|SG_SAMPLE_COMPRESSED),
50 SG_SAMPLE_ADPCM = (SG_SAMPLE_MONO|SG_SAMPLE_4BITS|SG_SAMPLE_COMPRESSED)
55 * manages everything we need to know for an individual audio sample
58 class SGSoundSampleInfo
62 ~SGSoundSampleInfo() {}
65 * Returns the format of this audio sample.
66 * @return SimGear format-id
68 unsigned int get_format_AL();
71 * Returns the format of this audio sample.
72 * @return SimGear format-id
74 inline unsigned int get_format() { return (_tracks | _bits | _compressed*256); }
77 * Get the reference name of this audio sample.
80 inline std::string get_sample_name() const { return _refname; }
83 * Returns the frequency (in Herz) of this audio sample.
86 inline unsigned int get_frequency() { return _frequency; }
89 * Get the current pitch value of this audio sample.
92 inline float get_pitch() { return _pitch; }
95 * Get the final volume value of this audio sample.
98 inline float get_volume() { return _volume * _master_volume; }
101 * Returns the size (in bytes) of this audio sample.
104 inline size_t get_size() const {
105 return (_samples * _tracks * _bits)/8;
110 * Get the absolute position of this sound.
111 * This is in the same coordinate system as OpenGL; y=up, z=back, x=right.
112 * @return Absolute position
114 inline SGVec3d& get_position() { return _absolute_pos; }
117 * Get the orientation vector of this sound.
118 * This is in the same coordinate system as OpenGL; y=up, z=back, x=right
119 * @return Orientaton vector
121 inline SGVec3f& get_orientation() { return _orivec; }
124 * Get the inner angle of the audio cone.
125 * @return Inner angle in degrees
127 inline float get_innerangle() { return _inner_angle; }
130 * Get the outer angle of the audio cone.
131 * @return Outer angle in degrees
133 inline float get_outerangle() { return _outer_angle; }
136 * Get the remaining gain at the edge of the outer cone.
139 inline float get_outergain() { return _outer_gain; }
142 * Get velocity vector (in meters per second) of this sound.
143 * This is in the same coordinate system as OpenGL; y=up, z=back, x=right
144 * @return Velocity vector
146 inline SGVec3f& get_velocity() { return _velocity; }
149 * Get reference distance ((in meters) of this sound.
150 * This is the distance where the gain will be half.
151 * @return Reference distance
153 inline float get_reference_dist() { return _reference_dist; }
156 * Get maximum distance (in meters) of this sound.
157 * This is the distance where this sound is no longer audible.
158 * @return dist Maximum distance
160 inline float get_max_dist() { return _max_dist; }
163 * Test if static data of audio sample configuration has changed.
164 * Calling this function will reset the flag so calling it a second
165 * time in a row will return false.
166 * @return Return true is the static data has changed in the mean time.
168 bool has_static_data_changed() {
169 bool b = _static_changed; _static_changed = false; return b;
173 // static sound emitter info
174 std::string _refname;
176 unsigned int _tracks;
177 unsigned int _samples;
178 unsigned int _frequency;
182 // dynamic sound emitter info (non 3d)
183 bool _static_changed;
188 float _master_volume;
190 // dynamic sound emitter info (3d)
198 float _reference_dist;
201 SGPropertyNode_ptr _pos_prop[3];
202 SGVec3d _absolute_pos; // absolute position
203 SGVec3d _relative_pos; // position relative to the base position
204 SGVec3d _direction; // orientation offset
205 SGVec3f _velocity; // Velocity of the source sound.
207 // The position and orientation of this sound
208 SGQuatd _orientation; // base orientation
209 SGVec3f _orivec; // orientation vector
210 SGVec3d _base_pos; // base position
215 static std::string random_string();
219 class SGSoundSample : public SGSoundSampleInfo, public SGReferenced {
223 * Empty constructor, can be used to read data to the systems
224 * memory and not to the driver.
230 * @param file File name of sound
231 Buffer data is freed by the sample group
233 SGSoundSample(const char *file, const SGPath& currentDir);
237 * @param data Pointer to a memory buffer containing this audio sample data
238 The application may free the data by calling free_data(), otherwise it
239 will be resident until the class is destroyed. This pointer will be
240 set to NULL after calling this function.
241 * @param len Byte length of array
242 * @param freq Frequency of the provided data (bytes per second)
243 * @param format SimGear format id of the data
245 SGSoundSample( void** data, int len, int freq, int format=SG_SAMPLE_MONO8 );
246 SGSoundSample( const unsigned char** data, int len, int freq,
247 int format = SG_SAMPLE_MONO8 );
252 virtual ~SGSoundSample ();
255 * Test if this audio sample configuration has changed since the last call.
256 * Calling this function will reset the flag so calling it a second
257 * time in a row will return false.
258 * @return Return true is the configuration has changed in the mean time.
261 bool b = _changed; _changed = false; return b;
265 * Detect whether this audio sample holds the information of a sound file.
266 * @return Return true if this sample is to be constructed from a file.
268 inline bool is_file() const { return _is_file; }
270 SGPath file_path() const;
273 * Schedule this audio sample for playing. Actual playing will only start
274 * at the next call op SoundGroup::update()
275 * @param _loop Define whether this sound should be played in a loop.
277 void play( bool loop = false ) {
278 _playing = true; _loop = loop; _changed = true; _static_changed = true;
282 * Check if this audio sample is set to be continuous looping.
283 * @return Return true if this audio sample is set to looping.
285 inline bool is_looping() { return _loop; }
288 * Schedule this audio sample to stop playing.
290 virtual void stop() {
291 _playing = false; _changed = true;
295 * Schedule this audio sample to play once.
298 inline void play_once() { play(false); }
301 * Schedule this audio sample to play looped.
304 inline void play_looped() { play(true); }
307 * Test if a audio sample is scheduled for playing.
308 * @return true if this audio sample is playing, false otherwise.
310 inline bool is_playing() { return _playing; }
314 * Set this sample to out-of-range (or not) and
315 * Schedule this audio sample to stop (or start) playing.
317 inline void set_out_of_range(bool oor = true) {
318 _out_of_range = oor; _playing = (!oor && _loop); _changed = true;
322 * Test if this sample to out-of-range or not.
324 inline bool test_out_of_range() {
325 return _out_of_range;
329 * Set the data associated with this audio sample
330 * @param data Pointer to a memory block containg this audio sample data.
331 This pointer will be set to NULL after calling this function.
333 inline void set_data( const unsigned char **data ) {
334 _data = (unsigned char*)*data; *data = NULL;
336 inline void set_data( const void **data ) {
337 _data = (unsigned char*)*data; *data = NULL;
341 * Return the data associated with this audio sample.
342 * @return A pointer to this sound data of this audio sample.
344 inline void* get_data() const { return _data; }
347 * Free the data associated with this audio sample
352 * Set the source id of this source
353 * @param sid source-id
355 virtual void set_source(unsigned int sid) {
356 _source = sid; _valid_source = true; _changed = true;
360 * Get the source id of this source
363 virtual unsigned int get_source() { return _source; }
366 * Test if the source-id of this audio sample is usable.
367 * @return true if the source-id is valid
369 virtual bool is_valid_source() const { return _valid_source; }
372 * Set the source-id of this audio sample to invalid.
374 virtual void no_valid_source() { _valid_source = false; }
377 * Set the buffer-id of this source
378 * @param bid buffer-id
380 inline void set_buffer(unsigned int bid) {
381 _buffer = bid; _valid_buffer = true; _changed = true;
385 * Get the buffer-id of this source
388 inline unsigned int get_buffer() { return _buffer; }
391 * Test if the buffer-id of this audio sample is usable.
392 * @return true if the buffer-id is valid
394 inline bool is_valid_buffer() const { return _valid_buffer; }
397 * Set the buffer-id of this audio sample to invalid.
399 inline void no_valid_buffer() { _valid_buffer = false; }
402 * Set the playback pitch of this audio sample.
403 * Should be between 0.0 and 2.0 for maximum compatibility.
406 inline void set_pitch( float p ) {
407 if (p > 2.0) p = 2.0; else if (p < 0.01) p = 0.01;
408 _pitch = p; _changed = true;
412 * Set the master volume of this sample. Should be between 0.0 and 1.0.
413 * The final volume is calculated by multiplying the master and audio sample
417 inline void set_master_volume( float v ) {
418 if (v > 1.0) v = 1.0; else if (v < 0.0) v = 0.0;
419 _master_volume = v; _changed = true;
423 * Set the volume of this audio sample. Should be between 0.0 and 1.0.
424 * The final volume is calculated by multiplying the master and audio sample
428 inline void set_volume( float v ) {
429 if (v > 1.0) v = 1.0; else if (v < 0.0) v = 0.0;
430 _volume = v; _changed = true;
434 * Set the SimGear format of this audio sample.
435 * @param format SimGear format-id
437 inline void set_format( int fmt ) {
438 _tracks = fmt & 0x3; _bits = fmt & 0x1C; _compressed = fmt & 0x100;
441 void set_format_AL( int fmt );
444 * Set the frequency (in Herz) of this audio sample.
445 * @param freq Frequency
447 inline void set_frequency( int freq ) { _frequency = freq; }
450 * Sets the size (in bytes) of this audio sample.
451 * @param size Data size
453 inline void set_size( size_t size ) {
454 _samples = size*8/(_bits*_tracks);
456 inline void set_no_samples(size_t samples) { _samples = samples; }
459 * Set the position of this sound relative to the base position.
460 * This is in the same coordinate system as OpenGL; y=up, z=back, x=right.
461 * @param pos Relative position of this sound
463 inline void set_relative_position( const SGVec3f& pos ) {
464 _relative_pos = toVec3d(pos); _changed = true;
468 * Set the base position in Cartesian coordinates
469 * @param pos position in Cartesian coordinates
471 inline void set_position( const SGVec3d& pos ) {
472 _base_pos = pos; _changed = true;
475 inline void set_position_properties(SGPropertyNode_ptr pos[3]) {
476 _pos_prop[0] = pos[0]; _pos_prop[1] = pos[1]; _pos_prop[2] = pos[2];
477 if (pos[0] || pos[1] || pos[2]) _use_pos_props = true;
482 * Set the orientation of this sound.
483 * @param ori Quaternation containing the orientation information
485 inline void set_orientation( const SGQuatd& ori ) {
486 _orientation = ori; _changed = true;
489 inline void set_rotation( const SGQuatd& ec2body ) {
490 _rotation = ec2body; _changed = true;
494 * Set direction of this sound relative to the orientation.
495 * This is in the same coordinate system as OpenGL; y=up, z=back, x=right
496 * @param dir Sound emission direction
498 inline void set_direction( const SGVec3f& dir ) {
499 _direction = toVec3d(dir); _static_changed = true;
503 * Define the audio cone parameters for directional audio.
504 * Note: setting it to 2 degree will result in 1 degree to both sides.
505 * @param inner Inner cone angle (0 - 360 degrees)
506 * @param outer Outer cone angle (0 - 360 degrees)
507 * @param gain Remaining gain at the edge of the outer cone (0.0 - 1.0)
509 void set_audio_cone( float inner, float outer, float gain ) {
510 _inner_angle = inner; _outer_angle = outer; _outer_gain = gain;
511 _static_changed = true;
515 * Set the velocity vector (in meters per second) of this sound.
516 * This is in the local frame coordinate system; x=north, y=east, z=down
517 * @param Velocity vector
519 inline void set_velocity( const SGVec3f& vel ) {
520 _velocity = vel; _changed = true;
524 * Set reference distance (in meters) of this sound.
525 * This is the distance where the gain will be half.
526 * @param dist Reference distance
528 inline void set_reference_dist( float dist ) {
529 _reference_dist = dist; _static_changed = true;
533 * Set maximum distance (in meters) of this sound.
534 * This is the distance where this sound is no longer audible.
535 * @param dist Maximum distance
537 inline void set_max_dist( float dist ) {
538 _max_dist = dist; _static_changed = true;
541 inline virtual bool is_queue() const { return false; }
543 void update_pos_and_orientation();
549 // Sources are points emitting sound.
551 unsigned int _source;
554 unsigned char* _data;
556 // Buffers hold sound data.
558 unsigned int _buffer;
561 #endif // _SG_SAMPLE_HXX