]> git.mxchange.org Git - simgear.git/blob - simgear/sound/sample_openal.hxx
Don't delete the sample data if it wasn't constructed as a file. It's now deleted...
[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 #ifndef __cplusplus
34 # error This library requires C++
35 #endif
36
37 #include <string>
38
39 #include <simgear/compiler.h>
40 #include <simgear/debug/logstream.hxx>
41 #include <simgear/structure/SGReferenced.hxx>
42 #include <simgear/structure/SGSharedPtr.hxx>
43 #include <simgear/math/SGMath.hxx>
44
45 // #include <plib/sg.h>
46
47 /**
48  * manages everything we need to know for an individual audio sample
49  */
50
51 class SGSoundSample : public SGReferenced {
52 public:
53
54      /**
55       * Empty constructor, can be used to read data to the systems
56       * memory and not to the driver.
57       */
58     SGSoundSample();
59
60     /**
61      * Constructor
62      * @param path Path name to sound
63      * @param file File name of sound
64        Buffer data is freed by the sample group
65      */
66     SGSoundSample( const char *path, const char *file );
67
68     /**
69      * Constructor.
70      * @param data Pointer to a memory buffer containing this audio sample data
71        The application may free the data by calling free_data(), otherwise it
72        will be resident untill the class is destroyed.
73      * @param len Byte length of array
74      * @param freq Frequency of the provided data (bytes per second)
75      * @param format OpenAL format id of the data
76      */
77     SGSoundSample( unsigned char *data, int len, int freq,
78                    int format = AL_FORMAT_MONO8 );
79
80     /**
81      * Destructor
82      */
83     ~SGSoundSample ();
84
85     /**
86      * Detect wheter this audio sample holds the information of a sound file.
87      * @return Return true if this audio sample is to be constructed from a file.
88      */
89     inline bool is_file() const { return _is_file; }
90
91     /**
92      * Test if this audio sample configuration has changed since the last call.
93      * Calling this function will reset the flag so calling it a second
94      * time in a row will return false.
95      * @return Return true is the configuration has changed in the mean time.
96      */
97     bool has_changed() {
98         bool b = _changed; _changed = false; return b;
99     }
100
101     /**
102      * Test if static dataa of audio sample configuration has changed.
103      * Calling this function will reset the flag so calling it a second
104      * time in a row will return false.
105      * @return Return true is the static data has changed in the mean time.
106      */
107     bool has_static_data_changed() {
108         bool b = _static_changed; _static_changed = false; return b;
109     }
110
111     /**
112      * Schedule this audio sample for playing. Actual playing will only start
113      * at the next call op SoundGroup::update()
114      * @param _loop Define whether this sound should be played in a loop.
115      */
116     void play( bool loop ) {
117         _playing = true; _loop = loop; _changed = true;
118     }
119
120     /**
121      * Check if this audio sample is set to be continuous looping.
122      * @return Return true if this audio sample is set to looping.
123      */
124     inline bool get_looping() { return _loop; }
125
126     /**
127      * Schedule this audio sample to stop playing.
128      */
129     void stop() {
130         _playing = false; _changed = true;
131     }
132
133     /**
134      * Schedule this audio sample to play once.
135      * @see #play
136      */
137     inline void play_once() { play(false); }
138
139     /** 
140      * Schedule this audio sample to play looped.
141      * @see #play
142      */
143     inline void play_looped() { play(true); }
144
145     /**
146      * Test if a audio sample is scheduled for playing.
147      * @return true if this audio sample is playing, false otherwise.
148      */
149     inline bool is_playing() { return _playing; }
150
151     /**
152      * sSt the data associated with this audio sample
153      * @param data Pointer to a memory block containg this audio sample data.
154      */
155     inline void set_data( unsigned char* data ) { _data = data; }
156
157     /**
158      * Return the data associated with this audio sample.
159      * @return A pointer to this sound data of this audio sample.
160      */
161     inline void* get_data() const { return _data; }
162
163     /**
164      * Free the data associated with this audio sample
165      */
166     void free_data() {
167         if (_data != NULL) { delete _data; _data = NULL; }
168     }
169
170     /**
171      * Set the source id of this source
172      * @param sid OpenAL source-id
173      */
174     void set_source(unsigned int sid) {
175         _source = sid; _valid_source = true; _changed = true;
176     }
177
178     /**
179      * Get the OpenAL source id of this source
180      * @return OpenAL source-id
181      */
182     inline unsigned int get_source() { return _source; }
183
184     /**
185      * Test if the source-id of this audio sample may be passed to OpenAL.
186      * @return true if the source-id is valid
187      */
188     inline bool is_valid_source() const { return _valid_source; }
189
190     /**
191      * Set the source-id of this audio sample to invalid.
192      */
193     inline void no_valid_source() { _valid_source = false; }
194
195     /**
196      * Set the OpenAL buffer-id of this source
197      * @param bid OpenAL buffer-id
198      */
199     void set_buffer(unsigned int bid) {
200         _buffer = bid; _valid_buffer = true; _changed = true;
201     } 
202
203     /**
204      * Get the OpenAL buffer-id of this source
205      * @return OpenAL buffer-id
206      */
207     inline unsigned int get_buffer() { return _buffer; }
208
209     /**
210      * Test if the buffer-id of this audio sample may be passed to OpenAL.
211      * @return true if the buffer-id is valid
212      */
213     inline bool is_valid_buffer() const { return _valid_buffer; }
214
215     /**
216      * Set the buffer-id of this audio sample to invalid.
217      */
218     inline void no_valid_buffer() { _valid_buffer = false; }
219
220     /**
221      * Set the playback pitch of this audio sample. 
222      * Should be between 0.0 and 2.0 for maximum compatibility.
223      * @param p Pitch
224      */
225     inline void set_pitch( float p ) { _pitch = p; _changed = true; }
226
227     /**
228      * Get the current pitch value of this audio sample.
229      * @return Pitch
230      */
231     inline float get_pitch() { return _pitch; }
232
233     /**
234      * Set the master volume of this sample. Should be between 0.0 and 1.0.
235      * The final volume is calculated by multiplying the master and audio sample
236      * volume.
237      * @param v Volume
238      */
239     inline void set_master_volume( float v ) {
240         _master_volume = v; _changed = true;
241     }
242
243     /**
244      * Set the volume of this audio sample. Should be between 0.0 and 1.0.
245      * The final volume is calculated by multiplying the master and audio sample
246      * volume.
247      * @param v Volume
248      */
249     inline void set_volume( float v ) { _volume = v; _changed = true; }
250
251     /**
252      * Get the final volume value of this audio sample.
253      * @return Volume
254      */
255     inline float get_volume() { return _volume * _master_volume; }
256
257     /**
258      * Set the OpenAL format of this audio sample.
259      * @param format OpenAL format-id
260      */
261     inline void set_format( int format ) { _format = format; }
262
263     /**
264      * Returns the format of this audio sample.
265      * @return OpenAL format-id
266      */
267     inline int get_format() { return _format; }
268
269     /**
270      * Set the frequency (in Herz) of this audio sample.
271      * @param freq Frequency
272      */
273     inline void set_frequency( int freq ) { _freq = freq; _changed = true; }
274
275     /**
276      * Returns the frequency (in Herz) of this audio sample.
277      * @return Frequency
278      */
279     inline int get_frequency() { return _freq; }
280
281     /**
282      * Sets the size (in bytes) of this audio sample.
283      * @param size Data size
284      */
285     inline void set_size( size_t size ) { _size = size; }
286
287     /**
288      * Returns the size (in bytes) of this audio sample.
289      * @return Data size
290      */
291     inline size_t get_size() const { return _size; }
292
293     /**
294      * Set the position of this sound relative to the base position.
295      * This is in the same coordinate system as OpenGL; y=up, z=back, x=right.
296      * @param pos Relative position of this sound
297      */
298     void set_relative_position( const SGVec3f& pos );
299
300     /**
301      * Set the base position of this sound in Geodetic coordinates.
302      * @param pos Geodetic position
303      */
304     void set_position( const SGGeod& pos );
305
306     /**
307      * Get the absolute position of this sound.
308      * This is in the same coordinate system as OpenGL; y=up, z=back, x=right.
309      * @return Absolute position
310      */
311     float *get_position() const { return toVec3f(_absolute_pos).data(); }
312
313     /**
314      * Set the orientation of this sound.
315      * @param ori Quaternation containing the orientation information
316      */
317     void set_orientation( const SGQuatd& ori );
318
319     /**
320      * Set direction of this sound relative to the orientation.
321      * This is in the same coordinate system as OpenGL; y=up, z=back, x=right
322      * @param dir Sound emission direction
323      */
324     void set_direction( const SGVec3d& dir );
325
326     /**
327      * Define the audio cone parameters for directional audio.
328      * Note: setting it to 1 degree will result in 0.5 degrees to both sides.
329      * @param inner Inner cone angle (0 - 360 degrees)
330      * @param outer Outer cone angle (0 - 360 degrees)
331      * @param gain Remaining gain at the edge of the outer cone (0.0 - 1.0)
332      */
333     void set_audio_cone( float inner, float outer, float gain ) {
334         _inner_angle = inner;
335         _outer_angle = outer;
336         _outer_gain = gain;
337         _static_changed = true;
338     }
339
340     /**
341      * Get the orientation vector of this sound.
342      * This is in the same coordinate system as OpenGL; y=up, z=back, x=right
343      * @return Orientaton vector
344      */
345     float *get_orientation() { return _orivec.data(); }
346
347     /**
348      * Get the inner angle of the audio cone.
349      * @return Inner angle in degrees
350      */
351     float get_innerangle() { return _inner_angle; }
352
353     /**
354      * Get the outer angle of the audio cone.
355      * @return Outer angle in degrees
356      */
357     float get_outerangle() { return _outer_angle; }
358
359     /**
360      * Get the remaining gain at the edge of the outer cone.
361      * @return Gain
362      */
363     float get_outergain() { return _outer_gain; }
364
365     /**
366      * Set the velocity vector (in meters per second) of this sound.
367      * This is in the same coordinate system as OpenGL; y=up, z=back, x=right
368      * @param Velocity vector
369      */
370     inline void set_velocity( const SGVec3d& vel ) {
371         _velocity = vel; _changed = true;
372     }
373
374     /**
375      * Get velocity vector (in meters per second) of this sound.
376      * This is in the same coordinate system as OpenGL; y=up, z=back, x=right
377      * @return Velocity vector
378      */
379     float *get_velocity() { return toVec3f(_velocity).data(); }
380
381
382     /**
383      * Set reference distance (in meters) of this sound.
384      * This is the distance where the gain will be half.
385      * @param dist Reference distance
386      */
387     inline void set_reference_dist( float dist ) {
388         _reference_dist = dist; _static_changed = true;
389     }
390
391     /**
392      * Get reference distance ((in meters) of this sound.
393      * This is the distance where the gain will be half.
394      * @return Reference distance
395      */
396     inline float get_reference_dist() { return _reference_dist; }
397
398
399     /**
400      * Set maximum distance (in meters) of this sound.
401      * This is the distance where this sound is no longer audible.
402      * @param dist Maximum distance
403      */
404     inline void set_max_dist( float dist ) {
405         _max_dist = dist; _static_changed = true;
406     }
407
408     /**
409      * Get maximum distance (in meters) of this sound.
410      * This is the distance where this sound is no longer audible.
411      * @return dist Maximum distance
412      */
413     inline float get_max_dist() { return _max_dist; }
414
415     /**
416      * Get the reference name of this audio sample.
417      * @return Sample name
418      */
419     inline std::string get_sample_name() const { return _refname; }
420
421 private:
422
423     // Position of the source sound.
424     SGVec3d _absolute_pos;      // absolute position
425     SGVec3d _relative_pos;      // position relative to the base position
426     SGVec3d _direction;         // orientation offset
427     SGVec3d _velocity;          // Velocity of the source sound.
428
429     // The position and orientation of this sound
430     SGQuatd _orientation;       // base orientation
431     SGVec3f _orivec;            // orientation vector for OpenAL
432     SGGeod _base_pos;           // base position
433
434     std::string _refname;       // name or file path
435     unsigned char *_data;
436
437     // configuration values
438     int _format;
439     size_t _size;
440     int _freq;
441
442     // Buffers hold sound data.
443     bool _valid_buffer;
444     unsigned int _buffer;
445
446     // Sources are points emitting sound.
447     bool _valid_source;
448     unsigned int _source;
449
450     // The orientation of this sound (direction and cut-off angles)
451     float _inner_angle;
452     float _outer_angle;
453     float _outer_gain;
454
455     float _pitch;
456     float _volume;
457     float _master_volume;
458     float _reference_dist;
459     float _max_dist;
460     bool _loop;
461
462     bool _playing;
463     bool _changed;
464     bool _static_changed;
465     bool _is_file;
466
467     void update_absolute_position();
468 };
469
470
471 #endif // _SG_SAMPLE_HXX
472
473