]> git.mxchange.org Git - simgear.git/blob - simgear/sound/sample_openal.hxx
Add support for specifying a positional offset relative to the listener.
[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 #if defined(__APPLE__)
40 # define AL_ILLEGAL_ENUM AL_INVALID_ENUM
41 # define AL_ILLEGAL_COMMAND AL_INVALID_OPERATION
42 # include <OpenAL/al.h>
43 # include <OpenAL/alut.h>
44 #else
45 # include <AL/al.h>
46 # include <AL/alut.h>
47 #endif
48
49 #include <plib/sg.h>
50
51 #include <simgear/debug/logstream.hxx>
52
53 SG_USING_STD(string);
54
55
56 /**
57  * manages everything we need to know for an individual sound sample
58  */
59
60 class SGSoundSample {
61
62 private:
63
64     string sample_name;
65
66     // Buffers hold sound data.
67     ALuint buffer;
68
69     // Sources are points emitting sound.
70     ALuint source;
71
72     // Position of the source sound.
73     ALfloat source_pos[3];
74
75     // A constant offset to be applied to the final source_pos
76     ALfloat offset_pos[3];
77
78     // Velocity of the source sound.
79     ALfloat source_vel[3];
80
81     // configuration values
82     ALenum format;
83     ALsizei size;
84     ALvoid* data;
85     ALsizei freq;
86
87     double pitch;
88     double volume;
89     double reference_dist;
90     double max_dist;
91     ALboolean loop;
92
93
94 public:
95
96     /**
97      * Constructor
98      * @param path Path name to sound
99      * @param file File name of sound
100      * @param cleanup Request clean up the intermediate data (this
101        should usually be true unless you want to manipulate the data
102        later.)
103      */
104     SGSoundSample( const char *path, const char *file, bool cleanup );
105     SGSoundSample( unsigned char *_data, int len, int _freq );
106     ~SGSoundSample();
107
108     /**
109      * Start playing this sample.
110      *
111      * @param _loop Define wether the sound should be played in a loop.
112      */
113     void play( bool _loop );
114
115     /**
116      * Stop playing this sample.
117      *
118      * @param sched A pointer to the appropriate scheduler.
119      */
120     void stop();
121
122     /**
123      * Play this sample once.
124      * @see #play
125      */
126     inline void play_once() { play(false); }
127
128     /** 
129      * Play this sample looped.
130      * @see #play
131      */
132     inline void play_looped() { play(true); }
133
134     /**
135      * Test if a sample is curretnly playing.
136      * @return true if is is playing, false otherwise.
137      */
138     inline bool is_playing( ) {
139         ALint result;
140         alGetSourcei( source, AL_SOURCE_STATE, &result );
141         if ( alGetError() != AL_NO_ERROR) {
142             SG_LOG( SG_GENERAL, SG_ALERT,
143                     "Oops AL error in sample is_playing(): " << sample_name );
144         }
145         return (result == AL_PLAYING) ;
146     }
147
148     /**
149      * Get the current pitch setting of this sample.
150      */
151     inline double get_pitch() const { return pitch; }
152
153     /**
154      * Set the pitch of this sample.
155      */
156     inline void set_pitch( double p ) {
157         // clamp in the range of 0.01 to 2.0
158         if ( p < 0.01 ) { p = 0.01; }
159         if ( p > 2.0 ) { p = 2.0; }
160         pitch = p;
161         alSourcef( source, AL_PITCH, pitch );
162         if ( alGetError() != AL_NO_ERROR) {
163             SG_LOG( SG_GENERAL, SG_ALERT,
164                     "Oops AL error in sample set_pitch()! " << p
165                     << " for " << sample_name );
166         }
167     }
168
169     /**
170      * Get the current volume setting of this sample.
171      */
172     inline double get_volume() const { return volume; }
173
174     /**
175      * Set the volume of this sample.
176      */
177     inline void set_volume( double v ) {
178         volume = v;
179         alSourcef( source, AL_GAIN, volume );
180         if ( alGetError() != AL_NO_ERROR) {
181             SG_LOG( SG_GENERAL, SG_ALERT,
182                     "Oops AL error in sample set_volume()! " << v
183                     << " for " << sample_name  );
184         }
185     }
186
187     /**
188      * Returns the size of the sounds sample
189      */
190     inline int get_size() {
191         return size;
192     }
193
194     /**
195      * Return a pointer to the raw data
196      */
197     inline char *get_data() {
198         return (char *)data;
199     }
200
201     /**
202      * Set position of sound source (uses same coordinate system as opengl)
203      */
204     inline void set_source_pos( ALfloat *pos ) {
205         source_pos[0] = pos[0];
206         source_pos[1] = pos[1];
207         source_pos[2] = pos[2];
208
209         sgVec3 final_pos;
210         sgAddVec3( final_pos, source_pos, offset_pos );
211
212         alSourcefv( source, AL_POSITION, final_pos );
213     }
214
215     /**
216      * Set "constant" offset position of sound source (uses same
217      * coordinate system as opengl)
218      */
219     inline void set_offset_pos( ALfloat *pos ) {
220         offset_pos[0] = pos[0];
221         offset_pos[1] = pos[1];
222         offset_pos[2] = pos[2];
223
224         sgVec3 final_pos;
225         sgAddVec3( final_pos, source_pos, offset_pos );
226
227         alSourcefv( source, AL_POSITION, final_pos );
228     }
229
230     /**
231      * Set velocity of sound source (uses same coordinate system as opengl)
232      */
233     inline void set_source_vel( ALfloat *vel ) {
234         source_vel[0] = vel[0];
235         source_vel[1] = vel[1];
236         source_vel[2] = vel[2];
237         alSourcefv( source, AL_VELOCITY, source_vel );
238     }
239
240
241     /**
242      * Set reference distance of sound (the distance where the gain
243      * will be half.)
244      */
245     inline void set_reference_dist( ALfloat dist ) {
246         reference_dist = dist;
247         alSourcef( source, AL_REFERENCE_DISTANCE, reference_dist );
248     }
249
250
251     /**
252      * Set maximume distance of sound (the distance where the sound is
253      * no longer audible.
254      */
255     inline void set_max_dist( ALfloat dist ) {
256         max_dist = dist;
257         alSourcef( source, AL_MAX_DISTANCE, max_dist );
258     }
259 };
260
261
262 #endif // _SG_SAMPLE_HXX
263
264