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;
90 audio_debug(
"MilesAudioManager::~MilesAudioManager(), this = "
93 GlobalMilesManager::get_global_ptr()->remove_manager(
this);
95 audio_debug(
"MilesAudioManager::~MilesAudioManager() finished");
104void MilesAudioManager::
106 audio_debug(
"shutdown() started");
107 GlobalMilesManager::get_global_ptr()->cleanup();
108 audio_debug(
"shutdown() finished");
115bool MilesAudioManager::
118 return do_is_valid();
125get_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.");
220void MilesAudioManager::
221uncache_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());
246void MilesAudioManager::
248 audio_debug(
"MilesAudioManager::clear_cache()");
256void MilesAudioManager::
257set_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());
272unsigned int MilesAudioManager::
273get_cache_limit()
const {
280void MilesAudioManager::
281set_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());
297PN_stdfloat MilesAudioManager::
305void MilesAudioManager::
306set_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());
322PN_stdfloat MilesAudioManager::
323get_play_rate()
const {
330void MilesAudioManager::
331set_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();
351bool MilesAudioManager::
359void MilesAudioManager::
360set_concurrent_sound_limit(
unsigned int limit) {
362 _concurrent_sound_limit = limit;
363 do_reduce_sounds_playing_to(_concurrent_sound_limit);
369unsigned int MilesAudioManager::
370get_concurrent_sound_limit()
const {
371 return _concurrent_sound_limit;
377void MilesAudioManager::
378reduce_sounds_playing_to(
unsigned int count) {
380 do_reduce_sounds_playing_to(count);
386void MilesAudioManager::
388 audio_debug(
"MilesAudioManager::stop_all_sounds()");
389 reduce_sounds_playing_to(0);
396void 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);
409void 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);
436void 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);
446PN_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);
456void 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);
466PN_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);
476void 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);
486PN_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);
502void MilesAudioManager::
503set_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);
583void 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) {
618void MilesAudioManager::
619release_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");
635void 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");
677void MilesAudioManager::
678output(std::ostream &out)
const {
680 out << get_type() <<
": " << _sounds_playing.size()
681 <<
" / " << _sounds_on_loan.size() <<
" sounds playing / total";
687void MilesAudioManager::
688write(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";
730bool 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;
754void MilesAudioManager::
755do_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());
767void MilesAudioManager::
769 if (_is_valid) { nassertv(do_is_valid()); }
772 if (_is_valid) { nassertv(do_is_valid()); }
779void MilesAudioManager::
780start_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);
798void MilesAudioManager::
799stop_service_stream(HSTREAM stream) {
801 Streams::iterator si = find(_streams.begin(), _streams.end(), stream);
802 if (si != _streams.end()) {
811void MilesAudioManager::
812most_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());
828void 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());
849void MilesAudioManager::
850starting_sound(MilesAudioSound *audio) {
852 if (_concurrent_sound_limit) {
853 do_reduce_sounds_playing_to(_concurrent_sound_limit);
855 _sounds_playing.insert(audio);
862void MilesAudioManager::
863stopping_sound(MilesAudioSound *audio) {
865 _sounds_playing.erase(audio);
866 if (_hasMidiSounds && _sounds_playing.size() == 0) {
867 GlobalMilesManager::get_global_ptr()->force_midi_reset();
877PT(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);
992void MilesAudioManager::
993thread_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();
1015void MilesAudioManager::
1016do_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();
1034MilesAudioManager::StreamThread::
1035StreamThread(MilesAudioManager *mgr) :
1036 Thread(
"StreamThread",
"StreamThread"),
1039 _keep_running =
true;
1045void MilesAudioManager::StreamThread::
1047 _mgr->thread_main(_keep_running);
1053MilesAudioManager::SoundData::
1055 _raw_data(MilesAudioManager::get_class_type()),
1064MilesAudioManager::SoundData::
1071PN_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);
1115void MilesAudioManager::SoundData::
1116set_length(PN_stdfloat length) {
The name of a file, such as a texture file or an Egg file.
std::string get_basename() const
Returns the basename part of the filename.
std::string get_extension() const
Returns the file extension.
Similar to MutexHolder, but for a light reentrant mutex.
A MovieAudio is actually any source that provides a sequence of audio samples.
A lightweight C++ object whose constructor calls acquire() and whose destructor calls release() on a ...
A thread; that is, a lightweight process.
is_threading_supported
Returns true if threading support has been compiled in and enabled, or false if no threading is avail...
static void consider_yield()
Possibly suspends the current thread for the rest of the current epoch, if it has run for enough this...
static void force_yield()
Suspends the current thread for the rest of the current epoch.
TypeHandle is the identifier used to differentiate C++ class types.
A hierarchy of directories and files that appears to be one continuous file system,...
bool resolve_filename(Filename &filename, const DSearchPath &searchpath, const std::string &default_extension=std::string()) const
Searches the given search path for the filename.
PointerTo< VirtualFile > get_file(const Filename &filename, bool status_only=false) const
Looks up the file by the indicated name in the file system.
static VirtualFileSystem * get_global_ptr()
Returns the default global VirtualFileSystem.
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.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
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.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.