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_receive_device_id (uint32_t device_id)
132 mmc->set_receive_device_id (device_id);
137 Session::set_mmc_send_device_id (uint32_t device_id)
140 mmc->set_send_device_id (device_id);
141 /* reset MMC buffer */
142 mmc_buffer[2] = mmc->send_device_id();
147 Session::set_mmc_port (string port_tag)
149 MIDI::byte old_recv_device_id = 0;
150 MIDI::byte old_send_device_id = 0;
151 bool reset_id = false;
153 if (port_tag.length() == 0) {
154 if (_mmc_port == 0) {
163 if ((port = MIDI::Manager::instance()->port (port_tag)) == 0) {
170 old_recv_device_id = mmc->receive_device_id();
171 old_recv_device_id = mmc->send_device_id();
176 mmc = new MIDI::MachineControl (*_mmc_port, 1.0,
177 MMC_CommandSignature,
178 MMC_ResponseSignature);
181 set_mmc_receive_device_id (old_recv_device_id);
182 set_mmc_send_device_id (old_send_device_id);
186 (mem_fun (*this, &Session::mmc_deferred_play));
187 mmc->DeferredPlay.connect
188 (mem_fun (*this, &Session::mmc_deferred_play));
190 (mem_fun (*this, &Session::mmc_stop));
191 mmc->FastForward.connect
192 (mem_fun (*this, &Session::mmc_fast_forward));
194 (mem_fun (*this, &Session::mmc_rewind));
196 (mem_fun (*this, &Session::mmc_pause));
197 mmc->RecordPause.connect
198 (mem_fun (*this, &Session::mmc_record_pause));
199 mmc->RecordStrobe.connect
200 (mem_fun (*this, &Session::mmc_record_strobe));
201 mmc->RecordExit.connect
202 (mem_fun (*this, &Session::mmc_record_exit));
204 (mem_fun (*this, &Session::mmc_locate));
206 (mem_fun (*this, &Session::mmc_step));
208 (mem_fun (*this, &Session::mmc_shuttle));
209 mmc->TrackRecordStatusChange.connect
210 (mem_fun (*this, &Session::mmc_record_enable));
213 /* also handle MIDI SPP because its so common */
215 _mmc_port->input()->start.connect (mem_fun (*this, &Session::spp_start));
216 _mmc_port->input()->contineu.connect (mem_fun (*this, &Session::spp_continue));
217 _mmc_port->input()->stop.connect (mem_fun (*this, &Session::spp_stop));
219 Config->set_mmc_port_name (port_tag);
222 MMC_PortChanged(); /* EMIT SIGNAL */
223 change_midi_ports ();
229 Session::set_midi_port (string port_tag)
231 if (port_tag.length() == 0) {
232 if (_midi_port == 0) {
241 if ((port = MIDI::Manager::instance()->port (port_tag)) == 0) {
247 /* XXX need something to forward this to control protocols ? or just
251 Config->set_midi_port_name (port_tag);
254 MIDI_PortChanged(); /* EMIT SIGNAL */
255 change_midi_ports ();
261 Session::set_trace_midi_input (bool yn, MIDI::Port* port)
263 MIDI::Parser* input_parser;
266 if ((input_parser = port->input()) != 0) {
267 input_parser->trace (yn, &cout, "input: ");
272 if ((input_parser = _mmc_port->input()) != 0) {
273 input_parser->trace (yn, &cout, "input: ");
277 if (_mtc_port && _mtc_port != _mmc_port) {
278 if ((input_parser = _mtc_port->input()) != 0) {
279 input_parser->trace (yn, &cout, "input: ");
283 if (_midi_port && _midi_port != _mmc_port && _midi_port != _mtc_port ) {
284 if ((input_parser = _midi_port->input()) != 0) {
285 input_parser->trace (yn, &cout, "input: ");
290 Config->set_trace_midi_input (yn);
294 Session::set_trace_midi_output (bool yn, MIDI::Port* port)
296 MIDI::Parser* output_parser;
299 if ((output_parser = port->output()) != 0) {
300 output_parser->trace (yn, &cout, "output: ");
304 if ((output_parser = _mmc_port->output()) != 0) {
305 output_parser->trace (yn, &cout, "output: ");
309 if (_mtc_port && _mtc_port != _mmc_port) {
310 if ((output_parser = _mtc_port->output()) != 0) {
311 output_parser->trace (yn, &cout, "output: ");
315 if (_midi_port && _midi_port != _mmc_port && _midi_port != _mtc_port ) {
316 if ((output_parser = _midi_port->output()) != 0) {
317 output_parser->trace (yn, &cout, "output: ");
323 Config->set_trace_midi_output (yn);
327 Session::get_trace_midi_input(MIDI::Port *port)
329 MIDI::Parser* input_parser;
331 if ((input_parser = port->input()) != 0) {
332 return input_parser->tracing();
337 if ((input_parser = _mmc_port->input()) != 0) {
338 return input_parser->tracing();
343 if ((input_parser = _mtc_port->input()) != 0) {
344 return input_parser->tracing();
349 if ((input_parser = _midi_port->input()) != 0) {
350 return input_parser->tracing();
359 Session::get_trace_midi_output(MIDI::Port *port)
361 MIDI::Parser* output_parser;
363 if ((output_parser = port->output()) != 0) {
364 return output_parser->tracing();
369 if ((output_parser = _mmc_port->output()) != 0) {
370 return output_parser->tracing();
375 if ((output_parser = _mtc_port->output()) != 0) {
376 return output_parser->tracing();
381 if ((output_parser = _midi_port->output()) != 0) {
382 return output_parser->tracing();
392 Session::setup_midi_control ()
394 outbound_mtc_smpte_frame = 0;
395 next_quarter_frame_to_send = -1;
397 /* setup the MMC buffer */
399 mmc_buffer[0] = 0xf0; // SysEx
400 mmc_buffer[1] = 0x7f; // Real Time SysEx ID for MMC
401 mmc_buffer[2] = (mmc ? mmc->send_device_id() : 0x7f);
402 mmc_buffer[3] = 0x6; // MCC
404 /* Set up the qtr frame message */
417 Session::midi_read (MIDI::Port* port)
421 /* reading from the MIDI port activates the Parser
422 that in turn generates signals that we care
423 about. the port is already set to NONBLOCK so that
424 can read freely here.
429 // cerr << "+++ READ ON " << port->name() << endl;
431 int nread = port->read (buf, sizeof (buf));
433 // cerr << "-- READ (" << nread << " ON " << port->name() << endl;
436 if ((size_t) nread < sizeof (buf)) {
441 } else if (nread == 0) {
443 } else if (errno == EAGAIN) {
446 fatal << string_compose(_("Error reading from MIDI port %1"), port->name()) << endmsg;
455 Session::spp_start (Parser& ignored)
457 if (Config->get_mmc_control() && (Config->get_slave_source() != MTC)) {
458 request_transport_speed (1.0);
463 Session::spp_continue (Parser& ignored)
469 Session::spp_stop (Parser& ignored)
471 if (Config->get_mmc_control()) {
477 Session::mmc_deferred_play (MIDI::MachineControl &mmc)
479 if (Config->get_mmc_control() && (Config->get_slave_source() != MTC)) {
480 request_transport_speed (1.0);
485 Session::mmc_record_pause (MIDI::MachineControl &mmc)
487 if (Config->get_mmc_control()) {
488 maybe_enable_record();
493 Session::mmc_record_strobe (MIDI::MachineControl &mmc)
495 if (!Config->get_mmc_control())
498 /* record strobe does an implicit "Play" command */
500 if (_transport_speed != 1.0) {
502 /* start_transport() will move from Enabled->Recording, so we
503 don't need to do anything here except enable recording.
504 its not the same as maybe_enable_record() though, because
505 that *can* switch to Recording, which we do not want.
508 save_state ("", true);
509 g_atomic_int_set (&_record_status, Enabled);
510 RecordStateChanged (); /* EMIT SIGNAL */
512 request_transport_speed (1.0);
521 Session::mmc_record_exit (MIDI::MachineControl &mmc)
523 if (Config->get_mmc_control()) {
524 disable_record (false);
529 Session::mmc_stop (MIDI::MachineControl &mmc)
531 if (Config->get_mmc_control()) {
537 Session::mmc_pause (MIDI::MachineControl &mmc)
539 if (Config->get_mmc_control()) {
541 /* We support RECORD_PAUSE, so the spec says that
542 we must interpret PAUSE like RECORD_PAUSE if
546 if (actively_recording()) {
547 maybe_enable_record ();
554 static bool step_queued = false;
557 Session::mmc_step (MIDI::MachineControl &mmc, int steps)
559 if (!Config->get_mmc_control()) {
564 struct timeval diff = { 0, 0 };
566 gettimeofday (&now, 0);
568 timersub (&now, &last_mmc_step, &diff);
570 gettimeofday (&now, 0);
571 timersub (&now, &last_mmc_step, &diff);
573 if (last_mmc_step.tv_sec != 0 && (diff.tv_usec + (diff.tv_sec * 1000000)) < _engine.usecs_per_cycle()) {
577 double diff_secs = diff.tv_sec + (diff.tv_usec / 1000000.0);
578 double cur_speed = (((steps * 0.5) * smpte_frames_per_second()) / diff_secs) / smpte_frames_per_second();
580 if (_transport_speed == 0 || cur_speed * _transport_speed < 0) {
581 /* change direction */
582 step_speed = cur_speed;
584 step_speed = (0.6 * step_speed) + (0.4 * cur_speed);
590 cerr << "delta = " << diff_secs
591 << " ct = " << _transport_speed
592 << " steps = " << steps
593 << " new speed = " << cur_speed
594 << " speed = " << step_speed
598 request_transport_speed (step_speed);
602 midi_timeouts.push_back (mem_fun (*this, &Session::mmc_step_timeout));
608 Session::mmc_rewind (MIDI::MachineControl &mmc)
610 if (Config->get_mmc_control()) {
611 request_transport_speed(-8.0f);
616 Session::mmc_fast_forward (MIDI::MachineControl &mmc)
618 if (Config->get_mmc_control()) {
619 request_transport_speed(8.0f);
624 Session::mmc_locate (MIDI::MachineControl &mmc, const MIDI::byte* mmc_tc)
626 if (!Config->get_mmc_control()) {
630 nframes_t target_frame;
633 smpte.hours = mmc_tc[0] & 0xf;
634 smpte.minutes = mmc_tc[1];
635 smpte.seconds = mmc_tc[2];
636 smpte.frames = mmc_tc[3];
637 smpte.rate = smpte_frames_per_second();
638 smpte.drop = smpte_drop_frames();
640 // Also takes smpte offset into account:
641 smpte_to_sample( smpte, target_frame, true /* use_offset */, false /* use_subframes */ );
643 if (target_frame > max_frames) {
644 target_frame = max_frames;
647 /* Some (all?) MTC/MMC devices do not send a full MTC frame
648 at the end of a locate, instead sending only an MMC
649 locate command. This causes the current position
650 of an MTC slave to become out of date. Catch this.
653 MTC_Slave* mtcs = dynamic_cast<MTC_Slave*> (_slave);
656 // cerr << "Locate *with* MTC slave\n";
657 mtcs->handle_locate (mmc_tc);
659 // cerr << "Locate without MTC slave\n";
660 request_locate (target_frame, false);
665 Session::mmc_shuttle (MIDI::MachineControl &mmc, float speed, bool forw)
667 if (!Config->get_mmc_control()) {
671 if (Config->get_shuttle_speed_threshold() >= 0 && speed > Config->get_shuttle_speed_threshold()) {
672 speed *= Config->get_shuttle_speed_factor();
676 request_transport_speed (speed);
678 request_transport_speed (-speed);
683 Session::mmc_record_enable (MIDI::MachineControl &mmc, size_t trk, bool enabled)
685 if (Config->get_mmc_control()) {
687 RouteList::iterator i;
688 boost::shared_ptr<RouteList> r = routes.reader();
690 for (i = r->begin(); i != r->end(); ++i) {
693 if ((at = dynamic_cast<AudioTrack*>((*i).get())) != 0) {
694 if (trk == at->remote_control_id()) {
695 at->set_record_enable (enabled, &mmc);
704 Session::send_full_time_code_in_another_thread ()
706 send_time_code_in_another_thread (true);
710 Session::send_midi_time_code_in_another_thread ()
712 send_time_code_in_another_thread (false);
716 Session::send_time_code_in_another_thread (bool full)
718 nframes_t two_smpte_frames_duration;
719 nframes_t quarter_frame_duration;
721 /* Duration of two smpte frames */
722 two_smpte_frames_duration = ((long) _frames_per_smpte_frame) << 1;
724 /* Duration of one quarter frame */
725 quarter_frame_duration = ((long) _frames_per_smpte_frame) >> 2;
727 if (_transport_frame < (outbound_mtc_smpte_frame + (next_quarter_frame_to_send * quarter_frame_duration)))
729 /* There is no work to do.
730 We throttle this here so that we don't overload
731 the transport thread with requests.
736 MIDIRequest* request = new MIDIRequest;
739 request->type = MIDIRequest::SendFullMTC;
741 request->type = MIDIRequest::SendMTC;
744 midi_requests.write (&request, 1);
749 Session::change_midi_ports ()
751 MIDIRequest* request = new MIDIRequest;
753 request->type = MIDIRequest::PortChange;
754 midi_requests.write (&request, 1);
759 Session::send_full_time_code ()
765 if (_mtc_port == 0 || !session_send_mtc) {
769 // Get smpte time for this transport frame
770 sample_to_smpte(_transport_frame, smpte, true /* use_offset */, false /* no subframes */);
772 // Check for negative smpte time and prepare for quarter frame transmission
773 if (smpte.negative) {
774 // Negative mtc is not defined, so sync slave to smpte zero.
775 // When _transport_frame gets there we will start transmitting quarter frames
781 smpte.negative = false;
782 smpte_to_sample( smpte, outbound_mtc_smpte_frame, true, false );
783 transmitting_smpte_time = smpte;
785 transmitting_smpte_time = smpte;
786 outbound_mtc_smpte_frame = _transport_frame;
787 if (((mtc_smpte_bits >> 5) != MIDI::MTC_25_FPS) && (transmitting_smpte_time.frames % 2)) {
788 // start MTC quarter frame transmission on an even frame
789 SMPTE::increment( transmitting_smpte_time );
790 outbound_mtc_smpte_frame += (nframes_t) _frames_per_smpte_frame;
794 // Compensate for audio latency
795 outbound_mtc_smpte_frame += _worst_output_latency;
797 next_quarter_frame_to_send = 0;
799 // Sync slave to the same smpte time as we are on (except if negative, see above)
807 msg[5] = mtc_smpte_bits | smpte.hours;
808 msg[6] = smpte.minutes;
809 msg[7] = smpte.seconds;
810 msg[8] = smpte.frames;
813 Glib::Mutex::Lock lm (midi_lock);
815 if (_mtc_port->midimsg (msg, sizeof (msg))) {
816 error << _("Session: could not send full MIDI time code") << endmsg;
826 Session::send_midi_time_code ()
828 if (_mtc_port == 0 || !session_send_mtc || transmitting_smpte_time.negative || (next_quarter_frame_to_send < 0) ) {
832 nframes_t two_smpte_frames_duration;
833 nframes_t quarter_frame_duration;
835 /* Duration of two smpte frames */
836 two_smpte_frames_duration = ((long) _frames_per_smpte_frame) << 1;
838 /* Duration of one quarter frame */
839 quarter_frame_duration = ((long) _frames_per_smpte_frame) >> 2;
841 while (_transport_frame >= (outbound_mtc_smpte_frame + (next_quarter_frame_to_send * quarter_frame_duration))) {
843 // Send quarter frames up to current time
845 Glib::Mutex::Lock lm (midi_lock);
847 switch(next_quarter_frame_to_send) {
849 mtc_msg[1] = 0x00 | (transmitting_smpte_time.frames & 0xf);
852 mtc_msg[1] = 0x10 | ((transmitting_smpte_time.frames & 0xf0) >> 4);
855 mtc_msg[1] = 0x20 | (transmitting_smpte_time.seconds & 0xf);
858 mtc_msg[1] = 0x30 | ((transmitting_smpte_time.seconds & 0xf0) >> 4);
861 mtc_msg[1] = 0x40 | (transmitting_smpte_time.minutes & 0xf);
864 mtc_msg[1] = 0x50 | ((transmitting_smpte_time.minutes & 0xf0) >> 4);
867 mtc_msg[1] = 0x60 | ((mtc_smpte_bits|transmitting_smpte_time.hours) & 0xf);
870 mtc_msg[1] = 0x70 | (((mtc_smpte_bits|transmitting_smpte_time.hours) & 0xf0) >> 4);
874 if (_mtc_port->midimsg (mtc_msg, 2)) {
875 error << string_compose(_("Session: cannot send quarter-frame MTC message (%1)"), strerror (errno))
881 // 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;
883 // Increment quarter frame counter
884 next_quarter_frame_to_send++;
886 if (next_quarter_frame_to_send >= 8) {
887 // Wrap quarter frame counter
888 next_quarter_frame_to_send = 0;
889 // Increment smpte time twice
890 SMPTE::increment( transmitting_smpte_time );
891 SMPTE::increment( transmitting_smpte_time );
892 // Re-calculate timing of first quarter frame
893 smpte_to_sample( transmitting_smpte_time, outbound_mtc_smpte_frame, true /* use_offset */, false );
894 // Compensate for audio latency
895 outbound_mtc_smpte_frame += _worst_output_latency;
902 /***********************************************************************
904 **********************************************************************/
907 Session::send_mmc_in_another_thread (MIDI::MachineControl::Command cmd, nframes_t target_frame)
909 MIDIRequest* request;
911 if (_mtc_port == 0 || !session_send_mmc) {
915 request = new MIDIRequest;
916 request->type = MIDIRequest::SendMMC;
917 request->mmc_cmd = cmd;
918 request->locate_frame = target_frame;
920 midi_requests.write (&request, 1);
925 Session::deliver_mmc (MIDI::MachineControl::Command cmd, nframes_t where)
927 using namespace MIDI;
931 if (_mmc_port == 0 || !session_send_mmc) {
935 mmc_buffer[nbytes++] = cmd;
937 // cerr << "delivering MMC, cmd = " << hex << (int) cmd << dec << endl;
940 case MachineControl::cmdLocate:
941 smpte_time_subframes (where, smpte);
943 mmc_buffer[nbytes++] = 0x6; // byte count
944 mmc_buffer[nbytes++] = 0x1; // "TARGET" subcommand
945 mmc_buffer[nbytes++] = smpte.hours;
946 mmc_buffer[nbytes++] = smpte.minutes;
947 mmc_buffer[nbytes++] = smpte.seconds;
948 mmc_buffer[nbytes++] = smpte.frames;
949 mmc_buffer[nbytes++] = smpte.subframes;
952 case MachineControl::cmdStop:
955 case MachineControl::cmdPlay:
956 /* always convert Play into Deferred Play */
957 mmc_buffer[4] = MachineControl::cmdDeferredPlay;
960 case MachineControl::cmdDeferredPlay:
963 case MachineControl::cmdRecordStrobe:
966 case MachineControl::cmdRecordExit:
969 case MachineControl::cmdRecordPause:
978 mmc_buffer[nbytes++] = 0xf7; // terminate SysEx/MMC message
980 Glib::Mutex::Lock lm (midi_lock);
982 if (_mmc_port->write (mmc_buffer, nbytes) != nbytes) {
983 error << string_compose(_("MMC: cannot send command %1%2%3"), &hex, cmd, &dec) << endmsg;
989 Session::mmc_step_timeout ()
994 gettimeofday (&now, 0);
996 timersub (&now, &last_mmc_step, &diff);
997 diff_usecs = diff.tv_sec * 1000000 + diff.tv_usec;
999 if (diff_usecs > 1000000.0 || fabs (_transport_speed) < 0.0000001) {
1000 /* too long or too slow, stop transport */
1001 request_transport_speed (0.0);
1002 step_queued = false;
1006 if (diff_usecs < 250000.0) {
1007 /* too short, just keep going */
1013 request_transport_speed (_transport_speed * 0.75);
1019 Session::send_midi_message (MIDI::Port * port, MIDI::eventType ev, MIDI::channel_t ch, MIDI::EventTwoBytes data)
1021 // in another thread, really
1023 MIDIRequest* request = new MIDIRequest;
1025 request->type = MIDIRequest::SendMessage;
1026 request->port = port;
1029 request->data = data;
1031 midi_requests.write (&request, 1);
1032 poke_midi_thread ();
1036 Session::deliver_midi (MIDI::Port * port, MIDI::byte* buf, int32_t bufsize)
1038 // in another thread, really
1040 MIDIRequest* request = new MIDIRequest;
1042 request->type = MIDIRequest::Deliver;
1043 request->port = port;
1045 request->size = bufsize;
1047 midi_requests.write (&request, 1);
1048 poke_midi_thread ();
1052 Session::deliver_midi_message (MIDI::Port * port, MIDI::eventType ev, MIDI::channel_t ch, MIDI::EventTwoBytes data)
1054 if (port == 0 || ev == MIDI::none) {
1058 midi_msg[0] = (ev & 0xF0) | (ch & 0xF);
1059 midi_msg[1] = data.controller_number;
1060 midi_msg[2] = data.value;
1062 port->write (midi_msg, 3);
1066 Session::deliver_data (MIDI::Port * port, MIDI::byte* buf, int32_t size)
1069 port->write (buf, size);
1072 /* this is part of the semantics of the Deliver request */
1077 /*---------------------------------------------------------------------------
1079 ---------------------------------------------------------------------------*/
1082 Session::start_midi_thread ()
1084 if (pipe (midi_request_pipe)) {
1085 error << string_compose(_("Cannot create transport request signal pipe (%1)"), strerror (errno)) << endmsg;
1089 if (fcntl (midi_request_pipe[0], F_SETFL, O_NONBLOCK)) {
1090 error << string_compose(_("UI: cannot set O_NONBLOCK on " "signal read pipe (%1)"), strerror (errno)) << endmsg;
1094 if (fcntl (midi_request_pipe[1], F_SETFL, O_NONBLOCK)) {
1095 error << string_compose(_("UI: cannot set O_NONBLOCK on " "signal write pipe (%1)"), strerror (errno)) << endmsg;
1099 if (pthread_create_and_store ("transport", &midi_thread, 0, _midi_thread_work, this)) {
1100 error << _("Session: could not create transport thread") << endmsg;
1104 // pthread_detach (midi_thread);
1110 Session::terminate_midi_thread ()
1113 MIDIRequest* request = new MIDIRequest;
1116 request->type = MIDIRequest::Quit;
1118 midi_requests.write (&request, 1);
1119 poke_midi_thread ();
1121 pthread_join (midi_thread, &status);
1126 Session::poke_midi_thread ()
1130 if (write (midi_request_pipe[1], &c, 1) != 1) {
1131 error << string_compose(_("cannot send signal to midi thread! (%1)"), strerror (errno)) << endmsg;
1136 Session::_midi_thread_work (void* arg)
1138 pthread_setcancelstate (PTHREAD_CANCEL_ENABLE, 0);
1139 pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, 0);
1141 ((Session *) arg)->midi_thread_work ();
1146 Session::midi_thread_work ()
1148 MIDIRequest* request;
1149 struct pollfd pfd[4];
1153 struct sched_param rtparam;
1156 vector<MIDI::Port*> ports;
1158 PBD::notify_gui_about_thread_creation (pthread_self(), X_("MIDI"), 2048);
1160 memset (&rtparam, 0, sizeof (rtparam));
1161 rtparam.sched_priority = 9; /* XXX should be relative to audio (JACK) thread */
1163 if ((x = pthread_setschedparam (pthread_self(), SCHED_FIFO, &rtparam)) != 0) {
1164 // do we care? not particularly.
1167 /* set up the port vector; 4 is the largest possible size for now */
1169 ports.push_back (0);
1170 ports.push_back (0);
1171 ports.push_back (0);
1172 ports.push_back (0);
1178 pfd[nfds].fd = midi_request_pipe[0];
1179 pfd[nfds].events = POLLIN|POLLHUP|POLLERR;
1182 /* if we are using MMC control, we obviously have to listen
1183 on the appropriate port.
1186 if (Config->get_mmc_control() && _mmc_port && _mmc_port->selectable() >= 0) {
1187 pfd[nfds].fd = _mmc_port->selectable();
1188 pfd[nfds].events = POLLIN|POLLHUP|POLLERR;
1189 ports[nfds] = _mmc_port;
1190 //cerr << "MIDI port " << nfds << " = MMC @ " << _mmc_port << endl;
1194 /* if MTC is being handled on a different port from MMC
1195 or we are not handling MMC at all, poll
1199 if (_mtc_port && (_mtc_port != _mmc_port || !Config->get_mmc_control()) && _mtc_port->selectable() >= 0) {
1200 pfd[nfds].fd = _mtc_port->selectable();
1201 pfd[nfds].events = POLLIN|POLLHUP|POLLERR;
1202 ports[nfds] = _mtc_port;
1203 //cerr << "MIDI port " << nfds << " = MTC @ " << _mtc_port << endl;
1207 if (_midi_port && (_midi_port != _mmc_port || !Config->get_mmc_control()) && (_midi_port != _mtc_port) && _midi_port->selectable() >= 0) {
1208 pfd[nfds].fd = _midi_port->selectable();
1209 pfd[nfds].events = POLLIN|POLLHUP|POLLERR;
1210 ports[nfds] = _midi_port;
1211 // cerr << "MIDI port " << nfds << " = MIDI @ " << _midi_port << endl;
1215 if (!midi_timeouts.empty()) {
1216 timeout = 100; /* 10msecs */
1218 timeout = -1; /* if there is no data, we don't care */
1222 // cerr << "MIDI poll on " << nfds << " for " << timeout << endl;
1223 if (poll (pfd, nfds, timeout) < 0) {
1224 if (errno == EINTR) {
1225 /* gdb at work, perhaps */
1229 error << string_compose(_("MIDI thread poll failed (%1)"), strerror (errno)) << endmsg;
1233 // cerr << "MIDI thread wakes at " << get_cycles () << endl;
1238 /* check the transport request pipe */
1240 if (pfd[0].revents & ~POLLIN) {
1241 error << _("Error on transport thread request pipe") << endmsg;
1245 if (pfd[0].revents & POLLIN) {
1249 // cerr << "MIDI request FIFO ready\n";
1252 /* empty the pipe of all current requests */
1255 size_t nread = read (midi_request_pipe[0], &foo, sizeof (foo));
1258 if ((size_t) nread < sizeof (foo)) {
1263 } else if (nread == 0) {
1265 } else if (errno == EAGAIN) {
1268 fatal << _("Error reading from transport request pipe") << endmsg;
1273 while (midi_requests.read (&request, 1) == 1) {
1275 switch (request->type) {
1277 case MIDIRequest::SendFullMTC:
1278 // cerr << "send full MTC\n";
1279 send_full_time_code ();
1280 // cerr << "... done\n";
1283 case MIDIRequest::SendMTC:
1284 // cerr << "send qtr MTC\n";
1285 send_midi_time_code ();
1286 // cerr << "... done\n";
1289 case MIDIRequest::SendMMC:
1290 // cerr << "send MMC\n";
1291 deliver_mmc (request->mmc_cmd, request->locate_frame);
1292 // cerr << "... done\n";
1295 case MIDIRequest::SendMessage:
1296 // cerr << "send Message\n";
1297 deliver_midi_message (request->port, request->ev, request->chan, request->data);
1298 // cerr << "... done\n";
1301 case MIDIRequest::Deliver:
1302 // cerr << "deliver\n";
1303 deliver_data (_midi_port, request->buf, request->size);
1304 // cerr << "... done\n";
1307 case MIDIRequest::PortChange:
1308 /* restart poll with new ports */
1309 // cerr << "rebind\n";
1313 case MIDIRequest::Quit:
1315 pthread_exit_pbd (0);
1333 /* now read the rest of the ports */
1335 for (int p = 1; p < nfds; ++p) {
1336 if ((pfd[p].revents & ~POLLIN)) {
1337 // error << string_compose(_("Transport: error polling MIDI port %1 (revents =%2%3%4"), p, &hex, pfd[p].revents, &dec) << endmsg;
1341 if (pfd[p].revents & POLLIN) {
1343 midi_read (ports[p]);
1347 /* timeout driven */
1349 if (fds_ready < 2 && timeout != -1) {
1351 for (MidiTimeoutList::iterator i = midi_timeouts.begin(); i != midi_timeouts.end(); ) {
1353 MidiTimeoutList::iterator tmp;
1358 midi_timeouts.erase (i);