00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "milesAudioSequence.h"
00016
00017 #ifdef HAVE_RAD_MSS //[
00018
00019 #include "milesAudioManager.h"
00020
00021
00022 TypeHandle MilesAudioSequence::_type_handle;
00023
00024 #undef miles_audio_debug
00025
00026 #ifndef NDEBUG //[
00027 #define miles_audio_debug(x) \
00028 audio_debug("MilesAudioSequence \""<<get_name()<<"\" "<< x )
00029 #else //][
00030 #define miles_audio_debug(x) ((void)0)
00031 #endif //]
00032
00033
00034
00035
00036
00037
00038
00039 MilesAudioSequence::
00040 MilesAudioSequence(MilesAudioManager *manager, MilesAudioManager::SoundData *sd,
00041 const string &file_name) :
00042 MilesAudioSound(manager, file_name),
00043 _sd(sd)
00044 {
00045 nassertv(sd != NULL);
00046 audio_debug("MilesAudioSequence(manager=0x"<<(void*)&manager
00047 <<", sd=0x"<<(void*)sd<<", file_name="<<file_name<<")");
00048
00049 _sequence = 0;
00050 _sequence_index = 0;
00051 }
00052
00053
00054
00055
00056
00057
00058 MilesAudioSequence::
00059 ~MilesAudioSequence() {
00060 miles_audio_debug("~MilesAudioSequence()");
00061 cleanup();
00062 _manager->release_sound(this);
00063 miles_audio_debug("~MilesAudioSequence() done");
00064 }
00065
00066
00067
00068
00069
00070
00071 void MilesAudioSequence::
00072 play() {
00073 miles_audio_debug("play()");
00074 if (_active) {
00075 stop();
00076
00077 if (_sd->_raw_data.empty()) {
00078 milesAudio_cat.warning()
00079 << "Could not play " << _file_name << ": no data\n";
00080 } else {
00081 _manager->starting_sound(this);
00082 nassertv(_sequence == 0);
00083
00084 GlobalMilesManager *mgr = GlobalMilesManager::get_global_ptr();
00085 if (!mgr->get_sequence(_sequence, _sequence_index, this)){
00086 milesAudio_cat.warning()
00087 << "Could not play " << _file_name << ": too many open sequences\n";
00088 _sequence = 0;
00089 } else {
00090 AIL_init_sequence(_sequence, &_sd->_raw_data[0], 0);
00091 AIL_set_sequence_user_data(_sequence, 0, (SINTa)this);
00092 AIL_register_sequence_callback(_sequence, finish_callback);
00093
00094 set_volume(_volume);
00095 set_play_rate(_play_rate);
00096 AIL_set_sequence_loop_count(_sequence, _loop_count);
00097
00098 if (_got_start_time) {
00099 do_set_time(_start_time);
00100 AIL_resume_sequence(_sequence);
00101 } else {
00102 AIL_start_sequence(_sequence);
00103 }
00104 }
00105
00106 _got_start_time = false;
00107 }
00108 } else {
00109
00110 audio_debug(" paused "<<_file_name );
00111 _paused = true;
00112 }
00113 }
00114
00115
00116
00117
00118
00119
00120 void MilesAudioSequence::
00121 stop() {
00122 miles_audio_debug("stop()");
00123 _manager->stopping_sound(this);
00124
00125
00126
00127
00128
00129
00130
00131 if (_sequence != 0) {
00132 AIL_end_sequence(_sequence);
00133
00134 GlobalMilesManager *mgr = GlobalMilesManager::get_global_ptr();
00135 mgr->release_sequence(_sequence_index, this);
00136
00137 _sequence = 0;
00138 _sequence_index = 0;
00139 }
00140 }
00141
00142
00143
00144
00145
00146
00147 PN_stdfloat MilesAudioSequence::
00148 get_time() const {
00149 if (_sequence == 0) {
00150 if (_got_start_time) {
00151 return _start_time;
00152 }
00153 return 0.0f;
00154 }
00155
00156 S32 current_ms;
00157 AIL_sequence_ms_position(_sequence, NULL, ¤t_ms);
00158 PN_stdfloat time = PN_stdfloat(current_ms * 0.001f);
00159
00160 return time;
00161 }
00162
00163
00164
00165
00166
00167
00168 void MilesAudioSequence::
00169 set_volume(PN_stdfloat volume) {
00170 miles_audio_debug("set_volume(volume="<<volume<<")");
00171
00172
00173
00174
00175
00176
00177 _volume = volume;
00178
00179 if (_sequence != 0) {
00180 volume *= _manager->get_volume();
00181
00182
00183 S32 milesVolume = (S32)(volume * 127.0f);
00184 milesVolume = min(milesVolume, 127);
00185 milesVolume = max(milesVolume, 0);
00186
00187 AIL_set_sequence_volume(_sequence, milesVolume, 0);
00188 }
00189 }
00190
00191
00192
00193
00194
00195
00196 void MilesAudioSequence::
00197 set_balance(PN_stdfloat balance_right) {
00198 miles_audio_debug("set_balance(balance_right="<<balance_right<<")");
00199 _balance = balance_right;
00200
00201
00202 }
00203
00204
00205
00206
00207
00208
00209 void MilesAudioSequence::
00210 set_play_rate(PN_stdfloat play_rate) {
00211 miles_audio_debug("set_play_rate(play_rate="<<play_rate<<")");
00212
00213
00214 _play_rate = play_rate;
00215
00216 if (_sequence != 0) {
00217 play_rate *= _manager->get_play_rate();
00218
00219 S32 percent = (S32)(play_rate * 100.0f);
00220 AIL_set_sequence_tempo(_sequence, percent, 0);
00221 }
00222 }
00223
00224
00225
00226
00227
00228
00229 PN_stdfloat MilesAudioSequence::
00230 length() const {
00231 if (_sequence == 0) {
00232
00233
00234 if (!_sd->_has_length) {
00235
00236
00237 ((MilesAudioSequence *)this)->determine_length();
00238 }
00239
00240 return _sd->get_length();
00241 }
00242
00243
00244
00245 S32 length_ms;
00246 AIL_sequence_ms_position(_sequence, &length_ms, NULL);
00247 PN_stdfloat time = (PN_stdfloat)length_ms * 0.001f;
00248 return time;
00249 }
00250
00251
00252
00253
00254
00255
00256 AudioSound::SoundStatus MilesAudioSequence::
00257 status() const {
00258 if (_sequence == 0) {
00259 return AudioSound::READY;
00260 }
00261 switch (AIL_sequence_status(_sequence)) {
00262 case SEQ_DONE:
00263 case SEQ_STOPPED:
00264 case SEQ_FREE:
00265 return AudioSound::READY;
00266
00267 case SEQ_PLAYING:
00268 case SEQ_PLAYINGBUTRELEASED:
00269 return AudioSound::PLAYING;
00270
00271 default:
00272 return AudioSound::BAD;
00273 }
00274 }
00275
00276
00277
00278
00279
00280
00281
00282
00283 void MilesAudioSequence::
00284 cleanup() {
00285 stop();
00286 }
00287
00288
00289
00290
00291
00292
00293
00294
00295 void MilesAudioSequence::
00296 internal_stop() {
00297 _sequence = 0;
00298 _sequence_index = 0;
00299 }
00300
00301
00302
00303
00304
00305
00306
00307 void AILCALLBACK MilesAudioSequence::
00308 finish_callback(HSEQUENCE sequence) {
00309 MilesAudioSequence *self = (MilesAudioSequence *)AIL_sequence_user_data(sequence, 0);
00310 if (milesAudio_cat.is_debug()) {
00311 milesAudio_cat.debug()
00312 << "finished " << *self << "\n";
00313 }
00314 self->_manager->_sounds_finished = true;
00315 }
00316
00317
00318
00319
00320
00321
00322 void MilesAudioSequence::
00323 do_set_time(PN_stdfloat time) {
00324 miles_audio_debug("do_set_time(time="<<time<<")");
00325
00326 nassertv(_sequence != 0);
00327
00328 S32 time_ms = (S32)(1000.0f * time);
00329
00330
00331 S32 length_ms;
00332 AIL_sequence_ms_position(_sequence, &length_ms, NULL);
00333 time_ms = min(time_ms, length_ms);
00334
00335 AIL_set_sequence_ms_position(_sequence, time_ms);
00336 }
00337
00338
00339
00340
00341
00342
00343
00344
00345 void MilesAudioSequence::
00346 determine_length() {
00347 nassertv(_sequence == 0);
00348
00349 GlobalMilesManager *mgr = GlobalMilesManager::get_global_ptr();
00350 if (!mgr->get_sequence(_sequence, _sequence_index, this)){
00351 milesAudio_cat.warning()
00352 << "Could not determine length of " << _file_name << ": too many open sequences\n";
00353 _sequence = 0;
00354 } else {
00355 AIL_init_sequence(_sequence, &_sd->_raw_data[0], 0);
00356 S32 length_ms;
00357 AIL_sequence_ms_position(_sequence, &length_ms, NULL);
00358 PN_stdfloat time = (PN_stdfloat)length_ms * 0.001f;
00359 mgr->release_sequence(_sequence_index, this);
00360 _sequence = 0;
00361 _sequence_index = 0;
00362
00363 _sd->set_length(time);
00364 }
00365 }
00366
00367 #endif //]