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/props/props.hxx>
41 SG_SAMPLE_16BITS = 16,
43 SG_SAMPLE_COMPRESSED = 256,
45 SG_SAMPLE_MONO8 = (SG_SAMPLE_MONO|SG_SAMPLE_8BITS),
46 SG_SAMPLE_MONO16 = (SG_SAMPLE_MONO|SG_SAMPLE_16BITS),
47 SG_SAMPLE_STEREO8 = (SG_SAMPLE_STEREO|SG_SAMPLE_8BITS),
48 SG_SAMPLE_STEREO16 = (SG_SAMPLE_STEREO|SG_SAMPLE_16BITS),
49 SG_SAMPLE_MONO_MULAW = (SG_SAMPLE_MONO16|SG_SAMPLE_COMPRESSED),
50 SG_SAMPLE_STEREO_MULAW = (SG_SAMPLE_STEREO16|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 printf("<-- samples: %i, tracks: %i, bits: %i\n", _samples, _tracks, _bits);
106 return (_samples * _tracks * _bits)/8;
111 * Get the absolute position of this sound.
112 * This is in the same coordinate system as OpenGL; y=up, z=back, x=right.
113 * @return Absolute position
115 inline SGVec3d& get_position() { return _absolute_pos; }
118 * Get the orientation vector of this sound.
119 * This is in the same coordinate system as OpenGL; y=up, z=back, x=right
120 * @return Orientaton vector
122 inline SGVec3f& get_orientation() { return _orivec; }
125 * Get the inner angle of the audio cone.
126 * @return Inner angle in degrees
128 inline float get_innerangle() { return _inner_angle; }
131 * Get the outer angle of the audio cone.
132 * @return Outer angle in degrees
134 inline float get_outerangle() { return _outer_angle; }
137 * Get the remaining gain at the edge of the outer cone.
140 inline float get_outergain() { return _outer_gain; }
143 * Get velocity vector (in meters per second) of this sound.
144 * This is in the same coordinate system as OpenGL; y=up, z=back, x=right
145 * @return Velocity vector
147 inline SGVec3f& get_velocity() { return _velocity; }
150 * Get reference distance ((in meters) of this sound.
151 * This is the distance where the gain will be half.
152 * @return Reference distance
154 inline float get_reference_dist() { return _reference_dist; }
157 * Get maximum distance (in meters) of this sound.
158 * This is the distance where this sound is no longer audible.
159 * @return dist Maximum distance
161 inline float get_max_dist() { return _max_dist; }
164 * Test if static data of audio sample configuration has changed.
165 * Calling this function will reset the flag so calling it a second
166 * time in a row will return false.
167 * @return Return true is the static data has changed in the mean time.
169 bool has_static_data_changed() {
170 bool b = _static_changed; _static_changed = false; return b;
174 // static sound emitter info
175 std::string _refname;
177 unsigned int _tracks;
178 unsigned int _samples;
179 unsigned int _frequency;
183 // dynamic sound emitter info (non 3d)
184 bool _static_changed;
189 float _master_volume;
191 // dynamic sound emitter info (3d)
199 float _reference_dist;
202 SGPropertyNode_ptr _pos_prop[3];
203 SGVec3d _absolute_pos; // absolute position
204 SGVec3d _relative_pos; // position relative to the base position
205 SGVec3d _direction; // orientation offset
206 SGVec3f _velocity; // Velocity of the source sound.
208 // The position and orientation of this sound
209 SGQuatd _orientation; // base orientation
210 SGVec3f _orivec; // orientation vector
211 SGVec3d _base_pos; // base position
216 static std::string random_string();
220 class SGSoundSample : public SGSoundSampleInfo, public SGReferenced {
224 * Empty constructor, can be used to read data to the systems
225 * memory and not to the driver.
231 * @param file File name of sound
232 Buffer data is freed by the sample group
234 SGSoundSample(const char *file, const SGPath& currentDir);
238 * @param data Pointer to a memory buffer containing this audio sample data
239 The application may free the data by calling free_data(), otherwise it
240 will be resident until the class is destroyed. This pointer will be
241 set to NULL after calling this function.
242 * @param len Byte length of array
243 * @param freq Frequency of the provided data (bytes per second)
244 * @param format SimGear format id of the data
246 SGSoundSample( void** data, int len, int freq, int format=SG_SAMPLE_MONO8 );
247 SGSoundSample( const unsigned char** data, int len, int freq,
248 int format = SG_SAMPLE_MONO8 );
253 virtual ~SGSoundSample ();
256 * Test if this audio sample configuration has changed since the last call.
257 * Calling this function will reset the flag so calling it a second
258 * time in a row will return false.
259 * @return Return true is the configuration has changed in the mean time.
262 bool b = _changed; _changed = false; return b;
266 * Detect whether this audio sample holds the information of a sound file.
267 * @return Return true if this sample is to be constructed from a file.
269 inline bool is_file() const { return _is_file; }
271 SGPath file_path() const;
274 * Schedule this audio sample for playing. Actual playing will only start
275 * at the next call op SoundGroup::update()
276 * @param _loop Define whether this sound should be played in a loop.
278 void play( bool loop = false ) {
279 _playing = true; _loop = loop; _changed = true; _static_changed = true;
283 * Check if this audio sample is set to be continuous looping.
284 * @return Return true if this audio sample is set to looping.
286 inline bool is_looping() { return _loop; }
289 * Schedule this audio sample to stop playing.
291 virtual void stop() {
292 _playing = false; _changed = true;
296 * Schedule this audio sample to play once.
299 inline void play_once() { play(false); }
302 * Schedule this audio sample to play looped.
305 inline void play_looped() { play(true); }
308 * Test if a audio sample is scheduled for playing.
309 * @return true if this audio sample is playing, false otherwise.
311 inline bool is_playing() { return _playing; }
315 * Set this sample to out-of-range (or not) and
316 * Schedule this audio sample to stop (or start) playing.
318 inline void set_out_of_range(bool oor = true) {
319 _out_of_range = oor; _playing = (!oor && _loop); _changed = true;
323 * Test if this sample to out-of-range or not.
325 inline bool test_out_of_range() {
326 return _out_of_range;
330 * Set the data associated with this audio sample
331 * @param data Pointer to a memory block containg this audio sample data.
332 This pointer will be set to NULL after calling this function.
334 inline void set_data( const unsigned char **data ) {
335 _data = (unsigned char*)*data; *data = NULL;
337 inline void set_data( const void **data ) {
338 _data = (unsigned char*)*data; *data = NULL;
342 * Return the data associated with this audio sample.
343 * @return A pointer to this sound data of this audio sample.
345 inline void* get_data() const { return _data; }
348 * Free the data associated with this audio sample
353 * Set the source id of this source
354 * @param sid source-id
356 virtual void set_source(unsigned int sid) {
357 _source = sid; _valid_source = true; _changed = true;
361 * Get the source id of this source
364 virtual unsigned int get_source() { return _source; }
367 * Test if the source-id of this audio sample is usable.
368 * @return true if the source-id is valid
370 virtual bool is_valid_source() const { return _valid_source; }
373 * Set the source-id of this audio sample to invalid.
375 virtual void no_valid_source() { _valid_source = false; }
378 * Set the buffer-id of this source
379 * @param bid buffer-id
381 inline void set_buffer(unsigned int bid) {
382 _buffer = bid; _valid_buffer = true; _changed = true;
386 * Get the buffer-id of this source
389 inline unsigned int get_buffer() { return _buffer; }
392 * Test if the buffer-id of this audio sample is usable.
393 * @return true if the buffer-id is valid
395 inline bool is_valid_buffer() const { return _valid_buffer; }
398 * Set the buffer-id of this audio sample to invalid.
400 inline void no_valid_buffer() { _valid_buffer = false; }
403 * Set the playback pitch of this audio sample.
404 * Should be between 0.0 and 2.0 for maximum compatibility.
407 inline void set_pitch( float p ) {
408 if (p > 2.0) p = 2.0; else if (p < 0.01) p = 0.01;
409 _pitch = p; _changed = true;
413 * Set the master volume of this sample. Should be between 0.0 and 1.0.
414 * The final volume is calculated by multiplying the master and audio sample
418 inline void set_master_volume( float v ) {
419 if (v > 1.0) v = 1.0; else if (v < 0.0) v = 0.0;
420 _master_volume = v; _changed = true;
424 * Set the volume of this audio sample. Should be between 0.0 and 1.0.
425 * The final volume is calculated by multiplying the master and audio sample
429 inline void set_volume( float v ) {
430 if (v > 1.0) v = 1.0; else if (v < 0.0) v = 0.0;
431 _volume = v; _changed = true;
435 * Set the SimGear format of this audio sample.
436 * @param format SimGear format-id
438 inline void set_format( int fmt ) {
439 _tracks = fmt & 0x3; _bits = fmt & 0x1C; _compressed = fmt & 0x100;
442 void set_format_AL( int fmt );
445 * Set the frequency (in Herz) of this audio sample.
446 * @param freq Frequency
448 inline void set_frequency( int freq ) { _frequency = freq; }
451 * Sets the size (in bytes) of this audio sample.
452 * @param size Data size
454 inline void set_size( size_t size ) {
455 _samples = size*8/(_bits*_tracks);
457 inline void set_no_samples(size_t samples) { _samples = samples; }
460 * Set the position of this sound relative to the base position.
461 * This is in the same coordinate system as OpenGL; y=up, z=back, x=right.
462 * @param pos Relative position of this sound
464 inline void set_relative_position( const SGVec3f& pos ) {
465 _relative_pos = toVec3d(pos); _changed = true;
469 * Set the base position in Cartesian coordinates
470 * @param pos position in Cartesian coordinates
472 inline void set_position( const SGVec3d& pos ) {
473 _base_pos = pos; _changed = true;
476 inline void set_position_properties(SGPropertyNode_ptr pos[3]) {
477 _pos_prop[0] = pos[0]; _pos_prop[1] = pos[1]; _pos_prop[2] = pos[2];
478 if (pos[0] || pos[1] || pos[2]) _use_pos_props = true;
483 * Set the orientation of this sound.
484 * @param ori Quaternation containing the orientation information
486 inline void set_orientation( const SGQuatd& ori ) {
487 _orientation = ori; _changed = true;
490 inline void set_rotation( const SGQuatd& ec2body ) {
491 _rotation = ec2body; _changed = true;
495 * Set direction of this sound relative to the orientation.
496 * This is in the same coordinate system as OpenGL; y=up, z=back, x=right
497 * @param dir Sound emission direction
499 inline void set_direction( const SGVec3f& dir ) {
500 _direction = toVec3d(dir); _static_changed = true;
504 * Define the audio cone parameters for directional audio.
505 * Note: setting it to 2 degree will result in 1 degree to both sides.
506 * @param inner Inner cone angle (0 - 360 degrees)
507 * @param outer Outer cone angle (0 - 360 degrees)
508 * @param gain Remaining gain at the edge of the outer cone (0.0 - 1.0)
510 void set_audio_cone( float inner, float outer, float gain ) {
511 _inner_angle = inner; _outer_angle = outer; _outer_gain = gain;
512 _static_changed = true;
516 * Set the velocity vector (in meters per second) of this sound.
517 * This is in the local frame coordinate system; x=north, y=east, z=down
518 * @param Velocity vector
520 inline void set_velocity( const SGVec3f& vel ) {
521 _velocity = vel; _changed = true;
525 * Set reference distance (in meters) of this sound.
526 * This is the distance where the gain will be half.
527 * @param dist Reference distance
529 inline void set_reference_dist( float dist ) {
530 _reference_dist = dist; _static_changed = true;
534 * Set maximum distance (in meters) of this sound.
535 * This is the distance where this sound is no longer audible.
536 * @param dist Maximum distance
538 inline void set_max_dist( float dist ) {
539 _max_dist = dist; _static_changed = true;
542 inline virtual bool is_queue() const { return false; }
544 void update_pos_and_orientation();
550 // Sources are points emitting sound.
552 unsigned int _source;
555 unsigned char* _data;
557 // Buffers hold sound data.
559 unsigned int _buffer;
562 #endif // _SG_SAMPLE_HXX