00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 #include <pandabase.h>
00020 #ifdef HAVE_RAD_MSS //[
00021 
00022 #include "milesAudioSound.h"
00023 #include "milesAudioManager.h"
00024 
00025 #define NEED_MILES_LENGTH_WORKAROUND
00026 
00027 #if (((MSS_MAJOR_VERSION == 6) && (MSS_MINOR_VERSION >= 5)) || (MSS_MAJOR_VERSION >= 7))
00028 #define MILES_6_5
00029 #endif
00030 
00031 #ifndef NDEBUG //[
00032   namespace {
00033     char
00034     getStatusChar(HAUDIO audio) {
00035       if (!audio) {
00036         return '0'; 
00037       }
00038       switch (AIL_quick_status(audio)) {
00039         case QSTAT_LOADED:
00040         case QSTAT_DONE:
00041           return 'r'; 
00042         case QSTAT_PLAYING:
00043           return 'p'; 
00044         default:
00045           return 'x'; 
00046       }
00047     }
00048   }
00049 
00050   #define miles_audio_debug(x) \
00051       audio_debug("MilesAudioSound "<<getStatusChar(_audio)<<" \""<<get_name() \
00052       <<"\" "<< x )
00053 #else //][
00054   #define miles_audio_debug(x) ((void)0)
00055 #endif //]
00056 
00057 MilesAudioSound::
00058 MilesAudioSound(MilesAudioManager* manager,
00059     HAUDIO audio, string file_name, float length)
00060     : _manager(manager), _file_name(file_name),
00061     _volume(1.0f), _balance(0),
00062     _loop_count(1), _length(length),
00063     _active(true), _paused(false) {
00064   nassertv(audio);
00065   nassertv(!file_name.empty());
00066   audio_debug("MilesAudioSound(manager=0x"<<(void*)&manager
00067       <<", audio=0x"<<(void*)audio<<", file_name="<<file_name<<")");
00068   
00069   _audio=AIL_quick_copy(audio);
00070 }
00071 
00072 MilesAudioSound::
00073 ~MilesAudioSound() {
00074   miles_audio_debug("~MilesAudioSound()");
00075   _manager->release_sound(this);
00076   AIL_quick_unload(_audio);
00077 }
00078 
00079 void MilesAudioSound::
00080 play() {
00081   #if 0
00082   if(_file_name.find(".mid")!=string::npos) {
00083      miles_audio_debug("play() midi");
00084   }
00085   #endif
00086   
00087   miles_audio_debug("play()");
00088   if (_active) {
00089     if(_manager->_bExclusive) {
00090         
00091         _manager->stop_all_sounds();
00092     }
00093     
00094     if (AIL_quick_play(_audio, _loop_count)) {
00095       audio_debug("  started sound " << _file_name );
00096     } else {
00097       audio_debug("  sound " << _file_name<<" failed to start, err: " <<AIL_last_error());
00098     }
00099   } else {
00100     
00101     audio_debug("  paused "<<_file_name );
00102     _paused=true;
00103   }
00104 }
00105 
00106 void MilesAudioSound::
00107 stop() {
00108   #if 0
00109   if(_file_name.find(".mid")!=string::npos) {
00110         miles_audio_debug("stop() midi");
00111   } 
00112   #endif
00113   miles_audio_debug("stopping snd " << _file_name);
00114   _paused=false;
00115   AIL_quick_halt(_audio);
00116 }
00117 
00118 void MilesAudioSound::
00119 halt() {
00120   #if 0
00121   if(_file_name.find(".mid")!=string::npos) {
00122         miles_audio_debug("halt() midi");
00123         int i=1;
00124   }
00125   #endif
00126 
00127   miles_audio_debug("halt()");
00128   AIL_quick_halt(_audio);
00129 }
00130 
00131 void MilesAudioSound::
00132 set_loop(bool loop) {
00133   miles_audio_debug("set_loop(loop="<<loop<<")");
00134   
00135   set_loop_count((loop)?0:1);
00136 }
00137 
00138 bool MilesAudioSound::
00139 get_loop() const {
00140   miles_audio_debug("get_loop() returning "<<(_loop_count==0));
00141   return (_loop_count == 0);
00142 }
00143 
00144 void MilesAudioSound::
00145 set_loop_count(unsigned long loop_count) {
00146   miles_audio_debug("set_loop_count(loop_count="<<loop_count<<")");
00147   if (_loop_count!=loop_count) {
00148     _loop_count=loop_count;
00149     if (status()==PLAYING) {
00150       
00151       
00152       
00153       
00154       
00155       
00156       
00157       halt();
00158       play();
00159     }
00160   }
00161 }
00162 
00163 unsigned long MilesAudioSound::
00164 get_loop_count() const {
00165   miles_audio_debug("get_loop_count() returning "<<_loop_count);
00166   return _loop_count;
00167 }
00168 
00169 void MilesAudioSound::
00170 set_time(float time) {
00171   miles_audio_debug("set_time(time="<<time<<")");
00172   S32 milisecond_time=S32(1000*time);
00173   AIL_quick_set_ms_position(_audio, milisecond_time);
00174 }
00175 
00176 float MilesAudioSound::
00177 get_time() const {
00178   S32 milisecond_time=AIL_quick_ms_position(_audio);
00179   float time=float(milisecond_time*.001);
00180   miles_audio_debug("get_time() returning "<<time);
00181   return time;
00182 }
00183 
00184 void MilesAudioSound::
00185 set_volume(float volume) {
00186   miles_audio_debug("set_volume(volume="<<volume<<")");
00187   
00188   
00189   
00190   _volume=volume;
00191   
00192   volume*=_manager->get_volume();
00193   #ifdef MILES_6_5
00194     
00195     F32 milesVolume=volume;
00196     milesVolume=min(milesVolume,1.0f);
00197     milesVolume=max(milesVolume,0.0f);
00198   #else
00199     
00200     S32 milesVolume=((S32)(127*volume))%128;
00201   #endif
00202   
00203   S32 audioType=AIL_quick_type(_audio);
00204   if ((audioType==AIL_QUICK_XMIDI_TYPE) || (audioType==AIL_QUICK_DLS_XMIDI_TYPE)) {
00205     
00206 
00207     
00208     #ifdef MILES_6_5
00209       F32 midiVolDelay =0.0f; 
00210     #else
00211       S32 midiVolDelay =0;
00212     #endif
00213     
00214     AIL_quick_set_volume(_audio, milesVolume, midiVolDelay); 
00215     audio_debug("  volume for this midi is now "<<milesVolume);
00216   } else {
00217     
00218     #ifdef MILES_6_5
00219       
00220       F32 milesBalance=(F32)((_balance+1.0f)*0.5f);
00221     #else
00222       
00223       S32 milesBalance=((S32)(63.5f*(_balance+1.0f)))%128;  
00224     #endif
00225     AIL_quick_set_volume(_audio, milesVolume, milesBalance);
00226     audio_debug("  volume for this wav or mp3 is now " << milesVolume
00227         <<", balance="<<milesBalance);
00228   }
00229 }
00230 
00231 float MilesAudioSound::
00232 get_volume() const {
00233   miles_audio_debug("get_volume() returning "<<_volume);
00234   return _volume;
00235 }
00236 
00237 void MilesAudioSound::
00238 set_active(bool active) {
00239   miles_audio_debug("set_active(active="<<active<<")");
00240   if (_active!=active) {
00241     _active=active;
00242     if (_active) {
00243       
00244       if (_paused
00245           &&
00246           _loop_count==0) {
00247         
00248         _paused=false;
00249         play();
00250       }
00251     } else {
00252       
00253       if (status()==PLAYING) {
00254         if (_loop_count==0) {
00255           
00256           _paused=true;
00257         }
00258 
00259         
00260         
00261         
00262         halt();
00263       }
00264     }
00265   }
00266 }
00267 
00268 bool MilesAudioSound::
00269 get_active() const {
00270   miles_audio_debug("get_active() returning "<<_active);
00271   return _active;
00272 }
00273 
00274 void MilesAudioSound::
00275 set_balance(float balance_right) {
00276   miles_audio_debug("set_balance(balance_right="<<balance_right<<")");
00277   _balance=balance_right;
00278   
00279   set_volume(_volume);
00280 }
00281 
00282 float MilesAudioSound::
00283 get_balance() const {
00284   audio_debug("MilesAudioSound::get_balance() returning "<<_balance);
00285   return _balance;
00286 }
00287 
00288 float MilesAudioSound::
00289 length() const {
00290   if (_length == 0.0f) {
00291    #ifndef NEED_MILES_LENGTH_WORKAROUND
00292         _length=((float)AIL_quick_ms_length(_audio))*0.001f;
00293         if (_length == 0.0f) {
00294             audio_error("ERROR: Miles returned length 0 for "<<_file_name << "!");
00295         }
00296    #else
00297         
00298         
00299         
00300         
00301         
00302 
00303         
00304         
00305 
00306         
00307         #ifdef CATCH_MILES_LENGTH_ERROR     
00308         _length=((float)AIL_quick_ms_length(_audio))*0.001f;
00309         if (_length == 0.0f) {
00310             audio_error("ERROR: Miles returned length 0 for "<<_file_name << "!");
00311             exit(1);
00312         }
00313         #endif
00314 
00315         if (AIL_quick_status(_audio)==QSTAT_PLAYING) {
00316           _length=((float)AIL_quick_ms_length(_audio))*0.001f;
00317         } else {
00318           AIL_quick_play(_audio, 1);
00319           _length=((float)AIL_quick_ms_length(_audio))*0.001f;
00320           AIL_quick_halt(_audio);
00321         }
00322    #endif
00323   }
00324 
00325   
00326   audio_debug("MilesAudioSound::length() returning "<<_length);
00327   return _length;
00328 }
00329 
00330 const string& MilesAudioSound::
00331 get_name() const {
00332   
00333   return _file_name;
00334 }
00335 
00336 AudioSound::SoundStatus MilesAudioSound::
00337 status() const {
00338   if (!_audio) {
00339     return AudioSound::BAD;
00340   }
00341   switch (AIL_quick_status(_audio)) {
00342     case QSTAT_LOADED:
00343     case QSTAT_DONE:
00344       return AudioSound::READY;
00345     case QSTAT_PLAYING:
00346       return AudioSound::PLAYING;
00347     default:
00348       return AudioSound::BAD;
00349   }
00350 }
00351 
00352 
00353 #endif //]