00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include <iostream>
00027
00028 #include <simgear/debug/logstream.hxx>
00029 #include <simgear/misc/sg_path.hxx>
00030
00031 #include "soundmgr_plib.hxx"
00032
00033 #define SOUND_SAFETY_MULT 3
00034 #define MAX_SOUND_SAFETY ( 1.0 / SOUND_SAFETY_MULT )
00035
00036
00037
00038
00039
00040
00041 SGSoundMgr::SGSoundMgr() {
00042 audio_sched = new slScheduler( 8000 );
00043 if ( audio_sched->notWorking() ) {
00044 SG_LOG( SG_GENERAL, SG_ALERT, "Audio initialization failed!" );
00045 } else {
00046 audio_sched -> setMaxConcurrent ( SL_MAX_MIXERINPUTS );
00047
00048 audio_mixer = new smMixer;
00049
00050 SG_LOG( SG_GENERAL, SG_INFO,
00051 "Rate = " << audio_sched->getRate()
00052 << " Bps = " << audio_sched->getBps()
00053 << " Stereo = " << audio_sched->getStereo() );
00054 }
00055 }
00056
00057
00058
00059 SGSoundMgr::~SGSoundMgr() {
00060
00061
00062
00063
00064 sample_map_iterator sample_current = samples.begin();
00065 sample_map_iterator sample_end = samples.end();
00066 for ( ; sample_current != sample_end; ++sample_current ) {
00067 sample_ref *sr = sample_current->second;
00068
00069 audio_sched->stopSample(sr->sample);
00070 delete sr->sample;
00071 delete sr;
00072 }
00073
00074
00075
00076
00077 sound_map_iterator sound_current = sounds.begin();
00078 sound_map_iterator sound_end = sounds.end();
00079 for ( ; sound_current != sound_end; ++sound_current ) {
00080 SGSoundSample *s = sound_current->second;
00081
00082 audio_sched->stopSample(s->get_sample());
00083 delete s->get_sample();
00084 delete s;
00085 }
00086
00087 delete audio_sched;
00088 delete audio_mixer;
00089 }
00090
00091
00092
00093 void SGSoundMgr::init() {
00094 safety = MAX_SOUND_SAFETY;
00095
00096
00097 audio_sched -> setSafetyMargin ( SOUND_SAFETY_MULT * safety ) ;
00098
00099
00100
00101
00102
00103 sample_map_iterator sample_current = samples.begin();
00104 sample_map_iterator sample_end = samples.end();
00105 for ( ; sample_current != sample_end; ++sample_current ) {
00106 sample_ref *sr = sample_current->second;
00107
00108 audio_sched->stopSample(sr->sample);
00109 delete sr->sample;
00110 delete sr;
00111 }
00112 samples.clear();
00113
00114
00115
00116
00117 sound_map_iterator sound_current = sounds.begin();
00118 sound_map_iterator sound_end = sounds.end();
00119 for ( ; sound_current != sound_end; ++sound_current ) {
00120 SGSoundSample *s = sound_current->second;
00121
00122 audio_sched->stopSample(s->get_sample());
00123 delete s->get_sample();
00124 delete s;
00125 }
00126 sounds.clear();
00127
00128 }
00129
00130
00131 void SGSoundMgr::bind ()
00132 {
00133
00134 }
00135
00136
00137 void SGSoundMgr::unbind ()
00138 {
00139
00140 }
00141
00142
00143
00144 void SGSoundMgr::update( double dt ) {
00145 if ( dt > safety ) {
00146 safety = dt;
00147 } else {
00148 safety = safety * 0.99 + dt * 0.01;
00149 }
00150 if ( safety > MAX_SOUND_SAFETY ) {
00151 safety = MAX_SOUND_SAFETY;
00152 }
00153
00154 audio_sched -> setSafetyMargin ( SOUND_SAFETY_MULT * safety ) ;
00155
00156 if ( !audio_sched->not_working() )
00157 audio_sched -> update();
00158 }
00159
00160
00161 void
00162 SGSoundMgr::pause ()
00163 {
00164 audio_sched->pauseSample(0, 0);
00165 }
00166
00167
00168 void
00169 SGSoundMgr::resume ()
00170 {
00171 audio_sched->resumeSample(0, 0);
00172 }
00173
00174
00175
00176 bool SGSoundMgr::add( SGSoundSample *sound, const string& refname ) {
00177
00178 sound_map_iterator sound_it = sounds.find( refname );
00179 if ( sound_it != sounds.end() ) {
00180
00181 return false;
00182 }
00183
00184 sample_map_iterator sample_it = samples.find( refname );
00185 if ( sample_it != samples.end() ) {
00186
00187
00188 samples.erase( sample_it );
00189 }
00190
00191 sample_ref *sr = new sample_ref;
00192
00193 sr->n=1;
00194 sr->sample = sound->get_sample();
00195 samples[refname] = sr;
00196
00197 sounds[refname] = sound;
00198
00199 return true;
00200 }
00201
00202
00203
00204 SGSoundSample *SGSoundMgr::add( const string &refname,
00205 const char *path, const char *file ) {
00206 SGSoundSample *sound;
00207
00208 SGPath slfile( path );
00209 if ( file )
00210 slfile.append( file );
00211
00212 if ( slfile.str().empty() )
00213 return NULL;
00214
00215 sample_map_iterator it = samples.find(slfile.str());
00216 if (it == samples.end()) {
00217
00218 sound = new SGSoundSample(slfile.c_str());
00219 sounds[refname] = sound;
00220
00221 sample_ref *sr = new sample_ref;
00222
00223 sr->n=1;
00224 sr->sample = sound->get_sample();
00225 samples[slfile.str()] = sr;
00226
00227 } else {
00228 sample_ref *sr = it->second;
00229
00230 sr->n++;
00231 sound =
00232 new SGSoundSample(sr->sample->getBuffer(), sr->sample->getLength());
00233 sounds[refname] = sound;
00234
00235 }
00236
00237 return sound;
00238 }
00239
00240
00241
00242 bool SGSoundMgr::remove( const string &refname ) {
00243
00244 sound_map_iterator it = sounds.find( refname );
00245 if ( it != sounds.end() ) {
00246
00247
00248 SGSoundSample *sample = it->second;
00249
00250
00251
00252
00253 audio_sched->stopSample( sample->get_sample() );
00254 audio_sched->addSampleEnvelope( sample->get_sample(), 0, 0,
00255 NULL,
00256 SL_PITCH_ENVELOPE );
00257 audio_sched->addSampleEnvelope( sample->get_sample(), 0, 1,
00258 NULL,
00259 SL_VOLUME_ENVELOPE );
00260
00261
00262
00263 audio_sched -> update();
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273 sounds.erase( it );
00274
00275
00276 return true;
00277 } else {
00278
00279 return false;
00280 }
00281 }
00282
00283
00284
00285 bool SGSoundMgr::exists( const string &refname ) {
00286 sound_map_iterator it = sounds.find( refname );
00287 if ( it != sounds.end() ) {
00288 return true;
00289 } else {
00290 return false;
00291 }
00292 }
00293
00294
00295
00296
00297 SGSoundSample *SGSoundMgr::find( const string &refname ) {
00298 sound_map_iterator it = sounds.find( refname );
00299 if ( it != sounds.end() ) {
00300 return it->second;
00301 } else {
00302 return NULL;
00303 }
00304 }
00305
00306
00307
00308
00309 bool SGSoundMgr::play_looped( const string &refname ) {
00310 SGSoundSample *sample;
00311
00312 if ((sample = find( refname )) == NULL)
00313 return false;
00314
00315 sample->play(audio_sched, true);
00316 return true;
00317 }
00318
00319
00320
00321 bool SGSoundMgr::play_once( const string& refname ) {
00322 SGSoundSample *sample;
00323
00324 if ((sample = find( refname )) == NULL)
00325 return false;
00326
00327 sample->play(audio_sched, false);
00328 return true;
00329 }
00330
00331
00332
00333 bool SGSoundMgr::is_playing( const string& refname ) {
00334 SGSoundSample *sample;
00335
00336 if ((sample = find( refname )) == NULL)
00337 return false;
00338
00339 return (sample->get_sample()->getPlayCount() > 0 );
00340 }
00341
00342
00343
00344 bool SGSoundMgr::stop( const string& refname ) {
00345 SGSoundSample *sample;
00346
00347 if ((sample = find( refname )) == NULL)
00348 return false;
00349
00350 audio_sched->stopSample( sample->get_sample() );
00351 return true;
00352 }