Browse Source

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

David Rose 17 years ago
parent
commit
d1c1c8e31f

+ 15 - 2
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 //]

+ 1 - 0
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;

+ 43 - 0
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 //]

+ 1 - 0
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;