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.
28 #include <midi++/mmc.h>
29 #include <midi++/port.h>
30 #include <midi++/manager.h>
31 #include <pbd/error.h>
32 #include <glibmm/thread.h>
33 #include <pbd/pthread_utils.h>
35 #include <ardour/configuration.h>
36 #include <ardour/audioengine.h>
37 #include <ardour/session.h>
38 #include <ardour/audio_track.h>
39 #include <ardour/audio_diskstream.h>
40 #include <ardour/slave.h>
41 #include <ardour/cycles.h>
46 using namespace ARDOUR;
50 MachineControl::CommandSignature MMC_CommandSignature;
51 MachineControl::ResponseSignature MMC_ResponseSignature;
53 MultiAllocSingleReleasePool Session::MIDIRequest::pool ("midi", sizeof (Session::MIDIRequest), 1024);
56 Session::use_config_midi_ports ()
60 if (default_mmc_port) {
61 set_mmc_port (default_mmc_port->name());
66 if (default_mtc_port) {
67 set_mtc_port (default_mtc_port->name());
72 if (default_midi_port) {
73 set_midi_port (default_midi_port->name());
82 /***********************************************************************
84 **********************************************************************/
87 Session::set_mtc_port (string port_tag)
91 if (port_tag.length() == 0) {
93 if (_slave && ((ms = dynamic_cast<MTC_Slave*> (_slave)) != 0)) {
94 error << _("Ardour is slaved to MTC - port cannot be reset") << endmsg;
108 if ((port = MIDI::Manager::instance()->port (port_tag)) == 0) {
109 error << string_compose (_("unknown port %1 requested for MTC"), port_tag) << endl;
115 if (_slave && ((ms = dynamic_cast<MTC_Slave*> (_slave)) != 0)) {
119 Config->set_mtc_port_name (port_tag);
122 MTC_PortChanged(); /* EMIT SIGNAL */
123 change_midi_ports ();
129 Session::set_mmc_device_id (uint32_t device_id)
132 mmc->set_device_id (device_id);
137 Session::set_mmc_port (string port_tag)
139 MIDI::byte old_device_id = 0;
140 bool reset_id = false;
142 if (port_tag.length() == 0) {
143 if (_mmc_port == 0) {
152 if ((port = MIDI::Manager::instance()->port (port_tag)) == 0) {
159 old_device_id = mmc->device_id();
164 mmc = new MIDI::MachineControl (*_mmc_port, 1.0,
165 MMC_CommandSignature,
166 MMC_ResponseSignature);
169 mmc->set_device_id (old_device_id);
173 (mem_fun (*this, &Session::mmc_deferred_play));
174 mmc->DeferredPlay.connect
175 (mem_fun (*this, &Session::mmc_deferred_play));
177 (mem_fun (*this, &Session::mmc_stop));
178 mmc->FastForward.connect
179 (mem_fun (*this, &Session::mmc_fast_forward));
181 (mem_fun (*this, &Session::mmc_rewind));
183 (mem_fun (*this, &Session::mmc_pause));
184 mmc->RecordPause.connect
185 (mem_fun (*this, &Session::mmc_record_pause));
186 mmc->RecordStrobe.connect
187 (mem_fun (*this, &Session::mmc_record_strobe));
188 mmc->RecordExit.connect
189 (mem_fun (*this, &Session::mmc_record_exit));
191 (mem_fun (*this, &Session::mmc_locate));
193 (mem_fun (*this, &Session::mmc_step));
195 (mem_fun (*this, &Session::mmc_shuttle));
196 mmc->TrackRecordStatusChange.connect
197 (mem_fun (*this, &Session::mmc_record_enable));
200 /* also handle MIDI SPP because its so common */
202 _mmc_port->input()->start.connect (mem_fun (*this, &Session::spp_start));
203 _mmc_port->input()->contineu.connect (mem_fun (*this, &Session::spp_continue));
204 _mmc_port->input()->stop.connect (mem_fun (*this, &Session::spp_stop));
206 Config->set_mmc_port_name (port_tag);
209 MMC_PortChanged(); /* EMIT SIGNAL */
210 change_midi_ports ();
216 Session::set_midi_port (string port_tag)
218 if (port_tag.length() == 0) {
219 if (_midi_port == 0) {
228 if ((port = MIDI::Manager::instance()->port (port_tag)) == 0) {
234 /* XXX need something to forward this to control protocols ? or just
238 Config->set_midi_port_name (port_tag);
241 MIDI_PortChanged(); /* EMIT SIGNAL */
242 change_midi_ports ();
248 Session::set_trace_midi_input (bool yn, MIDI::Port* port)
250 MIDI::Parser* input_parser;
253 if ((input_parser = port->input()) != 0) {
254 input_parser->trace (yn, &cout, "input: ");
259 if ((input_parser = _mmc_port->input()) != 0) {
260 input_parser->trace (yn, &cout, "input: ");
264 if (_mtc_port && _mtc_port != _mmc_port) {
265 if ((input_parser = _mtc_port->input()) != 0) {
266 input_parser->trace (yn, &cout, "input: ");
270 if (_midi_port && _midi_port != _mmc_port && _midi_port != _mtc_port ) {
271 if ((input_parser = _midi_port->input()) != 0) {
272 input_parser->trace (yn, &cout, "input: ");
277 Config->set_trace_midi_input (yn);
281 Session::set_trace_midi_output (bool yn, MIDI::Port* port)
283 MIDI::Parser* output_parser;
286 if ((output_parser = port->output()) != 0) {
287 output_parser->trace (yn, &cout, "output: ");
291 if ((output_parser = _mmc_port->output()) != 0) {
292 output_parser->trace (yn, &cout, "output: ");
296 if (_mtc_port && _mtc_port != _mmc_port) {
297 if ((output_parser = _mtc_port->output()) != 0) {
298 output_parser->trace (yn, &cout, "output: ");
302 if (_midi_port && _midi_port != _mmc_port && _midi_port != _mtc_port ) {
303 if ((output_parser = _midi_port->output()) != 0) {
304 output_parser->trace (yn, &cout, "output: ");
310 Config->set_trace_midi_output (yn);
314 Session::get_trace_midi_input(MIDI::Port *port)
316 MIDI::Parser* input_parser;
318 if ((input_parser = port->input()) != 0) {
319 return input_parser->tracing();
324 if ((input_parser = _mmc_port->input()) != 0) {
325 return input_parser->tracing();
330 if ((input_parser = _mtc_port->input()) != 0) {
331 return input_parser->tracing();
336 if ((input_parser = _midi_port->input()) != 0) {
337 return input_parser->tracing();
346 Session::get_trace_midi_output(MIDI::Port *port)
348 MIDI::Parser* output_parser;
350 if ((output_parser = port->output()) != 0) {
351 return output_parser->tracing();
356 if ((output_parser = _mmc_port->output()) != 0) {
357 return output_parser->tracing();
362 if ((output_parser = _mtc_port->output()) != 0) {
363 return output_parser->tracing();
368 if ((output_parser = _midi_port->output()) != 0) {
369 return output_parser->tracing();
379 Session::setup_midi_control ()
381 outbound_mtc_smpte_frame = 0;
382 next_quarter_frame_to_send = -1;
384 /* setup the MMC buffer */
386 mmc_buffer[0] = 0xf0; // SysEx
387 mmc_buffer[1] = 0x7f; // Real Time SysEx ID for MMC
388 mmc_buffer[2] = 0x7f; // "broadcast" device ID
389 mmc_buffer[3] = 0x6; // MCC
391 /* Set up the qtr frame message */
404 Session::midi_read (MIDI::Port* port)
408 /* reading from the MIDI port activates the Parser
409 that in turn generates signals that we care
410 about. the port is already set to NONBLOCK so that
411 can read freely here.
416 // cerr << "+++ READ ON " << port->name() << endl;
418 int nread = port->read (buf, sizeof (buf));
420 // cerr << "-- READ (" << nread << " ON " << port->name() << endl;
423 if ((size_t) nread < sizeof (buf)) {
428 } else if (nread == 0) {
430 } else if (errno == EAGAIN) {
433 fatal << string_compose(_("Error reading from MIDI port %1"), port->name()) << endmsg;
442 Session::spp_start (Parser& ignored)
444 if (Config->get_mmc_control() && (Config->get_slave_source() != MTC)) {
445 request_transport_speed (1.0);
450 Session::spp_continue (Parser& ignored)
456 Session::spp_stop (Parser& ignored)
458 if (Config->get_mmc_control()) {
464 Session::mmc_deferred_play (MIDI::MachineControl &mmc)
466 if (Config->get_mmc_control() && (Config->get_slave_source() != MTC)) {
467 request_transport_speed (1.0);
472 Session::mmc_record_pause (MIDI::MachineControl &mmc)
474 if (Config->get_mmc_control()) {
475 maybe_enable_record();
480 Session::mmc_record_strobe (MIDI::MachineControl &mmc)
482 if (!Config->get_mmc_control())
485 /* record strobe does an implicit "Play" command */
487 if (_transport_speed != 1.0) {
489 /* start_transport() will move from Enabled->Recording, so we
490 don't need to do anything here except enable recording.
491 its not the same as maybe_enable_record() though, because
492 that *can* switch to Recording, which we do not want.
495 save_state ("", true);
496 g_atomic_int_set (&_record_status, Enabled);
497 RecordStateChanged (); /* EMIT SIGNAL */
499 request_transport_speed (1.0);
508 Session::mmc_record_exit (MIDI::MachineControl &mmc)
510 if (Config->get_mmc_control()) {
511 disable_record (false);
516 Session::mmc_stop (MIDI::MachineControl &mmc)
518 if (Config->get_mmc_control()) {
524 Session::mmc_pause (MIDI::MachineControl &mmc)
526 if (Config->get_mmc_control()) {
528 /* We support RECORD_PAUSE, so the spec says that
529 we must interpret PAUSE like RECORD_PAUSE if
533 if (actively_recording()) {
534 maybe_enable_record ();
541 static bool step_queued = false;
544 Session::mmc_step (MIDI::MachineControl &mmc, int steps)
546 if (!Config->get_mmc_control()) {
551 struct timeval diff = { 0, 0 };
553 gettimeofday (&now, 0);
555 timersub (&now, &last_mmc_step, &diff);
557 gettimeofday (&now, 0);
558 timersub (&now, &last_mmc_step, &diff);
560 if (last_mmc_step.tv_sec != 0 && (diff.tv_usec + (diff.tv_sec * 1000000)) < _engine.usecs_per_cycle()) {
564 double diff_secs = diff.tv_sec + (diff.tv_usec / 1000000.0);
565 double cur_speed = (((steps * 0.5) * smpte_frames_per_second()) / diff_secs) / smpte_frames_per_second();
567 if (_transport_speed == 0 || cur_speed * _transport_speed < 0) {
568 /* change direction */
569 step_speed = cur_speed;
571 step_speed = (0.6 * step_speed) + (0.4 * cur_speed);
577 cerr << "delta = " << diff_secs
578 << " ct = " << _transport_speed
579 << " steps = " << steps
580 << " new speed = " << cur_speed
581 << " speed = " << step_speed
585 request_transport_speed (step_speed);
589 midi_timeouts.push_back (mem_fun (*this, &Session::mmc_step_timeout));
595 Session::mmc_rewind (MIDI::MachineControl &mmc)
597 if (Config->get_mmc_control()) {
598 request_transport_speed(-8.0f);
603 Session::mmc_fast_forward (MIDI::MachineControl &mmc)
605 if (Config->get_mmc_control()) {
606 request_transport_speed(8.0f);
611 Session::mmc_locate (MIDI::MachineControl &mmc, const MIDI::byte* mmc_tc)
613 if (!Config->get_mmc_control()) {
617 nframes_t target_frame;
620 smpte.hours = mmc_tc[0] & 0xf;
621 smpte.minutes = mmc_tc[1];
622 smpte.seconds = mmc_tc[2];
623 smpte.frames = mmc_tc[3];
624 smpte.rate = smpte_frames_per_second();
625 smpte.drop = smpte_drop_frames();
627 // Also takes smpte offset into account:
628 smpte_to_sample( smpte, target_frame, true /* use_offset */, false /* use_subframes */ );
630 if (target_frame > max_frames) {
631 target_frame = max_frames;
634 /* Some (all?) MTC/MMC devices do not send a full MTC frame
635 at the end of a locate, instead sending only an MMC
636 locate command. This causes the current position
637 of an MTC slave to become out of date. Catch this.
640 MTC_Slave* mtcs = dynamic_cast<MTC_Slave*> (_slave);
643 // cerr << "Locate *with* MTC slave\n";
644 mtcs->handle_locate (mmc_tc);
646 // cerr << "Locate without MTC slave\n";
647 request_locate (target_frame, false);
652 Session::mmc_shuttle (MIDI::MachineControl &mmc, float speed, bool forw)
654 if (!Config->get_mmc_control()) {
658 if (Config->get_shuttle_speed_threshold() >= 0 && speed > Config->get_shuttle_speed_threshold()) {
659 speed *= Config->get_shuttle_speed_factor();
663 request_transport_speed (speed);
665 request_transport_speed (-speed);
670 Session::mmc_record_enable (MIDI::MachineControl &mmc, size_t trk, bool enabled)
672 if (Config->get_mmc_control()) {
674 RouteList::iterator i;
675 boost::shared_ptr<RouteList> r = routes.reader();
677 for (i = r->begin(); i != r->end(); ++i) {
680 if ((at = dynamic_cast<AudioTrack*>((*i).get())) != 0) {
681 if (trk == at->remote_control_id()) {
682 at->set_record_enable (enabled, &mmc);
691 Session::send_full_time_code_in_another_thread ()
693 send_time_code_in_another_thread (true);
697 Session::send_midi_time_code_in_another_thread ()
699 send_time_code_in_another_thread (false);
703 Session::send_time_code_in_another_thread (bool full)
705 nframes_t two_smpte_frames_duration;
706 nframes_t quarter_frame_duration;
708 /* Duration of two smpte frames */
709 two_smpte_frames_duration = ((long) _frames_per_smpte_frame) << 1;
711 /* Duration of one quarter frame */
712 quarter_frame_duration = ((long) _frames_per_smpte_frame) >> 2;
714 if (_transport_frame < (outbound_mtc_smpte_frame + (next_quarter_frame_to_send * quarter_frame_duration)))
716 /* There is no work to do.
717 We throttle this here so that we don't overload
718 the transport thread with requests.
723 MIDIRequest* request = new MIDIRequest;
726 request->type = MIDIRequest::SendFullMTC;
728 request->type = MIDIRequest::SendMTC;
731 midi_requests.write (&request, 1);
736 Session::change_midi_ports ()
738 MIDIRequest* request = new MIDIRequest;
740 request->type = MIDIRequest::PortChange;
741 midi_requests.write (&request, 1);
746 Session::send_full_time_code ()
752 if (_mtc_port == 0 || !session_send_mtc) {
756 // Get smpte time for this transport frame
757 sample_to_smpte(_transport_frame, smpte, true /* use_offset */, false /* no subframes */);
759 // Check for negative smpte time and prepare for quarter frame transmission
760 if (smpte.negative) {
761 // Negative mtc is not defined, so sync slave to smpte zero.
762 // When _transport_frame gets there we will start transmitting quarter frames
768 smpte.negative = false;
769 smpte_to_sample( smpte, outbound_mtc_smpte_frame, true, false );
770 transmitting_smpte_time = smpte;
772 transmitting_smpte_time = smpte;
773 outbound_mtc_smpte_frame = _transport_frame;
774 if (((mtc_smpte_bits >> 5) != MIDI::MTC_25_FPS) && (transmitting_smpte_time.frames % 2)) {
775 // start MTC quarter frame transmission on an even frame
776 SMPTE::increment( transmitting_smpte_time );
777 outbound_mtc_smpte_frame += (nframes_t) _frames_per_smpte_frame;
781 // Compensate for audio latency
782 outbound_mtc_smpte_frame += _worst_output_latency;
784 next_quarter_frame_to_send = 0;
786 // Sync slave to the same smpte time as we are on (except if negative, see above)
794 msg[5] = mtc_smpte_bits | smpte.hours;
795 msg[6] = smpte.minutes;
796 msg[7] = smpte.seconds;
797 msg[8] = smpte.frames;
800 Glib::Mutex::Lock lm (midi_lock);
802 if (_mtc_port->midimsg (msg, sizeof (msg))) {
803 error << _("Session: could not send full MIDI time code") << endmsg;
813 Session::send_midi_time_code ()
815 if (_mtc_port == 0 || !session_send_mtc || transmitting_smpte_time.negative || (next_quarter_frame_to_send < 0) ) {
819 nframes_t two_smpte_frames_duration;
820 nframes_t quarter_frame_duration;
822 /* Duration of two smpte frames */
823 two_smpte_frames_duration = ((long) _frames_per_smpte_frame) << 1;
825 /* Duration of one quarter frame */
826 quarter_frame_duration = ((long) _frames_per_smpte_frame) >> 2;
828 while (_transport_frame >= (outbound_mtc_smpte_frame + (next_quarter_frame_to_send * quarter_frame_duration))) {
830 // Send quarter frames up to current time
832 Glib::Mutex::Lock lm (midi_lock);
834 switch(next_quarter_frame_to_send) {
836 mtc_msg[1] = 0x00 | (transmitting_smpte_time.frames & 0xf);
839 mtc_msg[1] = 0x10 | ((transmitting_smpte_time.frames & 0xf0) >> 4);
842 mtc_msg[1] = 0x20 | (transmitting_smpte_time.seconds & 0xf);
845 mtc_msg[1] = 0x30 | ((transmitting_smpte_time.seconds & 0xf0) >> 4);
848 mtc_msg[1] = 0x40 | (transmitting_smpte_time.minutes & 0xf);
851 mtc_msg[1] = 0x50 | ((transmitting_smpte_time.minutes & 0xf0) >> 4);
854 mtc_msg[1] = 0x60 | ((mtc_smpte_bits|transmitting_smpte_time.hours) & 0xf);
857 mtc_msg[1] = 0x70 | (((mtc_smpte_bits|transmitting_smpte_time.hours) & 0xf0) >> 4);
861 if (_mtc_port->midimsg (mtc_msg, 2)) {
862 error << string_compose(_("Session: cannot send quarter-frame MTC message (%1)"), strerror (errno))
868 // 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;
870 // Increment quarter frame counter
871 next_quarter_frame_to_send++;
873 if (next_quarter_frame_to_send >= 8) {
874 // Wrap quarter frame counter
875 next_quarter_frame_to_send = 0;
876 // Increment smpte time twice
877 SMPTE::increment( transmitting_smpte_time );
878 SMPTE::increment( transmitting_smpte_time );
879 // Re-calculate timing of first quarter frame
880 smpte_to_sample( transmitting_smpte_time, outbound_mtc_smpte_frame, true /* use_offset */, false );
881 // Compensate for audio latency
882 outbound_mtc_smpte_frame += _worst_output_latency;
889 /***********************************************************************
891 **********************************************************************/
894 Session::send_mmc_in_another_thread (MIDI::MachineControl::Command cmd, nframes_t target_frame)
896 MIDIRequest* request;
898 if (_mtc_port == 0 || !session_send_mmc) {
902 request = new MIDIRequest;
903 request->type = MIDIRequest::SendMMC;
904 request->mmc_cmd = cmd;
905 request->locate_frame = target_frame;
907 midi_requests.write (&request, 1);
912 Session::deliver_mmc (MIDI::MachineControl::Command cmd, nframes_t where)
914 using namespace MIDI;
918 if (_mmc_port == 0 || !session_send_mmc) {
922 mmc_buffer[nbytes++] = cmd;
924 // cerr << "delivering MMC, cmd = " << hex << (int) cmd << dec << endl;
927 case MachineControl::cmdLocate:
928 smpte_time_subframes (where, smpte);
930 mmc_buffer[nbytes++] = 0x6; // byte count
931 mmc_buffer[nbytes++] = 0x1; // "TARGET" subcommand
932 mmc_buffer[nbytes++] = smpte.hours;
933 mmc_buffer[nbytes++] = smpte.minutes;
934 mmc_buffer[nbytes++] = smpte.seconds;
935 mmc_buffer[nbytes++] = smpte.frames;
936 mmc_buffer[nbytes++] = smpte.subframes;
939 case MachineControl::cmdStop:
942 case MachineControl::cmdPlay:
943 /* always convert Play into Deferred Play */
944 mmc_buffer[4] = MachineControl::cmdDeferredPlay;
947 case MachineControl::cmdDeferredPlay:
950 case MachineControl::cmdRecordStrobe:
953 case MachineControl::cmdRecordExit:
956 case MachineControl::cmdRecordPause:
965 mmc_buffer[nbytes++] = 0xf7; // terminate SysEx/MMC message
967 Glib::Mutex::Lock lm (midi_lock);
969 if (_mmc_port->write (mmc_buffer, nbytes) != nbytes) {
970 error << string_compose(_("MMC: cannot send command %1%2%3"), &hex, cmd, &dec) << endmsg;
976 Session::mmc_step_timeout ()
981 gettimeofday (&now, 0);
983 timersub (&now, &last_mmc_step, &diff);
984 diff_usecs = diff.tv_sec * 1000000 + diff.tv_usec;
986 if (diff_usecs > 1000000.0 || fabs (_transport_speed) < 0.0000001) {
987 /* too long or too slow, stop transport */
988 request_transport_speed (0.0);
993 if (diff_usecs < 250000.0) {
994 /* too short, just keep going */
1000 request_transport_speed (_transport_speed * 0.75);
1006 Session::send_midi_message (MIDI::Port * port, MIDI::eventType ev, MIDI::channel_t ch, MIDI::EventTwoBytes data)
1008 // in another thread, really
1010 MIDIRequest* request = new MIDIRequest;
1012 request->type = MIDIRequest::SendMessage;
1013 request->port = port;
1016 request->data = data;
1018 midi_requests.write (&request, 1);
1019 poke_midi_thread ();
1023 Session::deliver_midi (MIDI::Port * port, MIDI::byte* buf, int32_t bufsize)
1025 // in another thread, really
1027 MIDIRequest* request = new MIDIRequest;
1029 request->type = MIDIRequest::Deliver;
1030 request->port = port;
1032 request->size = bufsize;
1034 midi_requests.write (&request, 1);
1035 poke_midi_thread ();
1039 Session::deliver_midi_message (MIDI::Port * port, MIDI::eventType ev, MIDI::channel_t ch, MIDI::EventTwoBytes data)
1041 if (port == 0 || ev == MIDI::none) {
1045 midi_msg[0] = (ev & 0xF0) | (ch & 0xF);
1046 midi_msg[1] = data.controller_number;
1047 midi_msg[2] = data.value;
1049 port->write (midi_msg, 3);
1053 Session::deliver_data (MIDI::Port * port, MIDI::byte* buf, int32_t size)
1056 port->write (buf, size);
1059 /* this is part of the semantics of the Deliver request */
1064 /*---------------------------------------------------------------------------
1066 ---------------------------------------------------------------------------*/
1069 Session::start_midi_thread ()
1071 if (pipe (midi_request_pipe)) {
1072 error << string_compose(_("Cannot create transport request signal pipe (%1)"), strerror (errno)) << endmsg;
1076 if (fcntl (midi_request_pipe[0], F_SETFL, O_NONBLOCK)) {
1077 error << string_compose(_("UI: cannot set O_NONBLOCK on " "signal read pipe (%1)"), strerror (errno)) << endmsg;
1081 if (fcntl (midi_request_pipe[1], F_SETFL, O_NONBLOCK)) {
1082 error << string_compose(_("UI: cannot set O_NONBLOCK on " "signal write pipe (%1)"), strerror (errno)) << endmsg;
1086 if (pthread_create_and_store ("transport", &midi_thread, 0, _midi_thread_work, this)) {
1087 error << _("Session: could not create transport thread") << endmsg;
1091 // pthread_detach (midi_thread);
1097 Session::terminate_midi_thread ()
1100 MIDIRequest* request = new MIDIRequest;
1103 request->type = MIDIRequest::Quit;
1105 midi_requests.write (&request, 1);
1106 poke_midi_thread ();
1108 pthread_join (midi_thread, &status);
1113 Session::poke_midi_thread ()
1117 if (write (midi_request_pipe[1], &c, 1) != 1) {
1118 error << string_compose(_("cannot send signal to midi thread! (%1)"), strerror (errno)) << endmsg;
1123 Session::_midi_thread_work (void* arg)
1125 pthread_setcancelstate (PTHREAD_CANCEL_ENABLE, 0);
1126 pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, 0);
1128 ((Session *) arg)->midi_thread_work ();
1133 Session::midi_thread_work ()
1135 MIDIRequest* request;
1136 struct pollfd pfd[4];
1140 struct sched_param rtparam;
1143 vector<MIDI::Port*> ports;
1145 PBD::ThreadCreatedWithRequestSize (pthread_self(), X_("MIDI"), 2048);
1147 memset (&rtparam, 0, sizeof (rtparam));
1148 rtparam.sched_priority = 9; /* XXX should be relative to audio (JACK) thread */
1150 if ((x = pthread_setschedparam (pthread_self(), SCHED_FIFO, &rtparam)) != 0) {
1151 // do we care? not particularly.
1154 /* set up the port vector; 4 is the largest possible size for now */
1156 ports.push_back (0);
1157 ports.push_back (0);
1158 ports.push_back (0);
1159 ports.push_back (0);
1165 pfd[nfds].fd = midi_request_pipe[0];
1166 pfd[nfds].events = POLLIN|POLLHUP|POLLERR;
1169 /* if we are using MMC control, we obviously have to listen
1170 on the appropriate port.
1173 if (Config->get_mmc_control() && _mmc_port && _mmc_port->selectable() >= 0) {
1174 pfd[nfds].fd = _mmc_port->selectable();
1175 pfd[nfds].events = POLLIN|POLLHUP|POLLERR;
1176 ports[nfds] = _mmc_port;
1180 /* if MTC is being handled on a different port from MMC
1181 or we are not handling MMC at all, poll
1185 if (_mtc_port && (_mtc_port != _mmc_port || !Config->get_mmc_control()) && _mtc_port->selectable() >= 0) {
1186 pfd[nfds].fd = _mtc_port->selectable();
1187 pfd[nfds].events = POLLIN|POLLHUP|POLLERR;
1188 ports[nfds] = _mtc_port;
1192 if (_midi_port && (_midi_port != _mmc_port || !Config->get_mmc_control()) && (_midi_port != _mtc_port) && _midi_port->selectable() >= 0) {
1193 pfd[nfds].fd = _midi_port->selectable();
1194 pfd[nfds].events = POLLIN|POLLHUP|POLLERR;
1195 ports[nfds] = _midi_port;
1199 if (!midi_timeouts.empty()) {
1200 timeout = 100; /* 10msecs */
1202 timeout = -1; /* if there is no data, we don't care */
1206 // cerr << "MIDI poll on " << nfds << " for " << timeout << endl;
1207 if (poll (pfd, nfds, timeout) < 0) {
1208 if (errno == EINTR) {
1209 /* gdb at work, perhaps */
1213 error << string_compose(_("MIDI thread poll failed (%1)"), strerror (errno)) << endmsg;
1217 // cerr << "MIDI thread wakes at " << get_cycles () << endl;
1222 /* check the transport request pipe */
1224 if (pfd[0].revents & ~POLLIN) {
1225 error << _("Error on transport thread request pipe") << endmsg;
1229 if (pfd[0].revents & POLLIN) {
1233 // cerr << "MIDI request FIFO ready\n";
1236 /* empty the pipe of all current requests */
1239 size_t nread = read (midi_request_pipe[0], &foo, sizeof (foo));
1242 if ((size_t) nread < sizeof (foo)) {
1247 } else if (nread == 0) {
1249 } else if (errno == EAGAIN) {
1252 fatal << _("Error reading from transport request pipe") << endmsg;
1257 while (midi_requests.read (&request, 1) == 1) {
1259 switch (request->type) {
1261 case MIDIRequest::SendFullMTC:
1262 // cerr << "send full MTC\n";
1263 send_full_time_code ();
1264 // cerr << "... done\n";
1267 case MIDIRequest::SendMTC:
1268 // cerr << "send qtr MTC\n";
1269 send_midi_time_code ();
1270 // cerr << "... done\n";
1273 case MIDIRequest::SendMMC:
1274 // cerr << "send MMC\n";
1275 deliver_mmc (request->mmc_cmd, request->locate_frame);
1276 // cerr << "... done\n";
1279 case MIDIRequest::SendMessage:
1280 // cerr << "send Message\n";
1281 deliver_midi_message (request->port, request->ev, request->chan, request->data);
1282 // cerr << "... done\n";
1285 case MIDIRequest::Deliver:
1286 // cerr << "deliver\n";
1287 deliver_data (_midi_port, request->buf, request->size);
1288 // cerr << "... done\n";
1291 case MIDIRequest::PortChange:
1292 /* restart poll with new ports */
1293 // cerr << "rebind\n";
1297 case MIDIRequest::Quit:
1299 pthread_exit_pbd (0);
1317 /* now read the rest of the ports */
1319 for (int p = 1; p < nfds; ++p) {
1320 if ((pfd[p].revents & ~POLLIN)) {
1321 // error << string_compose(_("Transport: error polling MIDI port %1 (revents =%2%3%4"), p, &hex, pfd[p].revents, &dec) << endmsg;
1325 if (pfd[p].revents & POLLIN) {
1327 midi_read (ports[p]);
1331 /* timeout driven */
1333 if (fds_ready < 2 && timeout != -1) {
1335 for (MidiTimeoutList::iterator i = midi_timeouts.begin(); i != midi_timeouts.end(); ) {
1337 MidiTimeoutList::iterator tmp;
1342 midi_timeouts.erase (i);