00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "milesAudioStream.h"
00016 #ifdef HAVE_RAD_MSS //[
00017
00018 #include "milesAudioManager.h"
00019 #include "pnotify.h"
00020
00021 TypeHandle MilesAudioStream::_type_handle;
00022
00023 #undef miles_audio_debug
00024
00025 #ifndef NDEBUG //[
00026 #define miles_audio_debug(x) \
00027 audio_debug("MilesAudioStream \""<<get_name()<<"\" "<< x )
00028 #else //][
00029 #define miles_audio_debug(x) ((void)0)
00030 #endif //]
00031
00032
00033
00034
00035
00036
00037 MilesAudioStream::
00038 MilesAudioStream(MilesAudioManager *manager, const string &file_name,
00039 const Filename &path) :
00040 MilesAudioSound(manager, file_name),
00041 _path(path)
00042 {
00043 _stream = 0;
00044 _got_length = false;
00045 }
00046
00047
00048
00049
00050
00051
00052 MilesAudioStream::
00053 ~MilesAudioStream() {
00054 miles_audio_debug("~MilesAudioStream()");
00055 cleanup();
00056
00057 miles_audio_debug("~MilesAudioStream() done");
00058 }
00059
00060
00061
00062
00063
00064
00065 void MilesAudioStream::
00066 play() {
00067 miles_audio_debug("play()");
00068 if (_active) {
00069
00070 _manager->starting_sound(this);
00071
00072 if (_stream == 0) {
00073 GlobalMilesManager *mgr = GlobalMilesManager::get_global_ptr();
00074 _stream = AIL_open_stream(mgr->_digital_driver, _path.c_str(), 0);
00075 if (_stream == 0) {
00076 milesAudio_cat.warning()
00077 << "Could not play " << _file_name << ": too many open streams\n";
00078 return;
00079 }
00080 AIL_set_stream_user_data(_stream, 0, (SINTa)this);
00081 AIL_register_stream_callback(_stream, finish_callback);
00082
00083 } else {
00084
00085
00086 AIL_pause_stream(_stream, 1);
00087 _manager->stop_service_stream(_stream);
00088 }
00089
00090
00091 nassertv(_stream != 0);
00092 HSAMPLE sample = AIL_stream_sample_handle(_stream);
00093 nassertv(sample != 0);
00094
00095 _original_playback_rate = AIL_sample_playback_rate(sample);
00096 set_volume(_volume);
00097 set_play_rate(_play_rate);
00098
00099 AIL_set_stream_loop_count(_stream, _loop_count);
00100
00101 AIL_start_stream(_stream);
00102 if (_got_start_time) {
00103
00104
00105 do_set_time(_start_time);
00106 }
00107
00108 if (miles_audio_panda_threads) {
00109 AIL_auto_service_stream(_stream, 0);
00110 _manager->start_service_stream(_stream);
00111 } else {
00112 AIL_auto_service_stream(_stream, 1);
00113 }
00114
00115 _got_start_time = false;
00116
00117 } else {
00118
00119 audio_debug(" paused "<<_file_name );
00120 _paused = true;
00121 }
00122 }
00123
00124
00125
00126
00127
00128
00129 void MilesAudioStream::
00130 stop() {
00131 if (_manager == (MilesAudioManager *)NULL) {
00132 return;
00133 }
00134 miles_audio_debug("stop()");
00135 _manager->stopping_sound(this);
00136
00137
00138
00139
00140
00141
00142
00143 if (_stream != 0) {
00144 _manager->stop_service_stream(_stream);
00145
00146 AIL_pause_stream(_stream, 1);
00147 AIL_close_stream(_stream);
00148 _stream = 0;
00149 }
00150 }
00151
00152
00153
00154
00155
00156
00157 PN_stdfloat MilesAudioStream::
00158 get_time() const {
00159 if (_stream == 0) {
00160 if (_got_start_time) {
00161 return _start_time;
00162 }
00163 return 0.0f;
00164 }
00165
00166 S32 current_ms;
00167 AIL_stream_ms_position(_stream, NULL, ¤t_ms);
00168 PN_stdfloat time = PN_stdfloat(current_ms * 0.001f);
00169
00170 return time;
00171 }
00172
00173
00174
00175
00176
00177
00178 void MilesAudioStream::
00179 set_volume(PN_stdfloat volume) {
00180 _volume = volume;
00181
00182 if (_stream != 0) {
00183 HSAMPLE sample = AIL_stream_sample_handle(_stream);
00184 nassertv(sample != 0);
00185
00186 volume *= _manager->get_volume();
00187
00188
00189 F32 milesVolume = volume;
00190 milesVolume = min(milesVolume, 1.0f);
00191 milesVolume = max(milesVolume, 0.0f);
00192
00193
00194 F32 milesBalance = (F32)((_balance + 1.0f) * 0.5f);
00195
00196 AIL_set_sample_volume_pan(sample, milesVolume, milesBalance);
00197 }
00198 }
00199
00200
00201
00202
00203
00204
00205 void MilesAudioStream::
00206 set_balance(PN_stdfloat balance_right) {
00207 _balance = balance_right;
00208
00209
00210 set_volume(_volume);
00211 }
00212
00213
00214
00215
00216
00217
00218 void MilesAudioStream::
00219 set_play_rate(PN_stdfloat play_rate) {
00220 _play_rate = play_rate;
00221
00222 if (_stream != 0) {
00223 HSAMPLE sample = AIL_stream_sample_handle(_stream);
00224 nassertv(sample != 0);
00225
00226 play_rate *= _manager->get_play_rate();
00227
00228
00229 S32 speed = (S32)(play_rate * (PN_stdfloat)_original_playback_rate);
00230 AIL_set_sample_playback_rate(sample, speed);
00231 audio_debug(" play_rate for this wav or mp3 is now " << speed);
00232 }
00233 }
00234
00235
00236
00237
00238
00239
00240 PN_stdfloat MilesAudioStream::
00241 length() const {
00242 if (!_got_length) {
00243 if (_stream == 0) {
00244 GlobalMilesManager *mgr = GlobalMilesManager::get_global_ptr();
00245 ((MilesAudioStream *)this)->_stream = AIL_open_stream(mgr->_digital_driver, _path.c_str(), 0);
00246 }
00247
00248 S32 length_ms;
00249 AIL_stream_ms_position(_stream, &length_ms, NULL);
00250 _length = (PN_stdfloat)length_ms * 0.001f;
00251 _got_length = true;
00252 }
00253
00254 return _length;
00255 }
00256
00257
00258
00259
00260
00261
00262 AudioSound::SoundStatus MilesAudioStream::
00263 status() const {
00264 if (!_stream) {
00265 return AudioSound::READY;
00266 }
00267
00268 switch (AIL_stream_status(_stream)) {
00269 case SMP_STOPPED:
00270 case SMP_DONE:
00271 return AudioSound::READY;
00272 case SMP_PLAYING:
00273 case SMP_PLAYINGBUTRELEASED:
00274 return AudioSound::PLAYING;
00275 default:
00276 return AudioSound::BAD;
00277 }
00278 }
00279
00280
00281
00282
00283
00284
00285
00286 void MilesAudioStream::
00287 cleanup() {
00288 if (_stream) {
00289 stop();
00290 }
00291 set_active(false);
00292 nassertv(_stream == 0);
00293
00294 if (_manager != (MilesAudioManager *)NULL) {
00295 _manager->release_sound(this);
00296 _manager = NULL;
00297 }
00298 }
00299
00300
00301
00302
00303
00304
00305
00306 void AILCALLBACK MilesAudioStream::
00307 finish_callback(HSTREAM stream) {
00308 MilesAudioStream *self = (MilesAudioStream *)AIL_stream_user_data(stream, 0);
00309 if (milesAudio_cat.is_debug()) {
00310 milesAudio_cat.debug()
00311 << "finished " << *self << "\n";
00312 }
00313 if (self->_manager == (MilesAudioManager *)NULL) {
00314 return;
00315 }
00316 self->_manager->_sounds_finished = true;
00317 }
00318
00319
00320
00321
00322
00323
00324 void MilesAudioStream::
00325 do_set_time(PN_stdfloat time) {
00326 nassertv(_stream != 0);
00327
00328 S32 time_ms = (S32)(1000.0f * time);
00329
00330
00331 S32 length_ms;
00332 AIL_stream_ms_position(_stream, &length_ms, NULL);
00333 time_ms = min(time_ms, length_ms);
00334
00335 AIL_set_stream_ms_position(_stream, time_ms);
00336 }
00337
00338
00339 #endif //]