17 #ifdef HAVE_RAD_MSS //[
40 audio_debug(
"Create_MilesAudioManager()");
41 return new MilesAudioManager();
51 _lock(
"MilesAudioManager::_lock"),
52 _streams_lock(
"MilesAudioManager::_streams_lock"),
53 _streams_cvar(_streams_lock)
55 audio_debug(
"MilesAudioManager::MilesAudioManager(), this = "
57 GlobalMilesManager::get_global_ptr()->add_manager(
this);
58 audio_debug(
" audio_active="<<audio_active);
59 audio_debug(
" audio_volume="<<audio_volume);
60 _cleanup_required =
true;
61 _active = audio_active;
62 _volume = audio_volume;
64 _cache_limit = audio_cache_limit;
65 _concurrent_sound_limit = 0;
67 _hasMidiSounds =
false;
68 _sounds_finished =
false;
89 ~MilesAudioManager() {
90 audio_debug(
"MilesAudioManager::~MilesAudioManager(), this = "
93 GlobalMilesManager::get_global_ptr()->remove_manager(
this);
95 audio_debug(
"MilesAudioManager::~MilesAudioManager() finished");
104 void MilesAudioManager::
106 audio_debug(
"shutdown() started");
107 GlobalMilesManager::get_global_ptr()->cleanup();
108 audio_debug(
"shutdown() finished");
115 bool MilesAudioManager::
118 return do_is_valid();
125 get_sound(
const Filename &file_name,
bool,
int) {
127 audio_debug(
"MilesAudioManager::get_sound(file_name=\""<<file_name<<
"\")");
129 if (!do_is_valid()) {
130 audio_debug(
"invalid MilesAudioManager returning NullSound");
131 return get_null_sound();
138 audio_debug(
"Reading "<<path);
139 audio_debug(
" resolved file_name is '"<<path<<
"'");
143 SoundMap::const_iterator si=_sounds.find(path);
144 if (si != _sounds.end()) {
147 audio_debug(
" sound found in pool 0x" << (
void*)sd);
153 while (_sounds.size() >= (
unsigned int)_cache_limit) {
158 std::pair<SoundMap::const_iterator, bool> ib
159 = _sounds.insert(SoundMap::value_type(path, sd));
162 audio_debug(
" failed map insert of "<<path);
163 nassertr(do_is_valid(),
nullptr);
164 return get_null_sound();
175 most_recently_used((*si).first);
176 if (sd->_file_type == AILFILETYPE_MIDI ||
177 sd->_file_type == AILFILETYPE_XMIDI ||
178 sd->_file_type == AILFILETYPE_XMIDI_DLS ||
179 sd->_file_type == AILFILETYPE_XMIDI_MLS) {
181 audioSound =
new MilesAudioSequence(
this, sd, file_name);
183 }
else if (!sd->_raw_data.empty()) {
185 audioSound =
new MilesAudioSample(
this, sd, file_name);
189 audioSound =
new MilesAudioStream(
this, file_name, path);
192 audioSound->set_active(_active);
194 bool inserted = _sounds_on_loan.insert((MilesAudioSound *)audioSound.p()).second;
195 nassertr(inserted, audioSound);
197 _hasMidiSounds |= (file_name.find(
".mid")!=string::npos);
203 audio_debug(
" returning 0x" << (
void*)audioSound);
204 nassertr(do_is_valid(),
nullptr);
213 nassert_raise(
"Miles audio manager does not support MovieAudio sources.");
220 void MilesAudioManager::
221 uncache_sound(
const Filename &file_name) {
222 audio_debug(
"MilesAudioManager::uncache_sound(file_name=\""
225 nassertv(do_is_valid());
231 audio_debug(
" path=\""<<path<<
"\"");
232 SoundMap::iterator i = _sounds.find(path);
233 if (i != _sounds.end()) {
234 nassertv(_lru.size() > 0);
235 LRU::iterator lru_i = find(_lru.begin(), _lru.end(), &(i->first));
236 nassertv(lru_i != _lru.end());
240 nassertv(do_is_valid());
246 void MilesAudioManager::
248 audio_debug(
"MilesAudioManager::clear_cache()");
256 void MilesAudioManager::
257 set_cache_limit(
unsigned int count) {
260 audio_debug(
"MilesAudioManager::set_cache_limit(count="<<count<<
")");
261 nassertv(do_is_valid());
262 while (_lru.size() > count) {
266 nassertv(do_is_valid());
272 unsigned int MilesAudioManager::
273 get_cache_limit()
const {
280 void MilesAudioManager::
281 set_volume(PN_stdfloat volume) {
282 audio_debug(
"MilesAudioManager::set_volume(volume="<<volume<<
")");
284 if (_volume != volume) {
287 AudioSet::iterator i = _sounds_on_loan.begin();
288 for (; i!=_sounds_on_loan.end(); ++i) {
289 (*i)->set_volume((*i)->get_volume());
297 PN_stdfloat MilesAudioManager::
305 void MilesAudioManager::
306 set_play_rate(PN_stdfloat play_rate) {
307 audio_debug(
"MilesAudioManager::set_play_rate(play_rate="<<play_rate<<
")");
309 if (_play_rate != play_rate) {
310 _play_rate = play_rate;
312 AudioSet::iterator i = _sounds_on_loan.begin();
313 for (; i != _sounds_on_loan.end(); ++i) {
314 (*i)->set_play_rate((*i)->get_play_rate());
322 PN_stdfloat MilesAudioManager::
323 get_play_rate()
const {
330 void MilesAudioManager::
331 set_active(
bool active) {
332 audio_debug(
"MilesAudioManager::set_active(flag="<<active<<
")");
334 if (_active != active) {
337 AudioSet::iterator i = _sounds_on_loan.begin();
338 for (; i != _sounds_on_loan.end(); ++i) {
339 (*i)->set_active(_active);
342 if ((!_active) && _hasMidiSounds) {
343 GlobalMilesManager::get_global_ptr()->force_midi_reset();
351 bool MilesAudioManager::
359 void MilesAudioManager::
360 set_concurrent_sound_limit(
unsigned int limit) {
362 _concurrent_sound_limit = limit;
363 do_reduce_sounds_playing_to(_concurrent_sound_limit);
369 unsigned int MilesAudioManager::
370 get_concurrent_sound_limit()
const {
371 return _concurrent_sound_limit;
377 void MilesAudioManager::
378 reduce_sounds_playing_to(
unsigned int count) {
380 do_reduce_sounds_playing_to(count);
386 void MilesAudioManager::
388 audio_debug(
"MilesAudioManager::stop_all_sounds()");
389 reduce_sounds_playing_to(0);
396 void MilesAudioManager::audio_3d_set_listener_attributes(PN_stdfloat px, PN_stdfloat py, PN_stdfloat pz, PN_stdfloat vx, PN_stdfloat vy, PN_stdfloat vz, PN_stdfloat fx, PN_stdfloat fy, PN_stdfloat fz, PN_stdfloat ux, PN_stdfloat uy, PN_stdfloat uz) {
397 audio_debug(
"MilesAudioManager::audio_3d_set_listener_attributes()");
399 GlobalMilesManager *mgr = GlobalMilesManager::get_global_ptr();
400 AIL_set_listener_3D_position(mgr->_digital_driver, px, pz, py);
401 AIL_set_listener_3D_velocity_vector(mgr->_digital_driver, vx, vz, vy);
402 AIL_set_listener_3D_orientation(mgr->_digital_driver, fx, fz, fy, ux, uz, uy);
409 void MilesAudioManager::audio_3d_get_listener_attributes(PN_stdfloat *px, PN_stdfloat *py, PN_stdfloat *pz, PN_stdfloat *vx, PN_stdfloat *vy, PN_stdfloat *vz, PN_stdfloat *fx, PN_stdfloat *fy, PN_stdfloat *fz, PN_stdfloat *ux, PN_stdfloat *uy, PN_stdfloat *uz) {
410 audio_debug(
"MilesAudioManager::audio_3d_get_listener_attributes()");
412 GlobalMilesManager *mgr = GlobalMilesManager::get_global_ptr();
413 float lpx, lpy, lpz, lvx, lvy, lvz, lfx, lfy, lfz, lux, luy, luz;
414 AIL_listener_3D_position(mgr->_digital_driver, &lpx, &lpz, &lpy);
415 AIL_listener_3D_velocity(mgr->_digital_driver, &lvx, &lvz, &lvy);
416 AIL_listener_3D_orientation(mgr->_digital_driver, &lfx, &lfz, &lfy, &lux, &luz, &luy);
436 void MilesAudioManager::audio_3d_set_distance_factor(PN_stdfloat factor) {
437 audio_debug(
"MilesAudioManager::audio_3d_set_distance_factor( factor= " << factor <<
")");
439 GlobalMilesManager *mgr = GlobalMilesManager::get_global_ptr();
440 AIL_set_3D_distance_factor(mgr->_digital_driver, factor);
446 PN_stdfloat MilesAudioManager::audio_3d_get_distance_factor()
const {
447 audio_debug(
"MilesAudioManager::audio_3d_get_distance_factor()");
449 GlobalMilesManager *mgr = GlobalMilesManager::get_global_ptr();
450 return AIL_3D_distance_factor(mgr->_digital_driver);
456 void MilesAudioManager::audio_3d_set_doppler_factor(PN_stdfloat factor) {
457 audio_debug(
"MilesAudioManager::audio_3d_set_doppler_factor(factor="<<factor<<
")");
459 GlobalMilesManager *mgr = GlobalMilesManager::get_global_ptr();
460 AIL_set_3D_doppler_factor(mgr->_digital_driver, factor);
466 PN_stdfloat MilesAudioManager::audio_3d_get_doppler_factor()
const {
467 audio_debug(
"MilesAudioManager::audio_3d_get_doppler_factor()");
469 GlobalMilesManager *mgr = GlobalMilesManager::get_global_ptr();
470 return AIL_3D_doppler_factor(mgr->_digital_driver);
476 void MilesAudioManager::audio_3d_set_drop_off_factor(PN_stdfloat factor) {
477 audio_debug(
"MilesAudioManager::audio_3d_set_drop_off_factor("<<factor<<
")");
479 GlobalMilesManager *mgr = GlobalMilesManager::get_global_ptr();
480 AIL_set_3D_rolloff_factor(mgr->_digital_driver, factor);
486 PN_stdfloat MilesAudioManager::audio_3d_get_drop_off_factor()
const {
487 audio_debug(
"MilesAudioManager::audio_3d_get_drop_off_factor()");
489 GlobalMilesManager *mgr = GlobalMilesManager::get_global_ptr();
490 return AIL_3D_rolloff_factor(mgr->_digital_driver);
502 void MilesAudioManager::
503 set_speaker_configuration(LVecBase3 *speaker1, LVecBase3 *speaker2, LVecBase3 *speaker3, LVecBase3 *speaker4, LVecBase3 *speaker5, LVecBase3 *speaker6, LVecBase3 *speaker7, LVecBase3 *speaker8, LVecBase3 *speaker9) {
504 audio_debug(
"MilesAudioManager::set_speaker_configuration()");
506 GlobalMilesManager *mgr = GlobalMilesManager::get_global_ptr();
508 MSSVECTOR3D speakers[9];
510 if(speaker1 !=
nullptr) {
511 speakers[0].x = speaker1->get_x();
512 speakers[0].y = speaker1->get_z();
513 speakers[0].z = speaker1->get_y();
515 if(speaker2 !=
nullptr) {
516 speakers[1].x = speaker2->get_x();
517 speakers[1].y = speaker2->get_z();
518 speakers[1].z = speaker2->get_y();
520 if(speaker3 !=
nullptr) {
521 speakers[2].x = speaker3->get_x();
522 speakers[2].y = speaker3->get_z();
523 speakers[2].z = speaker3->get_y();
525 if(speaker4 !=
nullptr) {
526 speakers[3].x = speaker4->get_x();
527 speakers[3].y = speaker4->get_z();
528 speakers[3].z = speaker4->get_y();
530 if(speaker5 !=
nullptr) {
531 speakers[4].x = speaker5->get_x();
532 speakers[4].y = speaker5->get_z();
533 speakers[4].z = speaker5->get_y();
535 if(speaker6 !=
nullptr) {
536 speakers[5].x = speaker6->get_x();
537 speakers[5].y = speaker6->get_z();
538 speakers[5].z = speaker6->get_y();
540 if(speaker7 !=
nullptr) {
541 speakers[6].x = speaker7->get_x();
542 speakers[6].y = speaker7->get_z();
543 speakers[6].z = speaker7->get_y();
545 if(speaker8 !=
nullptr) {
546 speakers[7].x = speaker8->get_x();
547 speakers[7].y = speaker8->get_z();
548 speakers[7].z = speaker8->get_y();
550 if(speaker9 !=
nullptr) {
551 speakers[8].x = speaker9->get_x();
552 speakers[8].y = speaker9->get_z();
553 speakers[8].z = speaker9->get_y();
556 if(speaker1 ==
nullptr) {
557 audio_error(
"No valid speaker positions specified in MilesAudioManager::set_speaker_configuration().");
558 }
else if(speaker2 ==
nullptr) {
559 AIL_set_speaker_configuration(mgr->_digital_driver, speakers, 1, 1.0);
560 }
else if(speaker3 ==
nullptr) {
561 AIL_set_speaker_configuration(mgr->_digital_driver, speakers, 2, 1.0);
562 }
else if(speaker4 ==
nullptr) {
563 AIL_set_speaker_configuration(mgr->_digital_driver, speakers, 3, 1.0);
564 }
else if(speaker5 ==
nullptr) {
565 AIL_set_speaker_configuration(mgr->_digital_driver, speakers, 4, 1.0);
566 }
else if(speaker6 ==
nullptr) {
567 AIL_set_speaker_configuration(mgr->_digital_driver, speakers, 5, 1.0);
568 }
else if(speaker7 ==
nullptr) {
569 AIL_set_speaker_configuration(mgr->_digital_driver, speakers, 6, 1.0);
570 }
else if(speaker8 ==
nullptr) {
571 AIL_set_speaker_configuration(mgr->_digital_driver, speakers, 7, 1.0);
572 }
else if(speaker9 ==
nullptr) {
573 AIL_set_speaker_configuration(mgr->_digital_driver, speakers, 8, 1.0);
575 AIL_set_speaker_configuration(mgr->_digital_driver, speakers, 9, 1.0);
583 void MilesAudioManager::
587 if (_stream_thread.is_null() && !_streams.empty()) {
590 do_service_streams();
594 if (_sounds_finished) {
595 _sounds_finished =
false;
603 SoundsPlaying::iterator si = _sounds_playing.begin();
604 while (si != _sounds_playing.end()) {
605 MilesAudioSound *sound = (*si);
608 if (sound->status() == AudioSound::READY) {
618 void MilesAudioManager::
619 release_sound(MilesAudioSound *audioSound) {
620 audio_debug(
"MilesAudioManager::release_sound(audioSound=\""
621 <<audioSound->get_name()<<
"\"), this = " << (
void *)
this);
623 AudioSet::iterator ai = _sounds_on_loan.find(audioSound);
624 if (ai != _sounds_on_loan.end()) {
625 _sounds_on_loan.erase(ai);
628 audio_debug(
"MilesAudioManager::release_sound() finished");
635 void MilesAudioManager::
637 audio_debug(
"MilesAudioManager::cleanup(), this = " << (
void *)
this
638 <<
", _cleanup_required = " << _cleanup_required);
640 if (!_cleanup_required) {
645 AudioSet orig_sounds;
646 orig_sounds.swap(_sounds_on_loan);
647 AudioSet::iterator ai;
648 for (ai = orig_sounds.begin(); ai != orig_sounds.end(); ++ai) {
655 if (!_stream_thread.is_null()) {
656 milesAudio_cat.info()
657 <<
"Stopping audio streaming thread.\n";
658 PT(StreamThread) old_thread;
661 nassertv(!_stream_thread.is_null());
662 _stream_thread->_keep_running =
false;
663 _streams_cvar.notify();
664 old_thread = _stream_thread;
665 _stream_thread.clear();
670 _cleanup_required =
false;
671 audio_debug(
"MilesAudioManager::cleanup() finished");
677 void MilesAudioManager::
678 output(std::ostream &out)
const {
680 out << get_type() <<
": " << _sounds_playing.size()
681 <<
" / " << _sounds_on_loan.size() <<
" sounds playing / total";
687 void MilesAudioManager::
688 write(std::ostream &out)
const {
691 out << (*this) <<
"\n";
692 AudioSet::const_iterator ai;
693 for (ai = _sounds_on_loan.begin(); ai != _sounds_on_loan.end(); ++ai) {
694 MilesAudioSound *sound = (*ai);
695 out <<
" " << *sound <<
"\n";
698 size_t total_preload = 0;
699 size_t num_preloaded = 0;
700 SoundMap::const_iterator si;
701 for (si = _sounds.begin(); si != _sounds.end(); ++si) {
702 if (!(*si).second->_raw_data.empty()) {
704 total_preload += (*si).second->_raw_data.size();
707 out << num_preloaded <<
" of " << _sounds.size() <<
" sounds preloaded, size used is " << (total_preload + 1023) / 1024 <<
"K\n";
711 out << _streams.size() <<
" streams opened.\n";
712 if (!_stream_thread.is_null()) {
713 out <<
"(Audio streaming thread has been started.)\n";
717 GlobalMilesManager *mgr = GlobalMilesManager::get_global_ptr();
719 int num_samples = mgr->get_num_samples();
720 out << num_samples <<
" sample handles allocated globally.\n";
722 int num_sequences = mgr->get_num_sequences();
723 out << num_sequences <<
" sequence handles allocated globally.\n";
730 bool MilesAudioManager::
733 if (_sounds.size() != _lru.size()) {
734 audio_debug(
"-- Error _sounds.size() != _lru.size() --");
738 LRU::const_iterator i = _lru.begin();
739 for (; i != _lru.end(); ++i) {
740 SoundMap::const_iterator smi = _sounds.find(**i);
741 if (smi == _sounds.end()) {
742 audio_debug(
"-- "<<**i<<
" in _lru and not in _sounds --");
748 return _is_valid && check;
754 void MilesAudioManager::
755 do_reduce_sounds_playing_to(
unsigned int count) {
756 int limit = _sounds_playing.size() - count;
757 while (limit-- > 0) {
758 SoundsPlaying::iterator sound = _sounds_playing.begin();
759 assert(sound != _sounds_playing.end());
767 void MilesAudioManager::
769 if (_is_valid) { nassertv(do_is_valid()); }
772 if (_is_valid) { nassertv(do_is_valid()); }
779 void MilesAudioManager::
780 start_service_stream(HSTREAM stream) {
782 nassertv(find(_streams.begin(), _streams.end(), stream) == _streams.end());
783 _streams.push_back(stream);
784 _streams_cvar.notify();
787 milesAudio_cat.info()
788 <<
"Starting audio streaming thread.\n";
789 _stream_thread =
new StreamThread(
this);
790 _stream_thread->start(TP_low,
true);
798 void MilesAudioManager::
799 stop_service_stream(HSTREAM stream) {
801 Streams::iterator si = find(_streams.begin(), _streams.end(), stream);
802 if (si != _streams.end()) {
811 void MilesAudioManager::
812 most_recently_used(
const string &path) {
813 audio_debug(
"MilesAudioManager::most_recently_used(path=\""
815 LRU::iterator i=find(_lru.begin(), _lru.end(), &path);
816 if (i != _lru.end()) {
820 assert(find(_lru.begin(), _lru.end(), &path) == _lru.end());
821 _lru.push_back(&path);
822 nassertv(do_is_valid());
828 void MilesAudioManager::
830 audio_debug(
"MilesAudioManager::uncache_a_sound()");
831 nassertv(do_is_valid());
833 assert(_lru.size()>0);
834 LRU::reference path=_lru.front();
835 SoundMap::iterator i = _sounds.find(*path);
836 assert(i != _sounds.end());
839 if (i != _sounds.end()) {
840 audio_debug(
" uncaching \""<<i->first<<
"\"");
843 nassertv(do_is_valid());
849 void MilesAudioManager::
850 starting_sound(MilesAudioSound *audio) {
852 if (_concurrent_sound_limit) {
853 do_reduce_sounds_playing_to(_concurrent_sound_limit);
855 _sounds_playing.insert(audio);
862 void MilesAudioManager::
863 stopping_sound(MilesAudioSound *audio) {
865 _sounds_playing.erase(audio);
866 if (_hasMidiSounds && _sounds_playing.size() == 0) {
867 GlobalMilesManager::get_global_ptr()->force_midi_reset();
877 PT(MilesAudioManager::SoundData) MilesAudioManager::
879 PT(SoundData) sd =
new SoundData;
883 if (file ==
nullptr) {
884 milesAudio_cat.warning()
885 <<
"No such file: " << file_name <<
"\n";
889 if (file->get_file_size() == 0) {
890 milesAudio_cat.warning()
891 <<
"File " << file_name <<
" is empty\n";
897 string extension = sd->_basename.get_extension();
898 if (extension ==
"pz" || extension ==
"gz") {
902 bool is_midi_file = (
downcase(extension) ==
"mid");
904 if ((miles_audio_preload_threshold == -1 || file->get_file_size() < (std::streamsize)miles_audio_preload_threshold) ||
910 if (!file->read_file(sd->_raw_data,
true)) {
911 milesAudio_cat.warning()
912 <<
"Unable to read " << file_name <<
"\n";
917 AIL_file_type(&sd->_raw_data[0], sd->_raw_data.size());
919 if (sd->_file_type == AILFILETYPE_MIDI) {
923 if (AIL_MIDI_to_XMI(&sd->_raw_data[0], sd->_raw_data.size(),
924 &xmi, &xmi_size, 0)) {
925 audio_debug(
"converted " << sd->_basename <<
" from standard MIDI ("
926 << sd->_raw_data.size() <<
" bytes) to XMIDI ("
927 << xmi_size <<
" bytes)");
930 sd->_raw_data.clear();
931 sd->_raw_data.insert(sd->_raw_data.end(),
932 (
unsigned char *)xmi, (
unsigned char *)xmi + xmi_size);
933 AIL_mem_free_lock(xmi);
934 sd->_file_type = AILFILETYPE_XMIDI;
936 milesAudio_cat.warning()
937 <<
"Could not convert " << sd->_basename <<
" to XMIDI.\n";
941 bool expand_to_wav =
false;
943 if (sd->_file_type != AILFILETYPE_MPEG_L3_AUDIO) {
944 audio_debug(sd->_basename <<
" is not an mp3 file.");
945 }
else if ((
int)sd->_raw_data.size() >= miles_audio_expand_mp3_threshold) {
946 audio_debug(sd->_basename <<
" is too large to expand in-memory.");
948 audio_debug(sd->_basename <<
" will be expanded in-memory.");
949 expand_to_wav =
true;
958 if (AIL_decompress_ASI(&sd->_raw_data[0], sd->_raw_data.size(),
959 sd->_basename.c_str(), &wav_data, &wav_data_size,
961 audio_debug(
"expanded " << sd->_basename <<
" from " << sd->_raw_data.size()
962 <<
" bytes to " << wav_data_size <<
" bytes.");
964 if (wav_data_size != 0) {
967 sd->_raw_data.clear();
968 sd->_raw_data.insert(sd->_raw_data.end(),
969 (
unsigned char *)wav_data, (
unsigned char *)wav_data + wav_data_size);
970 sd->_file_type = AILFILETYPE_PCM_WAV;
971 sd->_basename.set_extension(
"wav");
973 AIL_mem_free_lock(wav_data);
976 audio_debug(
"unable to expand " << sd->_basename);
992 void MilesAudioManager::
993 thread_main(
volatile bool &keep_running) {
996 while (keep_running) {
997 if (_streams.empty()) {
999 _streams_cvar.wait();
1001 do_service_streams();
1005 _streams_lock.release();
1007 _streams_lock.acquire();
1015 void MilesAudioManager::
1016 do_service_streams() {
1018 while (i < _streams.size()) {
1019 HSTREAM stream = _streams[i];
1022 _streams_lock.release();
1023 AIL_service_stream(stream, 0);
1025 _streams_lock.acquire();
1034 MilesAudioManager::StreamThread::
1035 StreamThread(MilesAudioManager *mgr) :
1036 Thread(
"StreamThread",
"StreamThread"),
1039 _keep_running =
true;
1045 void MilesAudioManager::StreamThread::
1047 _mgr->thread_main(_keep_running);
1053 MilesAudioManager::SoundData::
1055 _raw_data(MilesAudioManager::get_class_type()),
1064 MilesAudioManager::SoundData::
1071 PN_stdfloat MilesAudioManager::SoundData::
1076 if (_raw_data.empty()) {
1080 }
else if (_file_type == AILFILETYPE_MPEG_L3_AUDIO) {
1083 audio_debug(
"Computing length of mp3 file " << _basename);
1086 AIL_inspect_MP3(&info, &_raw_data[0], _raw_data.size());
1088 while (AIL_enumerate_MP3_frames(&info)) {
1089 _length += info.data_size * 8.0f / info.bit_rate;
1093 }
else if (_file_type == AILFILETYPE_PCM_WAV ||
1094 _file_type == AILFILETYPE_ADPCM_WAV ||
1095 _file_type == AILFILETYPE_OTHER_ASI_WAV) {
1096 audio_debug(
"Getting length of wav file " << _basename);
1099 if (AIL_WAV_info(&_raw_data[0], &info)) {
1100 _length = (PN_stdfloat)info.samples / (PN_stdfloat)info.rate;
1101 audio_debug(info.samples <<
" samples at " << info.rate
1102 <<
"; length is " << _length <<
" seconds.");
1108 nassertr(_has_length, 0.0f);
1115 void MilesAudioManager::SoundData::
1116 set_length(PN_stdfloat length) {