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);
597 g_atomic_int_set (&_record_status, Enabled);
598 RecordStateChanged (); /* EMIT SIGNAL */
600 request_transport_speed (1.0);
609 Session::mmc_record_exit (MIDI::MachineControl &mmc)
612 disable_record (false);
617 Session::mmc_stop (MIDI::MachineControl &mmc)
625 Session::mmc_pause (MIDI::MachineControl &mmc)
629 /* We support RECORD_PAUSE, so the spec says that
630 we must interpret PAUSE like RECORD_PAUSE if
634 if (actively_recording()) {
635 maybe_enable_record ();
642 static bool step_queued = false;
646 Session::mmc_step (MIDI::MachineControl &mmc, int steps)
653 struct timeval diff = { 0, 0 };
655 gettimeofday (&now, 0);
657 timersub (&now, &last_mmc_step, &diff);
659 gettimeofday (&now, 0);
660 timersub (&now, &last_mmc_step, &diff);
662 if (last_mmc_step.tv_sec != 0 && (diff.tv_usec + (diff.tv_sec * 1000000)) < _engine.usecs_per_cycle()) {
666 double diff_secs = diff.tv_sec + (diff.tv_usec / 1000000.0);
667 double cur_speed = (((steps * 0.5) * smpte_frames_per_second) / diff_secs) / smpte_frames_per_second;
669 if (_transport_speed == 0 || cur_speed * _transport_speed < 0) {
670 /* change direction */
671 step_speed = cur_speed;
673 step_speed = (0.6 * step_speed) + (0.4 * cur_speed);
679 cerr << "delta = " << diff_secs
680 << " ct = " << _transport_speed
681 << " steps = " << steps
682 << " new speed = " << cur_speed
683 << " speed = " << step_speed
687 request_transport_speed (step_speed);
691 midi_timeouts.push_back (mem_fun (*this, &Session::mmc_step_timeout));
697 Session::mmc_rewind (MIDI::MachineControl &mmc)
700 request_transport_speed(-8.0f);
705 Session::mmc_fast_forward (MIDI::MachineControl &mmc)
708 request_transport_speed(8.0f);
713 Session::mmc_locate (MIDI::MachineControl &mmc, const MIDI::byte* mmc_tc)
719 jack_nframes_t target_frame;
722 smpte.hours = mmc_tc[0] & 0xf;
723 smpte.minutes = mmc_tc[1];
724 smpte.seconds = mmc_tc[2];
725 smpte.frames = mmc_tc[3];
727 // Also takes smpte offset into account:
728 smpte_to_sample( smpte, target_frame, true /* use_offset */, false /* use_subframes */ );
730 if (target_frame > max_frames) {
731 target_frame = max_frames;
734 /* Some (all?) MTC/MMC devices do not send a full MTC frame
735 at the end of a locate, instead sending only an MMC
736 locate command. This causes the current position
737 of an MTC slave to become out of date. Catch this.
740 MTC_Slave* mtcs = dynamic_cast<MTC_Slave*> (_slave);
743 // cerr << "Locate *with* MTC slave\n";
744 mtcs->handle_locate (mmc_tc);
746 // cerr << "Locate without MTC slave\n";
747 request_locate (target_frame, false);
752 Session::mmc_shuttle (MIDI::MachineControl &mmc, float speed, bool forw)
754 cerr << "MMC shuttle, speed = " << speed << endl;
760 if (shuttle_speed_threshold >= 0 && speed > shuttle_speed_threshold) {
761 speed *= shuttle_speed_factor;
764 cerr << "requested MMC control speed = " << speed << endl;
767 request_transport_speed (speed);
769 request_transport_speed (-speed);
774 Session::mmc_record_enable (MIDI::MachineControl &mmc, size_t trk, bool enabled)
778 RouteList::iterator i;
779 boost::shared_ptr<RouteList> r = routes.reader();
781 for (i = r->begin(); i != r->end(); ++i) {
784 if ((at = dynamic_cast<AudioTrack*>((*i).get())) != 0) {
785 if (trk == at->remote_control_id()) {
786 at->set_record_enable (enabled, &mmc);
795 Session::send_full_time_code_in_another_thread ()
797 send_time_code_in_another_thread (true);
801 Session::send_midi_time_code_in_another_thread ()
803 send_time_code_in_another_thread (false);
807 Session::send_time_code_in_another_thread (bool full)
809 jack_nframes_t two_smpte_frames_duration;
810 jack_nframes_t quarter_frame_duration;
812 /* Duration of two smpte frames */
813 two_smpte_frames_duration = ((long) _frames_per_smpte_frame) << 1;
815 /* Duration of one quarter frame */
816 quarter_frame_duration = ((long) _frames_per_smpte_frame) >> 2;
818 if (_transport_frame < (outbound_mtc_smpte_frame + (next_quarter_frame_to_send * quarter_frame_duration)))
820 /* There is no work to do.
821 We throttle this here so that we don't overload
822 the transport thread with requests.
827 MIDIRequest* request = new MIDIRequest;
830 request->type = MIDIRequest::SendFullMTC;
832 request->type = MIDIRequest::SendMTC;
835 midi_requests.write (&request, 1);
840 Session::change_midi_ports ()
842 MIDIRequest* request = new MIDIRequest;
844 request->type = MIDIRequest::PortChange;
845 midi_requests.write (&request, 1);
850 Session::send_full_time_code ()
856 if (_mtc_port == 0 || !send_mtc) {
860 // Get smpte time for this transport frame
861 sample_to_smpte(_transport_frame, smpte, true /* use_offset */, false /* no subframes */);
863 // Check for negative smpte time and prepare for quarter frame transmission
864 if (smpte.negative) {
865 // Negative mtc is not defined, so sync slave to smpte zero.
866 // When _transport_frame gets there we will start transmitting quarter frames
872 smpte.negative = false;
873 smpte_to_sample( smpte, outbound_mtc_smpte_frame, true, false );
874 transmitting_smpte_time = smpte;
876 transmitting_smpte_time = smpte;
877 outbound_mtc_smpte_frame = _transport_frame;
878 if (((mtc_smpte_bits >> 5) != MIDI::MTC_25_FPS) && (transmitting_smpte_time.frames % 2)) {
879 // start MTC quarter frame transmission on an even frame
880 SMPTE::increment( transmitting_smpte_time );
881 outbound_mtc_smpte_frame += (jack_nframes_t) _frames_per_smpte_frame;
885 // Compensate for audio latency
886 outbound_mtc_smpte_frame += _worst_output_latency;
888 next_quarter_frame_to_send = 0;
890 // Sync slave to the same smpte time as we are on (except if negative, see above)
898 msg[5] = mtc_smpte_bits | smpte.hours;
899 msg[6] = smpte.minutes;
900 msg[7] = smpte.seconds;
901 msg[8] = smpte.frames;
904 Glib::Mutex::Lock lm (midi_lock);
906 if (_mtc_port->midimsg (msg, sizeof (msg))) {
907 error << _("Session: could not send full MIDI time code") << endmsg;
917 Session::send_midi_time_code ()
919 if (_mtc_port == 0 || !send_mtc || transmitting_smpte_time.negative || (next_quarter_frame_to_send < 0) ) {
923 jack_nframes_t two_smpte_frames_duration;
924 jack_nframes_t quarter_frame_duration;
926 /* Duration of two smpte frames */
927 two_smpte_frames_duration = ((long) _frames_per_smpte_frame) << 1;
929 /* Duration of one quarter frame */
930 quarter_frame_duration = ((long) _frames_per_smpte_frame) >> 2;
932 while (_transport_frame >= (outbound_mtc_smpte_frame + (next_quarter_frame_to_send * quarter_frame_duration))) {
934 // Send quarter frames up to current time
936 Glib::Mutex::Lock lm (midi_lock);
938 switch(next_quarter_frame_to_send) {
940 mtc_msg[1] = 0x00 | (transmitting_smpte_time.frames & 0xf);
943 mtc_msg[1] = 0x10 | ((transmitting_smpte_time.frames & 0xf0) >> 4);
946 mtc_msg[1] = 0x20 | (transmitting_smpte_time.seconds & 0xf);
949 mtc_msg[1] = 0x30 | ((transmitting_smpte_time.seconds & 0xf0) >> 4);
952 mtc_msg[1] = 0x40 | (transmitting_smpte_time.minutes & 0xf);
955 mtc_msg[1] = 0x50 | ((transmitting_smpte_time.minutes & 0xf0) >> 4);
958 mtc_msg[1] = 0x60 | ((mtc_smpte_bits|transmitting_smpte_time.hours) & 0xf);
961 mtc_msg[1] = 0x70 | (((mtc_smpte_bits|transmitting_smpte_time.hours) & 0xf0) >> 4);
965 if (_mtc_port->midimsg (mtc_msg, 2)) {
966 error << string_compose(_("Session: cannot send quarter-frame MTC message (%1)"), strerror (errno))
972 // 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;
974 // Increment quarter frame counter
975 next_quarter_frame_to_send++;
977 if (next_quarter_frame_to_send >= 8) {
978 // Wrap quarter frame counter
979 next_quarter_frame_to_send = 0;
980 // Increment smpte time twice
981 SMPTE::increment( transmitting_smpte_time );
982 SMPTE::increment( transmitting_smpte_time );
983 // Re-calculate timing of first quarter frame
984 smpte_to_sample( transmitting_smpte_time, outbound_mtc_smpte_frame, true /* use_offset */, false );
985 // Compensate for audio latency
986 outbound_mtc_smpte_frame += _worst_output_latency;
993 /***********************************************************************
995 **********************************************************************/
998 Session::send_mmc_in_another_thread (MIDI::MachineControl::Command cmd, jack_nframes_t target_frame)
1000 MIDIRequest* request;
1002 if (_mtc_port == 0 || !send_mmc) {
1006 request = new MIDIRequest;
1007 request->type = MIDIRequest::SendMMC;
1008 request->mmc_cmd = cmd;
1009 request->locate_frame = target_frame;
1011 midi_requests.write (&request, 1);
1012 poke_midi_thread ();
1016 Session::deliver_mmc (MIDI::MachineControl::Command cmd, jack_nframes_t where)
1018 using namespace MIDI;
1022 if (_mmc_port == 0 || !send_mmc) {
1026 mmc_buffer[nbytes++] = cmd;
1028 // cerr << "delivering MMC, cmd = " << hex << (int) cmd << dec << endl;
1031 case MachineControl::cmdLocate:
1032 smpte_time_subframes (where, smpte);
1034 mmc_buffer[nbytes++] = 0x6; // byte count
1035 mmc_buffer[nbytes++] = 0x1; // "TARGET" subcommand
1036 mmc_buffer[nbytes++] = smpte.hours;
1037 mmc_buffer[nbytes++] = smpte.minutes;
1038 mmc_buffer[nbytes++] = smpte.seconds;
1039 mmc_buffer[nbytes++] = smpte.frames;
1040 mmc_buffer[nbytes++] = smpte.subframes;
1043 case MachineControl::cmdStop:
1046 case MachineControl::cmdPlay:
1047 /* always convert Play into Deferred Play */
1048 mmc_buffer[4] = MachineControl::cmdDeferredPlay;
1051 case MachineControl::cmdDeferredPlay:
1054 case MachineControl::cmdRecordStrobe:
1057 case MachineControl::cmdRecordExit:
1060 case MachineControl::cmdRecordPause:
1069 mmc_buffer[nbytes++] = 0xf7; // terminate SysEx/MMC message
1071 Glib::Mutex::Lock lm (midi_lock);
1073 if (_mmc_port->write (mmc_buffer, nbytes) != nbytes) {
1074 error << string_compose(_("MMC: cannot send command %1%2%3"), &hex, cmd, &dec) << endmsg;
1080 Session::mmc_step_timeout ()
1083 struct timeval diff;
1085 gettimeofday (&now, 0);
1087 timersub (&now, &last_mmc_step, &diff);
1088 diff_usecs = diff.tv_sec * 1000000 + diff.tv_usec;
1090 if (diff_usecs > 1000000.0 || fabs (_transport_speed) < 0.0000001) {
1091 /* too long or too slow, stop transport */
1092 request_transport_speed (0.0);
1093 step_queued = false;
1097 if (diff_usecs < 250000.0) {
1098 /* too short, just keep going */
1104 request_transport_speed (_transport_speed * 0.75);
1110 Session::send_midi_message (MIDI::Port * port, MIDI::eventType ev, MIDI::channel_t ch, MIDI::EventTwoBytes data)
1112 // in another thread, really
1114 MIDIRequest* request = new MIDIRequest;
1116 request->type = MIDIRequest::SendMessage;
1117 request->port = port;
1120 request->data = data;
1122 midi_requests.write (&request, 1);
1123 poke_midi_thread ();
1127 Session::deliver_midi (MIDI::Port * port, MIDI::byte* buf, int32_t bufsize)
1129 // in another thread, really
1131 MIDIRequest* request = new MIDIRequest;
1133 request->type = MIDIRequest::Deliver;
1134 request->port = port;
1136 request->size = bufsize;
1138 midi_requests.write (&request, 1);
1139 poke_midi_thread ();
1143 Session::deliver_midi_message (MIDI::Port * port, MIDI::eventType ev, MIDI::channel_t ch, MIDI::EventTwoBytes data)
1145 if (port == 0 || ev == MIDI::none) {
1149 midi_msg[0] = (ev & 0xF0) | (ch & 0xF);
1150 midi_msg[1] = data.controller_number;
1151 midi_msg[2] = data.value;
1153 port->write (midi_msg, 3);
1157 Session::deliver_data (MIDI::Port * port, MIDI::byte* buf, int32_t size)
1160 port->write (buf, size);
1163 /* this is part of the semantics of the Deliver request */
1168 /*---------------------------------------------------------------------------
1170 ---------------------------------------------------------------------------*/
1173 Session::start_midi_thread ()
1175 if (pipe (midi_request_pipe)) {
1176 error << string_compose(_("Cannot create transport request signal pipe (%1)"), strerror (errno)) << endmsg;
1180 if (fcntl (midi_request_pipe[0], F_SETFL, O_NONBLOCK)) {
1181 error << string_compose(_("UI: cannot set O_NONBLOCK on " "signal read pipe (%1)"), strerror (errno)) << endmsg;
1185 if (fcntl (midi_request_pipe[1], F_SETFL, O_NONBLOCK)) {
1186 error << string_compose(_("UI: cannot set O_NONBLOCK on " "signal write pipe (%1)"), strerror (errno)) << endmsg;
1190 if (pthread_create_and_store ("transport", &midi_thread, 0, _midi_thread_work, this)) {
1191 error << _("Session: could not create transport thread") << endmsg;
1195 // pthread_detach (midi_thread);
1201 Session::terminate_midi_thread ()
1203 MIDIRequest* request = new MIDIRequest;
1206 request->type = MIDIRequest::Quit;
1208 midi_requests.write (&request, 1);
1209 poke_midi_thread ();
1211 pthread_join (midi_thread, &status);
1215 Session::poke_midi_thread ()
1219 if (write (midi_request_pipe[1], &c, 1) != 1) {
1220 error << string_compose(_("cannot send signal to midi thread! (%1)"), strerror (errno)) << endmsg;
1225 Session::_midi_thread_work (void* arg)
1227 pthread_setcancelstate (PTHREAD_CANCEL_ENABLE, 0);
1228 pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, 0);
1230 ((Session *) arg)->midi_thread_work ();
1235 Session::midi_thread_work ()
1237 MIDIRequest* request;
1238 struct pollfd pfd[4];
1242 struct sched_param rtparam;
1245 vector<MIDI::Port*> ports;
1247 PBD::ThreadCreatedWithRequestSize (pthread_self(), X_("MIDI"), 2048);
1249 memset (&rtparam, 0, sizeof (rtparam));
1250 rtparam.sched_priority = 9; /* XXX should be relative to audio (JACK) thread */
1252 if ((x = pthread_setschedparam (pthread_self(), SCHED_FIFO, &rtparam)) != 0) {
1253 // do we care? not particularly.
1256 /* set up the port vector; 4 is the largest possible size for now */
1258 ports.push_back (0);
1259 ports.push_back (0);
1260 ports.push_back (0);
1261 ports.push_back (0);
1267 pfd[nfds].fd = midi_request_pipe[0];
1268 pfd[nfds].events = POLLIN|POLLHUP|POLLERR;
1271 /* if we are using MMC control, we obviously have to listen
1272 on the appropriate port.
1275 if (mmc_control && _mmc_port && _mmc_port->selectable() >= 0) {
1276 pfd[nfds].fd = _mmc_port->selectable();
1277 pfd[nfds].events = POLLIN|POLLHUP|POLLERR;
1278 ports[nfds] = _mmc_port;
1282 /* if MTC is being handled on a different port from MMC
1283 or we are not handling MMC at all, poll
1287 if (_mtc_port && (_mtc_port != _mmc_port || !mmc_control) && _mtc_port->selectable() >= 0) {
1288 pfd[nfds].fd = _mtc_port->selectable();
1289 pfd[nfds].events = POLLIN|POLLHUP|POLLERR;
1290 ports[nfds] = _mtc_port;
1294 if (_midi_port && (_midi_port != _mmc_port || !mmc_control) && (_midi_port != _mtc_port) && _midi_port->selectable() >= 0) {
1295 pfd[nfds].fd = _midi_port->selectable();
1296 pfd[nfds].events = POLLIN|POLLHUP|POLLERR;
1297 ports[nfds] = _midi_port;
1301 if (!midi_timeouts.empty()) {
1302 timeout = 100; /* 10msecs */
1304 timeout = -1; /* if there is no data, we don't care */
1308 // cerr << "MIDI poll on " << nfds << " for " << timeout << endl;
1309 if (poll (pfd, nfds, timeout) < 0) {
1310 if (errno == EINTR) {
1311 /* gdb at work, perhaps */
1315 error << string_compose(_("MIDI thread poll failed (%1)"), strerror (errno)) << endmsg;
1319 // cerr << "MIDI thread wakes at " << get_cycles () << endl;
1324 /* check the transport request pipe */
1326 if (pfd[0].revents & ~POLLIN) {
1327 error << _("Error on transport thread request pipe") << endmsg;
1331 if (pfd[0].revents & POLLIN) {
1335 // cerr << "MIDI request FIFO ready\n";
1338 /* empty the pipe of all current requests */
1341 size_t nread = read (midi_request_pipe[0], &foo, sizeof (foo));
1344 if ((size_t) nread < sizeof (foo)) {
1349 } else if (nread == 0) {
1351 } else if (errno == EAGAIN) {
1354 fatal << _("Error reading from transport request pipe") << endmsg;
1359 while (midi_requests.read (&request, 1) == 1) {
1361 switch (request->type) {
1363 case MIDIRequest::SendFullMTC:
1364 // cerr << "send full MTC\n";
1365 send_full_time_code ();
1366 // cerr << "... done\n";
1369 case MIDIRequest::SendMTC:
1370 // cerr << "send qtr MTC\n";
1371 send_midi_time_code ();
1372 // cerr << "... done\n";
1375 case MIDIRequest::SendMMC:
1376 // cerr << "send MMC\n";
1377 deliver_mmc (request->mmc_cmd, request->locate_frame);
1378 // cerr << "... done\n";
1381 case MIDIRequest::SendMessage:
1382 // cerr << "send Message\n";
1383 deliver_midi_message (request->port, request->ev, request->chan, request->data);
1384 // cerr << "... done\n";
1387 case MIDIRequest::Deliver:
1388 // cerr << "deliver\n";
1389 deliver_data (_midi_port, request->buf, request->size);
1390 // cerr << "... done\n";
1393 case MIDIRequest::PortChange:
1394 /* restart poll with new ports */
1395 // cerr << "rebind\n";
1399 case MIDIRequest::Quit:
1401 pthread_exit_pbd (0);
1419 /* now read the rest of the ports */
1421 for (int p = 1; p < nfds; ++p) {
1422 if ((pfd[p].revents & ~POLLIN)) {
1423 // error << string_compose(_("Transport: error polling MIDI port %1 (revents =%2%3%4"), p, &hex, pfd[p].revents, &dec) << endmsg;
1427 if (pfd[p].revents & POLLIN) {
1429 midi_read (ports[p]);
1433 /* timeout driven */
1435 if (fds_ready < 2 && timeout != -1) {
1437 for (MidiTimeoutList::iterator i = midi_timeouts.begin(); i != midi_timeouts.end(); ) {
1439 MidiTimeoutList::iterator tmp;
1444 midi_timeouts.erase (i);
1454 Session::get_mmc_control () const
1460 Session::get_midi_control () const
1462 return midi_control;