3 Copyright (C) 1999-2002 Paul Davis
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
29 #include <midi++/mmc.h>
30 #include <midi++/port.h>
31 #include <midi++/manager.h>
32 #include <pbd/error.h>
33 #include <pbd/lockmonitor.h>
34 #include <pbd/pthread_utils.h>
36 #include <ardour/configuration.h>
37 #include <ardour/audioengine.h>
38 #include <ardour/session.h>
39 #include <ardour/audio_track.h>
40 #include <ardour/diskstream.h>
41 #include <ardour/slave.h>
42 #include <ardour/cycles.h>
43 #include <ardour/smpte.h>
48 using namespace ARDOUR;
49 //using namespace sigc;
52 MachineControl::CommandSignature MMC_CommandSignature;
53 MachineControl::ResponseSignature MMC_ResponseSignature;
55 MultiAllocSingleReleasePool Session::MIDIRequest::pool ("midi", sizeof (Session::MIDIRequest), 1024);
58 Session::use_config_midi_ports ()
62 if (default_mmc_port) {
63 set_mmc_port (default_mmc_port->name());
68 if (default_mtc_port) {
69 set_mtc_port (default_mtc_port->name());
74 if (default_midi_port) {
75 set_midi_port (default_midi_port->name());
84 /***********************************************************************
86 **********************************************************************/
89 Session::set_mmc_control (bool yn)
92 if (mmc_control == yn) {
100 ControlChanged (MMCControl); /* EMIT SIGNAL */
104 Session::set_midi_control (bool yn)
107 if (midi_control == yn) {
116 RWLockMonitor lm (route_lock, false, __LINE__, __FILE__);
117 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
118 (*i)->reset_midi_control (_midi_port, midi_control);
122 ControlChanged (MidiControl); /* EMIT SIGNAL */
126 Session::set_send_mtc (bool yn)
128 /* set the persistent option value regardless */
130 send_midi_timecode = yn;
133 /* only set the internal flag if we have
137 if (_mtc_port == 0 || send_mtc == yn) {
142 ControlChanged (SendMTC); /* EMIT SIGNAL */
146 Session::set_send_mmc (bool yn)
148 if (_mmc_port == 0) {
152 if (send_midi_machine_control == yn) {
156 /* only set the internal flag if we have
164 /* set the persistent option value regardless */
166 send_midi_machine_control = yn;
169 ControlChanged (SendMMC); /* EMIT SIGNAL */
173 Session::set_midi_feedback (bool yn)
178 Session::get_midi_feedback () const
184 Session::get_send_mtc () const
190 Session::get_send_mmc () const
196 Session::set_mtc_port (string port_tag)
200 if (port_tag.length() == 0) {
202 if (_slave && ((ms = dynamic_cast<MTC_Slave*> (_slave)) != 0)) {
203 error << _("Ardour is slaved to MTC - port cannot be reset") << endmsg;
207 if (_mtc_port == 0) {
217 if ((port = MIDI::Manager::instance()->port (port_tag)) == 0) {
218 error << string_compose (_("unknown port %1 requested for MTC"), port_tag) << endl;
224 if (_slave && ((ms = dynamic_cast<MTC_Slave*> (_slave)) != 0)) {
228 Config->set_mtc_port_name (port_tag);
231 MTC_PortChanged(); /* EMIT SIGNAL */
232 change_midi_ports ();
238 Session::set_mmc_port (string port_tag)
240 if (port_tag.length() == 0) {
241 if (_mmc_port == 0) {
250 if ((port = MIDI::Manager::instance()->port (port_tag)) == 0) {
260 mmc = new MIDI::MachineControl (*_mmc_port, 1.0,
261 MMC_CommandSignature,
262 MMC_ResponseSignature);
266 (mem_fun (*this, &Session::mmc_deferred_play));
267 mmc->DeferredPlay.connect
268 (mem_fun (*this, &Session::mmc_deferred_play));
270 (mem_fun (*this, &Session::mmc_stop));
271 mmc->FastForward.connect
272 (mem_fun (*this, &Session::mmc_fast_forward));
274 (mem_fun (*this, &Session::mmc_rewind));
276 (mem_fun (*this, &Session::mmc_pause));
277 mmc->RecordPause.connect
278 (mem_fun (*this, &Session::mmc_record_pause));
279 mmc->RecordStrobe.connect
280 (mem_fun (*this, &Session::mmc_record_strobe));
281 mmc->RecordExit.connect
282 (mem_fun (*this, &Session::mmc_record_exit));
284 (mem_fun (*this, &Session::mmc_locate));
286 (mem_fun (*this, &Session::mmc_step));
288 (mem_fun (*this, &Session::mmc_shuttle));
289 mmc->TrackRecordStatusChange.connect
290 (mem_fun (*this, &Session::mmc_record_enable));
292 /* also handle MIDI SPP because its so common */
294 _mmc_port->input()->start.connect (mem_fun (*this, &Session::spp_start));
295 _mmc_port->input()->contineu.connect (mem_fun (*this, &Session::spp_continue));
296 _mmc_port->input()->stop.connect (mem_fun (*this, &Session::spp_stop));
298 Config->set_mmc_port_name (port_tag);
301 MMC_PortChanged(); /* EMIT SIGNAL */
302 change_midi_ports ();
308 Session::set_midi_port (string port_tag)
310 if (port_tag.length() == 0) {
311 if (_midi_port == 0) {
320 if ((port = MIDI::Manager::instance()->port (port_tag)) == 0) {
326 /* XXX need something to forward this to control protocols ? or just
330 Config->set_midi_port_name (port_tag);
333 MIDI_PortChanged(); /* EMIT SIGNAL */
334 change_midi_ports ();
340 Session::set_trace_midi_input (bool yn, MIDI::Port* port)
342 MIDI::Parser* input_parser;
345 if ((input_parser = port->input()) != 0) {
346 input_parser->trace (yn, &cout, "input: ");
351 if ((input_parser = _mmc_port->input()) != 0) {
352 input_parser->trace (yn, &cout, "input: ");
356 if (_mtc_port && _mtc_port != _mmc_port) {
357 if ((input_parser = _mtc_port->input()) != 0) {
358 input_parser->trace (yn, &cout, "input: ");
362 if (_midi_port && _midi_port != _mmc_port && _midi_port != _mtc_port ) {
363 if ((input_parser = _midi_port->input()) != 0) {
364 input_parser->trace (yn, &cout, "input: ");
369 Config->set_trace_midi_input (yn);
373 Session::set_trace_midi_output (bool yn, MIDI::Port* port)
375 MIDI::Parser* output_parser;
378 if ((output_parser = port->output()) != 0) {
379 output_parser->trace (yn, &cout, "output: ");
383 if ((output_parser = _mmc_port->output()) != 0) {
384 output_parser->trace (yn, &cout, "output: ");
388 if (_mtc_port && _mtc_port != _mmc_port) {
389 if ((output_parser = _mtc_port->output()) != 0) {
390 output_parser->trace (yn, &cout, "output: ");
394 if (_midi_port && _midi_port != _mmc_port && _midi_port != _mtc_port ) {
395 if ((output_parser = _midi_port->output()) != 0) {
396 output_parser->trace (yn, &cout, "output: ");
402 Config->set_trace_midi_output (yn);
406 Session::get_trace_midi_input(MIDI::Port *port)
408 MIDI::Parser* input_parser;
410 if ((input_parser = port->input()) != 0) {
411 return input_parser->tracing();
416 if ((input_parser = _mmc_port->input()) != 0) {
417 return input_parser->tracing();
422 if ((input_parser = _mtc_port->input()) != 0) {
423 return input_parser->tracing();
428 if ((input_parser = _midi_port->input()) != 0) {
429 return input_parser->tracing();
438 Session::get_trace_midi_output(MIDI::Port *port)
440 MIDI::Parser* output_parser;
442 if ((output_parser = port->output()) != 0) {
443 return output_parser->tracing();
448 if ((output_parser = _mmc_port->output()) != 0) {
449 return output_parser->tracing();
454 if ((output_parser = _mtc_port->output()) != 0) {
455 return output_parser->tracing();
460 if ((output_parser = _midi_port->output()) != 0) {
461 return output_parser->tracing();
471 Session::setup_midi_control ()
473 outbound_mtc_smpte_frame = 0;
474 next_quarter_frame_to_send = 0;
476 /* setup the MMC buffer */
478 mmc_buffer[0] = 0xf0; // SysEx
479 mmc_buffer[1] = 0x7f; // Real Time SysEx ID for MMC
480 mmc_buffer[2] = 0x7f; // "broadcast" device ID
481 mmc_buffer[3] = 0x6; // MCC
483 /* Set up the qtr frame message */
494 if (_mmc_port != 0) {
496 send_mmc = send_midi_machine_control;
504 if (_mtc_port != 0) {
506 send_mtc = send_midi_timecode;
516 Session::midi_read (MIDI::Port* port)
520 /* reading from the MIDI port activates the Parser
521 that in turn generates signals that we care
522 about. the port is already set to NONBLOCK so that
523 can read freely here.
528 // cerr << "+++ READ ON " << port->name() << endl;
530 int nread = port->read (buf, sizeof (buf));
532 // cerr << "-- READ (" << nread << " ON " << port->name() << endl;
535 if ((size_t) nread < sizeof (buf)) {
540 } else if (nread == 0) {
542 } else if (errno == EAGAIN) {
545 fatal << string_compose(_("Error reading from MIDI port %1"), port->name()) << endmsg;
555 Session::spp_start (Parser& ignored)
557 if (mmc_control && (_slave_type != MTC)) {
558 request_transport_speed (1.0);
563 Session::spp_continue (Parser& ignored)
569 Session::spp_stop (Parser& ignored)
577 Session::mmc_deferred_play (MIDI::MachineControl &mmc)
579 if (mmc_control && (_slave_type != MTC)) {
580 request_transport_speed (1.0);
585 Session::mmc_record_pause (MIDI::MachineControl &mmc)
588 maybe_enable_record();
593 Session::mmc_record_strobe (MIDI::MachineControl &mmc)
598 /* record strobe does an implicit "Play" command */
600 if (_transport_speed != 1.0) {
602 /* start_transport() will move from Enabled->Recording, so we
603 don't need to do anything here except enable recording.
604 its not the same as maybe_enable_record() though, because
605 that *can* switch to Recording, which we do not want.
608 save_state ("", true);
609 atomic_set (&_record_status, Enabled);
610 RecordStateChanged (); /* EMIT SIGNAL */
612 request_transport_speed (1.0);
621 Session::mmc_record_exit (MIDI::MachineControl &mmc)
624 disable_record (false);
629 Session::mmc_stop (MIDI::MachineControl &mmc)
637 Session::mmc_pause (MIDI::MachineControl &mmc)
641 /* We support RECORD_PAUSE, so the spec says that
642 we must interpret PAUSE like RECORD_PAUSE if
646 if (actively_recording()) {
647 maybe_enable_record ();
654 static bool step_queued = false;
658 Session::mmc_step (MIDI::MachineControl &mmc, int steps)
665 struct timeval diff = { 0, 0 };
667 gettimeofday (&now, 0);
669 timersub (&now, &last_mmc_step, &diff);
671 gettimeofday (&now, 0);
672 timersub (&now, &last_mmc_step, &diff);
674 if (last_mmc_step.tv_sec != 0 && (diff.tv_usec + (diff.tv_sec * 1000000)) < _engine.usecs_per_cycle()) {
678 double diff_secs = diff.tv_sec + (diff.tv_usec / 1000000.0);
679 double cur_speed = (((steps * 0.5) * smpte_frames_per_second) / diff_secs) / smpte_frames_per_second;
681 if (_transport_speed == 0 || cur_speed * _transport_speed < 0) {
682 /* change direction */
683 step_speed = cur_speed;
685 step_speed = (0.6 * step_speed) + (0.4 * cur_speed);
691 cerr << "delta = " << diff_secs
692 << " ct = " << _transport_speed
693 << " steps = " << steps
694 << " new speed = " << cur_speed
695 << " speed = " << step_speed
699 request_transport_speed (step_speed);
703 midi_timeouts.push_back (mem_fun (*this, &Session::mmc_step_timeout));
709 Session::mmc_rewind (MIDI::MachineControl &mmc)
712 request_transport_speed(-8.0f);
717 Session::mmc_fast_forward (MIDI::MachineControl &mmc)
720 request_transport_speed(8.0f);
725 Session::mmc_locate (MIDI::MachineControl &mmc, const MIDI::byte* mmc_tc)
731 jack_nframes_t target_frame;
734 smpte.hours = mmc_tc[0] & 0xf;
735 smpte.minutes = mmc_tc[1];
736 smpte.seconds = mmc_tc[2];
737 smpte.frames = mmc_tc[3];
739 // Also takes smpte offset into account:
740 smpte_to_sample( smpte, target_frame, true /* use_offset */, false /* use_subframes */ );
742 if (target_frame > max_frames) {
743 target_frame = max_frames;
746 /* Some (all?) MTC/MMC devices do not send a full MTC frame
747 at the end of a locate, instead sending only an MMC
748 locate command. This causes the current position
749 of an MTC slave to become out of date. Catch this.
752 MTC_Slave* mtcs = dynamic_cast<MTC_Slave*> (_slave);
755 // cerr << "Locate *with* MTC slave\n";
756 mtcs->handle_locate (mmc_tc);
758 // cerr << "Locate without MTC slave\n";
759 request_locate (target_frame, false);
764 Session::mmc_shuttle (MIDI::MachineControl &mmc, float speed, bool forw)
766 cerr << "MMC shuttle, speed = " << speed << endl;
772 if (shuttle_speed_threshold >= 0 && speed > shuttle_speed_threshold) {
773 speed *= shuttle_speed_factor;
776 cerr << "requested MMC control speed = " << speed << endl;
779 request_transport_speed (speed);
781 request_transport_speed (-speed);
786 Session::mmc_record_enable (MIDI::MachineControl &mmc, size_t trk, bool enabled)
790 RouteList::iterator i;
791 RWLockMonitor (route_lock, false, __LINE__, __FILE__);
793 for (i = routes.begin(); i != routes.end(); ++i) {
796 if ((at = dynamic_cast<AudioTrack*>(*i)) != 0) {
797 if (trk == at->remote_control_id()) {
798 at->set_record_enable (enabled, &mmc);
808 Session::change_midi_ports ()
811 MIDIRequest* request = new MIDIRequest;
813 request->type = MIDIRequest::PortChange;
814 midi_requests.write (&request, 1);
819 /** Send MTC Full Frame message (complete SMPTE time) for the start of this cycle.
820 * Audio thread only, realtime safe. MIDI::Manager::cycle_start must
821 * have been called with the appropriate nframes parameter this cycle.
824 Session::send_full_time_code(jack_nframes_t nframes)
826 /* This function could easily send at a given frame offset, but would
827 * that be useful? [DR] */
832 _send_smpte_update = false;
834 if (_mtc_port == 0 || !send_mtc) {
838 // Get smpte time for this transport frame
839 sample_to_smpte(_transport_frame, smpte, true /* use_offset */, false /* no subframes */);
841 // Check for negative smpte time and prepare for quarter frame transmission
842 assert(!smpte.negative); // this shouldn't happen
843 if (smpte.negative) {
844 // Negative mtc is not defined, so sync slave to smpte zero.
845 // When _transport_frame gets there we will start transmitting quarter frames
851 smpte.negative = false;
852 smpte_to_sample( smpte, outbound_mtc_smpte_frame, true, false );
853 transmitting_smpte_time = smpte;
855 transmitting_smpte_time = smpte;
856 outbound_mtc_smpte_frame = _transport_frame;
857 if (((mtc_smpte_bits >> 5) != MIDI::MTC_25_FPS) && (transmitting_smpte_time.frames % 2)) {
858 // start MTC quarter frame transmission on an even frame
859 SMPTE::increment( transmitting_smpte_time );
860 outbound_mtc_smpte_frame += (jack_nframes_t) _frames_per_smpte_frame;
864 // Compensate for audio latency
865 outbound_mtc_smpte_frame += _worst_output_latency;
867 next_quarter_frame_to_send = 0;
869 // Sync slave to the same smpte time as we are on (except if negative, see above)
877 msg[5] = mtc_smpte_bits | smpte.hours;
878 msg[6] = smpte.minutes;
879 msg[7] = smpte.seconds;
880 msg[8] = smpte.frames;
882 // Send message at offset 0, sent time is for the start of this cycle
883 if (!_mtc_port->midimsg (msg, sizeof (msg), 0)) {
884 error << _("Session: could not send full MIDI time code") << endmsg;
891 /** Sends all time code messages for this cycle.
892 * Must be called exactly once per cycle from the audio thread. Realtime safe.
893 * This function assumes the state of full SMPTE is sane, eg. the slave is
894 * expecting quarter frame messages and has the right frame of reference (any
895 * full MTC SMPTE time messages that needed to be sent should have been sent
896 * earlier in the cycle).
899 Session::send_midi_time_code_for_cycle(jack_nframes_t nframes)
901 //cerr << "----------------------" << endl;
903 // FIXME: remove, just for debug print statement
904 static jack_nframes_t last_time = 0;
906 assert (next_quarter_frame_to_send >= 0);
908 if (_mtc_port == 0 || !send_mtc || transmitting_smpte_time.negative
909 /*|| (next_quarter_frame_to_send < 0)*/ ) {
910 printf("Not sending MTC\n");
914 /* Duration of one quarter frame */
915 jack_nframes_t quarter_frame_duration = ((long) _frames_per_smpte_frame) >> 2;
917 // FIXME: what was transmitting_smpte_time before??
918 //smpte_time(_transport_frame, transmitting_smpte_time);
919 //smpte_to_sample( transmitting_smpte_time, outbound_mtc_smpte_frame, true /* use_offset */, false );
923 if (_send_smpte_update) {
924 // Send full SMPTE time and reset quarter frames
925 cerr << "[DR] Sending full SMTPE update" << endl;
926 // Re-calculate timing of first quarter frame
927 smpte_to_sample( transmitting_smpte_time, outbound_mtc_smpte_frame, true /* use_offset */, false );
928 // Compensate for audio latency
929 //outbound_mtc_smpte_frame += _worst_output_latency;
930 send_full_time_code(nframes);
931 _send_smpte_update = false;
932 next_quarter_frame_to_send = 0;
936 //cerr << "A - " << _transport_frame << " - " << outbound_mtc_smpte_frame
937 //<< " - " << next_quarter_frame_to_send << " - " << quarter_frame_duration << endl;
939 // Note: Unlike the previous implementation of this function (for slow MIDI I/O),
940 // this now sends all MTC messages for _this_ frame, not messages from the past
941 // up until the start of the current frame (any messages in the past must have
942 // been sent last cycle). This assertion enforces this:
943 //assert(outbound_mtc_smpte_frame >= _transport_frame
944 // && (outbound_mtc_smpte_frame - _transport_frame) < nframes);
945 /*if ( ! (outbound_mtc_smpte_frame >= _transport_frame
946 && (outbound_mtc_smpte_frame - _transport_frame) < nframes)) { */
947 if (outbound_mtc_smpte_frame + (next_quarter_frame_to_send * quarter_frame_duration)
948 < _transport_frame) {
949 cerr << "[MTC] ERROR: MTC message stamped " << outbound_mtc_smpte_frame
950 << " in cycle starting " << _transport_frame << endl;
953 //cerr << "[MTC] OK" << endl;
956 // Send quarter frames for this cycle
957 while (_transport_frame + nframes > (outbound_mtc_smpte_frame +
958 (next_quarter_frame_to_send * quarter_frame_duration))) {
960 //cerr << "B: Next frame to send: " << next_quarter_frame_to_send << endl;
962 switch (next_quarter_frame_to_send) {
964 mtc_msg[1] = 0x00 | (transmitting_smpte_time.frames & 0xf);
967 mtc_msg[1] = 0x10 | ((transmitting_smpte_time.frames & 0xf0) >> 4);
970 mtc_msg[1] = 0x20 | (transmitting_smpte_time.seconds & 0xf);
973 mtc_msg[1] = 0x30 | ((transmitting_smpte_time.seconds & 0xf0) >> 4);
976 mtc_msg[1] = 0x40 | (transmitting_smpte_time.minutes & 0xf);
979 mtc_msg[1] = 0x50 | ((transmitting_smpte_time.minutes & 0xf0) >> 4);
982 mtc_msg[1] = 0x60 | ((mtc_smpte_bits|transmitting_smpte_time.hours) & 0xf);
985 mtc_msg[1] = 0x70 | (((mtc_smpte_bits|transmitting_smpte_time.hours) & 0xf0) >> 4);
989 jack_nframes_t msg_time = (outbound_mtc_smpte_frame
990 + (quarter_frame_duration * next_quarter_frame_to_send));
991 assert(msg_time >= _transport_frame);
992 assert(msg_time < _transport_frame + nframes);
994 jack_nframes_t out_stamp = msg_time - _transport_frame;
995 assert(out_stamp < nframes);
997 if (!_mtc_port->midimsg (mtc_msg, 2, out_stamp)) {
998 error << string_compose(_("Session: cannot send quarter-frame MTC message (%1)"), strerror (errno))
1003 /*cerr << "smpte = " << transmitting_smpte_time.hours
1004 << ":" << transmitting_smpte_time.minutes
1005 << ":" << transmitting_smpte_time.seconds
1006 << ":" << transmitting_smpte_time.frames
1007 << ", qfm = " << next_quarter_frame_to_send
1008 << ", stamp = " << out_stamp
1009 << ", delta = " << _transport_frame + out_stamp - last_time << endl;*/
1011 last_time = _transport_frame + out_stamp;
1013 // Increment quarter frame counter
1014 next_quarter_frame_to_send++;
1016 if (next_quarter_frame_to_send >= 8) {
1017 // Wrap quarter frame counter
1018 next_quarter_frame_to_send = 0;
1019 // Increment smpte time twice
1020 SMPTE::increment( transmitting_smpte_time );
1021 SMPTE::increment( transmitting_smpte_time );
1022 // Re-calculate timing of first quarter frame
1023 //smpte_to_sample( transmitting_smpte_time, outbound_mtc_smpte_frame, true /* use_offset */, false );
1024 outbound_mtc_smpte_frame += 8 * quarter_frame_duration;
1025 // Compensate for audio latency
1026 outbound_mtc_smpte_frame += _worst_output_latency;
1033 /***********************************************************************
1035 **********************************************************************/
1038 Session::send_mmc_in_another_thread (MIDI::MachineControl::Command cmd, jack_nframes_t target_frame)
1040 MIDIRequest* request;
1042 if (_mtc_port == 0 || !send_mmc) {
1046 request = new MIDIRequest;
1047 request->type = MIDIRequest::SendMMC;
1048 request->mmc_cmd = cmd;
1049 request->locate_frame = target_frame;
1051 midi_requests.write (&request, 1);
1052 poke_midi_thread ();
1056 Session::deliver_mmc (MIDI::MachineControl::Command cmd, jack_nframes_t where)
1059 using namespace MIDI;
1063 if (_mmc_port == 0 || !send_mmc) {
1067 mmc_buffer[nbytes++] = cmd;
1069 // cerr << "delivering MMC, cmd = " << hex << (int) cmd << dec << endl;
1072 case MachineControl::cmdLocate:
1073 smpte_time_subframes (where, smpte);
1075 mmc_buffer[nbytes++] = 0x6; // byte count
1076 mmc_buffer[nbytes++] = 0x1; // "TARGET" subcommand
1077 mmc_buffer[nbytes++] = smpte.hours;
1078 mmc_buffer[nbytes++] = smpte.minutes;
1079 mmc_buffer[nbytes++] = smpte.seconds;
1080 mmc_buffer[nbytes++] = smpte.frames;
1081 mmc_buffer[nbytes++] = smpte.subframes;
1084 case MachineControl::cmdStop:
1087 case MachineControl::cmdPlay:
1088 /* always convert Play into Deferred Play */
1089 mmc_buffer[4] = MachineControl::cmdDeferredPlay;
1092 case MachineControl::cmdDeferredPlay:
1095 case MachineControl::cmdRecordStrobe:
1098 case MachineControl::cmdRecordExit:
1101 case MachineControl::cmdRecordPause:
1110 mmc_buffer[nbytes++] = 0xf7; // terminate SysEx/MMC message
1112 LockMonitor lm (midi_lock, __LINE__, __FILE__);
1114 if (_mmc_port->write (mmc_buffer, nbytes) != nbytes) {
1115 error << string_compose(_("MMC: cannot send command %1%2%3"), &hex, cmd, &dec) << endmsg;
1119 cout << "MMC support broken." << endl;
1123 Session::mmc_step_timeout ()
1126 struct timeval diff;
1128 gettimeofday (&now, 0);
1130 timersub (&now, &last_mmc_step, &diff);
1131 diff_usecs = diff.tv_sec * 1000000 + diff.tv_usec;
1133 if (diff_usecs > 1000000.0 || fabs (_transport_speed) < 0.0000001) {
1134 /* too long or too slow, stop transport */
1135 request_transport_speed (0.0);
1136 step_queued = false;
1140 if (diff_usecs < 250000.0) {
1141 /* too short, just keep going */
1147 request_transport_speed (_transport_speed * 0.75);
1153 Session::send_midi_message (MIDI::Port * port, MIDI::eventType ev, MIDI::channel_t ch, MIDI::EventTwoBytes data)
1155 // in another thread, really
1157 MIDIRequest* request = new MIDIRequest;
1159 request->type = MIDIRequest::SendMessage;
1160 request->port = port;
1163 request->data = data;
1165 midi_requests.write (&request, 1);
1166 poke_midi_thread ();
1171 Session::deliver_midi (MIDI::Port * port, MIDI::byte* buf, int32_t bufsize)
1173 // in another thread, really
1175 MIDIRequest* request = new MIDIRequest;
1177 request->type = MIDIRequest::Deliver;
1178 request->port = port;
1180 request->size = bufsize;
1182 midi_requests.write (&request, 1);
1183 poke_midi_thread ();
1189 Session::deliver_midi_message (MIDI::Port * port, MIDI::eventType ev, MIDI::channel_t ch, MIDI::EventTwoBytes data)
1191 if (port == 0 || ev == MIDI::none) {
1195 midi_msg[0] = (ev & 0xF0) | (ch & 0xF);
1196 midi_msg[1] = data.controller_number;
1197 midi_msg[2] = data.value;
1199 port->write (midi_msg, 3);
1203 Session::deliver_data (MIDI::Port * port, MIDI::byte* buf, int32_t size)
1206 port->write (buf, size);
1209 /* this is part of the semantics of the Deliver request */
1216 /*---------------------------------------------------------------------------
1218 ---------------------------------------------------------------------------*/
1222 Session::start_midi_thread ()
1224 if (pipe (midi_request_pipe)) {
1225 error << string_compose(_("Cannot create transport request signal pipe (%1)"), strerror (errno)) << endmsg;
1229 if (fcntl (midi_request_pipe[0], F_SETFL, O_NONBLOCK)) {
1230 error << string_compose(_("UI: cannot set O_NONBLOCK on " "signal read pipe (%1)"), strerror (errno)) << endmsg;
1234 if (fcntl (midi_request_pipe[1], F_SETFL, O_NONBLOCK)) {
1235 error << string_compose(_("UI: cannot set O_NONBLOCK on " "signal write pipe (%1)"), strerror (errno)) << endmsg;
1239 if (pthread_create_and_store ("transport", &midi_thread, 0, _midi_thread_work, this)) {
1240 error << _("Session: could not create transport thread") << endmsg;
1244 // pthread_detach (midi_thread);
1250 Session::terminate_midi_thread ()
1252 MIDIRequest* request = new MIDIRequest;
1255 request->type = MIDIRequest::Quit;
1257 midi_requests.write (&request, 1);
1258 poke_midi_thread ();
1260 pthread_join (midi_thread, &status);
1264 Session::poke_midi_thread ()
1268 if (write (midi_request_pipe[1], &c, 1) != 1) {
1269 error << string_compose(_("cannot send signal to midi thread! (%1)"), strerror (errno)) << endmsg;
1274 Session::_midi_thread_work (void* arg)
1276 pthread_setcancelstate (PTHREAD_CANCEL_ENABLE, 0);
1277 pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, 0);
1279 ((Session *) arg)->midi_thread_work ();
1284 Session::midi_thread_work ()
1286 MIDIRequest* request;
1287 struct pollfd pfd[4];
1291 struct sched_param rtparam;
1294 vector<MIDI::Port*> ports;
1296 PBD::ThreadCreatedWithRequestSize (pthread_self(), X_("MIDI"), 2048);
1298 memset (&rtparam, 0, sizeof (rtparam));
1299 rtparam.sched_priority = 9; /* XXX should be relative to audio (JACK) thread */
1301 if ((x = pthread_setschedparam (pthread_self(), SCHED_FIFO, &rtparam)) != 0) {
1302 // do we care? not particularly.
1305 /* set up the port vector; 4 is the largest possible size for now */
1307 ports.push_back (0);
1308 ports.push_back (0);
1309 ports.push_back (0);
1310 ports.push_back (0);
1316 pfd[nfds].fd = midi_request_pipe[0];
1317 pfd[nfds].events = POLLIN|POLLHUP|POLLERR;
1320 /* if we are using MMC control, we obviously have to listen
1321 on the appropriate port.
1324 if (mmc_control && _mmc_port && _mmc_port->selectable() >= 0) {
1325 pfd[nfds].fd = _mmc_port->selectable();
1326 pfd[nfds].events = POLLIN|POLLHUP|POLLERR;
1327 ports[nfds] = _mmc_port;
1331 /* if MTC is being handled on a different port from MMC
1332 or we are not handling MMC at all, poll
1336 if (_mtc_port && (_mtc_port != _mmc_port || !mmc_control) && _mtc_port->selectable() >= 0) {
1337 pfd[nfds].fd = _mtc_port->selectable();
1338 pfd[nfds].events = POLLIN|POLLHUP|POLLERR;
1339 ports[nfds] = _mtc_port;
1343 if (_midi_port && (_midi_port != _mmc_port || !mmc_control) && (_midi_port != _mtc_port) && _midi_port->selectable() >= 0) {
1344 pfd[nfds].fd = _midi_port->selectable();
1345 pfd[nfds].events = POLLIN|POLLHUP|POLLERR;
1346 ports[nfds] = _midi_port;
1350 if (!midi_timeouts.empty()) {
1351 timeout = 100; /* 10msecs */
1353 timeout = -1; /* if there is no data, we don't care */
1357 // cerr << "MIDI poll on " << nfds << " for " << timeout << endl;
1358 if (poll (pfd, nfds, timeout) < 0) {
1359 if (errno == EINTR) {
1360 /* gdb at work, perhaps */
1364 error << string_compose(_("MIDI thread poll failed (%1)"), strerror (errno)) << endmsg;
1368 // cerr << "MIDI thread wakes at " << get_cycles () << endl;
1373 /* check the transport request pipe */
1375 if (pfd[0].revents & ~POLLIN) {
1376 error << _("Error on transport thread request pipe") << endmsg;
1380 if (pfd[0].revents & POLLIN) {
1384 // cerr << "MIDI request FIFO ready\n";
1387 /* empty the pipe of all current requests */
1390 size_t nread = read (midi_request_pipe[0], &foo, sizeof (foo));
1393 if ((size_t) nread < sizeof (foo)) {
1398 } else if (nread == 0) {
1400 } else if (errno == EAGAIN) {
1403 fatal << _("Error reading from transport request pipe") << endmsg;
1408 while (midi_requests.read (&request, 1) == 1) {
1410 switch (request->type) {
1412 case MIDIRequest::SendFullMTC:
1413 // cerr << "send full MTC\n";
1414 send_full_time_code ();
1415 // cerr << "... done\n";
1418 case MIDIRequest::SendMTC:
1419 // cerr << "send qtr MTC\n";
1420 send_midi_time_code ();
1421 // cerr << "... done\n";
1424 case MIDIRequest::SendMMC:
1425 // cerr << "send MMC\n";
1426 deliver_mmc (request->mmc_cmd, request->locate_frame);
1427 // cerr << "... done\n";
1430 case MIDIRequest::SendMessage:
1431 // cerr << "send Message\n";
1432 deliver_midi_message (request->port, request->ev, request->chan, request->data);
1433 // cerr << "... done\n";
1436 case MIDIRequest::Deliver:
1437 // cerr << "deliver\n";
1438 deliver_data (_midi_port, request->buf, request->size);
1439 // cerr << "... done\n";
1442 case MIDIRequest::PortChange:
1443 /* restart poll with new ports */
1444 // cerr << "rebind\n";
1448 case MIDIRequest::Quit:
1450 pthread_exit_pbd (0);
1468 /* now read the rest of the ports */
1470 for (int p = 1; p < nfds; ++p) {
1471 if ((pfd[p].revents & ~POLLIN)) {
1472 // error << string_compose(_("Transport: error polling MIDI port %1 (revents =%2%3%4"), p, &hex, pfd[p].revents, &dec) << endmsg;
1476 if (pfd[p].revents & POLLIN) {
1478 midi_read (ports[p]);
1482 /* timeout driven */
1484 if (fds_ready < 2 && timeout != -1) {
1486 for (MidiTimeoutList::iterator i = midi_timeouts.begin(); i != midi_timeouts.end(); ) {
1488 MidiTimeoutList::iterator tmp;
1493 midi_timeouts.erase (i);
1504 Session::get_mmc_control () const
1510 Session::get_midi_control () const
1512 return midi_control;