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 <glibmm/thread.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/audio_diskstream.h>
41 #include <ardour/slave.h>
42 #include <ardour/cycles.h>
47 using namespace ARDOUR;
51 MachineControl::CommandSignature MMC_CommandSignature;
52 MachineControl::ResponseSignature MMC_ResponseSignature;
54 MultiAllocSingleReleasePool Session::MIDIRequest::pool ("midi", sizeof (Session::MIDIRequest), 1024);
57 Session::use_config_midi_ports ()
61 if (default_mmc_port) {
62 set_mmc_port (default_mmc_port->name());
67 if (default_mtc_port) {
68 set_mtc_port (default_mtc_port->name());
73 if (default_midi_port) {
74 set_midi_port (default_midi_port->name());
83 /***********************************************************************
85 **********************************************************************/
88 Session::set_mmc_control (bool yn)
90 if (mmc_control == yn) {
98 ControlChanged (MMCControl); /* EMIT SIGNAL */
102 Session::set_midi_control (bool yn)
104 if (midi_control == yn) {
112 ControlChanged (MidiControl); /* EMIT SIGNAL */
116 Session::set_send_mtc (bool yn)
118 /* set the persistent option value regardless */
120 send_midi_timecode = yn;
123 /* only set the internal flag if we have
127 if (_mtc_port == 0 || send_mtc == yn) {
132 ControlChanged (SendMTC); /* EMIT SIGNAL */
136 Session::set_send_mmc (bool yn)
138 if (_mmc_port == 0) {
142 if (send_midi_machine_control == yn) {
146 /* only set the internal flag if we have
154 /* set the persistent option value regardless */
156 send_midi_machine_control = yn;
159 ControlChanged (SendMMC); /* EMIT SIGNAL */
163 Session::set_midi_feedback (bool yn)
168 Session::get_midi_feedback () const
174 Session::get_send_mtc () const
180 Session::get_send_mmc () const
186 Session::set_mtc_port (string port_tag)
190 if (port_tag.length() == 0) {
192 if (_slave && ((ms = dynamic_cast<MTC_Slave*> (_slave)) != 0)) {
193 error << _("Ardour is slaved to MTC - port cannot be reset") << endmsg;
197 if (_mtc_port == 0) {
207 if ((port = MIDI::Manager::instance()->port (port_tag)) == 0) {
208 error << string_compose (_("unknown port %1 requested for MTC"), port_tag) << endl;
214 if (_slave && ((ms = dynamic_cast<MTC_Slave*> (_slave)) != 0)) {
218 Config->set_mtc_port_name (port_tag);
221 MTC_PortChanged(); /* EMIT SIGNAL */
222 change_midi_ports ();
228 Session::set_mmc_port (string port_tag)
230 if (port_tag.length() == 0) {
231 if (_mmc_port == 0) {
240 if ((port = MIDI::Manager::instance()->port (port_tag)) == 0) {
250 mmc = new MIDI::MachineControl (*_mmc_port, 1.0,
251 MMC_CommandSignature,
252 MMC_ResponseSignature);
256 (mem_fun (*this, &Session::mmc_deferred_play));
257 mmc->DeferredPlay.connect
258 (mem_fun (*this, &Session::mmc_deferred_play));
260 (mem_fun (*this, &Session::mmc_stop));
261 mmc->FastForward.connect
262 (mem_fun (*this, &Session::mmc_fast_forward));
264 (mem_fun (*this, &Session::mmc_rewind));
266 (mem_fun (*this, &Session::mmc_pause));
267 mmc->RecordPause.connect
268 (mem_fun (*this, &Session::mmc_record_pause));
269 mmc->RecordStrobe.connect
270 (mem_fun (*this, &Session::mmc_record_strobe));
271 mmc->RecordExit.connect
272 (mem_fun (*this, &Session::mmc_record_exit));
274 (mem_fun (*this, &Session::mmc_locate));
276 (mem_fun (*this, &Session::mmc_step));
278 (mem_fun (*this, &Session::mmc_shuttle));
279 mmc->TrackRecordStatusChange.connect
280 (mem_fun (*this, &Session::mmc_record_enable));
282 /* also handle MIDI SPP because its so common */
284 _mmc_port->input()->start.connect (mem_fun (*this, &Session::spp_start));
285 _mmc_port->input()->contineu.connect (mem_fun (*this, &Session::spp_continue));
286 _mmc_port->input()->stop.connect (mem_fun (*this, &Session::spp_stop));
288 Config->set_mmc_port_name (port_tag);
291 MMC_PortChanged(); /* EMIT SIGNAL */
292 change_midi_ports ();
298 Session::set_midi_port (string port_tag)
300 if (port_tag.length() == 0) {
301 if (_midi_port == 0) {
310 if ((port = MIDI::Manager::instance()->port (port_tag)) == 0) {
316 /* XXX need something to forward this to control protocols ? or just
320 Config->set_midi_port_name (port_tag);
323 MIDI_PortChanged(); /* EMIT SIGNAL */
324 change_midi_ports ();
330 Session::set_trace_midi_input (bool yn, MIDI::Port* port)
332 MIDI::Parser* input_parser;
335 if ((input_parser = port->input()) != 0) {
336 input_parser->trace (yn, &cout, "input: ");
341 if ((input_parser = _mmc_port->input()) != 0) {
342 input_parser->trace (yn, &cout, "input: ");
346 if (_mtc_port && _mtc_port != _mmc_port) {
347 if ((input_parser = _mtc_port->input()) != 0) {
348 input_parser->trace (yn, &cout, "input: ");
352 if (_midi_port && _midi_port != _mmc_port && _midi_port != _mtc_port ) {
353 if ((input_parser = _midi_port->input()) != 0) {
354 input_parser->trace (yn, &cout, "input: ");
359 Config->set_trace_midi_input (yn);
363 Session::set_trace_midi_output (bool yn, MIDI::Port* port)
365 MIDI::Parser* output_parser;
368 if ((output_parser = port->output()) != 0) {
369 output_parser->trace (yn, &cout, "output: ");
373 if ((output_parser = _mmc_port->output()) != 0) {
374 output_parser->trace (yn, &cout, "output: ");
378 if (_mtc_port && _mtc_port != _mmc_port) {
379 if ((output_parser = _mtc_port->output()) != 0) {
380 output_parser->trace (yn, &cout, "output: ");
384 if (_midi_port && _midi_port != _mmc_port && _midi_port != _mtc_port ) {
385 if ((output_parser = _midi_port->output()) != 0) {
386 output_parser->trace (yn, &cout, "output: ");
392 Config->set_trace_midi_output (yn);
396 Session::get_trace_midi_input(MIDI::Port *port)
398 MIDI::Parser* input_parser;
400 if ((input_parser = port->input()) != 0) {
401 return input_parser->tracing();
406 if ((input_parser = _mmc_port->input()) != 0) {
407 return input_parser->tracing();
412 if ((input_parser = _mtc_port->input()) != 0) {
413 return input_parser->tracing();
418 if ((input_parser = _midi_port->input()) != 0) {
419 return input_parser->tracing();
428 Session::get_trace_midi_output(MIDI::Port *port)
430 MIDI::Parser* output_parser;
432 if ((output_parser = port->output()) != 0) {
433 return output_parser->tracing();
438 if ((output_parser = _mmc_port->output()) != 0) {
439 return output_parser->tracing();
444 if ((output_parser = _mtc_port->output()) != 0) {
445 return output_parser->tracing();
450 if ((output_parser = _midi_port->output()) != 0) {
451 return output_parser->tracing();
461 Session::setup_midi_control ()
463 outbound_mtc_smpte_frame = 0;
464 next_quarter_frame_to_send = -1;
466 /* setup the MMC buffer */
468 mmc_buffer[0] = 0xf0; // SysEx
469 mmc_buffer[1] = 0x7f; // Real Time SysEx ID for MMC
470 mmc_buffer[2] = 0x7f; // "broadcast" device ID
471 mmc_buffer[3] = 0x6; // MCC
473 /* Set up the qtr frame message */
484 if (_mmc_port != 0) {
486 send_mmc = send_midi_machine_control;
494 if (_mtc_port != 0) {
496 send_mtc = send_midi_timecode;
505 Session::midi_read (MIDI::Port* port)
509 /* reading from the MIDI port activates the Parser
510 that in turn generates signals that we care
511 about. the port is already set to NONBLOCK so that
512 can read freely here.
517 // cerr << "+++ READ ON " << port->name() << endl;
519 int nread = port->read (buf, sizeof (buf));
521 // cerr << "-- READ (" << nread << " ON " << port->name() << endl;
524 if ((size_t) nread < sizeof (buf)) {
529 } else if (nread == 0) {
531 } else if (errno == EAGAIN) {
534 fatal << string_compose(_("Error reading from MIDI port %1"), port->name()) << endmsg;
543 Session::spp_start (Parser& ignored)
545 if (mmc_control && (_slave_type != MTC)) {
546 request_transport_speed (1.0);
551 Session::spp_continue (Parser& ignored)
557 Session::spp_stop (Parser& ignored)
565 Session::mmc_deferred_play (MIDI::MachineControl &mmc)
567 if (mmc_control && (_slave_type != MTC)) {
568 request_transport_speed (1.0);
573 Session::mmc_record_pause (MIDI::MachineControl &mmc)
576 maybe_enable_record();
581 Session::mmc_record_strobe (MIDI::MachineControl &mmc)
586 /* record strobe does an implicit "Play" command */
588 if (_transport_speed != 1.0) {
590 /* start_transport() will move from Enabled->Recording, so we
591 don't need to do anything here except enable recording.
592 its not the same as maybe_enable_record() though, because
593 that *can* switch to Recording, which we do not want.
596 save_state ("", true);
598 g_atomic_int_set (&_record_status, Enabled);
599 RecordStateChanged (); /* EMIT SIGNAL */
601 request_transport_speed (1.0);
610 Session::mmc_record_exit (MIDI::MachineControl &mmc)
613 disable_record (false);
618 Session::mmc_stop (MIDI::MachineControl &mmc)
626 Session::mmc_pause (MIDI::MachineControl &mmc)
630 /* We support RECORD_PAUSE, so the spec says that
631 we must interpret PAUSE like RECORD_PAUSE if
635 if (actively_recording()) {
636 maybe_enable_record ();
643 static bool step_queued = false;
647 Session::mmc_step (MIDI::MachineControl &mmc, int steps)
654 struct timeval diff = { 0, 0 };
656 gettimeofday (&now, 0);
658 timersub (&now, &last_mmc_step, &diff);
660 gettimeofday (&now, 0);
661 timersub (&now, &last_mmc_step, &diff);
663 if (last_mmc_step.tv_sec != 0 && (diff.tv_usec + (diff.tv_sec * 1000000)) < _engine.usecs_per_cycle()) {
667 double diff_secs = diff.tv_sec + (diff.tv_usec / 1000000.0);
668 double cur_speed = (((steps * 0.5) * smpte_frames_per_second) / diff_secs) / smpte_frames_per_second;
670 if (_transport_speed == 0 || cur_speed * _transport_speed < 0) {
671 /* change direction */
672 step_speed = cur_speed;
674 step_speed = (0.6 * step_speed) + (0.4 * cur_speed);
680 cerr << "delta = " << diff_secs
681 << " ct = " << _transport_speed
682 << " steps = " << steps
683 << " new speed = " << cur_speed
684 << " speed = " << step_speed
688 request_transport_speed (step_speed);
692 midi_timeouts.push_back (mem_fun (*this, &Session::mmc_step_timeout));
698 Session::mmc_rewind (MIDI::MachineControl &mmc)
701 request_transport_speed(-8.0f);
706 Session::mmc_fast_forward (MIDI::MachineControl &mmc)
709 request_transport_speed(8.0f);
714 Session::mmc_locate (MIDI::MachineControl &mmc, const MIDI::byte* mmc_tc)
720 jack_nframes_t target_frame;
723 smpte.hours = mmc_tc[0] & 0xf;
724 smpte.minutes = mmc_tc[1];
725 smpte.seconds = mmc_tc[2];
726 smpte.frames = mmc_tc[3];
728 // Also takes smpte offset into account:
729 smpte_to_sample( smpte, target_frame, true /* use_offset */, false /* use_subframes */ );
731 if (target_frame > max_frames) {
732 target_frame = max_frames;
735 /* Some (all?) MTC/MMC devices do not send a full MTC frame
736 at the end of a locate, instead sending only an MMC
737 locate command. This causes the current position
738 of an MTC slave to become out of date. Catch this.
741 MTC_Slave* mtcs = dynamic_cast<MTC_Slave*> (_slave);
744 // cerr << "Locate *with* MTC slave\n";
745 mtcs->handle_locate (mmc_tc);
747 // cerr << "Locate without MTC slave\n";
748 request_locate (target_frame, false);
753 Session::mmc_shuttle (MIDI::MachineControl &mmc, float speed, bool forw)
755 cerr << "MMC shuttle, speed = " << speed << endl;
761 if (shuttle_speed_threshold >= 0 && speed > shuttle_speed_threshold) {
762 speed *= shuttle_speed_factor;
765 cerr << "requested MMC control speed = " << speed << endl;
768 request_transport_speed (speed);
770 request_transport_speed (-speed);
775 Session::mmc_record_enable (MIDI::MachineControl &mmc, size_t trk, bool enabled)
779 RouteList::iterator i;
780 boost::shared_ptr<RouteList> r = routes.reader();
782 for (i = r->begin(); i != r->end(); ++i) {
785 if ((at = dynamic_cast<AudioTrack*>((*i).get())) != 0) {
786 if (trk == at->remote_control_id()) {
787 at->set_record_enable (enabled, &mmc);
796 Session::send_full_time_code_in_another_thread ()
798 send_time_code_in_another_thread (true);
802 Session::send_midi_time_code_in_another_thread ()
804 send_time_code_in_another_thread (false);
808 Session::send_time_code_in_another_thread (bool full)
810 jack_nframes_t two_smpte_frames_duration;
811 jack_nframes_t quarter_frame_duration;
813 /* Duration of two smpte frames */
814 two_smpte_frames_duration = ((long) _frames_per_smpte_frame) << 1;
816 /* Duration of one quarter frame */
817 quarter_frame_duration = ((long) _frames_per_smpte_frame) >> 2;
819 if (_transport_frame < (outbound_mtc_smpte_frame + (next_quarter_frame_to_send * quarter_frame_duration)))
821 /* There is no work to do.
822 We throttle this here so that we don't overload
823 the transport thread with requests.
828 MIDIRequest* request = new MIDIRequest;
831 request->type = MIDIRequest::SendFullMTC;
833 request->type = MIDIRequest::SendMTC;
836 midi_requests.write (&request, 1);
841 Session::change_midi_ports ()
843 MIDIRequest* request = new MIDIRequest;
845 request->type = MIDIRequest::PortChange;
846 midi_requests.write (&request, 1);
851 Session::send_full_time_code ()
857 if (_mtc_port == 0 || !send_mtc) {
861 // Get smpte time for this transport frame
862 sample_to_smpte(_transport_frame, smpte, true /* use_offset */, false /* no subframes */);
864 // Check for negative smpte time and prepare for quarter frame transmission
865 if (smpte.negative) {
866 // Negative mtc is not defined, so sync slave to smpte zero.
867 // When _transport_frame gets there we will start transmitting quarter frames
873 smpte.negative = false;
874 smpte_to_sample( smpte, outbound_mtc_smpte_frame, true, false );
875 transmitting_smpte_time = smpte;
877 transmitting_smpte_time = smpte;
878 outbound_mtc_smpte_frame = _transport_frame;
879 if (((mtc_smpte_bits >> 5) != MIDI::MTC_25_FPS) && (transmitting_smpte_time.frames % 2)) {
880 // start MTC quarter frame transmission on an even frame
881 SMPTE::increment( transmitting_smpte_time );
882 outbound_mtc_smpte_frame += (jack_nframes_t) _frames_per_smpte_frame;
886 // Compensate for audio latency
887 outbound_mtc_smpte_frame += _worst_output_latency;
889 next_quarter_frame_to_send = 0;
891 // Sync slave to the same smpte time as we are on (except if negative, see above)
899 msg[5] = mtc_smpte_bits | smpte.hours;
900 msg[6] = smpte.minutes;
901 msg[7] = smpte.seconds;
902 msg[8] = smpte.frames;
905 Glib::Mutex::Lock lm (midi_lock);
907 if (_mtc_port->midimsg (msg, sizeof (msg))) {
908 error << _("Session: could not send full MIDI time code") << endmsg;
918 Session::send_midi_time_code ()
920 if (_mtc_port == 0 || !send_mtc || transmitting_smpte_time.negative || (next_quarter_frame_to_send < 0) ) {
924 jack_nframes_t two_smpte_frames_duration;
925 jack_nframes_t quarter_frame_duration;
927 /* Duration of two smpte frames */
928 two_smpte_frames_duration = ((long) _frames_per_smpte_frame) << 1;
930 /* Duration of one quarter frame */
931 quarter_frame_duration = ((long) _frames_per_smpte_frame) >> 2;
933 while (_transport_frame >= (outbound_mtc_smpte_frame + (next_quarter_frame_to_send * quarter_frame_duration))) {
935 // Send quarter frames up to current time
937 Glib::Mutex::Lock lm (midi_lock);
939 switch(next_quarter_frame_to_send) {
941 mtc_msg[1] = 0x00 | (transmitting_smpte_time.frames & 0xf);
944 mtc_msg[1] = 0x10 | ((transmitting_smpte_time.frames & 0xf0) >> 4);
947 mtc_msg[1] = 0x20 | (transmitting_smpte_time.seconds & 0xf);
950 mtc_msg[1] = 0x30 | ((transmitting_smpte_time.seconds & 0xf0) >> 4);
953 mtc_msg[1] = 0x40 | (transmitting_smpte_time.minutes & 0xf);
956 mtc_msg[1] = 0x50 | ((transmitting_smpte_time.minutes & 0xf0) >> 4);
959 mtc_msg[1] = 0x60 | ((mtc_smpte_bits|transmitting_smpte_time.hours) & 0xf);
962 mtc_msg[1] = 0x70 | (((mtc_smpte_bits|transmitting_smpte_time.hours) & 0xf0) >> 4);
966 if (_mtc_port->midimsg (mtc_msg, 2)) {
967 error << string_compose(_("Session: cannot send quarter-frame MTC message (%1)"), strerror (errno))
973 // cout << "smpte = " << transmitting_smpte_time.hours << ":" << transmitting_smpte_time.minutes << ":" << transmitting_smpte_time.seconds << ":" << transmitting_smpte_time.frames << ", qfm = " << next_quarter_frame_to_send << endl;
975 // Increment quarter frame counter
976 next_quarter_frame_to_send++;
978 if (next_quarter_frame_to_send >= 8) {
979 // Wrap quarter frame counter
980 next_quarter_frame_to_send = 0;
981 // Increment smpte time twice
982 SMPTE::increment( transmitting_smpte_time );
983 SMPTE::increment( transmitting_smpte_time );
984 // Re-calculate timing of first quarter frame
985 smpte_to_sample( transmitting_smpte_time, outbound_mtc_smpte_frame, true /* use_offset */, false );
986 // Compensate for audio latency
987 outbound_mtc_smpte_frame += _worst_output_latency;
994 /***********************************************************************
996 **********************************************************************/
999 Session::send_mmc_in_another_thread (MIDI::MachineControl::Command cmd, jack_nframes_t target_frame)
1001 MIDIRequest* request;
1003 if (_mtc_port == 0 || !send_mmc) {
1007 request = new MIDIRequest;
1008 request->type = MIDIRequest::SendMMC;
1009 request->mmc_cmd = cmd;
1010 request->locate_frame = target_frame;
1012 midi_requests.write (&request, 1);
1013 poke_midi_thread ();
1017 Session::deliver_mmc (MIDI::MachineControl::Command cmd, jack_nframes_t where)
1019 using namespace MIDI;
1023 if (_mmc_port == 0 || !send_mmc) {
1027 mmc_buffer[nbytes++] = cmd;
1029 // cerr << "delivering MMC, cmd = " << hex << (int) cmd << dec << endl;
1032 case MachineControl::cmdLocate:
1033 smpte_time_subframes (where, smpte);
1035 mmc_buffer[nbytes++] = 0x6; // byte count
1036 mmc_buffer[nbytes++] = 0x1; // "TARGET" subcommand
1037 mmc_buffer[nbytes++] = smpte.hours;
1038 mmc_buffer[nbytes++] = smpte.minutes;
1039 mmc_buffer[nbytes++] = smpte.seconds;
1040 mmc_buffer[nbytes++] = smpte.frames;
1041 mmc_buffer[nbytes++] = smpte.subframes;
1044 case MachineControl::cmdStop:
1047 case MachineControl::cmdPlay:
1048 /* always convert Play into Deferred Play */
1049 mmc_buffer[4] = MachineControl::cmdDeferredPlay;
1052 case MachineControl::cmdDeferredPlay:
1055 case MachineControl::cmdRecordStrobe:
1058 case MachineControl::cmdRecordExit:
1061 case MachineControl::cmdRecordPause:
1070 mmc_buffer[nbytes++] = 0xf7; // terminate SysEx/MMC message
1072 Glib::Mutex::Lock lm (midi_lock);
1074 if (_mmc_port->write (mmc_buffer, nbytes) != nbytes) {
1075 error << string_compose(_("MMC: cannot send command %1%2%3"), &hex, cmd, &dec) << endmsg;
1081 Session::mmc_step_timeout ()
1084 struct timeval diff;
1086 gettimeofday (&now, 0);
1088 timersub (&now, &last_mmc_step, &diff);
1089 diff_usecs = diff.tv_sec * 1000000 + diff.tv_usec;
1091 if (diff_usecs > 1000000.0 || fabs (_transport_speed) < 0.0000001) {
1092 /* too long or too slow, stop transport */
1093 request_transport_speed (0.0);
1094 step_queued = false;
1098 if (diff_usecs < 250000.0) {
1099 /* too short, just keep going */
1105 request_transport_speed (_transport_speed * 0.75);
1111 Session::send_midi_message (MIDI::Port * port, MIDI::eventType ev, MIDI::channel_t ch, MIDI::EventTwoBytes data)
1113 // in another thread, really
1115 MIDIRequest* request = new MIDIRequest;
1117 request->type = MIDIRequest::SendMessage;
1118 request->port = port;
1121 request->data = data;
1123 midi_requests.write (&request, 1);
1124 poke_midi_thread ();
1128 Session::deliver_midi (MIDI::Port * port, MIDI::byte* buf, int32_t bufsize)
1130 // in another thread, really
1132 MIDIRequest* request = new MIDIRequest;
1134 request->type = MIDIRequest::Deliver;
1135 request->port = port;
1137 request->size = bufsize;
1139 midi_requests.write (&request, 1);
1140 poke_midi_thread ();
1144 Session::deliver_midi_message (MIDI::Port * port, MIDI::eventType ev, MIDI::channel_t ch, MIDI::EventTwoBytes data)
1146 if (port == 0 || ev == MIDI::none) {
1150 midi_msg[0] = (ev & 0xF0) | (ch & 0xF);
1151 midi_msg[1] = data.controller_number;
1152 midi_msg[2] = data.value;
1154 port->write (midi_msg, 3);
1158 Session::deliver_data (MIDI::Port * port, MIDI::byte* buf, int32_t size)
1161 port->write (buf, size);
1164 /* this is part of the semantics of the Deliver request */
1169 /*---------------------------------------------------------------------------
1171 ---------------------------------------------------------------------------*/
1174 Session::start_midi_thread ()
1176 if (pipe (midi_request_pipe)) {
1177 error << string_compose(_("Cannot create transport request signal pipe (%1)"), strerror (errno)) << endmsg;
1181 if (fcntl (midi_request_pipe[0], F_SETFL, O_NONBLOCK)) {
1182 error << string_compose(_("UI: cannot set O_NONBLOCK on " "signal read pipe (%1)"), strerror (errno)) << endmsg;
1186 if (fcntl (midi_request_pipe[1], F_SETFL, O_NONBLOCK)) {
1187 error << string_compose(_("UI: cannot set O_NONBLOCK on " "signal write pipe (%1)"), strerror (errno)) << endmsg;
1191 if (pthread_create_and_store ("transport", &midi_thread, 0, _midi_thread_work, this)) {
1192 error << _("Session: could not create transport thread") << endmsg;
1196 // pthread_detach (midi_thread);
1202 Session::terminate_midi_thread ()
1204 MIDIRequest* request = new MIDIRequest;
1207 request->type = MIDIRequest::Quit;
1209 midi_requests.write (&request, 1);
1210 poke_midi_thread ();
1212 pthread_join (midi_thread, &status);
1216 Session::poke_midi_thread ()
1220 if (write (midi_request_pipe[1], &c, 1) != 1) {
1221 error << string_compose(_("cannot send signal to midi thread! (%1)"), strerror (errno)) << endmsg;
1226 Session::_midi_thread_work (void* arg)
1228 pthread_setcancelstate (PTHREAD_CANCEL_ENABLE, 0);
1229 pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, 0);
1231 ((Session *) arg)->midi_thread_work ();
1236 Session::midi_thread_work ()
1238 MIDIRequest* request;
1239 struct pollfd pfd[4];
1243 struct sched_param rtparam;
1246 vector<MIDI::Port*> ports;
1248 PBD::ThreadCreatedWithRequestSize (pthread_self(), X_("MIDI"), 2048);
1250 memset (&rtparam, 0, sizeof (rtparam));
1251 rtparam.sched_priority = 9; /* XXX should be relative to audio (JACK) thread */
1253 if ((x = pthread_setschedparam (pthread_self(), SCHED_FIFO, &rtparam)) != 0) {
1254 // do we care? not particularly.
1257 /* set up the port vector; 4 is the largest possible size for now */
1259 ports.push_back (0);
1260 ports.push_back (0);
1261 ports.push_back (0);
1262 ports.push_back (0);
1268 pfd[nfds].fd = midi_request_pipe[0];
1269 pfd[nfds].events = POLLIN|POLLHUP|POLLERR;
1272 /* if we are using MMC control, we obviously have to listen
1273 on the appropriate port.
1276 if (mmc_control && _mmc_port && _mmc_port->selectable() >= 0) {
1277 pfd[nfds].fd = _mmc_port->selectable();
1278 pfd[nfds].events = POLLIN|POLLHUP|POLLERR;
1279 ports[nfds] = _mmc_port;
1283 /* if MTC is being handled on a different port from MMC
1284 or we are not handling MMC at all, poll
1288 if (_mtc_port && (_mtc_port != _mmc_port || !mmc_control) && _mtc_port->selectable() >= 0) {
1289 pfd[nfds].fd = _mtc_port->selectable();
1290 pfd[nfds].events = POLLIN|POLLHUP|POLLERR;
1291 ports[nfds] = _mtc_port;
1295 if (_midi_port && (_midi_port != _mmc_port || !mmc_control) && (_midi_port != _mtc_port) && _midi_port->selectable() >= 0) {
1296 pfd[nfds].fd = _midi_port->selectable();
1297 pfd[nfds].events = POLLIN|POLLHUP|POLLERR;
1298 ports[nfds] = _midi_port;
1302 if (!midi_timeouts.empty()) {
1303 timeout = 100; /* 10msecs */
1305 timeout = -1; /* if there is no data, we don't care */
1309 // cerr << "MIDI poll on " << nfds << " for " << timeout << endl;
1310 if (poll (pfd, nfds, timeout) < 0) {
1311 if (errno == EINTR) {
1312 /* gdb at work, perhaps */
1316 error << string_compose(_("MIDI thread poll failed (%1)"), strerror (errno)) << endmsg;
1320 // cerr << "MIDI thread wakes at " << get_cycles () << endl;
1325 /* check the transport request pipe */
1327 if (pfd[0].revents & ~POLLIN) {
1328 error << _("Error on transport thread request pipe") << endmsg;
1332 if (pfd[0].revents & POLLIN) {
1336 // cerr << "MIDI request FIFO ready\n";
1339 /* empty the pipe of all current requests */
1342 size_t nread = read (midi_request_pipe[0], &foo, sizeof (foo));
1345 if ((size_t) nread < sizeof (foo)) {
1350 } else if (nread == 0) {
1352 } else if (errno == EAGAIN) {
1355 fatal << _("Error reading from transport request pipe") << endmsg;
1360 while (midi_requests.read (&request, 1) == 1) {
1362 switch (request->type) {
1364 case MIDIRequest::SendFullMTC:
1365 // cerr << "send full MTC\n";
1366 send_full_time_code ();
1367 // cerr << "... done\n";
1370 case MIDIRequest::SendMTC:
1371 // cerr << "send qtr MTC\n";
1372 send_midi_time_code ();
1373 // cerr << "... done\n";
1376 case MIDIRequest::SendMMC:
1377 // cerr << "send MMC\n";
1378 deliver_mmc (request->mmc_cmd, request->locate_frame);
1379 // cerr << "... done\n";
1382 case MIDIRequest::SendMessage:
1383 // cerr << "send Message\n";
1384 deliver_midi_message (request->port, request->ev, request->chan, request->data);
1385 // cerr << "... done\n";
1388 case MIDIRequest::Deliver:
1389 // cerr << "deliver\n";
1390 deliver_data (_midi_port, request->buf, request->size);
1391 // cerr << "... done\n";
1394 case MIDIRequest::PortChange:
1395 /* restart poll with new ports */
1396 // cerr << "rebind\n";
1400 case MIDIRequest::Quit:
1402 pthread_exit_pbd (0);
1420 /* now read the rest of the ports */
1422 for (int p = 1; p < nfds; ++p) {
1423 if ((pfd[p].revents & ~POLLIN)) {
1424 // error << string_compose(_("Transport: error polling MIDI port %1 (revents =%2%3%4"), p, &hex, pfd[p].revents, &dec) << endmsg;
1428 if (pfd[p].revents & POLLIN) {
1430 midi_read (ports[p]);
1434 /* timeout driven */
1436 if (fds_ready < 2 && timeout != -1) {
1438 for (MidiTimeoutList::iterator i = midi_timeouts.begin(); i != midi_timeouts.end(); ) {
1440 MidiTimeoutList::iterator tmp;
1445 midi_timeouts.erase (i);
1455 Session::get_mmc_control () const
1461 Session::get_midi_control () const
1463 return midi_control;