]> git.mxchange.org Git - simgear.git/blob - simgear/sound/soundmgr.hxx
Add some more descriptive comments
[simgear.git] / simgear / sound / soundmgr.hxx
1 // soundmgr.hxx -- Sound effect management class
2 //
3 // Sound manager initially written by David Findlay
4 // <david_j_findlay@yahoo.com.au> 2001
5 //
6 // C++-ified by Curtis Olson, started March 2001.
7 //
8 // Copyright (C) 2001  Curtis L. Olson - curt@flightgear.org
9 //
10 // This program is free software; you can redistribute it and/or
11 // modify it under the terms of the GNU General Public License as
12 // published by the Free Software Foundation; either version 2 of the
13 // License, or (at your option) any later version.
14 //
15 // This program is distributed in the hope that it will be useful, but
16 // WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18 // General Public License for more details.
19 //
20 // You should have received a copy of the GNU General Public License
21 // along with this program; if not, write to the Free Software
22 // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 //
24 // $Id$
25
26 /**
27  * \file soundmgr.hxx
28  * Provides a sound manager class to keep track of
29  * multiple sounds and manage playing them with different effects and
30  * timings.
31  */
32
33 #ifndef _SG_SOUNDMGR_HXX
34 #define _SG_SOUNDMGR_HXX 1
35
36 #ifndef __cplusplus
37 # error This library requires C++
38 #endif
39
40 #include <simgear/compiler.h>
41 #include <simgear/timing/timestamp.hxx>
42
43 #include STL_STRING
44 #include <map>
45
46 #include <plib/sl.h>
47 #include <plib/sm.h>
48
49 SG_USING_STD(map);
50 SG_USING_STD(string);
51
52
53 /**
54  * manages everything we need to know for an individual sound sample
55  */
56 class SGSimpleSound {
57
58 private:
59
60     slSample *sample;
61     slEnvelope *pitch_envelope;
62     slEnvelope *volume_envelope;
63     double pitch;
64     double volume;
65
66 public:
67
68     SGSimpleSound( const char *path, const char *file = NULL );
69     SGSimpleSound( unsigned char *buffer, int len );
70     ~SGSimpleSound();
71
72     /**
73      * Start playing this sample.
74      *
75      * @param sched A pointer to the appropriate scheduler.
76      * @param looped Define wether the sound should be played in a loop.
77      */
78     void play( slScheduler *sched, bool looped );
79
80     /**
81      * Stop playing this sample.
82      *
83      * @param sched A pointer to the appropriate scheduler.
84      */
85     void stop( slScheduler *sched );
86
87     /**
88      * Play this sample once.
89      * @see #play
90      */
91     inline void play_once( slScheduler *sched ) { play( sched, false); }
92
93     /** 
94      * Play this sample looped.
95      * @see #play
96      */
97     inline void play_looped( slScheduler *sched ) { play( sched, true); }
98
99     /**
100      * Test if a sample is curretnly playing.
101      * @return true if is is playing, false otherwise.
102      */
103     inline bool is_playing( ) {
104         return ( sample->getPlayCount() > 0 );
105     }
106
107     /**
108      * Get the current pitch setting of this sample.
109      */
110     inline double get_pitch() const { return pitch; }
111
112     /**
113      * Set the pitch of this sample.
114      */
115     inline void set_pitch( double p ) {
116        pitch = p;
117        pitch_envelope->setStep( 0, 0.01, pitch );
118     }
119
120     /**
121      * Get the current volume setting of this sample.
122      */
123     inline double get_volume() const { return volume; }
124
125     /**
126      * Set the volume of this sample.
127      */
128     inline void set_volume( double v ) {
129        volume = v;
130        volume_envelope->setStep( 0, 0.01, volume );
131     }
132
133     /**
134      * Get a refference to the raw sample.
135      */
136     inline slSample *get_sample() { return sample; }
137
138     /**
139      * Get the pitch envelope setting of this sample.
140      */
141     inline slEnvelope *get_pitch_envelope() { return pitch_envelope; }
142
143     /**
144      * Get the volume envelope setting of this sample.
145      */
146     inline slEnvelope *get_volume_envelope() { return volume_envelope; }
147 };
148
149
150 typedef struct {
151         int n;
152         slSample *sample;
153 } sample_ref;
154
155 typedef map < string, sample_ref * > sample_map;
156 typedef sample_map::iterator sample_map_iterator;
157 typedef sample_map::const_iterator const_sample_map_iterator;
158
159 typedef map < string, SGSimpleSound * > sound_map;
160 typedef sound_map::iterator sound_map_iterator;
161 typedef sound_map::const_iterator const_sound_map_iterator;
162
163
164 /**
165  * Manage a collection of SGSimpleSound instances
166  */
167 class SGSoundMgr
168 {
169
170     slScheduler *audio_sched;
171     smMixer *audio_mixer;
172
173     sound_map sounds;
174     sample_map samples;
175
176     double safety;
177
178 public:
179
180     SGSoundMgr();
181     ~SGSoundMgr();
182
183
184     /**
185      * (re) initialize the sound manager.
186      */
187     void init();
188
189
190     /**
191      * Bind properties for the sound manager.
192      */
193     void bind ();
194
195
196     /**
197      * Unbind properties for the sound manager.
198      */
199     void unbind ();
200
201
202     /**
203      * Run the audio scheduler.
204      */
205     void update(double dt);
206
207
208     /**
209      * Pause all sounds.
210      */
211     void pause ();
212
213
214     /**
215      * Resume all sounds.
216      */
217     void resume ();
218
219
220     /**
221      * is audio working?
222      */
223     inline bool is_working() const { return !audio_sched->notWorking(); }
224
225     /**
226      * reinitialize the sound manager
227      */
228     inline void reinit() { init(); }
229
230     /**
231      * add a sound effect, return true if successful
232      */
233     bool add( SGSimpleSound *sound, const string& refname);
234
235     /**
236      * Add a sound file to the sound manager.
237      *
238      * The advantage of using this function over the previous one is that
239      * it doesn't load a sample if it already is in memory, but instead it
240      * uses the already loaded sample data.
241      *
242      * @param refname A refference name to make a distincion between samples.
243      * @param path The path or full filename of the sample to load.
244      * @param file An optional filename which will be appended to the path.
245      * @return An instance of the sound for further manipulation.
246      */
247     SGSimpleSound *add( const string& refname,
248                       const char *path, const char *file = NULL );
249
250     /** 
251      * remove a sound effect, return true if successful
252      */
253     bool remove( const string& refname );
254
255     /**
256      * return true of the specified sound exists in the sound manager system
257      */
258     bool exists( const string& refname );
259
260     /**
261      * return a pointer to the SGSimpleSound if the specified sound
262      * exists in the sound manager system, otherwise return NULL
263      */
264      SGSimpleSound *find( const string& refname );
265
266     /**
267      * tell the scheduler to play the indexed sample in a continuous
268      * loop
269      */
270     bool play_looped( const string& refname );
271
272     /**
273      * tell the scheduler to play the indexed sample once
274      */
275     bool play_once( const string& refname );
276
277     /**
278      * return true of the specified sound is currently being played
279      */
280     bool is_playing( const string& refname );
281
282     /**
283      * immediate stop playing the sound
284      */
285     bool stop( const string& refname );
286
287     /** 
288      * return the audio scheduler 
289      */
290     inline slScheduler *get_scheduler( ) { return audio_sched; };
291 };
292
293
294 #endif // _SG_SOUNDMGR_HXX
295
296