reinstate thread buffer debug output
[ardour.git] / libs / ardour / session_midi.cc
index c5efb1f3f88110295d643329335a4641d610a7cb..caceebf8535cb095ebfdf0c3f8e14a487999572a 100644 (file)
@@ -1,4 +1,3 @@
-
 /*
   Copyright (C) 1999-2002 Paul Davis
 
 #include "midi++/mmc.h"
 #include "midi++/port.h"
 #include "midi++/manager.h"
+
 #include "pbd/error.h"
 #include "pbd/pthread_utils.h"
 
-#include "ardour/configuration.h"
-#include "ardour/debug.h"
-#include "ardour/audioengine.h"
-#include "ardour/session.h"
+#include "timecode/time.h"
+
 #include "ardour/audio_track.h"
+#include "ardour/audioengine.h"
+#include "ardour/debug.h"
 #include "ardour/midi_track.h"
 #include "ardour/midi_ui.h"
-#include "ardour/audio_diskstream.h"
+#include "ardour/session.h"
 #include "ardour/slave.h"
-#include "ardour/cycles.h"
-#include "ardour/timecode.h"
 
 #include "i18n.h"
 
@@ -90,23 +88,23 @@ Session::setup_midi_control ()
 }
 
 void
-Session::spp_start (Parser &, nframes_t /*timestamp*/)
+Session::spp_start ()
 {
-       if (Config->get_mmc_control() && (!config.get_external_sync() || config.get_sync_source() != JACK)) {
+       if (Config->get_mmc_control ()) {
                request_transport_speed (1.0);
        }
 }
 
 void
-Session::spp_continue (Parser& ignored, nframes_t timestamp)
+Session::spp_continue ()
 {
-       spp_start (ignored, timestamp);
+       spp_start ();
 }
 
 void
-Session::spp_stop (Parser&, nframes_t /*timestamp*/)
+Session::spp_stop ()
 {
-       if (Config->get_mmc_control()) {
+       if (Config->get_mmc_control ()) {
                request_stop ();
        }
 }
@@ -114,7 +112,7 @@ Session::spp_stop (Parser&, nframes_t /*timestamp*/)
 void
 Session::mmc_deferred_play (MIDI::MachineControl &/*mmc*/)
 {
-       if (Config->get_mmc_control() && (!config.get_external_sync() || (config.get_sync_source() != JACK))) {
+       if (Config->get_mmc_control ()) {
                request_transport_speed (1.0);
        }
 }
@@ -122,7 +120,7 @@ Session::mmc_deferred_play (MIDI::MachineControl &/*mmc*/)
 void
 Session::mmc_record_pause (MIDI::MachineControl &/*mmc*/)
 {
-       if (Config->get_mmc_control()) {
+       if (Config->get_mmc_control ()) {
                maybe_enable_record();
        }
 }
@@ -159,7 +157,7 @@ Session::mmc_record_strobe (MIDI::MachineControl &/*mmc*/)
 void
 Session::mmc_record_exit (MIDI::MachineControl &/*mmc*/)
 {
-       if (Config->get_mmc_control()) {
+       if (Config->get_mmc_control ()) {
                disable_record (false);
        }
 }
@@ -167,7 +165,7 @@ Session::mmc_record_exit (MIDI::MachineControl &/*mmc*/)
 void
 Session::mmc_stop (MIDI::MachineControl &/*mmc*/)
 {
-       if (Config->get_mmc_control()) {
+       if (Config->get_mmc_control ()) {
                request_stop ();
        }
 }
@@ -175,7 +173,7 @@ Session::mmc_stop (MIDI::MachineControl &/*mmc*/)
 void
 Session::mmc_pause (MIDI::MachineControl &/*mmc*/)
 {
-       if (Config->get_mmc_control()) {
+       if (Config->get_mmc_control ()) {
 
                /* We support RECORD_PAUSE, so the spec says that
                   we must interpret PAUSE like RECORD_PAUSE if
@@ -195,7 +193,7 @@ static bool step_queued = false;
 void
 Session::mmc_step (MIDI::MachineControl &/*mmc*/, int steps)
 {
-       if (!Config->get_mmc_control()) {
+       if (!Config->get_mmc_control ()) {
                return;
        }
 
@@ -234,7 +232,7 @@ Session::mmc_step (MIDI::MachineControl &/*mmc*/, int steps)
             << endl;
 #endif
 
-       request_transport_speed (step_speed);
+       request_transport_speed_nonzero (step_speed);
        last_mmc_step = now;
 
        if (!step_queued) {
@@ -250,7 +248,7 @@ Session::mmc_step (MIDI::MachineControl &/*mmc*/, int steps)
 void
 Session::mmc_rewind (MIDI::MachineControl &/*mmc*/)
 {
-       if (Config->get_mmc_control()) {
+       if (Config->get_mmc_control ()) {
                request_transport_speed(-8.0f);
        }
 }
@@ -258,7 +256,7 @@ Session::mmc_rewind (MIDI::MachineControl &/*mmc*/)
 void
 Session::mmc_fast_forward (MIDI::MachineControl &/*mmc*/)
 {
-       if (Config->get_mmc_control()) {
+       if (Config->get_mmc_control ()) {
                request_transport_speed(8.0f);
        }
 }
@@ -266,7 +264,7 @@ Session::mmc_fast_forward (MIDI::MachineControl &/*mmc*/)
 void
 Session::mmc_locate (MIDI::MachineControl &/*mmc*/, const MIDI::byte* mmc_tc)
 {
-       if (!Config->get_mmc_control()) {
+       if (!Config->get_mmc_control ()) {
                return;
        }
 
@@ -307,7 +305,7 @@ Session::mmc_locate (MIDI::MachineControl &/*mmc*/, const MIDI::byte* mmc_tc)
 void
 Session::mmc_shuttle (MIDI::MachineControl &/*mmc*/, float speed, bool forw)
 {
-       if (!Config->get_mmc_control()) {
+       if (!Config->get_mmc_control ()) {
                return;
        }
 
@@ -316,28 +314,29 @@ Session::mmc_shuttle (MIDI::MachineControl &/*mmc*/, float speed, bool forw)
        }
 
        if (forw) {
-               request_transport_speed (speed);
+               request_transport_speed_nonzero (speed);
        } else {
-               request_transport_speed (-speed);
+               request_transport_speed_nonzero (-speed);
        }
 }
 
 void
 Session::mmc_record_enable (MIDI::MachineControl &mmc, size_t trk, bool enabled)
 {
-       if (Config->get_mmc_control()) {
+       if (!Config->get_mmc_control ()) {
+               return;
+       }
 
-               RouteList::iterator i;
-               boost::shared_ptr<RouteList> r = routes.reader();
+       RouteList::iterator i;
+       boost::shared_ptr<RouteList> r = routes.reader();
 
-               for (i = r->begin(); i != r->end(); ++i) {
-                       AudioTrack *at;
+       for (i = r->begin(); i != r->end(); ++i) {
+               AudioTrack *at;
 
-                       if ((at = dynamic_cast<AudioTrack*>((*i).get())) != 0) {
-                               if (trk == at->remote_control_id()) {
-                                       at->set_record_enabled (enabled, &mmc);
-                                       break;
-                               }
+               if ((at = dynamic_cast<AudioTrack*>((*i).get())) != 0) {
+                       if (trk == at->remote_control_id()) {
+                               at->set_record_enabled (enabled, &mmc);
+                               break;
                        }
                }
        }
@@ -349,7 +348,7 @@ Session::mmc_record_enable (MIDI::MachineControl &mmc, size_t trk, bool enabled)
  * @param t time to send.
  */
 int
-Session::send_full_time_code (nframes64_t const t)
+Session::send_full_time_code (framepos_t const t)
 {
        /* This function could easily send at a given frame offset, but would
         * that be useful?  Does ardour do sub-block accurate locating? [DR] */
@@ -359,7 +358,7 @@ Session::send_full_time_code (nframes64_t const t)
 
        _send_timecode_update = false;
 
-       if (!session_send_mtc || _slave) {
+       if (_engine.freewheeling() || !Config->get_send_mtc() || _slave) {
                return 0;
        }
 
@@ -373,11 +372,11 @@ Session::send_full_time_code (nframes64_t const t)
        if (((mtc_timecode_bits >> 5) != MIDI::MTC_25_FPS) && (transmitting_timecode_time.frames % 2)) {
                // start MTC quarter frame transmission on an even frame
                Timecode::increment (transmitting_timecode_time, config.get_subframes_per_frame());
-               outbound_mtc_timecode_frame += (nframes_t) _frames_per_timecode_frame;
+               outbound_mtc_timecode_frame += _frames_per_timecode_frame;
        }
 
        // Compensate for audio latency
-       outbound_mtc_timecode_frame += _worst_output_latency;
+       outbound_mtc_timecode_frame += worst_playback_latency();
        next_quarter_frame_to_send = 0;
 
        // Sync slave to the same Timecode time as we are on
@@ -399,20 +398,21 @@ Session::send_full_time_code (nframes64_t const t)
                return -1;
        }
 
+       _pframes_since_last_mtc = 0;
        return 0;
 }
 
 /** Send MTC (quarter-frame) messages for this cycle.
- * Must be called exactly once per cycle from the audio thread.  Realtime safe.
+ * Must be called exactly once per cycle from the process thread.  Realtime safe.
  * This function assumes the state of full Timecode is sane, eg. the slave is
  * expecting quarter frame messages and has the right frame of reference (any
  * full MTC Timecode time messages that needed to be sent should have been sent
  * earlier already this cycle by send_full_time_code)
  */
 int
-Session::send_midi_time_code_for_cycle(nframes_t nframes)
+Session::send_midi_time_code_for_cycle (framepos_t start_frame, framepos_t end_frame, pframes_t nframes)
 {
-       if (_slave || !session_send_mtc || transmitting_timecode_time.negative || (next_quarter_frame_to_send < 0)) {
+       if (_engine.freewheeling() || _slave || !_send_qf_mtc || transmitting_timecode_time.negative || (next_quarter_frame_to_send < 0)) {
                // cerr << "(MTC) Not sending MTC\n";
                return 0;
        }
@@ -421,57 +421,54 @@ Session::send_midi_time_code_for_cycle(nframes_t nframes)
        assert (next_quarter_frame_to_send <= 7);
 
        /* Duration of one quarter frame */
-       nframes_t quarter_frame_duration = ((nframes_t) _frames_per_timecode_frame) >> 2;
+       framecnt_t const quarter_frame_duration = ((framecnt_t) _frames_per_timecode_frame) >> 2;
 
-       DEBUG_TRACE (DEBUG::MTC, string_compose ("TF %1 SF %2 NQ %3 FD %4\n",  _transport_frame, outbound_mtc_timecode_frame,
+       DEBUG_TRACE (DEBUG::MTC, string_compose ("TF %1 SF %2 NQ %3 FD %4\n", start_frame, outbound_mtc_timecode_frame,
                                                 next_quarter_frame_to_send, quarter_frame_duration));
 
-       assert((outbound_mtc_timecode_frame + (next_quarter_frame_to_send * quarter_frame_duration))
-                       >= _transport_frame);
-
+       assert ((outbound_mtc_timecode_frame + (next_quarter_frame_to_send * quarter_frame_duration)) >= _transport_frame);
 
-       // Send quarter frames for this cycle
-       while (_transport_frame + nframes > (outbound_mtc_timecode_frame +
-                               (next_quarter_frame_to_send * quarter_frame_duration))) {
+       /* Send quarter frames for this cycle */
+       while (end_frame > (outbound_mtc_timecode_frame + (next_quarter_frame_to_send * quarter_frame_duration))) {
 
                DEBUG_TRACE (DEBUG::MTC, string_compose ("next frame to send: %1\n", next_quarter_frame_to_send));
 
                switch (next_quarter_frame_to_send) {
                        case 0:
-                               mtc_msg[1] =  0x00 | (transmitting_timecode_time.frames & 0xf);
+                               mtc_msg[1] = 0x00 | (transmitting_timecode_time.frames & 0xf);
                                break;
                        case 1:
-                               mtc_msg[1] =  0x10 | ((transmitting_timecode_time.frames & 0xf0) >> 4);
+                               mtc_msg[1] = 0x10 | ((transmitting_timecode_time.frames & 0xf0) >> 4);
                                break;
                        case 2:
-                               mtc_msg[1] =  0x20 | (transmitting_timecode_time.seconds & 0xf);
+                               mtc_msg[1] = 0x20 | (transmitting_timecode_time.seconds & 0xf);
                                break;
                        case 3:
-                               mtc_msg[1] =  0x30 | ((transmitting_timecode_time.seconds & 0xf0) >> 4);
+                               mtc_msg[1] = 0x30 | ((transmitting_timecode_time.seconds & 0xf0) >> 4);
                                break;
                        case 4:
-                               mtc_msg[1] =  0x40 | (transmitting_timecode_time.minutes & 0xf);
+                               mtc_msg[1] = 0x40 | (transmitting_timecode_time.minutes & 0xf);
                                break;
                        case 5:
                                mtc_msg[1] = 0x50 | ((transmitting_timecode_time.minutes & 0xf0) >> 4);
                                break;
                        case 6:
-                               mtc_msg[1] = 0x60 | ((mtc_timecode_bits|transmitting_timecode_time.hours) & 0xf);
+                               mtc_msg[1] = 0x60 | ((mtc_timecode_bits | transmitting_timecode_time.hours) & 0xf);
                                break;
                        case 7:
-                               mtc_msg[1] = 0x70 | (((mtc_timecode_bits|transmitting_timecode_time.hours) & 0xf0) >> 4);
+                               mtc_msg[1] = 0x70 | (((mtc_timecode_bits | transmitting_timecode_time.hours) & 0xf0) >> 4);
                                break;
                }
 
-               const nframes_t msg_time = (outbound_mtc_timecode_frame
-                       + (quarter_frame_duration * next_quarter_frame_to_send));
+               const framepos_t msg_time = outbound_mtc_timecode_frame + (quarter_frame_duration * next_quarter_frame_to_send);
 
                // This message must fall within this block or something is broken
-               assert(msg_time >= _transport_frame);
-               assert(msg_time < _transport_frame + nframes);
+               assert (msg_time >= start_frame);
+               assert (msg_time < end_frame);
 
-               nframes_t out_stamp = msg_time - _transport_frame;
-               assert(out_stamp < nframes);
+               /* convert from session frames back to JACK frames using the transport speed */
+               pframes_t const out_stamp = (msg_time - start_frame) / _transport_speed;
+               assert (out_stamp < nframes);
 
                if (MIDI::Manager::instance()->mtc_output_port()->midimsg (mtc_msg, 2, out_stamp)) {
                        error << string_compose(_("Session: cannot send quarter-frame MTC message (%1)"), strerror (errno))
@@ -494,8 +491,8 @@ Session::send_midi_time_code_for_cycle(nframes_t nframes)
                        // Wrap quarter frame counter
                        next_quarter_frame_to_send = 0;
                        // Increment timecode time twice
-                       Timecode::increment( transmitting_timecode_time, config.get_subframes_per_frame() );
-                       Timecode::increment( transmitting_timecode_time, config.get_subframes_per_frame() );
+                       Timecode::increment (transmitting_timecode_time, config.get_subframes_per_frame());
+                       Timecode::increment (transmitting_timecode_time, config.get_subframes_per_frame());
                        // Re-calculate timing of first quarter frame
                        //timecode_to_sample( transmitting_timecode_time, outbound_mtc_timecode_frame, true /* use_offset */, false );
                        outbound_mtc_timecode_frame += 8 * quarter_frame_duration;
@@ -535,14 +532,10 @@ Session::mmc_step_timeout ()
 
        /* slow it down */
 
-       request_transport_speed (_transport_speed * 0.75);
+       request_transport_speed_nonzero (_transport_speed * 0.75);
        return true;
 }
 
-/*---------------------------------------------------------------------------
-  MIDI THREAD
-  ---------------------------------------------------------------------------*/
-
 int
 Session::start_midi_thread ()
 {
@@ -551,12 +544,3 @@ Session::start_midi_thread ()
        return 0;
 }
 
-void
-Session::terminate_midi_thread ()
-{
-       if (midi_control_ui) {
-               midi_control_ui->quit ();
-       }
-}
-
-