From d1c1c8e31fff5d3fa9e3aada0080e172312df4b9 Mon Sep 17 00:00:00 2001 From: David Rose Date: Mon, 3 Nov 2008 18:47:12 +0000 Subject: [PATCH] allow querying length of midi file before it starts to play. --- panda/src/audiotraits/milesAudioManager.cxx | 17 +++++++- panda/src/audiotraits/milesAudioManager.h | 1 + panda/src/audiotraits/milesAudioSequence.cxx | 43 ++++++++++++++++++++ panda/src/audiotraits/milesAudioSequence.h | 1 + 4 files changed, 60 insertions(+), 2 deletions(-) diff --git a/panda/src/audiotraits/milesAudioManager.cxx b/panda/src/audiotraits/milesAudioManager.cxx index aa158fdc3a..38d180c8d1 100644 --- a/panda/src/audiotraits/milesAudioManager.cxx +++ b/panda/src/audiotraits/milesAudioManager.cxx @@ -958,7 +958,8 @@ thread_main() { MilesAudioManager::SoundData:: SoundData() : _raw_data(MilesAudioManager::get_class_type()), - _has_length(false) + _has_length(false), + _length(0.0f) { } @@ -972,7 +973,7 @@ MilesAudioManager::SoundData:: } //////////////////////////////////////////////////////////////////// -// Function: MilesAudioManager::SoundData::Destructor +// Function: MilesAudioManager::SoundData::get_length // Access: Public // Description: //////////////////////////////////////////////////////////////////// @@ -1013,7 +1014,19 @@ get_length() { } } + nassertr(_has_length, 0.0f); return _length; } +//////////////////////////////////////////////////////////////////// +// Function: MilesAudioManager::SoundData::set_length +// Access: Public +// Description: Records the sample length, as determined externally. +//////////////////////////////////////////////////////////////////// +void MilesAudioManager::SoundData:: +set_length(float length) { + _length = length; + _has_length = true; +} + #endif //] diff --git a/panda/src/audiotraits/milesAudioManager.h b/panda/src/audiotraits/milesAudioManager.h index 1601a21158..e976796f29 100644 --- a/panda/src/audiotraits/milesAudioManager.h +++ b/panda/src/audiotraits/milesAudioManager.h @@ -110,6 +110,7 @@ private: SoundData(); ~SoundData(); float get_length(); + void set_length(float length); Filename _basename; S32 _file_type; diff --git a/panda/src/audiotraits/milesAudioSequence.cxx b/panda/src/audiotraits/milesAudioSequence.cxx index db0f218ed9..8260a01ddc 100644 --- a/panda/src/audiotraits/milesAudioSequence.cxx +++ b/panda/src/audiotraits/milesAudioSequence.cxx @@ -228,6 +228,20 @@ set_play_rate(float play_rate) { //////////////////////////////////////////////////////////////////// float MilesAudioSequence:: length() const { + if (_sequence == 0) { + // The MIDI file hasn't been started yet. See if the length is + // cached in the SoundData. + if (!_sd->_has_length) { + // It isn't cached, so load the sequence temporarily to + // determine its length. + ((MilesAudioSequence *)this)->determine_length(); + } + + return _sd->get_length(); + } + + // The MIDI file has already been started, so we can ask it + // directly. S32 length_ms; AIL_sequence_ms_position(_sequence, &length_ms, NULL); float time = (float)length_ms * 0.001f; @@ -321,4 +335,33 @@ do_set_time(float time) { AIL_set_sequence_ms_position(_sequence, time_ms); } + +//////////////////////////////////////////////////////////////////// +// Function: MilesAudioSequence::determine_length +// Access: Private +// Description: Temporarily loads the sequence to determine its +// length. Stores the result on the _sd. +//////////////////////////////////////////////////////////////////// +void MilesAudioSequence:: +determine_length() { + nassertv(_sequence == 0); + + GlobalMilesManager *mgr = GlobalMilesManager::get_global_ptr(); + if (!mgr->get_sequence(_sequence, _sequence_index, this)){ + milesAudio_cat.warning() + << "Could not determine length of " << _file_name << ": too many open sequences\n"; + _sequence = 0; + } else { + AIL_init_sequence(_sequence, &_sd->_raw_data[0], 0); + S32 length_ms; + AIL_sequence_ms_position(_sequence, &length_ms, NULL); + float time = (float)length_ms * 0.001f; + mgr->release_sequence(_sequence_index, this); + _sequence = 0; + _sequence_index = 0; + + _sd->set_length(time); + } +} + #endif //] diff --git a/panda/src/audiotraits/milesAudioSequence.h b/panda/src/audiotraits/milesAudioSequence.h index d4ed85e8ad..a16000282f 100644 --- a/panda/src/audiotraits/milesAudioSequence.h +++ b/panda/src/audiotraits/milesAudioSequence.h @@ -55,6 +55,7 @@ private: void internal_stop(); static void AILCALLBACK finish_callback(HSEQUENCE sequence); void do_set_time(float time); + void determine_length(); PT(MilesAudioManager::SoundData) _sd; HSEQUENCE _sequence;