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") {
899 extension =
Filename(sd->_basename.get_basename_wo_extension()).get_extension();
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) {
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
is_threading_supported
Returns true if threading support has been compiled in and enabled, or false if no threading is avail...
A hierarchy of directories and files that appears to be one continuous file system,...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
string downcase(const string &s)
Returns the input string with all uppercase letters converted to lowercase.
bool resolve_filename(Filename &filename, const DSearchPath &searchpath, const std::string &default_extension=std::string()) const
Searches the given search path for the filename.
A lightweight C++ object whose constructor calls acquire() and whose destructor calls release() on a ...
static void consider_yield()
Possibly suspends the current thread for the rest of the current epoch, if it has run for enough this...
The abstract base class for a file or directory within the VirtualFileSystem.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
static void force_yield()
Suspends the current thread for the rest of the current epoch.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
The name of a file, such as a texture file or an Egg file.
static VirtualFileSystem * get_global_ptr()
Returns the default global VirtualFileSystem.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PointerTo< VirtualFile > get_file(const Filename &filename, bool status_only=false) const
Looks up the file by the indicated name in the file system.
Similar to MutexHolder, but for a light reentrant mutex.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
std::string get_basename() const
Returns the basename part of the filename.
A thread; that is, a lightweight process.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
TypeHandle is the identifier used to differentiate C++ class types.
A MovieAudio is actually any source that provides a sequence of audio samples.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.