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/diskstream.h>
41 #include <ardour/slave.h>
42 #include <ardour/cycles.h>
47 using namespace ARDOUR;
48 //using namespace sigc;
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) {
113 Glib::RWLock::ReaderLock guard (route_lock);
114 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
115 (*i)->reset_midi_control (_midi_port, midi_control);
119 ControlChanged (MidiControl); /* EMIT SIGNAL */
123 Session::set_send_mtc (bool yn)
125 /* set the persistent option value regardless */
127 send_midi_timecode = yn;
130 /* only set the internal flag if we have
134 if (_mtc_port == 0 || send_mtc == yn) {
139 ControlChanged (SendMTC); /* EMIT SIGNAL */
143 Session::set_send_mmc (bool yn)
145 if (_mmc_port == 0) {
149 if (send_midi_machine_control == yn) {
153 /* only set the internal flag if we have
161 /* set the persistent option value regardless */
163 send_midi_machine_control = yn;
166 ControlChanged (SendMMC); /* EMIT SIGNAL */
170 Session::set_midi_feedback (bool yn)
175 Session::get_midi_feedback () const
181 Session::get_send_mtc () const
187 Session::get_send_mmc () const
193 Session::set_mtc_port (string port_tag)
197 if (port_tag.length() == 0) {
199 if (_slave && ((ms = dynamic_cast<MTC_Slave*> (_slave)) != 0)) {
200 error << _("Ardour is slaved to MTC - port cannot be reset") << endmsg;
204 if (_mtc_port == 0) {
214 if ((port = MIDI::Manager::instance()->port (port_tag)) == 0) {
215 error << string_compose (_("unknown port %1 requested for MTC"), port_tag) << endl;
221 if (_slave && ((ms = dynamic_cast<MTC_Slave*> (_slave)) != 0)) {
225 Config->set_mtc_port_name (port_tag);
228 MTC_PortChanged(); /* EMIT SIGNAL */
229 change_midi_ports ();
235 Session::set_mmc_port (string port_tag)
237 if (port_tag.length() == 0) {
238 if (_mmc_port == 0) {
247 if ((port = MIDI::Manager::instance()->port (port_tag)) == 0) {
257 mmc = new MIDI::MachineControl (*_mmc_port, 1.0,
258 MMC_CommandSignature,
259 MMC_ResponseSignature);
263 (mem_fun (*this, &Session::mmc_deferred_play));
264 mmc->DeferredPlay.connect
265 (mem_fun (*this, &Session::mmc_deferred_play));
267 (mem_fun (*this, &Session::mmc_stop));
268 mmc->FastForward.connect
269 (mem_fun (*this, &Session::mmc_fast_forward));
271 (mem_fun (*this, &Session::mmc_rewind));
273 (mem_fun (*this, &Session::mmc_pause));
274 mmc->RecordPause.connect
275 (mem_fun (*this, &Session::mmc_record_pause));
276 mmc->RecordStrobe.connect
277 (mem_fun (*this, &Session::mmc_record_strobe));
278 mmc->RecordExit.connect
279 (mem_fun (*this, &Session::mmc_record_exit));
281 (mem_fun (*this, &Session::mmc_locate));
283 (mem_fun (*this, &Session::mmc_step));
285 (mem_fun (*this, &Session::mmc_shuttle));
286 mmc->TrackRecordStatusChange.connect
287 (mem_fun (*this, &Session::mmc_record_enable));
289 /* also handle MIDI SPP because its so common */
291 _mmc_port->input()->start.connect (mem_fun (*this, &Session::spp_start));
292 _mmc_port->input()->contineu.connect (mem_fun (*this, &Session::spp_continue));
293 _mmc_port->input()->stop.connect (mem_fun (*this, &Session::spp_stop));
295 Config->set_mmc_port_name (port_tag);
298 MMC_PortChanged(); /* EMIT SIGNAL */
299 change_midi_ports ();
305 Session::set_midi_port (string port_tag)
307 if (port_tag.length() == 0) {
308 if (_midi_port == 0) {
317 if ((port = MIDI::Manager::instance()->port (port_tag)) == 0) {
323 /* XXX need something to forward this to control protocols ? or just
327 Config->set_midi_port_name (port_tag);
330 MIDI_PortChanged(); /* EMIT SIGNAL */
331 change_midi_ports ();
337 Session::set_trace_midi_input (bool yn, MIDI::Port* port)
339 MIDI::Parser* input_parser;
342 if ((input_parser = port->input()) != 0) {
343 input_parser->trace (yn, &cout, "input: ");
348 if ((input_parser = _mmc_port->input()) != 0) {
349 input_parser->trace (yn, &cout, "input: ");
353 if (_mtc_port && _mtc_port != _mmc_port) {
354 if ((input_parser = _mtc_port->input()) != 0) {
355 input_parser->trace (yn, &cout, "input: ");
359 if (_midi_port && _midi_port != _mmc_port && _midi_port != _mtc_port ) {
360 if ((input_parser = _midi_port->input()) != 0) {
361 input_parser->trace (yn, &cout, "input: ");
366 Config->set_trace_midi_input (yn);
370 Session::set_trace_midi_output (bool yn, MIDI::Port* port)
372 MIDI::Parser* output_parser;
375 if ((output_parser = port->output()) != 0) {
376 output_parser->trace (yn, &cout, "output: ");
380 if ((output_parser = _mmc_port->output()) != 0) {
381 output_parser->trace (yn, &cout, "output: ");
385 if (_mtc_port && _mtc_port != _mmc_port) {
386 if ((output_parser = _mtc_port->output()) != 0) {
387 output_parser->trace (yn, &cout, "output: ");
391 if (_midi_port && _midi_port != _mmc_port && _midi_port != _mtc_port ) {
392 if ((output_parser = _midi_port->output()) != 0) {
393 output_parser->trace (yn, &cout, "output: ");
399 Config->set_trace_midi_output (yn);
403 Session::get_trace_midi_input(MIDI::Port *port)
405 MIDI::Parser* input_parser;
407 if ((input_parser = port->input()) != 0) {
408 return input_parser->tracing();
413 if ((input_parser = _mmc_port->input()) != 0) {
414 return input_parser->tracing();
419 if ((input_parser = _mtc_port->input()) != 0) {
420 return input_parser->tracing();
425 if ((input_parser = _midi_port->input()) != 0) {
426 return input_parser->tracing();
435 Session::get_trace_midi_output(MIDI::Port *port)
437 MIDI::Parser* output_parser;
439 if ((output_parser = port->output()) != 0) {
440 return output_parser->tracing();
445 if ((output_parser = _mmc_port->output()) != 0) {
446 return output_parser->tracing();
451 if ((output_parser = _mtc_port->output()) != 0) {
452 return output_parser->tracing();
457 if ((output_parser = _midi_port->output()) != 0) {
458 return output_parser->tracing();
468 Session::setup_midi_control ()
470 outbound_mtc_smpte_frame = 0;
471 next_quarter_frame_to_send = -1;
473 /* setup the MMC buffer */
475 mmc_buffer[0] = 0xf0; // SysEx
476 mmc_buffer[1] = 0x7f; // Real Time SysEx ID for MMC
477 mmc_buffer[2] = 0x7f; // "broadcast" device ID
478 mmc_buffer[3] = 0x6; // MCC
480 /* Set up the qtr frame message */
491 if (_mmc_port != 0) {
493 send_mmc = send_midi_machine_control;
501 if (_mtc_port != 0) {
503 send_mtc = send_midi_timecode;
512 Session::midi_read (MIDI::Port* port)
516 /* reading from the MIDI port activates the Parser
517 that in turn generates signals that we care
518 about. the port is already set to NONBLOCK so that
519 can read freely here.
524 // cerr << "+++ READ ON " << port->name() << endl;
526 int nread = port->read (buf, sizeof (buf));
528 // cerr << "-- READ (" << nread << " ON " << port->name() << endl;
531 if ((size_t) nread < sizeof (buf)) {
536 } else if (nread == 0) {
538 } else if (errno == EAGAIN) {
541 fatal << string_compose(_("Error reading from MIDI port %1"), port->name()) << endmsg;
550 Session::spp_start (Parser& ignored)
552 if (mmc_control && (_slave_type != MTC)) {
553 request_transport_speed (1.0);
558 Session::spp_continue (Parser& ignored)
564 Session::spp_stop (Parser& ignored)
572 Session::mmc_deferred_play (MIDI::MachineControl &mmc)
574 if (mmc_control && (_slave_type != MTC)) {
575 request_transport_speed (1.0);
580 Session::mmc_record_pause (MIDI::MachineControl &mmc)
583 maybe_enable_record();
588 Session::mmc_record_strobe (MIDI::MachineControl &mmc)
593 /* record strobe does an implicit "Play" command */
595 if (_transport_speed != 1.0) {
597 /* start_transport() will move from Enabled->Recording, so we
598 don't need to do anything here except enable recording.
599 its not the same as maybe_enable_record() though, because
600 that *can* switch to Recording, which we do not want.
603 save_state ("", true);
604 g_atomic_int_set (&_record_status, Enabled);
605 RecordStateChanged (); /* EMIT SIGNAL */
607 request_transport_speed (1.0);
616 Session::mmc_record_exit (MIDI::MachineControl &mmc)
619 disable_record (false);
624 Session::mmc_stop (MIDI::MachineControl &mmc)
632 Session::mmc_pause (MIDI::MachineControl &mmc)
636 /* We support RECORD_PAUSE, so the spec says that
637 we must interpret PAUSE like RECORD_PAUSE if
641 if (actively_recording()) {
642 maybe_enable_record ();
649 static bool step_queued = false;
653 Session::mmc_step (MIDI::MachineControl &mmc, int steps)
660 struct timeval diff = { 0, 0 };
662 gettimeofday (&now, 0);
664 timersub (&now, &last_mmc_step, &diff);
666 gettimeofday (&now, 0);
667 timersub (&now, &last_mmc_step, &diff);
669 if (last_mmc_step.tv_sec != 0 && (diff.tv_usec + (diff.tv_sec * 1000000)) < _engine.usecs_per_cycle()) {
673 double diff_secs = diff.tv_sec + (diff.tv_usec / 1000000.0);
674 double cur_speed = (((steps * 0.5) * smpte_frames_per_second) / diff_secs) / smpte_frames_per_second;
676 if (_transport_speed == 0 || cur_speed * _transport_speed < 0) {
677 /* change direction */
678 step_speed = cur_speed;
680 step_speed = (0.6 * step_speed) + (0.4 * cur_speed);
686 cerr << "delta = " << diff_secs
687 << " ct = " << _transport_speed
688 << " steps = " << steps
689 << " new speed = " << cur_speed
690 << " speed = " << step_speed
694 request_transport_speed (step_speed);
698 midi_timeouts.push_back (mem_fun (*this, &Session::mmc_step_timeout));
704 Session::mmc_rewind (MIDI::MachineControl &mmc)
707 request_transport_speed(-8.0f);
712 Session::mmc_fast_forward (MIDI::MachineControl &mmc)
715 request_transport_speed(8.0f);
720 Session::mmc_locate (MIDI::MachineControl &mmc, const MIDI::byte* mmc_tc)
726 jack_nframes_t target_frame;
729 smpte.hours = mmc_tc[0] & 0xf;
730 smpte.minutes = mmc_tc[1];
731 smpte.seconds = mmc_tc[2];
732 smpte.frames = mmc_tc[3];
734 // Also takes smpte offset into account:
735 smpte_to_sample( smpte, target_frame, true /* use_offset */, false /* use_subframes */ );
737 if (target_frame > max_frames) {
738 target_frame = max_frames;
741 /* Some (all?) MTC/MMC devices do not send a full MTC frame
742 at the end of a locate, instead sending only an MMC
743 locate command. This causes the current position
744 of an MTC slave to become out of date. Catch this.
747 MTC_Slave* mtcs = dynamic_cast<MTC_Slave*> (_slave);
750 // cerr << "Locate *with* MTC slave\n";
751 mtcs->handle_locate (mmc_tc);
753 // cerr << "Locate without MTC slave\n";
754 request_locate (target_frame, false);
759 Session::mmc_shuttle (MIDI::MachineControl &mmc, float speed, bool forw)
761 cerr << "MMC shuttle, speed = " << speed << endl;
767 if (shuttle_speed_threshold >= 0 && speed > shuttle_speed_threshold) {
768 speed *= shuttle_speed_factor;
771 cerr << "requested MMC control speed = " << speed << endl;
774 request_transport_speed (speed);
776 request_transport_speed (-speed);
781 Session::mmc_record_enable (MIDI::MachineControl &mmc, size_t trk, bool enabled)
785 RouteList::iterator i;
786 Glib::RWLock::ReaderLock guard (route_lock);
788 for (i = routes.begin(); i != routes.end(); ++i) {
791 if ((at = dynamic_cast<AudioTrack*>(*i)) != 0) {
792 if (trk == at->remote_control_id()) {
793 at->set_record_enable (enabled, &mmc);
802 Session::send_full_time_code_in_another_thread ()
804 send_time_code_in_another_thread (true);
808 Session::send_midi_time_code_in_another_thread ()
810 send_time_code_in_another_thread (false);
814 Session::send_time_code_in_another_thread (bool full)
816 jack_nframes_t two_smpte_frames_duration;
817 jack_nframes_t quarter_frame_duration;
819 /* Duration of two smpte frames */
820 two_smpte_frames_duration = ((long) _frames_per_smpte_frame) << 1;
822 /* Duration of one quarter frame */
823 quarter_frame_duration = ((long) _frames_per_smpte_frame) >> 2;
825 if (_transport_frame < (outbound_mtc_smpte_frame + (next_quarter_frame_to_send * quarter_frame_duration)))
827 /* There is no work to do.
828 We throttle this here so that we don't overload
829 the transport thread with requests.
834 MIDIRequest* request = new MIDIRequest;
837 request->type = MIDIRequest::SendFullMTC;
839 request->type = MIDIRequest::SendMTC;
842 midi_requests.write (&request, 1);
847 Session::change_midi_ports ()
849 MIDIRequest* request = new MIDIRequest;
851 request->type = MIDIRequest::PortChange;
852 midi_requests.write (&request, 1);
857 Session::send_full_time_code ()
863 if (_mtc_port == 0 || !send_mtc) {
867 // Get smpte time for this transport frame
868 sample_to_smpte(_transport_frame, smpte, true /* use_offset */, false /* no subframes */);
870 // Check for negative smpte time and prepare for quarter frame transmission
871 if (smpte.negative) {
872 // Negative mtc is not defined, so sync slave to smpte zero.
873 // When _transport_frame gets there we will start transmitting quarter frames
879 smpte.negative = false;
880 smpte_to_sample( smpte, outbound_mtc_smpte_frame, true, false );
881 transmitting_smpte_time = smpte;
883 transmitting_smpte_time = smpte;
884 outbound_mtc_smpte_frame = _transport_frame;
885 if (((mtc_smpte_bits >> 5) != MIDI::MTC_25_FPS) && (transmitting_smpte_time.frames % 2)) {
886 // start MTC quarter frame transmission on an even frame
887 smpte_increment( transmitting_smpte_time );
888 outbound_mtc_smpte_frame += (jack_nframes_t) _frames_per_smpte_frame;
892 // Compensate for audio latency
893 outbound_mtc_smpte_frame += _worst_output_latency;
895 next_quarter_frame_to_send = 0;
897 // Sync slave to the same smpte time as we are on (except if negative, see above)
905 msg[5] = mtc_smpte_bits | smpte.hours;
906 msg[6] = smpte.minutes;
907 msg[7] = smpte.seconds;
908 msg[8] = smpte.frames;
911 Glib::Mutex::Lock lm (midi_lock);
913 if (_mtc_port->midimsg (msg, sizeof (msg))) {
914 error << _("Session: could not send full MIDI time code") << endmsg;
924 Session::send_midi_time_code ()
926 if (_mtc_port == 0 || !send_mtc || transmitting_smpte_time.negative || (next_quarter_frame_to_send < 0) ) {
930 jack_nframes_t two_smpte_frames_duration;
931 jack_nframes_t quarter_frame_duration;
933 /* Duration of two smpte frames */
934 two_smpte_frames_duration = ((long) _frames_per_smpte_frame) << 1;
936 /* Duration of one quarter frame */
937 quarter_frame_duration = ((long) _frames_per_smpte_frame) >> 2;
939 while (_transport_frame >= (outbound_mtc_smpte_frame + (next_quarter_frame_to_send * quarter_frame_duration))) {
941 // Send quarter frames up to current time
943 Glib::Mutex::Lock lm (midi_lock);
945 switch(next_quarter_frame_to_send) {
947 mtc_msg[1] = 0x00 | (transmitting_smpte_time.frames & 0xf);
950 mtc_msg[1] = 0x10 | ((transmitting_smpte_time.frames & 0xf0) >> 4);
953 mtc_msg[1] = 0x20 | (transmitting_smpte_time.seconds & 0xf);
956 mtc_msg[1] = 0x30 | ((transmitting_smpte_time.seconds & 0xf0) >> 4);
959 mtc_msg[1] = 0x40 | (transmitting_smpte_time.minutes & 0xf);
962 mtc_msg[1] = 0x50 | ((transmitting_smpte_time.minutes & 0xf0) >> 4);
965 mtc_msg[1] = 0x60 | ((mtc_smpte_bits|transmitting_smpte_time.hours) & 0xf);
968 mtc_msg[1] = 0x70 | (((mtc_smpte_bits|transmitting_smpte_time.hours) & 0xf0) >> 4);
972 if (_mtc_port->midimsg (mtc_msg, 2)) {
973 error << string_compose(_("Session: cannot send quarter-frame MTC message (%1)"), strerror (errno))
979 // 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;
981 // Increment quarter frame counter
982 next_quarter_frame_to_send++;
984 if (next_quarter_frame_to_send >= 8) {
985 // Wrap quarter frame counter
986 next_quarter_frame_to_send = 0;
987 // Increment smpte time twice
988 smpte_increment( transmitting_smpte_time );
989 smpte_increment( transmitting_smpte_time );
990 // Re-calculate timing of first quarter frame
991 smpte_to_sample( transmitting_smpte_time, outbound_mtc_smpte_frame, true /* use_offset */, false );
992 // Compensate for audio latency
993 outbound_mtc_smpte_frame += _worst_output_latency;
1000 /***********************************************************************
1002 **********************************************************************/
1005 Session::send_mmc_in_another_thread (MIDI::MachineControl::Command cmd, jack_nframes_t target_frame)
1007 MIDIRequest* request;
1009 if (_mtc_port == 0 || !send_mmc) {
1013 request = new MIDIRequest;
1014 request->type = MIDIRequest::SendMMC;
1015 request->mmc_cmd = cmd;
1016 request->locate_frame = target_frame;
1018 midi_requests.write (&request, 1);
1019 poke_midi_thread ();
1023 Session::deliver_mmc (MIDI::MachineControl::Command cmd, jack_nframes_t where)
1025 using namespace MIDI;
1029 if (_mmc_port == 0 || !send_mmc) {
1033 mmc_buffer[nbytes++] = cmd;
1035 // cerr << "delivering MMC, cmd = " << hex << (int) cmd << dec << endl;
1038 case MachineControl::cmdLocate:
1039 smpte_time_subframes (where, smpte);
1041 mmc_buffer[nbytes++] = 0x6; // byte count
1042 mmc_buffer[nbytes++] = 0x1; // "TARGET" subcommand
1043 mmc_buffer[nbytes++] = smpte.hours;
1044 mmc_buffer[nbytes++] = smpte.minutes;
1045 mmc_buffer[nbytes++] = smpte.seconds;
1046 mmc_buffer[nbytes++] = smpte.frames;
1047 mmc_buffer[nbytes++] = smpte.subframes;
1050 case MachineControl::cmdStop:
1053 case MachineControl::cmdPlay:
1054 /* always convert Play into Deferred Play */
1055 mmc_buffer[4] = MachineControl::cmdDeferredPlay;
1058 case MachineControl::cmdDeferredPlay:
1061 case MachineControl::cmdRecordStrobe:
1064 case MachineControl::cmdRecordExit:
1067 case MachineControl::cmdRecordPause:
1076 mmc_buffer[nbytes++] = 0xf7; // terminate SysEx/MMC message
1078 Glib::Mutex::Lock lm (midi_lock);
1080 if (_mmc_port->write (mmc_buffer, nbytes) != nbytes) {
1081 error << string_compose(_("MMC: cannot send command %1%2%3"), &hex, cmd, &dec) << endmsg;
1087 Session::mmc_step_timeout ()
1090 struct timeval diff;
1092 gettimeofday (&now, 0);
1094 timersub (&now, &last_mmc_step, &diff);
1095 diff_usecs = diff.tv_sec * 1000000 + diff.tv_usec;
1097 if (diff_usecs > 1000000.0 || fabs (_transport_speed) < 0.0000001) {
1098 /* too long or too slow, stop transport */
1099 request_transport_speed (0.0);
1100 step_queued = false;
1104 if (diff_usecs < 250000.0) {
1105 /* too short, just keep going */
1111 request_transport_speed (_transport_speed * 0.75);
1117 Session::send_midi_message (MIDI::Port * port, MIDI::eventType ev, MIDI::channel_t ch, MIDI::EventTwoBytes data)
1119 // in another thread, really
1121 MIDIRequest* request = new MIDIRequest;
1123 request->type = MIDIRequest::SendMessage;
1124 request->port = port;
1127 request->data = data;
1129 midi_requests.write (&request, 1);
1130 poke_midi_thread ();
1134 Session::deliver_midi (MIDI::Port * port, MIDI::byte* buf, int32_t bufsize)
1136 // in another thread, really
1138 MIDIRequest* request = new MIDIRequest;
1140 request->type = MIDIRequest::Deliver;
1141 request->port = port;
1143 request->size = bufsize;
1145 midi_requests.write (&request, 1);
1146 poke_midi_thread ();
1150 Session::deliver_midi_message (MIDI::Port * port, MIDI::eventType ev, MIDI::channel_t ch, MIDI::EventTwoBytes data)
1152 if (port == 0 || ev == MIDI::none) {
1156 midi_msg[0] = (ev & 0xF0) | (ch & 0xF);
1157 midi_msg[1] = data.controller_number;
1158 midi_msg[2] = data.value;
1160 port->write (midi_msg, 3);
1164 Session::deliver_data (MIDI::Port * port, MIDI::byte* buf, int32_t size)
1167 port->write (buf, size);
1170 /* this is part of the semantics of the Deliver request */
1175 /*---------------------------------------------------------------------------
1177 ---------------------------------------------------------------------------*/
1180 Session::start_midi_thread ()
1182 if (pipe (midi_request_pipe)) {
1183 error << string_compose(_("Cannot create transport request signal pipe (%1)"), strerror (errno)) << endmsg;
1187 if (fcntl (midi_request_pipe[0], F_SETFL, O_NONBLOCK)) {
1188 error << string_compose(_("UI: cannot set O_NONBLOCK on " "signal read pipe (%1)"), strerror (errno)) << endmsg;
1192 if (fcntl (midi_request_pipe[1], F_SETFL, O_NONBLOCK)) {
1193 error << string_compose(_("UI: cannot set O_NONBLOCK on " "signal write pipe (%1)"), strerror (errno)) << endmsg;
1197 if (pthread_create_and_store ("transport", &midi_thread, 0, _midi_thread_work, this)) {
1198 error << _("Session: could not create transport thread") << endmsg;
1202 // pthread_detach (midi_thread);
1208 Session::terminate_midi_thread ()
1210 MIDIRequest* request = new MIDIRequest;
1213 request->type = MIDIRequest::Quit;
1215 midi_requests.write (&request, 1);
1216 poke_midi_thread ();
1218 pthread_join (midi_thread, &status);
1222 Session::poke_midi_thread ()
1226 if (write (midi_request_pipe[1], &c, 1) != 1) {
1227 error << string_compose(_("cannot send signal to midi thread! (%1)"), strerror (errno)) << endmsg;
1232 Session::_midi_thread_work (void* arg)
1234 pthread_setcancelstate (PTHREAD_CANCEL_ENABLE, 0);
1235 pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, 0);
1237 ((Session *) arg)->midi_thread_work ();
1242 Session::midi_thread_work ()
1244 MIDIRequest* request;
1245 struct pollfd pfd[4];
1249 struct sched_param rtparam;
1252 vector<MIDI::Port*> ports;
1254 PBD::ThreadCreatedWithRequestSize (pthread_self(), X_("MIDI"), 2048);
1256 memset (&rtparam, 0, sizeof (rtparam));
1257 rtparam.sched_priority = 9; /* XXX should be relative to audio (JACK) thread */
1259 if ((x = pthread_setschedparam (pthread_self(), SCHED_FIFO, &rtparam)) != 0) {
1260 // do we care? not particularly.
1263 /* set up the port vector; 4 is the largest possible size for now */
1265 ports.push_back (0);
1266 ports.push_back (0);
1267 ports.push_back (0);
1268 ports.push_back (0);
1274 pfd[nfds].fd = midi_request_pipe[0];
1275 pfd[nfds].events = POLLIN|POLLHUP|POLLERR;
1278 /* if we are using MMC control, we obviously have to listen
1279 on the appropriate port.
1282 if (mmc_control && _mmc_port && _mmc_port->selectable() >= 0) {
1283 pfd[nfds].fd = _mmc_port->selectable();
1284 pfd[nfds].events = POLLIN|POLLHUP|POLLERR;
1285 ports[nfds] = _mmc_port;
1289 /* if MTC is being handled on a different port from MMC
1290 or we are not handling MMC at all, poll
1294 if (_mtc_port && (_mtc_port != _mmc_port || !mmc_control) && _mtc_port->selectable() >= 0) {
1295 pfd[nfds].fd = _mtc_port->selectable();
1296 pfd[nfds].events = POLLIN|POLLHUP|POLLERR;
1297 ports[nfds] = _mtc_port;
1301 if (_midi_port && (_midi_port != _mmc_port || !mmc_control) && (_midi_port != _mtc_port) && _midi_port->selectable() >= 0) {
1302 pfd[nfds].fd = _midi_port->selectable();
1303 pfd[nfds].events = POLLIN|POLLHUP|POLLERR;
1304 ports[nfds] = _midi_port;
1308 if (!midi_timeouts.empty()) {
1309 timeout = 100; /* 10msecs */
1311 timeout = -1; /* if there is no data, we don't care */
1315 // cerr << "MIDI poll on " << nfds << " for " << timeout << endl;
1316 if (poll (pfd, nfds, timeout) < 0) {
1317 if (errno == EINTR) {
1318 /* gdb at work, perhaps */
1322 error << string_compose(_("MIDI thread poll failed (%1)"), strerror (errno)) << endmsg;
1326 // cerr << "MIDI thread wakes at " << get_cycles () << endl;
1331 /* check the transport request pipe */
1333 if (pfd[0].revents & ~POLLIN) {
1334 error << _("Error on transport thread request pipe") << endmsg;
1338 if (pfd[0].revents & POLLIN) {
1342 // cerr << "MIDI request FIFO ready\n";
1345 /* empty the pipe of all current requests */
1348 size_t nread = read (midi_request_pipe[0], &foo, sizeof (foo));
1351 if ((size_t) nread < sizeof (foo)) {
1356 } else if (nread == 0) {
1358 } else if (errno == EAGAIN) {
1361 fatal << _("Error reading from transport request pipe") << endmsg;
1366 while (midi_requests.read (&request, 1) == 1) {
1368 switch (request->type) {
1370 case MIDIRequest::SendFullMTC:
1371 // cerr << "send full MTC\n";
1372 send_full_time_code ();
1373 // cerr << "... done\n";
1376 case MIDIRequest::SendMTC:
1377 // cerr << "send qtr MTC\n";
1378 send_midi_time_code ();
1379 // cerr << "... done\n";
1382 case MIDIRequest::SendMMC:
1383 // cerr << "send MMC\n";
1384 deliver_mmc (request->mmc_cmd, request->locate_frame);
1385 // cerr << "... done\n";
1388 case MIDIRequest::SendMessage:
1389 // cerr << "send Message\n";
1390 deliver_midi_message (request->port, request->ev, request->chan, request->data);
1391 // cerr << "... done\n";
1394 case MIDIRequest::Deliver:
1395 // cerr << "deliver\n";
1396 deliver_data (_midi_port, request->buf, request->size);
1397 // cerr << "... done\n";
1400 case MIDIRequest::PortChange:
1401 /* restart poll with new ports */
1402 // cerr << "rebind\n";
1406 case MIDIRequest::Quit:
1408 pthread_exit_pbd (0);
1426 /* now read the rest of the ports */
1428 for (int p = 1; p < nfds; ++p) {
1429 if ((pfd[p].revents & ~POLLIN)) {
1430 // error << string_compose(_("Transport: error polling MIDI port %1 (revents =%2%3%4"), p, &hex, pfd[p].revents, &dec) << endmsg;
1434 if (pfd[p].revents & POLLIN) {
1436 midi_read (ports[p]);
1440 /* timeout driven */
1442 if (fds_ready < 2 && timeout != -1) {
1444 for (MidiTimeoutList::iterator i = midi_timeouts.begin(); i != midi_timeouts.end(); ) {
1446 MidiTimeoutList::iterator tmp;
1451 midi_timeouts.erase (i);
1461 Session::get_mmc_control () const
1467 Session::get_midi_control () const
1469 return midi_control;