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>
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 RWLockMonitor lm (route_lock, false, __LINE__, __FILE__);
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::get_send_mtc () const
176 Session::get_send_mmc () const
182 Session::set_mtc_port (string port_tag)
186 if (port_tag.length() == 0) {
188 if (_slave && ((ms = dynamic_cast<MTC_Slave*> (_slave)) != 0)) {
189 error << _("Ardour is slaved to MTC - port cannot be reset") << endmsg;
193 if (_mtc_port == 0) {
203 if ((port = MIDI::Manager::instance()->port (port_tag)) == 0) {
204 error << string_compose (_("unknown port %1 requested for MTC"), port_tag) << endl;
210 if (_slave && ((ms = dynamic_cast<MTC_Slave*> (_slave)) != 0)) {
214 Config->set_mtc_port_name (port_tag);
217 MTC_PortChanged(); /* EMIT SIGNAL */
218 change_midi_ports ();
224 Session::set_mmc_port (string port_tag)
226 if (port_tag.length() == 0) {
227 if (_mmc_port == 0) {
236 if ((port = MIDI::Manager::instance()->port (port_tag)) == 0) {
246 mmc = new MIDI::MachineControl (*_mmc_port, 1.0,
247 MMC_CommandSignature,
248 MMC_ResponseSignature);
252 (mem_fun (*this, &Session::mmc_deferred_play));
253 mmc->DeferredPlay.connect
254 (mem_fun (*this, &Session::mmc_deferred_play));
256 (mem_fun (*this, &Session::mmc_stop));
257 mmc->FastForward.connect
258 (mem_fun (*this, &Session::mmc_fast_forward));
260 (mem_fun (*this, &Session::mmc_rewind));
262 (mem_fun (*this, &Session::mmc_pause));
263 mmc->RecordPause.connect
264 (mem_fun (*this, &Session::mmc_record_pause));
265 mmc->RecordStrobe.connect
266 (mem_fun (*this, &Session::mmc_record_strobe));
267 mmc->RecordExit.connect
268 (mem_fun (*this, &Session::mmc_record_exit));
270 (mem_fun (*this, &Session::mmc_locate));
272 (mem_fun (*this, &Session::mmc_step));
274 (mem_fun (*this, &Session::mmc_shuttle));
275 mmc->TrackRecordStatusChange.connect
276 (mem_fun (*this, &Session::mmc_record_enable));
278 /* also handle MIDI SPP because its so common */
280 _mmc_port->input()->start.connect (mem_fun (*this, &Session::spp_start));
281 _mmc_port->input()->contineu.connect (mem_fun (*this, &Session::spp_continue));
282 _mmc_port->input()->stop.connect (mem_fun (*this, &Session::spp_stop));
284 Config->set_mmc_port_name (port_tag);
287 MMC_PortChanged(); /* EMIT SIGNAL */
288 change_midi_ports ();
294 Session::set_midi_port (string port_tag)
296 if (port_tag.length() == 0) {
297 if (_midi_port == 0) {
306 if ((port = MIDI::Manager::instance()->port (port_tag)) == 0) {
312 Config->set_midi_port_name (port_tag);
315 MIDI_PortChanged(); /* EMIT SIGNAL */
316 change_midi_ports ();
322 Session::set_trace_midi_input (bool yn, MIDI::Port* port)
324 MIDI::Parser* input_parser;
327 if ((input_parser = port->input()) != 0) {
328 input_parser->trace (yn, &cout, "input: ");
333 if ((input_parser = _mmc_port->input()) != 0) {
334 input_parser->trace (yn, &cout, "input: ");
338 if (_mtc_port && _mtc_port != _mmc_port) {
339 if ((input_parser = _mtc_port->input()) != 0) {
340 input_parser->trace (yn, &cout, "input: ");
344 if (_midi_port && _midi_port != _mmc_port && _midi_port != _mtc_port ) {
345 if ((input_parser = _midi_port->input()) != 0) {
346 input_parser->trace (yn, &cout, "input: ");
351 Config->set_trace_midi_input (yn);
355 Session::set_trace_midi_output (bool yn, MIDI::Port* port)
357 MIDI::Parser* output_parser;
360 if ((output_parser = port->output()) != 0) {
361 output_parser->trace (yn, &cout, "output: ");
365 if ((output_parser = _mmc_port->output()) != 0) {
366 output_parser->trace (yn, &cout, "output: ");
370 if (_mtc_port && _mtc_port != _mmc_port) {
371 if ((output_parser = _mtc_port->output()) != 0) {
372 output_parser->trace (yn, &cout, "output: ");
376 if (_midi_port && _midi_port != _mmc_port && _midi_port != _mtc_port ) {
377 if ((output_parser = _midi_port->output()) != 0) {
378 output_parser->trace (yn, &cout, "output: ");
384 Config->set_trace_midi_output (yn);
388 Session::get_trace_midi_input(MIDI::Port *port)
390 MIDI::Parser* input_parser;
392 if ((input_parser = port->input()) != 0) {
393 return input_parser->tracing();
398 if ((input_parser = _mmc_port->input()) != 0) {
399 return input_parser->tracing();
404 if ((input_parser = _mtc_port->input()) != 0) {
405 return input_parser->tracing();
410 if ((input_parser = _midi_port->input()) != 0) {
411 return input_parser->tracing();
420 Session::get_trace_midi_output(MIDI::Port *port)
422 MIDI::Parser* output_parser;
424 if ((output_parser = port->output()) != 0) {
425 return output_parser->tracing();
430 if ((output_parser = _mmc_port->output()) != 0) {
431 return output_parser->tracing();
436 if ((output_parser = _mtc_port->output()) != 0) {
437 return output_parser->tracing();
442 if ((output_parser = _midi_port->output()) != 0) {
443 return output_parser->tracing();
454 Session::set_midi_feedback (bool yn)
456 if (_midi_port == 0) {
464 /* make sure the feedback thread is alive */
467 /* maybe put the feedback thread to sleep */
471 ControlChanged (MidiFeedback); /* EMIT SIGNAL */
473 send_all_midi_feedback ();
477 Session::send_all_midi_feedback ()
480 // send out current state of all routes
481 RWLockMonitor lm (route_lock, false, __LINE__, __FILE__);
482 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
483 (*i)->send_all_midi_feedback ();
489 Session::setup_midi_control ()
491 outbound_mtc_smpte_frame = 0;
492 next_quarter_frame_to_send = -1;
494 /* setup the MMC buffer */
496 mmc_buffer[0] = 0xf0; // SysEx
497 mmc_buffer[1] = 0x7f; // Real Time SysEx ID for MMC
498 mmc_buffer[2] = 0x7f; // "broadcast" device ID
499 mmc_buffer[3] = 0x6; // MCC
501 /* Set up the qtr frame message */
512 if (_mmc_port != 0) {
514 send_mmc = send_midi_machine_control;
522 if (_mtc_port != 0) {
524 send_mtc = send_midi_timecode;
533 Session::midi_read (MIDI::Port* port)
537 /* reading from the MIDI port activates the Parser
538 that in turn generates signals that we care
539 about. the port is already set to NONBLOCK so that
540 can read freely here.
545 // cerr << "+++ READ ON " << port->name() << endl;
547 int nread = port->read (buf, sizeof (buf));
549 // cerr << "-- READ (" << nread << " ON " << port->name() << endl;
552 if ((size_t) nread < sizeof (buf)) {
557 } else if (nread == 0) {
559 } else if (errno == EAGAIN) {
562 fatal << string_compose(_("Error reading from MIDI port %1"), port->name()) << endmsg;
571 Session::spp_start (Parser& ignored)
573 if (mmc_control && (_slave_type != MTC)) {
574 request_transport_speed (1.0);
579 Session::spp_continue (Parser& ignored)
585 Session::spp_stop (Parser& ignored)
593 Session::mmc_deferred_play (MIDI::MachineControl &mmc)
595 if (mmc_control && (_slave_type != MTC)) {
596 request_transport_speed (1.0);
601 Session::mmc_record_pause (MIDI::MachineControl &mmc)
604 maybe_enable_record();
609 Session::mmc_record_strobe (MIDI::MachineControl &mmc)
614 /* record strobe does an implicit "Play" command */
616 if (_transport_speed != 1.0) {
618 /* start_transport() will move from Enabled->Recording, so we
619 don't need to do anything here except enable recording.
620 its not the same as maybe_enable_record() though, because
621 that *can* switch to Recording, which we do not want.
624 save_state ("", true);
625 atomic_set (&_record_status, Enabled);
626 RecordStateChanged (); /* EMIT SIGNAL */
628 request_transport_speed (1.0);
637 Session::mmc_record_exit (MIDI::MachineControl &mmc)
645 Session::mmc_stop (MIDI::MachineControl &mmc)
653 Session::mmc_pause (MIDI::MachineControl &mmc)
657 /* We support RECORD_PAUSE, so the spec says that
658 we must interpret PAUSE like RECORD_PAUSE if
662 if (actively_recording()) {
663 maybe_enable_record ();
670 static bool step_queued = false;
674 Session::mmc_step (MIDI::MachineControl &mmc, int steps)
681 struct timeval diff = { 0, 0 };
683 gettimeofday (&now, 0);
685 timersub (&now, &last_mmc_step, &diff);
687 gettimeofday (&now, 0);
688 timersub (&now, &last_mmc_step, &diff);
690 if (last_mmc_step.tv_sec != 0 && (diff.tv_usec + (diff.tv_sec * 1000000)) < _engine.usecs_per_cycle()) {
694 double diff_secs = diff.tv_sec + (diff.tv_usec / 1000000.0);
695 double cur_speed = (((steps * 0.5) * smpte_frames_per_second) / diff_secs) / smpte_frames_per_second;
697 if (_transport_speed == 0 || cur_speed * _transport_speed < 0) {
698 /* change direction */
699 step_speed = cur_speed;
701 step_speed = (0.6 * step_speed) + (0.4 * cur_speed);
707 cerr << "delta = " << diff_secs
708 << " ct = " << _transport_speed
709 << " steps = " << steps
710 << " new speed = " << cur_speed
711 << " speed = " << step_speed
715 request_transport_speed (step_speed);
719 midi_timeouts.push_back (mem_fun (*this, &Session::mmc_step_timeout));
725 Session::mmc_rewind (MIDI::MachineControl &mmc)
728 request_transport_speed(-8.0f);
733 Session::mmc_fast_forward (MIDI::MachineControl &mmc)
736 request_transport_speed(8.0f);
741 Session::mmc_locate (MIDI::MachineControl &mmc, const MIDI::byte* mmc_tc)
747 jack_nframes_t target_frame;
750 smpte.hours = mmc_tc[0] & 0xf;
751 smpte.minutes = mmc_tc[1];
752 smpte.seconds = mmc_tc[2];
753 smpte.frames = mmc_tc[3];
755 // Also takes smpte offset into account:
756 smpte_to_sample( smpte, target_frame, true /* use_offset */, false /* use_subframes */ );
758 if (target_frame > max_frames) {
759 target_frame = max_frames;
762 /* Some (all?) MTC/MMC devices do not send a full MTC frame
763 at the end of a locate, instead sending only an MMC
764 locate command. This causes the current position
765 of an MTC slave to become out of date. Catch this.
768 MTC_Slave* mtcs = dynamic_cast<MTC_Slave*> (_slave);
771 // cerr << "Locate *with* MTC slave\n";
772 mtcs->handle_locate (mmc_tc);
774 // cerr << "Locate without MTC slave\n";
775 request_locate (target_frame, false);
780 Session::mmc_shuttle (MIDI::MachineControl &mmc, float speed, bool forw)
782 cerr << "MMC shuttle, speed = " << speed << endl;
788 if (shuttle_speed_threshold >= 0 && speed > shuttle_speed_threshold) {
789 speed *= shuttle_speed_factor;
792 cerr << "requested MMC control speed = " << speed << endl;
795 request_transport_speed (speed);
797 request_transport_speed (-speed);
802 Session::mmc_record_enable (MIDI::MachineControl &mmc, size_t trk, bool enabled)
806 RouteList::iterator i;
807 RWLockMonitor (route_lock, false, __LINE__, __FILE__);
809 for (i = routes.begin(); i != routes.end(); ++i) {
812 if ((at = dynamic_cast<AudioTrack*>(*i)) != 0) {
813 if (trk == at->remote_control_id()) {
814 at->set_record_enable (enabled, &mmc);
823 Session::send_full_time_code_in_another_thread ()
825 send_time_code_in_another_thread (true);
829 Session::send_midi_time_code_in_another_thread ()
831 send_time_code_in_another_thread (false);
835 Session::send_time_code_in_another_thread (bool full)
837 jack_nframes_t two_smpte_frames_duration;
838 jack_nframes_t quarter_frame_duration;
840 /* Duration of two smpte frames */
841 two_smpte_frames_duration = ((long) _frames_per_smpte_frame) << 1;
843 /* Duration of one quarter frame */
844 quarter_frame_duration = ((long) _frames_per_smpte_frame) >> 2;
846 if (_transport_frame < (outbound_mtc_smpte_frame + (next_quarter_frame_to_send * quarter_frame_duration)))
848 /* There is no work to do.
849 We throttle this here so that we don't overload
850 the transport thread with requests.
855 MIDIRequest* request = new MIDIRequest;
858 request->type = MIDIRequest::SendFullMTC;
860 request->type = MIDIRequest::SendMTC;
863 midi_requests.write (&request, 1);
868 Session::change_midi_ports ()
870 MIDIRequest* request = new MIDIRequest;
872 request->type = MIDIRequest::PortChange;
873 midi_requests.write (&request, 1);
878 Session::send_full_time_code ()
884 if (_mtc_port == 0 || !send_mtc) {
888 // Get smpte time for this transport frame
889 sample_to_smpte(_transport_frame, smpte, true /* use_offset */, false /* no subframes */);
891 // Check for negative smpte time and prepare for quarter frame transmission
892 if (smpte.negative) {
893 // Negative mtc is not defined, so sync slave to smpte zero.
894 // When _transport_frame gets there we will start transmitting quarter frames
900 smpte.negative = false;
901 smpte_to_sample( smpte, outbound_mtc_smpte_frame, true, false );
902 transmitting_smpte_time = smpte;
904 transmitting_smpte_time = smpte;
905 outbound_mtc_smpte_frame = _transport_frame;
906 if (((mtc_smpte_bits >> 5) != MIDI::MTC_25_FPS) && (transmitting_smpte_time.frames % 2)) {
907 // start MTC quarter frame transmission on an even frame
908 smpte_increment( transmitting_smpte_time );
909 outbound_mtc_smpte_frame += (jack_nframes_t) _frames_per_smpte_frame;
913 // Compensate for audio latency
914 outbound_mtc_smpte_frame += _worst_output_latency;
916 next_quarter_frame_to_send = 0;
918 // Sync slave to the same smpte time as we are on (except if negative, see above)
926 msg[5] = mtc_smpte_bits | smpte.hours;
927 msg[6] = smpte.minutes;
928 msg[7] = smpte.seconds;
929 msg[8] = smpte.frames;
932 LockMonitor lm (midi_lock, __LINE__, __FILE__);
934 if (_mtc_port->midimsg (msg, sizeof (msg))) {
935 error << _("Session: could not send full MIDI time code") << endmsg;
945 Session::send_midi_time_code ()
947 if (_mtc_port == 0 || !send_mtc || transmitting_smpte_time.negative || (next_quarter_frame_to_send < 0) ) {
951 jack_nframes_t two_smpte_frames_duration;
952 jack_nframes_t quarter_frame_duration;
954 /* Duration of two smpte frames */
955 two_smpte_frames_duration = ((long) _frames_per_smpte_frame) << 1;
957 /* Duration of one quarter frame */
958 quarter_frame_duration = ((long) _frames_per_smpte_frame) >> 2;
960 while (_transport_frame >= (outbound_mtc_smpte_frame + (next_quarter_frame_to_send * quarter_frame_duration))) {
962 // Send quarter frames up to current time
964 LockMonitor lm (midi_lock, __LINE__, __FILE__);
966 switch(next_quarter_frame_to_send) {
968 mtc_msg[1] = 0x00 | (transmitting_smpte_time.frames & 0xf);
971 mtc_msg[1] = 0x10 | ((transmitting_smpte_time.frames & 0xf0) >> 4);
974 mtc_msg[1] = 0x20 | (transmitting_smpte_time.seconds & 0xf);
977 mtc_msg[1] = 0x30 | ((transmitting_smpte_time.seconds & 0xf0) >> 4);
980 mtc_msg[1] = 0x40 | (transmitting_smpte_time.minutes & 0xf);
983 mtc_msg[1] = 0x50 | ((transmitting_smpte_time.minutes & 0xf0) >> 4);
986 mtc_msg[1] = 0x60 | ((mtc_smpte_bits|transmitting_smpte_time.hours) & 0xf);
989 mtc_msg[1] = 0x70 | (((mtc_smpte_bits|transmitting_smpte_time.hours) & 0xf0) >> 4);
993 if (_mtc_port->midimsg (mtc_msg, 2)) {
994 error << string_compose(_("Session: cannot send quarter-frame MTC message (%1)"), strerror (errno))
1000 // 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;
1002 // Increment quarter frame counter
1003 next_quarter_frame_to_send++;
1005 if (next_quarter_frame_to_send >= 8) {
1006 // Wrap quarter frame counter
1007 next_quarter_frame_to_send = 0;
1008 // Increment smpte time twice
1009 smpte_increment( transmitting_smpte_time );
1010 smpte_increment( transmitting_smpte_time );
1011 // Re-calculate timing of first quarter frame
1012 smpte_to_sample( transmitting_smpte_time, outbound_mtc_smpte_frame, true /* use_offset */, false );
1013 // Compensate for audio latency
1014 outbound_mtc_smpte_frame += _worst_output_latency;
1021 /***********************************************************************
1023 **********************************************************************/
1026 Session::send_mmc_in_another_thread (MIDI::MachineControl::Command cmd, jack_nframes_t target_frame)
1028 MIDIRequest* request;
1030 if (_mtc_port == 0 || !send_mmc) {
1034 request = new MIDIRequest;
1035 request->type = MIDIRequest::SendMMC;
1036 request->mmc_cmd = cmd;
1037 request->locate_frame = target_frame;
1039 midi_requests.write (&request, 1);
1040 poke_midi_thread ();
1044 Session::deliver_mmc (MIDI::MachineControl::Command cmd, jack_nframes_t where)
1046 using namespace MIDI;
1050 if (_mmc_port == 0 || !send_mmc) {
1054 mmc_buffer[nbytes++] = cmd;
1056 // cerr << "delivering MMC, cmd = " << hex << (int) cmd << dec << endl;
1059 case MachineControl::cmdLocate:
1060 smpte_time_subframes (where, smpte);
1062 mmc_buffer[nbytes++] = 0x6; // byte count
1063 mmc_buffer[nbytes++] = 0x1; // "TARGET" subcommand
1064 mmc_buffer[nbytes++] = smpte.hours;
1065 mmc_buffer[nbytes++] = smpte.minutes;
1066 mmc_buffer[nbytes++] = smpte.seconds;
1067 mmc_buffer[nbytes++] = smpte.frames;
1068 mmc_buffer[nbytes++] = smpte.subframes;
1071 case MachineControl::cmdStop:
1074 case MachineControl::cmdPlay:
1075 /* always convert Play into Deferred Play */
1076 mmc_buffer[4] = MachineControl::cmdDeferredPlay;
1079 case MachineControl::cmdDeferredPlay:
1082 case MachineControl::cmdRecordStrobe:
1085 case MachineControl::cmdRecordExit:
1088 case MachineControl::cmdRecordPause:
1097 mmc_buffer[nbytes++] = 0xf7; // terminate SysEx/MMC message
1099 LockMonitor lm (midi_lock, __LINE__, __FILE__);
1101 if (_mmc_port->write (mmc_buffer, nbytes) != nbytes) {
1102 error << string_compose(_("MMC: cannot send command %1%2%3"), &hex, cmd, &dec) << endmsg;
1108 Session::mmc_step_timeout ()
1111 struct timeval diff;
1113 gettimeofday (&now, 0);
1115 timersub (&now, &last_mmc_step, &diff);
1116 diff_usecs = diff.tv_sec * 1000000 + diff.tv_usec;
1118 if (diff_usecs > 1000000.0 || fabs (_transport_speed) < 0.0000001) {
1119 /* too long or too slow, stop transport */
1120 request_transport_speed (0.0);
1121 step_queued = false;
1125 if (diff_usecs < 250000.0) {
1126 /* too short, just keep going */
1132 request_transport_speed (_transport_speed * 0.75);
1138 Session::send_midi_message (MIDI::Port * port, MIDI::eventType ev, MIDI::channel_t ch, MIDI::EventTwoBytes data)
1140 // in another thread, really
1142 MIDIRequest* request = new MIDIRequest;
1144 request->type = MIDIRequest::SendMessage;
1145 request->port = port;
1148 request->data = data;
1150 midi_requests.write (&request, 1);
1151 poke_midi_thread ();
1155 Session::deliver_midi (MIDI::Port * port, MIDI::byte* buf, int32_t bufsize)
1157 // in another thread, really
1159 MIDIRequest* request = new MIDIRequest;
1161 request->type = MIDIRequest::Deliver;
1162 request->port = port;
1164 request->size = bufsize;
1166 midi_requests.write (&request, 1);
1167 poke_midi_thread ();
1171 Session::deliver_midi_message (MIDI::Port * port, MIDI::eventType ev, MIDI::channel_t ch, MIDI::EventTwoBytes data)
1173 if (port == 0 || ev == MIDI::none) {
1177 midi_msg[0] = (ev & 0xF0) | (ch & 0xF);
1178 midi_msg[1] = data.controller_number;
1179 midi_msg[2] = data.value;
1181 port->write (midi_msg, 3);
1185 Session::deliver_data (MIDI::Port * port, MIDI::byte* buf, int32_t size)
1188 port->write (buf, size);
1191 /* this is part of the semantics of the Deliver request */
1196 /*---------------------------------------------------------------------------
1198 ---------------------------------------------------------------------------*/
1201 Session::start_midi_thread ()
1203 if (pipe (midi_request_pipe)) {
1204 error << string_compose(_("Cannot create transport request signal pipe (%1)"), strerror (errno)) << endmsg;
1208 if (fcntl (midi_request_pipe[0], F_SETFL, O_NONBLOCK)) {
1209 error << string_compose(_("UI: cannot set O_NONBLOCK on " "signal read pipe (%1)"), strerror (errno)) << endmsg;
1213 if (fcntl (midi_request_pipe[1], F_SETFL, O_NONBLOCK)) {
1214 error << string_compose(_("UI: cannot set O_NONBLOCK on " "signal write pipe (%1)"), strerror (errno)) << endmsg;
1218 if (pthread_create_and_store ("transport", &midi_thread, 0, _midi_thread_work, this)) {
1219 error << _("Session: could not create transport thread") << endmsg;
1223 // pthread_detach (midi_thread);
1229 Session::terminate_midi_thread ()
1231 MIDIRequest* request = new MIDIRequest;
1234 request->type = MIDIRequest::Quit;
1236 midi_requests.write (&request, 1);
1237 poke_midi_thread ();
1239 pthread_join (midi_thread, &status);
1243 Session::poke_midi_thread ()
1247 if (write (midi_request_pipe[1], &c, 1) != 1) {
1248 error << string_compose(_("cannot send signal to midi thread! (%1)"), strerror (errno)) << endmsg;
1253 Session::_midi_thread_work (void* arg)
1255 pthread_setcancelstate (PTHREAD_CANCEL_ENABLE, 0);
1256 pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, 0);
1258 ((Session *) arg)->midi_thread_work ();
1263 Session::midi_thread_work ()
1265 MIDIRequest* request;
1266 struct pollfd pfd[4];
1270 struct sched_param rtparam;
1273 vector<MIDI::Port*> ports;
1275 PBD::ThreadCreatedWithRequestSize (pthread_self(), X_("MIDI"), 2048);
1277 memset (&rtparam, 0, sizeof (rtparam));
1278 rtparam.sched_priority = 9; /* XXX should be relative to audio (JACK) thread */
1280 if ((x = pthread_setschedparam (pthread_self(), SCHED_FIFO, &rtparam)) != 0) {
1281 // do we care? not particularly.
1284 /* set up the port vector; 4 is the largest possible size for now */
1286 ports.push_back (0);
1287 ports.push_back (0);
1288 ports.push_back (0);
1289 ports.push_back (0);
1295 pfd[nfds].fd = midi_request_pipe[0];
1296 pfd[nfds].events = POLLIN|POLLHUP|POLLERR;
1299 /* if we are using MMC control, we obviously have to listen
1300 on the appropriate port.
1303 if (mmc_control && _mmc_port && _mmc_port->selectable() >= 0) {
1304 pfd[nfds].fd = _mmc_port->selectable();
1305 pfd[nfds].events = POLLIN|POLLHUP|POLLERR;
1306 ports[nfds] = _mmc_port;
1310 /* if MTC is being handled on a different port from MMC
1311 or we are not handling MMC at all, poll
1315 if (_mtc_port && (_mtc_port != _mmc_port || !mmc_control) && _mtc_port->selectable() >= 0) {
1316 pfd[nfds].fd = _mtc_port->selectable();
1317 pfd[nfds].events = POLLIN|POLLHUP|POLLERR;
1318 ports[nfds] = _mtc_port;
1322 if (_midi_port && (_midi_port != _mmc_port || !mmc_control) && (_midi_port != _mtc_port) && _midi_port->selectable() >= 0) {
1323 pfd[nfds].fd = _midi_port->selectable();
1324 pfd[nfds].events = POLLIN|POLLHUP|POLLERR;
1325 ports[nfds] = _midi_port;
1329 if (!midi_timeouts.empty()) {
1330 timeout = 100; /* 10msecs */
1332 timeout = -1; /* if there is no data, we don't care */
1336 // cerr << "MIDI poll on " << nfds << " for " << timeout << endl;
1337 if (poll (pfd, nfds, timeout) < 0) {
1338 if (errno == EINTR) {
1339 /* gdb at work, perhaps */
1343 error << string_compose(_("MIDI thread poll failed (%1)"), strerror (errno)) << endmsg;
1347 // cerr << "MIDI thread wakes at " << get_cycles () << endl;
1352 /* check the transport request pipe */
1354 if (pfd[0].revents & ~POLLIN) {
1355 error << _("Error on transport thread request pipe") << endmsg;
1359 if (pfd[0].revents & POLLIN) {
1363 // cerr << "MIDI request FIFO ready\n";
1366 /* empty the pipe of all current requests */
1369 size_t nread = read (midi_request_pipe[0], &foo, sizeof (foo));
1372 if ((size_t) nread < sizeof (foo)) {
1377 } else if (nread == 0) {
1379 } else if (errno == EAGAIN) {
1382 fatal << _("Error reading from transport request pipe") << endmsg;
1387 while (midi_requests.read (&request, 1) == 1) {
1389 switch (request->type) {
1391 case MIDIRequest::SendFullMTC:
1392 // cerr << "send full MTC\n";
1393 send_full_time_code ();
1394 // cerr << "... done\n";
1397 case MIDIRequest::SendMTC:
1398 // cerr << "send qtr MTC\n";
1399 send_midi_time_code ();
1400 // cerr << "... done\n";
1403 case MIDIRequest::SendMMC:
1404 // cerr << "send MMC\n";
1405 deliver_mmc (request->mmc_cmd, request->locate_frame);
1406 // cerr << "... done\n";
1409 case MIDIRequest::SendMessage:
1410 // cerr << "send Message\n";
1411 deliver_midi_message (request->port, request->ev, request->chan, request->data);
1412 // cerr << "... done\n";
1415 case MIDIRequest::Deliver:
1416 // cerr << "deliver\n";
1417 deliver_data (_midi_port, request->buf, request->size);
1418 // cerr << "... done\n";
1421 case MIDIRequest::PortChange:
1422 /* restart poll with new ports */
1423 // cerr << "rebind\n";
1427 case MIDIRequest::Quit:
1429 pthread_exit_pbd (0);
1447 /* now read the rest of the ports */
1449 for (int p = 1; p < nfds; ++p) {
1450 if ((pfd[p].revents & ~POLLIN)) {
1451 // error << string_compose(_("Transport: error polling MIDI port %1 (revents =%2%3%4"), p, &hex, pfd[p].revents, &dec) << endmsg;
1455 if (pfd[p].revents & POLLIN) {
1457 midi_read (ports[p]);
1461 /* timeout driven */
1463 if (fds_ready < 2 && timeout != -1) {
1465 for (MidiTimeoutList::iterator i = midi_timeouts.begin(); i != midi_timeouts.end(); ) {
1467 MidiTimeoutList::iterator tmp;
1472 midi_timeouts.erase (i);
1482 Session::get_mmc_control () const
1487 Session::get_midi_feedback () const
1489 /* since this a "write" function we have to check the port as well
1490 as the control toggle.
1492 return _midi_port && midi_feedback;
1495 Session::get_midi_control () const
1497 return midi_control;