16 #ifdef HAVE_RAD_MSS //[ 23 #undef miles_audio_debug 26 #define miles_audio_debug(x) \ 27 audio_debug("MilesAudioSample \""<<get_name()<<"\" "<< x ) 29 #define miles_audio_debug(x) ((void)0) 36 MilesAudioSample(MilesAudioManager *manager, MilesAudioManager::SoundData *sd,
37 const std::string &file_name) :
38 MilesAudioSound(manager, file_name),
41 nassertv(sd !=
nullptr);
42 audio_debug(
"MilesAudioSample(manager=0x"<<(
void*)&manager
43 <<
", sd=0x"<<(
void*)sd<<
", file_name="<<file_name<<
")");
47 _original_playback_rate = 1.0f;
55 miles_audio_debug(
"~MilesAudioSample()");
57 miles_audio_debug(
"~MilesAudioSample() done");
63 void MilesAudioSample::
65 miles_audio_debug(
"play()");
67 if (_sd->_raw_data.empty()) {
68 milesAudio_cat.warning()
69 <<
"Could not play " << _file_name <<
": no data\n";
72 _manager->starting_sound(
this);
74 nassertv(_sample == 0);
76 GlobalMilesManager *mgr = GlobalMilesManager::get_global_ptr();
77 if (!mgr->get_sample(_sample, _sample_index,
this)){
78 milesAudio_cat.warning()
79 <<
"Could not play " << _file_name <<
": too many open samples\n";
82 AIL_set_named_sample_file(_sample, _sd->_basename.c_str(),
83 &_sd->_raw_data[0], _sd->_raw_data.size(),
85 _original_playback_rate = AIL_sample_playback_rate(_sample);
86 AIL_set_sample_user_data(_sample, 0, (SINTa)
this);
87 AIL_register_EOS_callback(_sample, finish_callback);
90 set_play_rate(_play_rate);
91 AIL_set_sample_loop_count(_sample, _loop_count);
93 if (_got_start_time) {
94 do_set_time(_start_time);
95 AIL_resume_sample(_sample);
97 AIL_start_sample(_sample);
101 _got_start_time =
false;
105 audio_debug(
" paused "<<_file_name );
113 void MilesAudioSample::
115 if (_manager ==
nullptr) {
119 miles_audio_debug(
"stop()");
120 _manager->stopping_sound(
this);
132 AIL_end_sample(_sample);
134 GlobalMilesManager *mgr = GlobalMilesManager::get_global_ptr();
135 mgr->release_sample(_sample_index,
this);
145 PN_stdfloat MilesAudioSample::
148 if (_got_start_time) {
155 AIL_sample_ms_position(_sample,
nullptr, ¤t_ms);
156 PN_stdfloat time = PN_stdfloat(current_ms * 0.001f);
164 void MilesAudioSample::
165 set_volume(PN_stdfloat volume) {
166 miles_audio_debug(
"set_volume(volume="<<volume<<
")");
175 volume *= _manager->get_volume();
178 F32 milesVolume = volume;
179 milesVolume = std::min(milesVolume, 1.0f);
180 milesVolume = std::max(milesVolume, 0.0f);
183 F32 milesBalance = (F32)((_balance + 1.0f) * 0.5f);
185 AIL_set_sample_volume_pan(_sample, milesVolume, milesBalance);
192 void MilesAudioSample::
193 set_balance(PN_stdfloat balance_right) {
194 miles_audio_debug(
"set_balance(balance_right="<<balance_right<<
")");
195 _balance = balance_right;
204 void MilesAudioSample::
205 set_play_rate(PN_stdfloat play_rate) {
206 miles_audio_debug(
"set_play_rate(play_rate="<<play_rate<<
")");
209 _play_rate = play_rate;
212 play_rate *= _manager->get_play_rate();
215 S32 speed = (S32)(play_rate * (PN_stdfloat)_original_playback_rate);
216 AIL_set_sample_playback_rate(_sample, speed);
217 audio_debug(
" play_rate for this wav or mp3 is now " << speed);
224 PN_stdfloat MilesAudioSample::
226 return _sd->get_length();
232 AudioSound::SoundStatus MilesAudioSample::
235 return AudioSound::READY;
237 switch (AIL_sample_status(_sample)) {
241 return AudioSound::READY;
244 case SMP_PLAYINGBUTRELEASED:
245 return AudioSound::PLAYING;
248 return AudioSound::BAD;
256 void MilesAudioSample::
260 nassertv(_sample == 0);
262 if (_manager !=
nullptr) {
263 _manager->release_sound(
this);
271 void MilesAudioSample::
272 output(std::ostream &out)
const {
273 out << get_type() <<
" " << get_name() <<
" " << status();
274 if (!_sd.is_null()) {
275 out <<
" " << (_sd->_raw_data.size() + 1023) / 1024 <<
"K";
283 void MilesAudioSample::set_3d_attributes(PN_stdfloat px, PN_stdfloat py, PN_stdfloat pz, PN_stdfloat vx, PN_stdfloat vy, PN_stdfloat vz) {
284 audio_debug(
"MilesAudioSample::set_3d_attributes() Setting a sound's 3D Coordinates.");
287 AIL_set_sample_3D_position(_sample, px, pz, py);
288 AIL_set_sample_3D_velocity_vector(_sample, vx, vz, vy);
290 audio_warning(
"_sample == 0 in MilesAudioSample::set_3d_attributes().");
297 void MilesAudioSample::get_3d_attributes(PN_stdfloat *px, PN_stdfloat *py, PN_stdfloat *pz, PN_stdfloat *vx, PN_stdfloat *vy, PN_stdfloat *vz) {
298 audio_debug(
"MilesAudioSample::get_3d_attributes().");
301 float lpx, lpy, lpz, lvx, lvy, lvz;
302 AIL_sample_3D_position(_sample, &lpx, &lpz, &lpy);
303 AIL_sample_3D_velocity(_sample, &lvx, &lvz, &lvy);
311 audio_warning(
"_sample == 0 in MilesAudioSample::get_3d_attributes().");
320 void MilesAudioSample::set_3d_min_distance(PN_stdfloat dist) {
321 audio_debug(
"MilesAudioSample::set_3d_min_distance() Setting the sound's 3D min distance ( min= " << dist <<
" ) ");
327 int auto_3D_wet_atten;
328 AIL_sample_3D_distances(_sample, &max_dist,
nullptr, &auto_3D_wet_atten);
330 AIL_set_sample_3D_distances(_sample, max_dist, dist, auto_3D_wet_atten);
332 audio_warning(
"_sample == 0 in MilesAudioSample::set_3d_min_distance().");
339 PN_stdfloat MilesAudioSample::get_3d_min_distance()
const {
340 audio_debug(
"MilesAudioSample::get_3d_min_distance() ");
344 AIL_sample_3D_distances(_sample,
nullptr, &min_dist,
nullptr);
345 return (PN_stdfloat)min_dist;
347 audio_warning(
"_sample == 0 in MilesAudioSample::get_3d_min_distance().");
357 void MilesAudioSample::set_3d_max_distance(PN_stdfloat dist) {
358 audio_debug(
"MilesAudioSample::set_3d_max_distance() Setting the sound's 3D max distance ( max= " << dist <<
" ) ");
364 int auto_3D_wet_atten;
365 AIL_sample_3D_distances(_sample,
nullptr, &min_dist, &auto_3D_wet_atten);
367 AIL_set_sample_3D_distances(_sample, dist, min_dist, auto_3D_wet_atten);
369 audio_warning(
"_sample == 0 in MilesAudioSample::set_3d_max_distance().");
376 PN_stdfloat MilesAudioSample::get_3d_max_distance()
const {
377 audio_debug(
"MilesAudioSample::get_3d_max_distance() ");
381 AIL_sample_3D_distances(_sample, &max_dist,
nullptr,
nullptr);
382 return (PN_stdfloat)max_dist;
384 audio_warning(
"_sample == 0 in MilesAudioSample::get_3d_max_distance().");
407 PN_stdfloat MilesAudioSample::
408 get_speaker_level(
int index) {
409 audio_debug(
"MilesAudioSample::get_speaker_level(" << index <<
")");
413 float *levels = AIL_sample_channel_levels(_sample, &numLevels);
415 if(index < numLevels) {
416 return (PN_stdfloat)levels[index];
418 audio_error(
"index out of range in MilesAudioSample::get_speaker_level. numLevels: " << numLevels);
422 audio_warning(
"Warning: MilesAudioSample::get_speaker_level only works for sounds that are currently playing");
449 void MilesAudioSample::
450 set_speaker_levels(PN_stdfloat level1, PN_stdfloat level2, PN_stdfloat level3, PN_stdfloat level4, PN_stdfloat level5, PN_stdfloat level6, PN_stdfloat level7, PN_stdfloat level8, PN_stdfloat level9) {
451 audio_debug(
"MilesAudioSample::set_speaker_levels()");
454 float levels[9] = {level1, level2, level3, level4, level5, level6, level7, level8, level9};
456 if((level1 < 0.0) || (level1 > 1.0)) {
457 audio_error(
"No valid levels specified in MilesAudioSample::set_speaker_levels().");
458 }
else if((level2 < 0.0) || (level2 > 1.0)) {
459 AIL_set_sample_channel_levels(_sample, levels, 1);
460 }
else if((level3 < 0.0) || (level3 > 1.0)) {
461 AIL_set_sample_channel_levels(_sample, levels, 2);
462 }
else if((level4 < 0.0) || (level4 > 1.0)) {
463 AIL_set_sample_channel_levels(_sample, levels, 3);
464 }
else if((level5 < 0.0) || (level5 > 1.0)) {
465 AIL_set_sample_channel_levels(_sample, levels, 4);
466 }
else if((level6 < 0.0) || (level6 > 1.0)) {
467 AIL_set_sample_channel_levels(_sample, levels, 5);
468 }
else if((level7 < 0.0) || (level7 > 1.0)) {
469 AIL_set_sample_channel_levels(_sample, levels, 6);
470 }
else if((level8 < 0.0) || (level8 > 1.0)) {
471 AIL_set_sample_channel_levels(_sample, levels, 7);
472 }
else if((level9 < 0.0) || (level9 > 1.0)) {
473 AIL_set_sample_channel_levels(_sample, levels, 8);
475 AIL_set_sample_channel_levels(_sample, levels, 9);
478 audio_warning(
"Warning: MilesAudioSample::set_speaker_levels only works for sounds that are currently playing");
486 void MilesAudioSample::
496 void AILCALLBACK MilesAudioSample::
497 finish_callback(HSAMPLE sample) {
498 MilesAudioSample *
self = (MilesAudioSample *)AIL_sample_user_data(sample, 0);
499 if (milesAudio_cat.is_debug()) {
500 milesAudio_cat.debug()
501 <<
"finished " << *
self <<
"\n";
503 if (self->_manager ==
nullptr) {
506 self->_manager->_sounds_finished =
true;
512 void MilesAudioSample::
513 do_set_time(PN_stdfloat time) {
514 miles_audio_debug(
"do_set_time(time="<<time<<
")");
515 nassertv(_sample != 0);
518 PN_stdfloat max_time = length();
519 if (time > max_time) {
520 milesAudio_cat.warning()
521 <<
"set_time(" << time <<
") requested for sound of length " 526 S32 time_ms = (S32)(1000.0f * time);
527 AIL_set_sample_ms_position(_sample, time_ms);
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
TypeHandle is the identifier used to differentiate C++ class types.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.