a grab bag of changes correcting and improving the way MIDI note on/off tracking...
[ardour.git] / libs / ardour / midi_diskstream.cc
index 81217b179acea4a185242a28649547fa58f629db..e3d7014457a01ffe2ff0c98889c8f00cdc552054 100644 (file)
@@ -252,7 +252,6 @@ MidiDiskstream::use_new_playlist ()
        if ((playlist = boost::dynamic_pointer_cast<MidiPlaylist> (PlaylistFactory::create (
                        DataType::MIDI, _session, newname, hidden()))) != 0) {
 
-               playlist->set_orig_diskstream_id (id());
                return use_playlist (playlist);
 
        } else {
@@ -280,7 +279,6 @@ MidiDiskstream::use_copy_playlist ()
        newname = Playlist::bump_name (_playlist->name(), _session);
 
        if ((playlist  = boost::dynamic_pointer_cast<MidiPlaylist>(PlaylistFactory::create (midi_playlist(), newname))) != 0) {
-               playlist->set_orig_diskstream_id (id());
                return use_playlist (playlist);
        } else {
                return -1;
@@ -739,16 +737,16 @@ MidiDiskstream::read (framepos_t& start, framecnt_t dur, bool reversed)
                        start = loop_start + ((start - loop_start) % loop_length);
                        //cerr << "to " << start << endl;
                }
-               //cerr << "start is " << start << "  loopstart: " << loop_start << "  loopend: " << loop_end << endl;
+               // cerr << "start is " << start << "  loopstart: " << loop_start << "  loopend: " << loop_end << endl;
        }
 
        while (dur) {
 
                /* take any loop into account. we can't read past the end of the loop. */
 
-               if (loc && (loop_end - start < dur)) {
+               if (loc && (loop_end - start <= dur)) {
                        this_read = loop_end - start;
-                       //cerr << "reloop true: thisread: " << this_read << "  dur: " << dur << endl;
+                       // cerr << "reloop true: thisread: " << this_read << "  dur: " << dur << endl;
                        reloop = true;
                } else {
                        reloop = false;
@@ -946,7 +944,7 @@ MidiDiskstream::transport_stopped_wallclock (struct tm& /*when*/, time_t /*twhen
        Glib::Mutex::Lock lm (capture_info_lock);
 
        if (capture_info.empty()) {
-               return;
+               goto no_capture_stuff_to_do;
        }
 
        if (abort_capture) {
@@ -1099,12 +1097,12 @@ MidiDiskstream::transport_stopped_wallclock (struct tm& /*when*/, time_t /*twhen
                delete *ci;
        }
 
-       if (_playlist) {
-               midi_playlist()->clear_note_trackers ();
-       }
-
        capture_info.clear ();
        capture_start_frame = 0;
+
+  no_capture_stuff_to_do:
+
+       reset_tracker ();
 }
 
 void
@@ -1134,6 +1132,10 @@ MidiDiskstream::transport_looped (framepos_t transport_frame)
                last_recordable_frame = max_framepos;
                was_recording = true;
        }
+
+       if (!Config->get_seamless_loop()) {
+               reset_tracker ();
+       }
 }
 
 void
@@ -1200,7 +1202,7 @@ MidiDiskstream::engage_record_enable ()
        boost::shared_ptr<MidiPort> sp = _source_port.lock ();
        
        if (sp && Config->get_monitoring_model() == HardwareMonitoring) {
-               sp->request_monitor_input (!(_session.config.get_auto_input() && rolling));
+               sp->request_jack_monitors_input (!(_session.config.get_auto_input() && rolling));
        }
 
        RecordEnableChanged (); /* EMIT SIGNAL */
@@ -1373,12 +1375,12 @@ MidiDiskstream::allocate_temporary_buffers ()
 }
 
 void
-MidiDiskstream::monitor_input (bool yn)
+MidiDiskstream::ensure_jack_monitors_input (bool yn)
 {
        boost::shared_ptr<MidiPort> sp = _source_port.lock ();
        
        if (sp) {
-               sp->ensure_monitor_input (yn);
+               sp->ensure_jack_monitors_input (yn);
        }
 }
 
@@ -1400,15 +1402,25 @@ MidiDiskstream::set_align_style_from_io ()
 float
 MidiDiskstream::playback_buffer_load () const
 {
-       return (float) ((double) _playback_buf->read_space()/
-                       (double) _playback_buf->capacity());
+       /* For MIDI it's not trivial to differentiate the following two cases:
+          
+          1.  The playback buffer is empty because the system has run out of time to fill it.
+          2.  The playback buffer is empty because there is no more data on the playlist.
+
+          If we use a simple buffer load computation, we will report that the MIDI diskstream
+          cannot keep up when #2 happens, when in fact it can.  Since MIDI data rates
+          are so low compared to audio, just give a pretend answer here.
+       */
+       
+       return 1;
 }
 
 float
 MidiDiskstream::capture_buffer_load () const
 {
-       return (float) ((double) _capture_buf->write_space()/
-                       (double) _capture_buf->capacity());
+       /* We don't report playback buffer load, so don't report capture load either */
+       
+       return 1;
 }
 
 int
@@ -1467,3 +1479,15 @@ MidiDiskstream::get_gui_feed_buffer () const
        b->copy (_gui_feed_buffer);
        return b;
 }
+
+void
+MidiDiskstream::reset_tracker ()
+{
+       _playback_buf->reset_tracker ();
+
+       boost::shared_ptr<MidiPlaylist> mp (midi_playlist());
+
+       if (mp) {
+               mp->clear_note_trackers ();
+       }
+}