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_mtc_port (string port_tag)
92 if (port_tag.length() == 0) {
94 if (_slave && ((ms = dynamic_cast<MTC_Slave*> (_slave)) != 0)) {
95 error << _("Ardour is slaved to MTC - port cannot be reset") << endmsg;
109 if ((port = MIDI::Manager::instance()->port (port_tag)) == 0) {
110 error << string_compose (_("unknown port %1 requested for MTC"), port_tag) << endl;
116 if (_slave && ((ms = dynamic_cast<MTC_Slave*> (_slave)) != 0)) {
120 Config->set_mtc_port_name (port_tag);
123 MTC_PortChanged(); /* EMIT SIGNAL */
124 change_midi_ports ();
130 Session::set_mmc_port (string port_tag)
132 if (port_tag.length() == 0) {
133 if (_mmc_port == 0) {
142 if ((port = MIDI::Manager::instance()->port (port_tag)) == 0) {
152 mmc = new MIDI::MachineControl (*_mmc_port, 1.0,
153 MMC_CommandSignature,
154 MMC_ResponseSignature);
158 (mem_fun (*this, &Session::mmc_deferred_play));
159 mmc->DeferredPlay.connect
160 (mem_fun (*this, &Session::mmc_deferred_play));
162 (mem_fun (*this, &Session::mmc_stop));
163 mmc->FastForward.connect
164 (mem_fun (*this, &Session::mmc_fast_forward));
166 (mem_fun (*this, &Session::mmc_rewind));
168 (mem_fun (*this, &Session::mmc_pause));
169 mmc->RecordPause.connect
170 (mem_fun (*this, &Session::mmc_record_pause));
171 mmc->RecordStrobe.connect
172 (mem_fun (*this, &Session::mmc_record_strobe));
173 mmc->RecordExit.connect
174 (mem_fun (*this, &Session::mmc_record_exit));
176 (mem_fun (*this, &Session::mmc_locate));
178 (mem_fun (*this, &Session::mmc_step));
180 (mem_fun (*this, &Session::mmc_shuttle));
181 mmc->TrackRecordStatusChange.connect
182 (mem_fun (*this, &Session::mmc_record_enable));
184 /* also handle MIDI SPP because its so common */
186 _mmc_port->input()->start.connect (mem_fun (*this, &Session::spp_start));
187 _mmc_port->input()->contineu.connect (mem_fun (*this, &Session::spp_continue));
188 _mmc_port->input()->stop.connect (mem_fun (*this, &Session::spp_stop));
190 Config->set_mmc_port_name (port_tag);
193 MMC_PortChanged(); /* EMIT SIGNAL */
194 change_midi_ports ();
200 Session::set_midi_port (string port_tag)
202 if (port_tag.length() == 0) {
203 if (_midi_port == 0) {
212 if ((port = MIDI::Manager::instance()->port (port_tag)) == 0) {
218 /* XXX need something to forward this to control protocols ? or just
222 Config->set_midi_port_name (port_tag);
225 MIDI_PortChanged(); /* EMIT SIGNAL */
226 change_midi_ports ();
232 Session::set_trace_midi_input (bool yn, MIDI::Port* port)
234 MIDI::Parser* input_parser;
237 if ((input_parser = port->input()) != 0) {
238 input_parser->trace (yn, &cout, "input: ");
243 if ((input_parser = _mmc_port->input()) != 0) {
244 input_parser->trace (yn, &cout, "input: ");
248 if (_mtc_port && _mtc_port != _mmc_port) {
249 if ((input_parser = _mtc_port->input()) != 0) {
250 input_parser->trace (yn, &cout, "input: ");
254 if (_midi_port && _midi_port != _mmc_port && _midi_port != _mtc_port ) {
255 if ((input_parser = _midi_port->input()) != 0) {
256 input_parser->trace (yn, &cout, "input: ");
261 Config->set_trace_midi_input (yn);
265 Session::set_trace_midi_output (bool yn, MIDI::Port* port)
267 MIDI::Parser* output_parser;
270 if ((output_parser = port->output()) != 0) {
271 output_parser->trace (yn, &cout, "output: ");
275 if ((output_parser = _mmc_port->output()) != 0) {
276 output_parser->trace (yn, &cout, "output: ");
280 if (_mtc_port && _mtc_port != _mmc_port) {
281 if ((output_parser = _mtc_port->output()) != 0) {
282 output_parser->trace (yn, &cout, "output: ");
286 if (_midi_port && _midi_port != _mmc_port && _midi_port != _mtc_port ) {
287 if ((output_parser = _midi_port->output()) != 0) {
288 output_parser->trace (yn, &cout, "output: ");
294 Config->set_trace_midi_output (yn);
298 Session::get_trace_midi_input(MIDI::Port *port)
300 MIDI::Parser* input_parser;
302 if ((input_parser = port->input()) != 0) {
303 return input_parser->tracing();
308 if ((input_parser = _mmc_port->input()) != 0) {
309 return input_parser->tracing();
314 if ((input_parser = _mtc_port->input()) != 0) {
315 return input_parser->tracing();
320 if ((input_parser = _midi_port->input()) != 0) {
321 return input_parser->tracing();
330 Session::get_trace_midi_output(MIDI::Port *port)
332 MIDI::Parser* output_parser;
334 if ((output_parser = port->output()) != 0) {
335 return output_parser->tracing();
340 if ((output_parser = _mmc_port->output()) != 0) {
341 return output_parser->tracing();
346 if ((output_parser = _mtc_port->output()) != 0) {
347 return output_parser->tracing();
352 if ((output_parser = _midi_port->output()) != 0) {
353 return output_parser->tracing();
363 Session::setup_midi_control ()
365 outbound_mtc_smpte_frame = 0;
366 next_quarter_frame_to_send = -1;
368 /* setup the MMC buffer */
370 mmc_buffer[0] = 0xf0; // SysEx
371 mmc_buffer[1] = 0x7f; // Real Time SysEx ID for MMC
372 mmc_buffer[2] = 0x7f; // "broadcast" device ID
373 mmc_buffer[3] = 0x6; // MCC
375 /* Set up the qtr frame message */
386 if (_mmc_port != 0) {
388 Config->set_send_mmc (session_send_mmc);
393 session_send_mmc = false;
396 if (_mtc_port != 0) {
398 Config->set_send_mtc (session_send_mtc);
401 session_send_mtc = false;
406 Session::midi_read (MIDI::Port* port)
410 /* reading from the MIDI port activates the Parser
411 that in turn generates signals that we care
412 about. the port is already set to NONBLOCK so that
413 can read freely here.
418 // cerr << "+++ READ ON " << port->name() << endl;
420 int nread = port->read (buf, sizeof (buf));
422 // cerr << "-- READ (" << nread << " ON " << port->name() << endl;
425 if ((size_t) nread < sizeof (buf)) {
430 } else if (nread == 0) {
432 } else if (errno == EAGAIN) {
435 fatal << string_compose(_("Error reading from MIDI port %1"), port->name()) << endmsg;
444 Session::spp_start (Parser& ignored)
446 if (Config->get_mmc_control() && (Config->get_slave_source() != MTC)) {
447 request_transport_speed (1.0);
452 Session::spp_continue (Parser& ignored)
458 Session::spp_stop (Parser& ignored)
460 if (Config->get_mmc_control()) {
466 Session::mmc_deferred_play (MIDI::MachineControl &mmc)
468 if (Config->get_mmc_control() && (Config->get_slave_source() != MTC)) {
469 request_transport_speed (1.0);
474 Session::mmc_record_pause (MIDI::MachineControl &mmc)
476 if (Config->get_mmc_control()) {
477 maybe_enable_record();
482 Session::mmc_record_strobe (MIDI::MachineControl &mmc)
484 if (!Config->get_mmc_control())
487 /* record strobe does an implicit "Play" command */
489 if (_transport_speed != 1.0) {
491 /* start_transport() will move from Enabled->Recording, so we
492 don't need to do anything here except enable recording.
493 its not the same as maybe_enable_record() though, because
494 that *can* switch to Recording, which we do not want.
497 save_state ("", true);
498 g_atomic_int_set (&_record_status, Enabled);
499 RecordStateChanged (); /* EMIT SIGNAL */
501 request_transport_speed (1.0);
510 Session::mmc_record_exit (MIDI::MachineControl &mmc)
512 if (Config->get_mmc_control()) {
513 disable_record (false);
518 Session::mmc_stop (MIDI::MachineControl &mmc)
520 if (Config->get_mmc_control()) {
526 Session::mmc_pause (MIDI::MachineControl &mmc)
528 if (Config->get_mmc_control()) {
530 /* We support RECORD_PAUSE, so the spec says that
531 we must interpret PAUSE like RECORD_PAUSE if
535 if (actively_recording()) {
536 maybe_enable_record ();
543 static bool step_queued = false;
547 Session::mmc_step (MIDI::MachineControl &mmc, int steps)
549 if (!Config->get_mmc_control()) {
554 struct timeval diff = { 0, 0 };
556 gettimeofday (&now, 0);
558 timersub (&now, &last_mmc_step, &diff);
560 gettimeofday (&now, 0);
561 timersub (&now, &last_mmc_step, &diff);
563 if (last_mmc_step.tv_sec != 0 && (diff.tv_usec + (diff.tv_sec * 1000000)) < _engine.usecs_per_cycle()) {
567 double diff_secs = diff.tv_sec + (diff.tv_usec / 1000000.0);
568 double cur_speed = (((steps * 0.5) * Config->get_smpte_frames_per_second()) / diff_secs) / Config->get_smpte_frames_per_second();
570 if (_transport_speed == 0 || cur_speed * _transport_speed < 0) {
571 /* change direction */
572 step_speed = cur_speed;
574 step_speed = (0.6 * step_speed) + (0.4 * cur_speed);
580 cerr << "delta = " << diff_secs
581 << " ct = " << _transport_speed
582 << " steps = " << steps
583 << " new speed = " << cur_speed
584 << " speed = " << step_speed
588 request_transport_speed (step_speed);
592 midi_timeouts.push_back (mem_fun (*this, &Session::mmc_step_timeout));
598 Session::mmc_rewind (MIDI::MachineControl &mmc)
600 if (Config->get_mmc_control()) {
601 request_transport_speed(-8.0f);
606 Session::mmc_fast_forward (MIDI::MachineControl &mmc)
608 if (Config->get_mmc_control()) {
609 request_transport_speed(8.0f);
614 Session::mmc_locate (MIDI::MachineControl &mmc, const MIDI::byte* mmc_tc)
616 if (!Config->get_mmc_control()) {
620 nframes_t target_frame;
623 smpte.hours = mmc_tc[0] & 0xf;
624 smpte.minutes = mmc_tc[1];
625 smpte.seconds = mmc_tc[2];
626 smpte.frames = mmc_tc[3];
628 // Also takes smpte offset into account:
629 smpte_to_sample( smpte, target_frame, true /* use_offset */, false /* use_subframes */ );
631 if (target_frame > max_frames) {
632 target_frame = max_frames;
635 /* Some (all?) MTC/MMC devices do not send a full MTC frame
636 at the end of a locate, instead sending only an MMC
637 locate command. This causes the current position
638 of an MTC slave to become out of date. Catch this.
641 MTC_Slave* mtcs = dynamic_cast<MTC_Slave*> (_slave);
644 // cerr << "Locate *with* MTC slave\n";
645 mtcs->handle_locate (mmc_tc);
647 // cerr << "Locate without MTC slave\n";
648 request_locate (target_frame, false);
653 Session::mmc_shuttle (MIDI::MachineControl &mmc, float speed, bool forw)
655 if (!Config->get_mmc_control()) {
659 if (Config->get_shuttle_speed_threshold() >= 0 && speed > Config->get_shuttle_speed_threshold()) {
660 speed *= Config->get_shuttle_speed_factor();
664 request_transport_speed (speed);
666 request_transport_speed (-speed);
671 Session::mmc_record_enable (MIDI::MachineControl &mmc, size_t trk, bool enabled)
673 if (Config->get_mmc_control()) {
675 RouteList::iterator i;
676 boost::shared_ptr<RouteList> r = routes.reader();
678 for (i = r->begin(); i != r->end(); ++i) {
681 if ((at = dynamic_cast<AudioTrack*>((*i).get())) != 0) {
682 if (trk == at->remote_control_id()) {
683 at->set_record_enable (enabled, &mmc);
692 Session::send_full_time_code_in_another_thread ()
694 send_time_code_in_another_thread (true);
698 Session::send_midi_time_code_in_another_thread ()
700 send_time_code_in_another_thread (false);
704 Session::send_time_code_in_another_thread (bool full)
706 nframes_t two_smpte_frames_duration;
707 nframes_t quarter_frame_duration;
709 /* Duration of two smpte frames */
710 two_smpte_frames_duration = ((long) _frames_per_smpte_frame) << 1;
712 /* Duration of one quarter frame */
713 quarter_frame_duration = ((long) _frames_per_smpte_frame) >> 2;
715 if (_transport_frame < (outbound_mtc_smpte_frame + (next_quarter_frame_to_send * quarter_frame_duration)))
717 /* There is no work to do.
718 We throttle this here so that we don't overload
719 the transport thread with requests.
724 MIDIRequest* request = new MIDIRequest;
727 request->type = MIDIRequest::SendFullMTC;
729 request->type = MIDIRequest::SendMTC;
732 midi_requests.write (&request, 1);
737 Session::change_midi_ports ()
739 MIDIRequest* request = new MIDIRequest;
741 request->type = MIDIRequest::PortChange;
742 midi_requests.write (&request, 1);
747 Session::send_full_time_code ()
753 if (_mtc_port == 0 || !session_send_mtc) {
757 // Get smpte time for this transport frame
758 sample_to_smpte(_transport_frame, smpte, true /* use_offset */, false /* no subframes */);
760 // Check for negative smpte time and prepare for quarter frame transmission
761 if (smpte.negative) {
762 // Negative mtc is not defined, so sync slave to smpte zero.
763 // When _transport_frame gets there we will start transmitting quarter frames
769 smpte.negative = false;
770 smpte_to_sample( smpte, outbound_mtc_smpte_frame, true, false );
771 transmitting_smpte_time = smpte;
773 transmitting_smpte_time = smpte;
774 outbound_mtc_smpte_frame = _transport_frame;
775 if (((mtc_smpte_bits >> 5) != MIDI::MTC_25_FPS) && (transmitting_smpte_time.frames % 2)) {
776 // start MTC quarter frame transmission on an even frame
777 SMPTE::increment( transmitting_smpte_time );
778 outbound_mtc_smpte_frame += (nframes_t) _frames_per_smpte_frame;
782 // Compensate for audio latency
783 outbound_mtc_smpte_frame += _worst_output_latency;
785 next_quarter_frame_to_send = 0;
787 // Sync slave to the same smpte time as we are on (except if negative, see above)
795 msg[5] = mtc_smpte_bits | smpte.hours;
796 msg[6] = smpte.minutes;
797 msg[7] = smpte.seconds;
798 msg[8] = smpte.frames;
801 Glib::Mutex::Lock lm (midi_lock);
803 if (_mtc_port->midimsg (msg, sizeof (msg))) {
804 error << _("Session: could not send full MIDI time code") << endmsg;
814 Session::send_midi_time_code ()
816 if (_mtc_port == 0 || !session_send_mtc || transmitting_smpte_time.negative || (next_quarter_frame_to_send < 0) ) {
820 nframes_t two_smpte_frames_duration;
821 nframes_t quarter_frame_duration;
823 /* Duration of two smpte frames */
824 two_smpte_frames_duration = ((long) _frames_per_smpte_frame) << 1;
826 /* Duration of one quarter frame */
827 quarter_frame_duration = ((long) _frames_per_smpte_frame) >> 2;
829 while (_transport_frame >= (outbound_mtc_smpte_frame + (next_quarter_frame_to_send * quarter_frame_duration))) {
831 // Send quarter frames up to current time
833 Glib::Mutex::Lock lm (midi_lock);
835 switch(next_quarter_frame_to_send) {
837 mtc_msg[1] = 0x00 | (transmitting_smpte_time.frames & 0xf);
840 mtc_msg[1] = 0x10 | ((transmitting_smpte_time.frames & 0xf0) >> 4);
843 mtc_msg[1] = 0x20 | (transmitting_smpte_time.seconds & 0xf);
846 mtc_msg[1] = 0x30 | ((transmitting_smpte_time.seconds & 0xf0) >> 4);
849 mtc_msg[1] = 0x40 | (transmitting_smpte_time.minutes & 0xf);
852 mtc_msg[1] = 0x50 | ((transmitting_smpte_time.minutes & 0xf0) >> 4);
855 mtc_msg[1] = 0x60 | ((mtc_smpte_bits|transmitting_smpte_time.hours) & 0xf);
858 mtc_msg[1] = 0x70 | (((mtc_smpte_bits|transmitting_smpte_time.hours) & 0xf0) >> 4);
862 if (_mtc_port->midimsg (mtc_msg, 2)) {
863 error << string_compose(_("Session: cannot send quarter-frame MTC message (%1)"), strerror (errno))
869 // 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;
871 // Increment quarter frame counter
872 next_quarter_frame_to_send++;
874 if (next_quarter_frame_to_send >= 8) {
875 // Wrap quarter frame counter
876 next_quarter_frame_to_send = 0;
877 // Increment smpte time twice
878 SMPTE::increment( transmitting_smpte_time );
879 SMPTE::increment( transmitting_smpte_time );
880 // Re-calculate timing of first quarter frame
881 smpte_to_sample( transmitting_smpte_time, outbound_mtc_smpte_frame, true /* use_offset */, false );
882 // Compensate for audio latency
883 outbound_mtc_smpte_frame += _worst_output_latency;
890 /***********************************************************************
892 **********************************************************************/
895 Session::send_mmc_in_another_thread (MIDI::MachineControl::Command cmd, nframes_t target_frame)
897 MIDIRequest* request;
899 if (_mtc_port == 0 || !session_send_mmc) {
903 request = new MIDIRequest;
904 request->type = MIDIRequest::SendMMC;
905 request->mmc_cmd = cmd;
906 request->locate_frame = target_frame;
908 midi_requests.write (&request, 1);
913 Session::deliver_mmc (MIDI::MachineControl::Command cmd, nframes_t where)
915 using namespace MIDI;
919 if (_mmc_port == 0 || !session_send_mmc) {
923 mmc_buffer[nbytes++] = cmd;
925 // cerr << "delivering MMC, cmd = " << hex << (int) cmd << dec << endl;
928 case MachineControl::cmdLocate:
929 smpte_time_subframes (where, smpte);
931 mmc_buffer[nbytes++] = 0x6; // byte count
932 mmc_buffer[nbytes++] = 0x1; // "TARGET" subcommand
933 mmc_buffer[nbytes++] = smpte.hours;
934 mmc_buffer[nbytes++] = smpte.minutes;
935 mmc_buffer[nbytes++] = smpte.seconds;
936 mmc_buffer[nbytes++] = smpte.frames;
937 mmc_buffer[nbytes++] = smpte.subframes;
940 case MachineControl::cmdStop:
943 case MachineControl::cmdPlay:
944 /* always convert Play into Deferred Play */
945 mmc_buffer[4] = MachineControl::cmdDeferredPlay;
948 case MachineControl::cmdDeferredPlay:
951 case MachineControl::cmdRecordStrobe:
954 case MachineControl::cmdRecordExit:
957 case MachineControl::cmdRecordPause:
966 mmc_buffer[nbytes++] = 0xf7; // terminate SysEx/MMC message
968 Glib::Mutex::Lock lm (midi_lock);
970 if (_mmc_port->write (mmc_buffer, nbytes) != nbytes) {
971 error << string_compose(_("MMC: cannot send command %1%2%3"), &hex, cmd, &dec) << endmsg;
977 Session::mmc_step_timeout ()
982 gettimeofday (&now, 0);
984 timersub (&now, &last_mmc_step, &diff);
985 diff_usecs = diff.tv_sec * 1000000 + diff.tv_usec;
987 if (diff_usecs > 1000000.0 || fabs (_transport_speed) < 0.0000001) {
988 /* too long or too slow, stop transport */
989 request_transport_speed (0.0);
994 if (diff_usecs < 250000.0) {
995 /* too short, just keep going */
1001 request_transport_speed (_transport_speed * 0.75);
1007 Session::send_midi_message (MIDI::Port * port, MIDI::eventType ev, MIDI::channel_t ch, MIDI::EventTwoBytes data)
1009 // in another thread, really
1011 MIDIRequest* request = new MIDIRequest;
1013 request->type = MIDIRequest::SendMessage;
1014 request->port = port;
1017 request->data = data;
1019 midi_requests.write (&request, 1);
1020 poke_midi_thread ();
1024 Session::deliver_midi (MIDI::Port * port, MIDI::byte* buf, int32_t bufsize)
1026 // in another thread, really
1028 MIDIRequest* request = new MIDIRequest;
1030 request->type = MIDIRequest::Deliver;
1031 request->port = port;
1033 request->size = bufsize;
1035 midi_requests.write (&request, 1);
1036 poke_midi_thread ();
1040 Session::deliver_midi_message (MIDI::Port * port, MIDI::eventType ev, MIDI::channel_t ch, MIDI::EventTwoBytes data)
1042 if (port == 0 || ev == MIDI::none) {
1046 midi_msg[0] = (ev & 0xF0) | (ch & 0xF);
1047 midi_msg[1] = data.controller_number;
1048 midi_msg[2] = data.value;
1050 port->write (midi_msg, 3);
1054 Session::deliver_data (MIDI::Port * port, MIDI::byte* buf, int32_t size)
1057 port->write (buf, size);
1060 /* this is part of the semantics of the Deliver request */
1065 /*---------------------------------------------------------------------------
1067 ---------------------------------------------------------------------------*/
1070 Session::start_midi_thread ()
1072 if (pipe (midi_request_pipe)) {
1073 error << string_compose(_("Cannot create transport request signal pipe (%1)"), strerror (errno)) << endmsg;
1077 if (fcntl (midi_request_pipe[0], F_SETFL, O_NONBLOCK)) {
1078 error << string_compose(_("UI: cannot set O_NONBLOCK on " "signal read pipe (%1)"), strerror (errno)) << endmsg;
1082 if (fcntl (midi_request_pipe[1], F_SETFL, O_NONBLOCK)) {
1083 error << string_compose(_("UI: cannot set O_NONBLOCK on " "signal write pipe (%1)"), strerror (errno)) << endmsg;
1087 if (pthread_create_and_store ("transport", &midi_thread, 0, _midi_thread_work, this)) {
1088 error << _("Session: could not create transport thread") << endmsg;
1092 // pthread_detach (midi_thread);
1098 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);
1112 Session::poke_midi_thread ()
1116 if (write (midi_request_pipe[1], &c, 1) != 1) {
1117 error << string_compose(_("cannot send signal to midi thread! (%1)"), strerror (errno)) << endmsg;
1122 Session::_midi_thread_work (void* arg)
1124 pthread_setcancelstate (PTHREAD_CANCEL_ENABLE, 0);
1125 pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, 0);
1127 ((Session *) arg)->midi_thread_work ();
1132 Session::midi_thread_work ()
1134 MIDIRequest* request;
1135 struct pollfd pfd[4];
1139 struct sched_param rtparam;
1142 vector<MIDI::Port*> ports;
1144 PBD::ThreadCreatedWithRequestSize (pthread_self(), X_("MIDI"), 2048);
1146 memset (&rtparam, 0, sizeof (rtparam));
1147 rtparam.sched_priority = 9; /* XXX should be relative to audio (JACK) thread */
1149 if ((x = pthread_setschedparam (pthread_self(), SCHED_FIFO, &rtparam)) != 0) {
1150 // do we care? not particularly.
1153 /* set up the port vector; 4 is the largest possible size for now */
1155 ports.push_back (0);
1156 ports.push_back (0);
1157 ports.push_back (0);
1158 ports.push_back (0);
1164 pfd[nfds].fd = midi_request_pipe[0];
1165 pfd[nfds].events = POLLIN|POLLHUP|POLLERR;
1168 /* if we are using MMC control, we obviously have to listen
1169 on the appropriate port.
1172 if (Config->get_mmc_control() && _mmc_port && _mmc_port->selectable() >= 0) {
1173 pfd[nfds].fd = _mmc_port->selectable();
1174 pfd[nfds].events = POLLIN|POLLHUP|POLLERR;
1175 ports[nfds] = _mmc_port;
1179 /* if MTC is being handled on a different port from MMC
1180 or we are not handling MMC at all, poll
1184 if (_mtc_port && (_mtc_port != _mmc_port || !Config->get_mmc_control()) && _mtc_port->selectable() >= 0) {
1185 pfd[nfds].fd = _mtc_port->selectable();
1186 pfd[nfds].events = POLLIN|POLLHUP|POLLERR;
1187 ports[nfds] = _mtc_port;
1191 if (_midi_port && (_midi_port != _mmc_port || !Config->get_mmc_control()) && (_midi_port != _mtc_port) && _midi_port->selectable() >= 0) {
1192 pfd[nfds].fd = _midi_port->selectable();
1193 pfd[nfds].events = POLLIN|POLLHUP|POLLERR;
1194 ports[nfds] = _midi_port;
1198 if (!midi_timeouts.empty()) {
1199 timeout = 100; /* 10msecs */
1201 timeout = -1; /* if there is no data, we don't care */
1205 // cerr << "MIDI poll on " << nfds << " for " << timeout << endl;
1206 if (poll (pfd, nfds, timeout) < 0) {
1207 if (errno == EINTR) {
1208 /* gdb at work, perhaps */
1212 error << string_compose(_("MIDI thread poll failed (%1)"), strerror (errno)) << endmsg;
1216 // cerr << "MIDI thread wakes at " << get_cycles () << endl;
1221 /* check the transport request pipe */
1223 if (pfd[0].revents & ~POLLIN) {
1224 error << _("Error on transport thread request pipe") << endmsg;
1228 if (pfd[0].revents & POLLIN) {
1232 // cerr << "MIDI request FIFO ready\n";
1235 /* empty the pipe of all current requests */
1238 size_t nread = read (midi_request_pipe[0], &foo, sizeof (foo));
1241 if ((size_t) nread < sizeof (foo)) {
1246 } else if (nread == 0) {
1248 } else if (errno == EAGAIN) {
1251 fatal << _("Error reading from transport request pipe") << endmsg;
1256 while (midi_requests.read (&request, 1) == 1) {
1258 switch (request->type) {
1260 case MIDIRequest::SendFullMTC:
1261 // cerr << "send full MTC\n";
1262 send_full_time_code ();
1263 // cerr << "... done\n";
1266 case MIDIRequest::SendMTC:
1267 // cerr << "send qtr MTC\n";
1268 send_midi_time_code ();
1269 // cerr << "... done\n";
1272 case MIDIRequest::SendMMC:
1273 // cerr << "send MMC\n";
1274 deliver_mmc (request->mmc_cmd, request->locate_frame);
1275 // cerr << "... done\n";
1278 case MIDIRequest::SendMessage:
1279 // cerr << "send Message\n";
1280 deliver_midi_message (request->port, request->ev, request->chan, request->data);
1281 // cerr << "... done\n";
1284 case MIDIRequest::Deliver:
1285 // cerr << "deliver\n";
1286 deliver_data (_midi_port, request->buf, request->size);
1287 // cerr << "... done\n";
1290 case MIDIRequest::PortChange:
1291 /* restart poll with new ports */
1292 // cerr << "rebind\n";
1296 case MIDIRequest::Quit:
1298 pthread_exit_pbd (0);
1316 /* now read the rest of the ports */
1318 for (int p = 1; p < nfds; ++p) {
1319 if ((pfd[p].revents & ~POLLIN)) {
1320 // error << string_compose(_("Transport: error polling MIDI port %1 (revents =%2%3%4"), p, &hex, pfd[p].revents, &dec) << endmsg;
1324 if (pfd[p].revents & POLLIN) {
1326 midi_read (ports[p]);
1330 /* timeout driven */
1332 if (fds_ready < 2 && timeout != -1) {
1334 for (MidiTimeoutList::iterator i = midi_timeouts.begin(); i != midi_timeouts.end(); ) {
1336 MidiTimeoutList::iterator tmp;
1341 midi_timeouts.erase (i);