]> git.mxchange.org Git - simgear.git/blob - simgear/sound/sample_openal.hxx
Switch to out own audio format defines
[simgear.git] / simgear / sound / sample_openal.hxx
1 // sample_openal.hxx -- Audio sample encapsulation class
2 // 
3 // Written by Curtis Olson, started April 2004.
4 // Modified to match the new SoundSystem by Erik Hofman, October 2009
5 //
6 // Copyright (C) 2004  Curtis L. Olson - http://www.flightgear.org/~curt
7 // Copyright (C) 2009 Erik Hofman <erik@ehofman.com>
8 //
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.
13 //
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.
18 //
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.
22 //
23 // $Id$
24
25 /**
26  * \file audio sample.hxx
27  * Provides a audio sample encapsulation
28  */
29
30 #ifndef _SG_SAMPLE_HXX
31 #define _SG_SAMPLE_HXX 1
32
33 #include <simgear/math/SGMath.hxx>
34 #include <simgear/props/props.hxx>
35      
36 enum {
37     SG_SAMPLE_MONO = 1,
38     SG_SAMPLE_STEREO = 2,
39
40     SG_SAMPLE_4BITS = 4,
41     SG_SAMPLE_8BITS = 8,
42     SG_SAMPLE_16BITS = 16,
43
44     SG_SAMPLE_UNCOMPRESSED = 0,
45     SG_SAMPLE_COMPRESSED = 256,
46
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)
51 };
52
53
54 /**
55  * manages everything we need to know for an individual audio sample
56  */
57
58 class SGSoundSampleInfo
59 {
60 public:
61     SGSoundSampleInfo();
62     ~SGSoundSampleInfo() {}
63
64     /**
65      * Returns the format of this audio sample.
66      * @return SimGear format-id
67      */
68     inline unsigned int get_format() { return (_tracks | _bits | _compressed*256); }
69
70     /**
71      * Get the reference name of this audio sample.
72      * @return Sample name
73      */
74     inline std::string get_sample_name() const { return _refname; }
75
76     /**
77      * Returns the frequency (in Herz) of this audio sample.
78      * @return Frequency
79      */
80     inline unsigned int get_frequency() { return _frequency; }
81
82     /**
83      * Get the current pitch value of this audio sample.
84      * @return Pitch
85      */
86     inline float get_pitch() { return _pitch; }
87
88     /**
89      * Get the final volume value of this audio sample.
90      * @return Volume
91      */
92     inline float get_volume() { return _volume * _master_volume; }
93
94     /**
95      * Returns the size (in bytes) of this audio sample.
96      * @return Data size
97      */
98     inline size_t get_size() const {
99         return (_samples * _tracks * _bits)/8;
100     }
101
102
103     /**
104      * Get the absolute position of this sound.
105      * This is in the same coordinate system as OpenGL; y=up, z=back, x=right.
106      * @return Absolute position
107      */
108     inline SGVec3d& get_position() { return _absolute_pos; }
109
110     /**
111      * Get the orientation vector of this sound.
112      * This is in the same coordinate system as OpenGL; y=up, z=back, x=right
113      * @return Orientaton vector
114      */
115     inline SGVec3f& get_orientation() { return _orivec; }
116
117     /**
118      * Get the inner angle of the audio cone.
119      * @return Inner angle in degrees
120      */
121     inline float get_innerangle() { return _inner_angle; }
122
123     /**
124      * Get the outer angle of the audio cone.
125      * @return Outer angle in degrees
126      */
127     inline float get_outerangle() { return _outer_angle; }
128
129     /**
130      * Get the remaining gain at the edge of the outer cone.
131      * @return Gain
132      */
133     inline float get_outergain() { return _outer_gain; }
134
135     /**
136      * Get velocity vector (in meters per second) of this sound.
137      * This is in the same coordinate system as OpenGL; y=up, z=back, x=right
138      * @return Velocity vector
139      */
140     inline SGVec3f& get_velocity() { return _velocity; }
141
142     /**
143      * Get reference distance ((in meters) of this sound.
144      * This is the distance where the gain will be half.
145      * @return Reference distance
146      */
147     inline float get_reference_dist() { return _reference_dist; }
148
149     /**
150      * Get maximum distance (in meters) of this sound.
151      * This is the distance where this sound is no longer audible.
152      * @return dist Maximum distance
153      */
154     inline float get_max_dist() { return _max_dist; }
155
156     /**
157      * Test if static data of audio sample configuration has changed.
158      * Calling this function will reset the flag so calling it a second
159      * time in a row will return false.
160      * @return Return true is the static data has changed in the mean time.
161      */
162     bool has_static_data_changed() {
163         bool b = _static_changed; _static_changed = false; return b;
164     }
165
166 protected:
167     // static sound emitter info
168     std::string _refname;
169     unsigned int _bits;
170     unsigned int _tracks;
171     unsigned int _samples;
172     unsigned int _frequency;
173     bool _compressed;
174     bool _loop;
175
176     // dynamic sound emitter info (non 3d)
177     bool _static_changed;
178     bool _playing;
179
180     float _pitch;
181     float _volume;
182     float _master_volume;
183
184     // dynamic sound emitter info (3d)
185     bool _use_pos_props;
186     bool _out_of_range;
187
188     float _inner_angle;
189     float _outer_angle;
190     float _outer_gain;
191
192     float _reference_dist;
193     float _max_dist;
194
195     SGPropertyNode_ptr _pos_prop[3];
196     SGVec3d _absolute_pos;      // absolute position
197     SGVec3d _relative_pos;      // position relative to the base position
198     SGVec3d _direction;         // orientation offset
199     SGVec3f _velocity;          // Velocity of the source sound.
200
201     // The position and orientation of this sound
202     SGQuatd _orientation;       // base orientation
203     SGVec3f _orivec;            // orientation vector
204     SGVec3d _base_pos;          // base position
205
206     SGQuatd _rotation;
207
208 private:
209     static std::string random_string();
210 };
211
212
213 class SGSoundSample : public SGSoundSampleInfo, public SGReferenced {
214 public:
215
216      /**
217       * Empty constructor, can be used to read data to the systems
218       * memory and not to the driver.
219       */
220     SGSoundSample();
221
222     /**
223      * Constructor
224      * @param file File name of sound
225        Buffer data is freed by the sample group
226      */
227     SGSoundSample(const char *file, const SGPath& currentDir);
228
229     /**
230      * Constructor.
231      * @param data Pointer to a memory buffer containing this audio sample data
232        The application may free the data by calling free_data(), otherwise it
233        will be resident until the class is destroyed. This pointer will be
234        set to NULL after calling this function.
235      * @param len Byte length of array
236      * @param freq Frequency of the provided data (bytes per second)
237      * @param format SimGear format id of the data
238      */
239     SGSoundSample( void** data, int len, int freq, int format=SG_SAMPLE_MONO8 );
240     SGSoundSample( const unsigned char** data, int len, int freq,
241                    int format = SG_SAMPLE_MONO8 );
242
243     /**
244      * Destructor
245      */
246     virtual ~SGSoundSample ();
247
248     /**
249      * Test if this audio sample configuration has changed since the last call.
250      * Calling this function will reset the flag so calling it a second
251      * time in a row will return false.
252      * @return Return true is the configuration has changed in the mean time.
253      */
254     bool has_changed() {
255         bool b = _changed; _changed = false; return b;
256     }
257
258     /**
259      * Detect whether this audio sample holds the information of a sound file.
260      * @return Return true if this sample is to be constructed from a file.
261      */
262     inline bool is_file() const { return _is_file; }
263
264     SGPath file_path() const;
265
266     /**
267      * Schedule this audio sample for playing. Actual playing will only start
268      * at the next call op SoundGroup::update()
269      * @param _loop Define whether this sound should be played in a loop.
270      */
271     void play( bool loop = false ) {
272         _playing = true; _loop = loop; _changed = true; _static_changed = true;
273     }
274
275     /**
276      * Check if this audio sample is set to be continuous looping.
277      * @return Return true if this audio sample is set to looping.
278      */
279     inline bool is_looping() { return _loop; }
280
281     /**
282      * Schedule this audio sample to stop playing.
283      */
284     virtual void stop() {
285         _playing = false; _changed = true;
286     }
287
288     /**
289      * Schedule this audio sample to play once.
290      * @see #play
291      */
292     inline void play_once() { play(false); }
293
294     /** 
295      * Schedule this audio sample to play looped.
296      * @see #play
297      */
298     inline void play_looped() { play(true); }
299
300     /**
301      * Test if a audio sample is scheduled for playing.
302      * @return true if this audio sample is playing, false otherwise.
303      */
304     inline bool is_playing() { return _playing; }
305
306
307     /**
308      * Set this sample to out-of-range (or not) and
309      * Schedule this audio sample to stop (or start) playing.
310      */
311     inline void set_out_of_range(bool oor = true) {
312         _out_of_range = oor; _playing = (!oor && _loop); _changed = true;
313     }
314
315     /**
316      * Test if this sample to out-of-range or not.
317      */
318     inline bool test_out_of_range() {
319         return _out_of_range;
320     }
321
322     /**
323      * Set the data associated with this audio sample
324      * @param data Pointer to a memory block containg this audio sample data.
325        This pointer will be set to NULL after calling this function.
326      */
327     inline void set_data( const unsigned char **data ) {
328         _data = (unsigned char*)*data; *data = NULL;
329     }
330     inline void set_data( const void **data ) {
331         _data = (unsigned char*)*data; *data = NULL;
332     }
333
334     /**
335      * Return the data associated with this audio sample.
336      * @return A pointer to this sound data of this audio sample.
337      */
338     inline void* get_data() const { return _data; }
339
340     /**
341      * Free the data associated with this audio sample
342      */
343     void free_data();
344
345     /**
346      * Set the source id of this source
347      * @param sid source-id
348      */
349     virtual void set_source(unsigned int sid) {
350         _source = sid; _valid_source = true; _changed = true;
351     }
352
353     /**
354      * Get the source id of this source
355      * @return source-id
356      */
357     virtual unsigned int get_source() { return _source; }
358
359     /**
360      * Test if the source-id of this audio sample is usable.
361      * @return true if the source-id is valid
362      */
363     virtual bool is_valid_source() const { return _valid_source; }
364
365     /**
366      * Set the source-id of this audio sample to invalid.
367      */
368     virtual void no_valid_source() { _valid_source = false; }
369
370     /**
371      * Set the buffer-id of this source
372      * @param bid buffer-id
373      */
374     inline void set_buffer(unsigned int bid) {
375         _buffer = bid; _valid_buffer = true; _changed = true;
376     } 
377
378     /**
379      * Get the buffer-id of this source
380      * @return buffer-id
381      */
382     inline unsigned int get_buffer() { return _buffer; }
383
384     /**
385      * Test if the buffer-id of this audio sample is usable.
386      * @return true if the buffer-id is valid
387      */
388     inline bool is_valid_buffer() const { return _valid_buffer; }
389
390     /**
391      * Set the buffer-id of this audio sample to invalid.
392      */
393     inline void no_valid_buffer() { _valid_buffer = false; }
394
395     /**
396      * Set the playback pitch of this audio sample. 
397      * Should be between 0.0 and 2.0 for maximum compatibility.
398      * @param p Pitch
399      */
400     inline void set_pitch( float p ) {
401         if (p > 2.0) p = 2.0; else if (p < 0.01) p = 0.01;
402         _pitch = p; _changed = true;
403     }
404
405     /**
406      * Set the master volume of this sample. Should be between 0.0 and 1.0.
407      * The final volume is calculated by multiplying the master and audio sample
408      * volume.
409      * @param v Volume
410      */
411     inline void set_master_volume( float v ) {
412         if (v > 1.0) v = 1.0; else if (v < 0.0) v = 0.0;
413         _master_volume = v; _changed = true;
414     }
415
416     /**
417      * Set the volume of this audio sample. Should be between 0.0 and 1.0.
418      * The final volume is calculated by multiplying the master and audio sample
419      * volume.
420      * @param v Volume
421      */
422     inline void set_volume( float v ) {
423         if (v > 1.0) v = 1.0; else if (v < 0.0) v = 0.0;
424         _volume = v; _changed = true;
425     }
426
427     /**
428      * Set the SimGear format of this audio sample.
429      * @param format SimGear format-id
430      */
431     inline void set_format( int fmt ) {
432         _tracks = fmt & 0x3; _bits = fmt & 0x1C; _compressed = fmt & 0x100;
433     }
434
435     /**
436      * Set the frequency (in Herz) of this audio sample.
437      * @param freq Frequency
438      */
439     inline void set_frequency( int freq ) { _frequency = freq; }
440
441     /**
442      * Sets the size (in bytes) of this audio sample.
443      * @param size Data size
444      */
445     inline void set_size( size_t size ) {
446         _samples = size*8/(_bits*_tracks);
447     }
448     inline void set_no_samples(size_t samples) { _samples = samples; }
449
450     /**
451      * Set the position of this sound relative to the base position.
452      * This is in the same coordinate system as OpenGL; y=up, z=back, x=right.
453      * @param pos Relative position of this sound
454      */
455     inline void set_relative_position( const SGVec3f& pos ) {
456         _relative_pos = toVec3d(pos); _changed = true;
457     }
458
459     /**
460      * Set the base position in Cartesian coordinates
461      * @param pos position in Cartesian coordinates
462      */
463     inline void set_position( const SGVec3d& pos ) {
464        _base_pos = pos; _changed = true;
465     }
466
467     inline void set_position_properties(SGPropertyNode_ptr pos[3]) {
468         _pos_prop[0] = pos[0]; _pos_prop[1] = pos[1]; _pos_prop[2] = pos[2];
469         if (pos[0] || pos[1] || pos[2]) _use_pos_props = true;
470         _changed = true;
471     }
472
473     /**
474      * Set the orientation of this sound.
475      * @param ori Quaternation containing the orientation information
476      */
477     inline void set_orientation( const SGQuatd& ori ) {
478         _orientation = ori; _changed = true;
479     }
480
481     inline void set_rotation( const SGQuatd& ec2body ) {
482         _rotation = ec2body; _changed = true;
483     }
484
485     /**
486      * Set direction of this sound relative to the orientation.
487      * This is in the same coordinate system as OpenGL; y=up, z=back, x=right
488      * @param dir Sound emission direction
489      */
490     inline void set_direction( const SGVec3f& dir ) {
491         _direction = toVec3d(dir); _static_changed = true;
492     }
493
494     /**
495      * Define the audio cone parameters for directional audio.
496      * Note: setting it to 2 degree will result in 1 degree to both sides.
497      * @param inner Inner cone angle (0 - 360 degrees)
498      * @param outer Outer cone angle (0 - 360 degrees)
499      * @param gain Remaining gain at the edge of the outer cone (0.0 - 1.0)
500      */
501     void set_audio_cone( float inner, float outer, float gain ) {
502         _inner_angle = inner; _outer_angle = outer; _outer_gain = gain;
503         _static_changed = true;
504     }
505
506     /**
507      * Set the velocity vector (in meters per second) of this sound.
508      * This is in the local frame coordinate system; x=north, y=east, z=down
509      * @param Velocity vector
510      */
511     inline void set_velocity( const SGVec3f& vel ) {
512         _velocity = vel; _changed = true;
513     }
514
515     /**
516      * Set reference distance (in meters) of this sound.
517      * This is the distance where the gain will be half.
518      * @param dist Reference distance
519      */
520     inline void set_reference_dist( float dist ) {
521         _reference_dist = dist; _static_changed = true;
522     }
523
524     /**
525      * Set maximum distance (in meters) of this sound.
526      * This is the distance where this sound is no longer audible.
527      * @param dist Maximum distance
528      */
529     inline void set_max_dist( float dist ) {
530         _max_dist = dist; _static_changed = true;
531     }
532
533     inline virtual bool is_queue() const { return false; }
534
535     void update_pos_and_orientation();
536
537 protected:
538     bool _is_file;
539     bool _changed;
540
541     // Sources are points emitting sound.
542     bool _valid_source;
543     unsigned int _source;
544
545 private:
546     unsigned char* _data;
547
548     // Buffers hold sound data.
549     bool _valid_buffer;
550     unsigned int _buffer;
551 };
552
553 #endif // _SG_SAMPLE_HXX
554
555