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) * smpte_frames_per_second()) / diff_secs) / 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];
627 smpte.rate = smpte_frames_per_second();
628 smpte.drop = smpte_drop_frames();
630 // Also takes smpte offset into account:
631 smpte_to_sample( smpte, target_frame, true /* use_offset */, false /* use_subframes */ );
633 if (target_frame > max_frames) {
634 target_frame = max_frames;
637 /* Some (all?) MTC/MMC devices do not send a full MTC frame
638 at the end of a locate, instead sending only an MMC
639 locate command. This causes the current position
640 of an MTC slave to become out of date. Catch this.
643 MTC_Slave* mtcs = dynamic_cast<MTC_Slave*> (_slave);
646 // cerr << "Locate *with* MTC slave\n";
647 mtcs->handle_locate (mmc_tc);
649 // cerr << "Locate without MTC slave\n";
650 request_locate (target_frame, false);
655 Session::mmc_shuttle (MIDI::MachineControl &mmc, float speed, bool forw)
657 if (!Config->get_mmc_control()) {
661 if (Config->get_shuttle_speed_threshold() >= 0 && speed > Config->get_shuttle_speed_threshold()) {
662 speed *= Config->get_shuttle_speed_factor();
666 request_transport_speed (speed);
668 request_transport_speed (-speed);
673 Session::mmc_record_enable (MIDI::MachineControl &mmc, size_t trk, bool enabled)
675 if (Config->get_mmc_control()) {
677 RouteList::iterator i;
678 boost::shared_ptr<RouteList> r = routes.reader();
680 for (i = r->begin(); i != r->end(); ++i) {
683 if ((at = dynamic_cast<AudioTrack*>((*i).get())) != 0) {
684 if (trk == at->remote_control_id()) {
685 at->set_record_enable (enabled, &mmc);
694 Session::send_full_time_code_in_another_thread ()
696 send_time_code_in_another_thread (true);
700 Session::send_midi_time_code_in_another_thread ()
702 send_time_code_in_another_thread (false);
706 Session::send_time_code_in_another_thread (bool full)
708 nframes_t two_smpte_frames_duration;
709 nframes_t quarter_frame_duration;
711 /* Duration of two smpte frames */
712 two_smpte_frames_duration = ((long) _frames_per_smpte_frame) << 1;
714 /* Duration of one quarter frame */
715 quarter_frame_duration = ((long) _frames_per_smpte_frame) >> 2;
717 if (_transport_frame < (outbound_mtc_smpte_frame + (next_quarter_frame_to_send * quarter_frame_duration)))
719 /* There is no work to do.
720 We throttle this here so that we don't overload
721 the transport thread with requests.
726 MIDIRequest* request = new MIDIRequest;
729 request->type = MIDIRequest::SendFullMTC;
731 request->type = MIDIRequest::SendMTC;
734 midi_requests.write (&request, 1);
739 Session::change_midi_ports ()
741 MIDIRequest* request = new MIDIRequest;
743 request->type = MIDIRequest::PortChange;
744 midi_requests.write (&request, 1);
749 Session::send_full_time_code ()
755 if (_mtc_port == 0 || !session_send_mtc) {
759 // Get smpte time for this transport frame
760 sample_to_smpte(_transport_frame, smpte, true /* use_offset */, false /* no subframes */);
762 // Check for negative smpte time and prepare for quarter frame transmission
763 if (smpte.negative) {
764 // Negative mtc is not defined, so sync slave to smpte zero.
765 // When _transport_frame gets there we will start transmitting quarter frames
771 smpte.negative = false;
772 smpte_to_sample( smpte, outbound_mtc_smpte_frame, true, false );
773 transmitting_smpte_time = smpte;
775 transmitting_smpte_time = smpte;
776 outbound_mtc_smpte_frame = _transport_frame;
777 if (((mtc_smpte_bits >> 5) != MIDI::MTC_25_FPS) && (transmitting_smpte_time.frames % 2)) {
778 // start MTC quarter frame transmission on an even frame
779 SMPTE::increment( transmitting_smpte_time );
780 outbound_mtc_smpte_frame += (nframes_t) _frames_per_smpte_frame;
784 // Compensate for audio latency
785 outbound_mtc_smpte_frame += _worst_output_latency;
787 next_quarter_frame_to_send = 0;
789 // Sync slave to the same smpte time as we are on (except if negative, see above)
797 msg[5] = mtc_smpte_bits | smpte.hours;
798 msg[6] = smpte.minutes;
799 msg[7] = smpte.seconds;
800 msg[8] = smpte.frames;
803 Glib::Mutex::Lock lm (midi_lock);
805 if (_mtc_port->midimsg (msg, sizeof (msg))) {
806 error << _("Session: could not send full MIDI time code") << endmsg;
816 Session::send_midi_time_code ()
818 if (_mtc_port == 0 || !session_send_mtc || transmitting_smpte_time.negative || (next_quarter_frame_to_send < 0) ) {
822 nframes_t two_smpte_frames_duration;
823 nframes_t quarter_frame_duration;
825 /* Duration of two smpte frames */
826 two_smpte_frames_duration = ((long) _frames_per_smpte_frame) << 1;
828 /* Duration of one quarter frame */
829 quarter_frame_duration = ((long) _frames_per_smpte_frame) >> 2;
831 while (_transport_frame >= (outbound_mtc_smpte_frame + (next_quarter_frame_to_send * quarter_frame_duration))) {
833 // Send quarter frames up to current time
835 Glib::Mutex::Lock lm (midi_lock);
837 switch(next_quarter_frame_to_send) {
839 mtc_msg[1] = 0x00 | (transmitting_smpte_time.frames & 0xf);
842 mtc_msg[1] = 0x10 | ((transmitting_smpte_time.frames & 0xf0) >> 4);
845 mtc_msg[1] = 0x20 | (transmitting_smpte_time.seconds & 0xf);
848 mtc_msg[1] = 0x30 | ((transmitting_smpte_time.seconds & 0xf0) >> 4);
851 mtc_msg[1] = 0x40 | (transmitting_smpte_time.minutes & 0xf);
854 mtc_msg[1] = 0x50 | ((transmitting_smpte_time.minutes & 0xf0) >> 4);
857 mtc_msg[1] = 0x60 | ((mtc_smpte_bits|transmitting_smpte_time.hours) & 0xf);
860 mtc_msg[1] = 0x70 | (((mtc_smpte_bits|transmitting_smpte_time.hours) & 0xf0) >> 4);
864 if (_mtc_port->midimsg (mtc_msg, 2)) {
865 error << string_compose(_("Session: cannot send quarter-frame MTC message (%1)"), strerror (errno))
871 // 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;
873 // Increment quarter frame counter
874 next_quarter_frame_to_send++;
876 if (next_quarter_frame_to_send >= 8) {
877 // Wrap quarter frame counter
878 next_quarter_frame_to_send = 0;
879 // Increment smpte time twice
880 SMPTE::increment( transmitting_smpte_time );
881 SMPTE::increment( transmitting_smpte_time );
882 // Re-calculate timing of first quarter frame
883 smpte_to_sample( transmitting_smpte_time, outbound_mtc_smpte_frame, true /* use_offset */, false );
884 // Compensate for audio latency
885 outbound_mtc_smpte_frame += _worst_output_latency;
892 /***********************************************************************
894 **********************************************************************/
897 Session::send_mmc_in_another_thread (MIDI::MachineControl::Command cmd, nframes_t target_frame)
899 MIDIRequest* request;
901 if (_mtc_port == 0 || !session_send_mmc) {
905 request = new MIDIRequest;
906 request->type = MIDIRequest::SendMMC;
907 request->mmc_cmd = cmd;
908 request->locate_frame = target_frame;
910 midi_requests.write (&request, 1);
915 Session::deliver_mmc (MIDI::MachineControl::Command cmd, nframes_t where)
917 using namespace MIDI;
921 if (_mmc_port == 0 || !session_send_mmc) {
925 mmc_buffer[nbytes++] = cmd;
927 // cerr << "delivering MMC, cmd = " << hex << (int) cmd << dec << endl;
930 case MachineControl::cmdLocate:
931 smpte_time_subframes (where, smpte);
933 mmc_buffer[nbytes++] = 0x6; // byte count
934 mmc_buffer[nbytes++] = 0x1; // "TARGET" subcommand
935 mmc_buffer[nbytes++] = smpte.hours;
936 mmc_buffer[nbytes++] = smpte.minutes;
937 mmc_buffer[nbytes++] = smpte.seconds;
938 mmc_buffer[nbytes++] = smpte.frames;
939 mmc_buffer[nbytes++] = smpte.subframes;
942 case MachineControl::cmdStop:
945 case MachineControl::cmdPlay:
946 /* always convert Play into Deferred Play */
947 mmc_buffer[4] = MachineControl::cmdDeferredPlay;
950 case MachineControl::cmdDeferredPlay:
953 case MachineControl::cmdRecordStrobe:
956 case MachineControl::cmdRecordExit:
959 case MachineControl::cmdRecordPause:
968 mmc_buffer[nbytes++] = 0xf7; // terminate SysEx/MMC message
970 Glib::Mutex::Lock lm (midi_lock);
972 if (_mmc_port->write (mmc_buffer, nbytes) != nbytes) {
973 error << string_compose(_("MMC: cannot send command %1%2%3"), &hex, cmd, &dec) << endmsg;
979 Session::mmc_step_timeout ()
984 gettimeofday (&now, 0);
986 timersub (&now, &last_mmc_step, &diff);
987 diff_usecs = diff.tv_sec * 1000000 + diff.tv_usec;
989 if (diff_usecs > 1000000.0 || fabs (_transport_speed) < 0.0000001) {
990 /* too long or too slow, stop transport */
991 request_transport_speed (0.0);
996 if (diff_usecs < 250000.0) {
997 /* too short, just keep going */
1003 request_transport_speed (_transport_speed * 0.75);
1009 Session::send_midi_message (MIDI::Port * port, MIDI::eventType ev, MIDI::channel_t ch, MIDI::EventTwoBytes data)
1011 // in another thread, really
1013 MIDIRequest* request = new MIDIRequest;
1015 request->type = MIDIRequest::SendMessage;
1016 request->port = port;
1019 request->data = data;
1021 midi_requests.write (&request, 1);
1022 poke_midi_thread ();
1026 Session::deliver_midi (MIDI::Port * port, MIDI::byte* buf, int32_t bufsize)
1028 // in another thread, really
1030 MIDIRequest* request = new MIDIRequest;
1032 request->type = MIDIRequest::Deliver;
1033 request->port = port;
1035 request->size = bufsize;
1037 midi_requests.write (&request, 1);
1038 poke_midi_thread ();
1042 Session::deliver_midi_message (MIDI::Port * port, MIDI::eventType ev, MIDI::channel_t ch, MIDI::EventTwoBytes data)
1044 if (port == 0 || ev == MIDI::none) {
1048 midi_msg[0] = (ev & 0xF0) | (ch & 0xF);
1049 midi_msg[1] = data.controller_number;
1050 midi_msg[2] = data.value;
1052 port->write (midi_msg, 3);
1056 Session::deliver_data (MIDI::Port * port, MIDI::byte* buf, int32_t size)
1059 port->write (buf, size);
1062 /* this is part of the semantics of the Deliver request */
1067 /*---------------------------------------------------------------------------
1069 ---------------------------------------------------------------------------*/
1072 Session::start_midi_thread ()
1074 if (pipe (midi_request_pipe)) {
1075 error << string_compose(_("Cannot create transport request signal pipe (%1)"), strerror (errno)) << endmsg;
1079 if (fcntl (midi_request_pipe[0], F_SETFL, O_NONBLOCK)) {
1080 error << string_compose(_("UI: cannot set O_NONBLOCK on " "signal read pipe (%1)"), strerror (errno)) << endmsg;
1084 if (fcntl (midi_request_pipe[1], F_SETFL, O_NONBLOCK)) {
1085 error << string_compose(_("UI: cannot set O_NONBLOCK on " "signal write pipe (%1)"), strerror (errno)) << endmsg;
1089 if (pthread_create_and_store ("transport", &midi_thread, 0, _midi_thread_work, this)) {
1090 error << _("Session: could not create transport thread") << endmsg;
1094 // pthread_detach (midi_thread);
1100 Session::terminate_midi_thread ()
1102 MIDIRequest* request = new MIDIRequest;
1105 request->type = MIDIRequest::Quit;
1107 midi_requests.write (&request, 1);
1108 poke_midi_thread ();
1110 pthread_join (midi_thread, &status);
1114 Session::poke_midi_thread ()
1118 if (write (midi_request_pipe[1], &c, 1) != 1) {
1119 error << string_compose(_("cannot send signal to midi thread! (%1)"), strerror (errno)) << endmsg;
1124 Session::_midi_thread_work (void* arg)
1126 pthread_setcancelstate (PTHREAD_CANCEL_ENABLE, 0);
1127 pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, 0);
1129 ((Session *) arg)->midi_thread_work ();
1134 Session::midi_thread_work ()
1136 MIDIRequest* request;
1137 struct pollfd pfd[4];
1141 struct sched_param rtparam;
1144 vector<MIDI::Port*> ports;
1146 PBD::ThreadCreatedWithRequestSize (pthread_self(), X_("MIDI"), 2048);
1148 memset (&rtparam, 0, sizeof (rtparam));
1149 rtparam.sched_priority = 9; /* XXX should be relative to audio (JACK) thread */
1151 if ((x = pthread_setschedparam (pthread_self(), SCHED_FIFO, &rtparam)) != 0) {
1152 // do we care? not particularly.
1155 /* set up the port vector; 4 is the largest possible size for now */
1157 ports.push_back (0);
1158 ports.push_back (0);
1159 ports.push_back (0);
1160 ports.push_back (0);
1166 pfd[nfds].fd = midi_request_pipe[0];
1167 pfd[nfds].events = POLLIN|POLLHUP|POLLERR;
1170 /* if we are using MMC control, we obviously have to listen
1171 on the appropriate port.
1174 if (Config->get_mmc_control() && _mmc_port && _mmc_port->selectable() >= 0) {
1175 pfd[nfds].fd = _mmc_port->selectable();
1176 pfd[nfds].events = POLLIN|POLLHUP|POLLERR;
1177 ports[nfds] = _mmc_port;
1181 /* if MTC is being handled on a different port from MMC
1182 or we are not handling MMC at all, poll
1186 if (_mtc_port && (_mtc_port != _mmc_port || !Config->get_mmc_control()) && _mtc_port->selectable() >= 0) {
1187 pfd[nfds].fd = _mtc_port->selectable();
1188 pfd[nfds].events = POLLIN|POLLHUP|POLLERR;
1189 ports[nfds] = _mtc_port;
1193 if (_midi_port && (_midi_port != _mmc_port || !Config->get_mmc_control()) && (_midi_port != _mtc_port) && _midi_port->selectable() >= 0) {
1194 pfd[nfds].fd = _midi_port->selectable();
1195 pfd[nfds].events = POLLIN|POLLHUP|POLLERR;
1196 ports[nfds] = _midi_port;
1200 if (!midi_timeouts.empty()) {
1201 timeout = 100; /* 10msecs */
1203 timeout = -1; /* if there is no data, we don't care */
1207 // cerr << "MIDI poll on " << nfds << " for " << timeout << endl;
1208 if (poll (pfd, nfds, timeout) < 0) {
1209 if (errno == EINTR) {
1210 /* gdb at work, perhaps */
1214 error << string_compose(_("MIDI thread poll failed (%1)"), strerror (errno)) << endmsg;
1218 // cerr << "MIDI thread wakes at " << get_cycles () << endl;
1223 /* check the transport request pipe */
1225 if (pfd[0].revents & ~POLLIN) {
1226 error << _("Error on transport thread request pipe") << endmsg;
1230 if (pfd[0].revents & POLLIN) {
1234 // cerr << "MIDI request FIFO ready\n";
1237 /* empty the pipe of all current requests */
1240 size_t nread = read (midi_request_pipe[0], &foo, sizeof (foo));
1243 if ((size_t) nread < sizeof (foo)) {
1248 } else if (nread == 0) {
1250 } else if (errno == EAGAIN) {
1253 fatal << _("Error reading from transport request pipe") << endmsg;
1258 while (midi_requests.read (&request, 1) == 1) {
1260 switch (request->type) {
1262 case MIDIRequest::SendFullMTC:
1263 // cerr << "send full MTC\n";
1264 send_full_time_code ();
1265 // cerr << "... done\n";
1268 case MIDIRequest::SendMTC:
1269 // cerr << "send qtr MTC\n";
1270 send_midi_time_code ();
1271 // cerr << "... done\n";
1274 case MIDIRequest::SendMMC:
1275 // cerr << "send MMC\n";
1276 deliver_mmc (request->mmc_cmd, request->locate_frame);
1277 // cerr << "... done\n";
1280 case MIDIRequest::SendMessage:
1281 // cerr << "send Message\n";
1282 deliver_midi_message (request->port, request->ev, request->chan, request->data);
1283 // cerr << "... done\n";
1286 case MIDIRequest::Deliver:
1287 // cerr << "deliver\n";
1288 deliver_data (_midi_port, request->buf, request->size);
1289 // cerr << "... done\n";
1292 case MIDIRequest::PortChange:
1293 /* restart poll with new ports */
1294 // cerr << "rebind\n";
1298 case MIDIRequest::Quit:
1300 pthread_exit_pbd (0);
1318 /* now read the rest of the ports */
1320 for (int p = 1; p < nfds; ++p) {
1321 if ((pfd[p].revents & ~POLLIN)) {
1322 // error << string_compose(_("Transport: error polling MIDI port %1 (revents =%2%3%4"), p, &hex, pfd[p].revents, &dec) << endmsg;
1326 if (pfd[p].revents & POLLIN) {
1328 midi_read (ports[p]);
1332 /* timeout driven */
1334 if (fds_ready < 2 && timeout != -1) {
1336 for (MidiTimeoutList::iterator i = midi_timeouts.begin(); i != midi_timeouts.end(); ) {
1338 MidiTimeoutList::iterator tmp;
1343 midi_timeouts.erase (i);