allow querying length of midi file before it starts to play.

This commit is contained in:
David Rose 2008-11-03 18:47:12 +00:00
parent fcdb44e081
commit d1c1c8e31f
4 changed files with 60 additions and 2 deletions

View File

@ -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 //]

View File

@ -110,6 +110,7 @@ private:
SoundData();
~SoundData();
float get_length();
void set_length(float length);
Filename _basename;
S32 _file_type;

View File

@ -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 //]

View File

@ -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;