]> git.mxchange.org Git - simgear.git/blob - simgear/sound/sample_openal.hxx
I had overlooked a few memory allocation/deallocation issues for audio buffers.
[simgear.git] / simgear / sound / sample_openal.hxx
1 // sample.hxx -- Sound sample encapsulation class
2 // 
3 // Written by Curtis Olson, started April 2004.
4 //
5 // Copyright (C) 2004  Curtis L. Olson - curt@flightgear.org
6 //
7 // This program is free software; you can redistribute it and/or
8 // modify it under the terms of the GNU General Public License as
9 // published by the Free Software Foundation; either version 2 of the
10 // License, or (at your option) any later version.
11 //
12 // This program is distributed in the hope that it will be useful, but
13 // WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 // General Public License for more details.
16 //
17 // You should have received a copy of the GNU General Public License
18 // along with this program; if not, write to the Free Software
19 // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 //
21 // $Id$
22
23 /**
24  * \file sample.hxx
25  * Provides a sound sample encapsulation
26  */
27
28 #ifndef _SG_SAMPLE_HXX
29 #define _SG_SAMPLE_HXX 1
30
31 #ifndef __cplusplus
32 # error This library requires C++
33 #endif
34
35 #include <simgear/compiler.h>
36
37 #include STL_STRING
38
39 #include <simgear/debug/logstream.hxx>
40
41 #include <plib/sg.h>
42
43 #if defined(__APPLE__)
44 # define AL_ILLEGAL_ENUM AL_INVALID_ENUM
45 # define AL_ILLEGAL_COMMAND AL_INVALID_OPERATION
46 # include <OpenAL/al.h>
47 # include <OpenAL/alut.h>
48 #else
49 # include <AL/al.h>
50 # include <AL/alut.h>
51 #endif
52
53 SG_USING_STD(string);
54
55 /**
56  * manages everything we need to know for an individual sound sample
57  */
58
59 class SGSoundSample {
60
61 private:
62
63     string sample_name;
64
65     // Buffers hold sound data.
66     ALuint buffer;
67
68     // Sources are points emitting sound.
69     ALuint source;
70
71     // Position of the source sound.
72     ALfloat source_pos[3];
73
74     // A constant offset to be applied to the final source_pos
75     ALfloat offset_pos[3];
76
77     // Velocity of the source sound.
78     ALfloat source_vel[3];
79
80     // configuration values
81     ALenum format;
82     ALsizei size;
83     ALvoid* data;
84     ALsizei freq;
85
86     double pitch;
87     double volume;
88     double reference_dist;
89     double max_dist;
90     ALboolean loop;
91
92
93 public:
94
95     /**
96      * Constructor
97      * @param path Path name to sound
98      * @param file File name of sound
99      * @param cleanup Request clean up the intermediate data (this
100        should usually be true unless you want to manipulate the data
101        later.)
102      */
103     SGSoundSample( const char *path, const char *file, bool cleanup );
104
105     /**
106      * Constructor.
107      * @param _data Pointer to a memory buffer containing the sample data
108      * @param len Byte length of array
109      * @param _freq Frequency of the provided data (bytes per second)
110      * @param cleanup Request clean up the intermediate data (this
111        should usually be true unless you want to manipulate the data
112        later.)
113      */
114     SGSoundSample( unsigned char *_data, int len, int _freq, bool cleanup );
115
116     ~SGSoundSample();
117
118     /**
119      * Start playing this sample.
120      *
121      * @param _loop Define wether the sound should be played in a loop.
122      */
123     void play( bool _loop );
124
125     /**
126      * Stop playing this sample.
127      *
128      * @param sched A pointer to the appropriate scheduler.
129      */
130     void stop();
131
132     /**
133      * Play this sample once.
134      * @see #play
135      */
136     inline void play_once() { play(false); }
137
138     /** 
139      * Play this sample looped.
140      * @see #play
141      */
142     inline void play_looped() { play(true); }
143
144     /**
145      * Test if a sample is curretnly playing.
146      * @return true if is is playing, false otherwise.
147      */
148     inline bool is_playing( ) {
149         ALint result;
150         alGetSourcei( source, AL_SOURCE_STATE, &result );
151         if ( alGetError() != AL_NO_ERROR) {
152             SG_LOG( SG_GENERAL, SG_ALERT,
153                     "Oops AL error in sample is_playing(): " << sample_name );
154         }
155         return (result == AL_PLAYING) ;
156     }
157
158     /**
159      * Get the current pitch setting of this sample.
160      */
161     inline double get_pitch() const { return pitch; }
162
163     /**
164      * Set the pitch of this sample.
165      */
166     inline void set_pitch( double p ) {
167         // clamp in the range of 0.01 to 2.0
168         if ( p < 0.01 ) { p = 0.01; }
169         if ( p > 2.0 ) { p = 2.0; }
170         pitch = p;
171         alSourcef( source, AL_PITCH, pitch );
172         if ( alGetError() != AL_NO_ERROR) {
173             SG_LOG( SG_GENERAL, SG_ALERT,
174                     "Oops AL error in sample set_pitch()! " << p
175                     << " for " << sample_name );
176         }
177     }
178
179     /**
180      * Get the current volume setting of this sample.
181      */
182     inline double get_volume() const { return volume; }
183
184     /**
185      * Set the volume of this sample.
186      */
187     inline void set_volume( double v ) {
188         volume = v;
189         alSourcef( source, AL_GAIN, volume );
190         if ( alGetError() != AL_NO_ERROR) {
191             SG_LOG( SG_GENERAL, SG_ALERT,
192                     "Oops AL error in sample set_volume()! " << v
193                     << " for " << sample_name  );
194         }
195     }
196
197     /**
198      * Returns the size of the sounds sample
199      */
200     inline int get_size() {
201         return size;
202     }
203
204     /**
205      * Return a pointer to the raw data
206      */
207     inline char *get_data() {
208         return (char *)data;
209     }
210
211     /**
212      * Set position of sound source (uses same coordinate system as opengl)
213      */
214     inline void set_source_pos( ALfloat *pos ) {
215         source_pos[0] = pos[0];
216         source_pos[1] = pos[1];
217         source_pos[2] = pos[2];
218
219         sgVec3 final_pos;
220         sgAddVec3( final_pos, source_pos, offset_pos );
221
222         alSourcefv( source, AL_POSITION, final_pos );
223     }
224
225     /**
226      * Set "constant" offset position of sound source (uses same
227      * coordinate system as opengl)
228      */
229     inline void set_offset_pos( ALfloat *pos ) {
230         offset_pos[0] = pos[0];
231         offset_pos[1] = pos[1];
232         offset_pos[2] = pos[2];
233
234         sgVec3 final_pos;
235         sgAddVec3( final_pos, source_pos, offset_pos );
236
237         alSourcefv( source, AL_POSITION, final_pos );
238     }
239
240     /**
241      * Set velocity of sound source (uses same coordinate system as opengl)
242      */
243     inline void set_source_vel( ALfloat *vel ) {
244         source_vel[0] = vel[0];
245         source_vel[1] = vel[1];
246         source_vel[2] = vel[2];
247         alSourcefv( source, AL_VELOCITY, source_vel );
248     }
249
250
251     /**
252      * Set reference distance of sound (the distance where the gain
253      * will be half.)
254      */
255     inline void set_reference_dist( ALfloat dist ) {
256         reference_dist = dist;
257         alSourcef( source, AL_REFERENCE_DISTANCE, reference_dist );
258     }
259
260
261     /**
262      * Set maximume distance of sound (the distance where the sound is
263      * no longer audible.
264      */
265     inline void set_max_dist( ALfloat dist ) {
266         max_dist = dist;
267         alSourcef( source, AL_MAX_DISTANCE, max_dist );
268     }
269 };
270
271
272 #endif // _SG_SAMPLE_HXX
273
274