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