]> git.mxchange.org Git - simgear.git/blob - simgear/sound/sample_openal.hxx
Remove unused sample queue code
[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     unsigned int get_format_AL();
69
70     /**
71      * Returns the format of this audio sample.
72      * @return SimGear format-id
73      */
74     inline unsigned int get_format() { return (_tracks | _bits | _compressed*256); }
75
76     /**
77      * Get the reference name of this audio sample.
78      * @return Sample name
79      */
80     inline std::string get_sample_name() const { return _refname; }
81
82     /**
83      * Returns the frequency (in Herz) of this audio sample.
84      * @return Frequency
85      */
86     inline unsigned int get_frequency() { return _frequency; }
87
88     /**
89      * Get the current pitch value of this audio sample.
90      * @return Pitch
91      */
92     inline float get_pitch() { return _pitch; }
93
94     /**
95      * Get the final volume value of this audio sample.
96      * @return Volume
97      */
98     inline float get_volume() { return _volume * _master_volume; }
99
100     /**
101      * Returns the size (in bytes) of this audio sample.
102      * @return Data size
103      */
104     inline size_t get_size() const {
105         return (_samples * _tracks * _bits)/8;
106     }
107
108
109     /**
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
113      */
114     inline SGVec3d& get_position() { return _absolute_pos; }
115
116     /**
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
120      */
121     inline SGVec3f& get_orientation() { return _orivec; }
122
123     /**
124      * Get the inner angle of the audio cone.
125      * @return Inner angle in degrees
126      */
127     inline float get_innerangle() { return _inner_angle; }
128
129     /**
130      * Get the outer angle of the audio cone.
131      * @return Outer angle in degrees
132      */
133     inline float get_outerangle() { return _outer_angle; }
134
135     /**
136      * Get the remaining gain at the edge of the outer cone.
137      * @return Gain
138      */
139     inline float get_outergain() { return _outer_gain; }
140
141     /**
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
145      */
146     inline SGVec3f& get_velocity() { return _velocity; }
147
148     /**
149      * Get reference distance ((in meters) of this sound.
150      * This is the distance where the gain will be half.
151      * @return Reference distance
152      */
153     inline float get_reference_dist() { return _reference_dist; }
154
155     /**
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
159      */
160     inline float get_max_dist() { return _max_dist; }
161
162     /**
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.
167      */
168     bool has_static_data_changed() {
169         bool b = _static_changed; _static_changed = false; return b;
170     }
171
172 protected:
173     // static sound emitter info
174     std::string _refname;
175     unsigned int _bits;
176     unsigned int _tracks;
177     unsigned int _samples;
178     unsigned int _frequency;
179     bool _compressed;
180     bool _loop;
181
182     // dynamic sound emitter info (non 3d)
183     bool _static_changed;
184     bool _playing;
185
186     float _pitch;
187     float _volume;
188     float _master_volume;
189
190     // dynamic sound emitter info (3d)
191     bool _use_pos_props;
192     bool _out_of_range;
193
194     float _inner_angle;
195     float _outer_angle;
196     float _outer_gain;
197
198     float _reference_dist;
199     float _max_dist;
200
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.
206
207     // The position and orientation of this sound
208     SGQuatd _orientation;       // base orientation
209     SGVec3f _orivec;            // orientation vector
210     SGVec3d _base_pos;          // base position
211
212     SGQuatd _rotation;
213
214 private:
215     static std::string random_string();
216 };
217
218
219 class SGSoundSample : public SGSoundSampleInfo, public SGReferenced {
220 public:
221
222      /**
223       * Empty constructor, can be used to read data to the systems
224       * memory and not to the driver.
225       */
226     SGSoundSample();
227
228     /**
229      * Constructor
230      * @param file File name of sound
231        Buffer data is freed by the sample group
232      */
233     SGSoundSample(const char *file, const SGPath& currentDir);
234
235     /**
236      * Constructor.
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
244      */
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 );
248
249     /**
250      * Destructor
251      */
252     virtual ~SGSoundSample ();
253
254     /**
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.
259      */
260     bool has_changed() {
261         bool b = _changed; _changed = false; return b;
262     }
263
264     /**
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.
267      */
268     inline bool is_file() const { return _is_file; }
269
270     SGPath file_path() const;
271
272     /**
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.
276      */
277     void play( bool loop = false ) {
278         _playing = true; _loop = loop; _changed = true; _static_changed = true;
279     }
280
281     /**
282      * Check if this audio sample is set to be continuous looping.
283      * @return Return true if this audio sample is set to looping.
284      */
285     inline bool is_looping() { return _loop; }
286
287     /**
288      * Schedule this audio sample to stop playing.
289      */
290     virtual void stop() {
291         _playing = false; _changed = true;
292     }
293
294     /**
295      * Schedule this audio sample to play once.
296      * @see #play
297      */
298     inline void play_once() { play(false); }
299
300     /** 
301      * Schedule this audio sample to play looped.
302      * @see #play
303      */
304     inline void play_looped() { play(true); }
305
306     /**
307      * Test if a audio sample is scheduled for playing.
308      * @return true if this audio sample is playing, false otherwise.
309      */
310     inline bool is_playing() { return _playing; }
311
312
313     /**
314      * Set this sample to out-of-range (or not) and
315      * Schedule this audio sample to stop (or start) playing.
316      */
317     inline void set_out_of_range(bool oor = true) {
318         _out_of_range = oor; _playing = (!oor && _loop); _changed = true;
319     }
320
321     /**
322      * Test if this sample to out-of-range or not.
323      */
324     inline bool test_out_of_range() {
325         return _out_of_range;
326     }
327
328     /**
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.
332      */
333     inline void set_data( const unsigned char **data ) {
334         _data = (unsigned char*)*data; *data = NULL;
335     }
336     inline void set_data( const void **data ) {
337         _data = (unsigned char*)*data; *data = NULL;
338     }
339
340     /**
341      * Return the data associated with this audio sample.
342      * @return A pointer to this sound data of this audio sample.
343      */
344     inline void* get_data() const { return _data; }
345
346     /**
347      * Free the data associated with this audio sample
348      */
349     void free_data();
350
351     /**
352      * Set the source id of this source
353      * @param sid source-id
354      */
355     virtual void set_source(unsigned int sid) {
356         _source = sid; _valid_source = true; _changed = true;
357     }
358
359     /**
360      * Get the source id of this source
361      * @return source-id
362      */
363     virtual unsigned int get_source() { return _source; }
364
365     /**
366      * Test if the source-id of this audio sample is usable.
367      * @return true if the source-id is valid
368      */
369     virtual bool is_valid_source() const { return _valid_source; }
370
371     /**
372      * Set the source-id of this audio sample to invalid.
373      */
374     virtual void no_valid_source() { _valid_source = false; }
375
376     /**
377      * Set the buffer-id of this source
378      * @param bid buffer-id
379      */
380     inline void set_buffer(unsigned int bid) {
381         _buffer = bid; _valid_buffer = true; _changed = true;
382     } 
383
384     /**
385      * Get the buffer-id of this source
386      * @return buffer-id
387      */
388     inline unsigned int get_buffer() { return _buffer; }
389
390     /**
391      * Test if the buffer-id of this audio sample is usable.
392      * @return true if the buffer-id is valid
393      */
394     inline bool is_valid_buffer() const { return _valid_buffer; }
395
396     /**
397      * Set the buffer-id of this audio sample to invalid.
398      */
399     inline void no_valid_buffer() { _valid_buffer = false; }
400
401     /**
402      * Set the playback pitch of this audio sample. 
403      * Should be between 0.0 and 2.0 for maximum compatibility.
404      * @param p Pitch
405      */
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;
409     }
410
411     /**
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
414      * volume.
415      * @param v Volume
416      */
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;
420     }
421
422     /**
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
425      * volume.
426      * @param v Volume
427      */
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;
431     }
432
433     /**
434      * Set the SimGear format of this audio sample.
435      * @param format SimGear format-id
436      */
437     inline void set_format( int fmt ) {
438         _tracks = fmt & 0x3; _bits = fmt & 0x1C; _compressed = fmt & 0x100;
439     }
440
441     void set_format_AL( int fmt );
442
443     /**
444      * Set the frequency (in Herz) of this audio sample.
445      * @param freq Frequency
446      */
447     inline void set_frequency( int freq ) { _frequency = freq; }
448
449     /**
450      * Sets the size (in bytes) of this audio sample.
451      * @param size Data size
452      */
453     inline void set_size( size_t size ) {
454         _samples = size*8/(_bits*_tracks);
455     }
456     inline void set_no_samples(size_t samples) { _samples = samples; }
457
458     /**
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
462      */
463     inline void set_relative_position( const SGVec3f& pos ) {
464         _relative_pos = toVec3d(pos); _changed = true;
465     }
466
467     /**
468      * Set the base position in Cartesian coordinates
469      * @param pos position in Cartesian coordinates
470      */
471     inline void set_position( const SGVec3d& pos ) {
472        _base_pos = pos; _changed = true;
473     }
474
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;
478         _changed = true;
479     }
480
481     /**
482      * Set the orientation of this sound.
483      * @param ori Quaternation containing the orientation information
484      */
485     inline void set_orientation( const SGQuatd& ori ) {
486         _orientation = ori; _changed = true;
487     }
488
489     inline void set_rotation( const SGQuatd& ec2body ) {
490         _rotation = ec2body; _changed = true;
491     }
492
493     /**
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
497      */
498     inline void set_direction( const SGVec3f& dir ) {
499         _direction = toVec3d(dir); _static_changed = true;
500     }
501
502     /**
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)
508      */
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;
512     }
513
514     /**
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
518      */
519     inline void set_velocity( const SGVec3f& vel ) {
520         _velocity = vel; _changed = true;
521     }
522
523     /**
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
527      */
528     inline void set_reference_dist( float dist ) {
529         _reference_dist = dist; _static_changed = true;
530     }
531
532     /**
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
536      */
537     inline void set_max_dist( float dist ) {
538         _max_dist = dist; _static_changed = true;
539     }
540
541     inline virtual bool is_queue() const { return false; }
542
543     void update_pos_and_orientation();
544
545 protected:
546     bool _is_file;
547     bool _changed;
548
549     // Sources are points emitting sound.
550     bool _valid_source;
551     unsigned int _source;
552
553 private:
554     unsigned char* _data;
555
556     // Buffers hold sound data.
557     bool _valid_buffer;
558     unsigned int _buffer;
559 };
560
561 #endif // _SG_SAMPLE_HXX
562
563