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 */
402 if (_mmc_port != 0) {
404 Config->set_send_mmc (session_send_mmc);
409 session_send_mmc = false;
412 if (_mtc_port != 0) {
414 Config->set_send_mtc (session_send_mtc);
417 session_send_mtc = false;
422 Session::midi_read (MIDI::Port* port)
426 /* reading from the MIDI port activates the Parser
427 that in turn generates signals that we care
428 about. the port is already set to NONBLOCK so that
429 can read freely here.
434 // cerr << "+++ READ ON " << port->name() << endl;
436 int nread = port->read (buf, sizeof (buf));
438 // cerr << "-- READ (" << nread << " ON " << port->name() << endl;
441 if ((size_t) nread < sizeof (buf)) {
446 } else if (nread == 0) {
448 } else if (errno == EAGAIN) {
451 fatal << string_compose(_("Error reading from MIDI port %1"), port->name()) << endmsg;
460 Session::spp_start (Parser& ignored)
462 if (Config->get_mmc_control() && (Config->get_slave_source() != MTC)) {
463 request_transport_speed (1.0);
468 Session::spp_continue (Parser& ignored)
474 Session::spp_stop (Parser& ignored)
476 if (Config->get_mmc_control()) {
482 Session::mmc_deferred_play (MIDI::MachineControl &mmc)
484 if (Config->get_mmc_control() && (Config->get_slave_source() != MTC)) {
485 request_transport_speed (1.0);
490 Session::mmc_record_pause (MIDI::MachineControl &mmc)
492 if (Config->get_mmc_control()) {
493 maybe_enable_record();
498 Session::mmc_record_strobe (MIDI::MachineControl &mmc)
500 if (!Config->get_mmc_control())
503 /* record strobe does an implicit "Play" command */
505 if (_transport_speed != 1.0) {
507 /* start_transport() will move from Enabled->Recording, so we
508 don't need to do anything here except enable recording.
509 its not the same as maybe_enable_record() though, because
510 that *can* switch to Recording, which we do not want.
513 save_state ("", true);
514 g_atomic_int_set (&_record_status, Enabled);
515 RecordStateChanged (); /* EMIT SIGNAL */
517 request_transport_speed (1.0);
526 Session::mmc_record_exit (MIDI::MachineControl &mmc)
528 if (Config->get_mmc_control()) {
529 disable_record (false);
534 Session::mmc_stop (MIDI::MachineControl &mmc)
536 if (Config->get_mmc_control()) {
542 Session::mmc_pause (MIDI::MachineControl &mmc)
544 if (Config->get_mmc_control()) {
546 /* We support RECORD_PAUSE, so the spec says that
547 we must interpret PAUSE like RECORD_PAUSE if
551 if (actively_recording()) {
552 maybe_enable_record ();
559 static bool step_queued = false;
562 Session::mmc_step (MIDI::MachineControl &mmc, int steps)
564 if (!Config->get_mmc_control()) {
569 struct timeval diff = { 0, 0 };
571 gettimeofday (&now, 0);
573 timersub (&now, &last_mmc_step, &diff);
575 gettimeofday (&now, 0);
576 timersub (&now, &last_mmc_step, &diff);
578 if (last_mmc_step.tv_sec != 0 && (diff.tv_usec + (diff.tv_sec * 1000000)) < _engine.usecs_per_cycle()) {
582 double diff_secs = diff.tv_sec + (diff.tv_usec / 1000000.0);
583 double cur_speed = (((steps * 0.5) * smpte_frames_per_second()) / diff_secs) / smpte_frames_per_second();
585 if (_transport_speed == 0 || cur_speed * _transport_speed < 0) {
586 /* change direction */
587 step_speed = cur_speed;
589 step_speed = (0.6 * step_speed) + (0.4 * cur_speed);
595 cerr << "delta = " << diff_secs
596 << " ct = " << _transport_speed
597 << " steps = " << steps
598 << " new speed = " << cur_speed
599 << " speed = " << step_speed
603 request_transport_speed (step_speed);
607 midi_timeouts.push_back (mem_fun (*this, &Session::mmc_step_timeout));
613 Session::mmc_rewind (MIDI::MachineControl &mmc)
615 if (Config->get_mmc_control()) {
616 request_transport_speed(-8.0f);
621 Session::mmc_fast_forward (MIDI::MachineControl &mmc)
623 if (Config->get_mmc_control()) {
624 request_transport_speed(8.0f);
629 Session::mmc_locate (MIDI::MachineControl &mmc, const MIDI::byte* mmc_tc)
631 if (!Config->get_mmc_control()) {
635 nframes_t target_frame;
638 smpte.hours = mmc_tc[0] & 0xf;
639 smpte.minutes = mmc_tc[1];
640 smpte.seconds = mmc_tc[2];
641 smpte.frames = mmc_tc[3];
642 smpte.rate = smpte_frames_per_second();
643 smpte.drop = smpte_drop_frames();
645 // Also takes smpte offset into account:
646 smpte_to_sample( smpte, target_frame, true /* use_offset */, false /* use_subframes */ );
648 if (target_frame > max_frames) {
649 target_frame = max_frames;
652 /* Some (all?) MTC/MMC devices do not send a full MTC frame
653 at the end of a locate, instead sending only an MMC
654 locate command. This causes the current position
655 of an MTC slave to become out of date. Catch this.
658 MTC_Slave* mtcs = dynamic_cast<MTC_Slave*> (_slave);
661 // cerr << "Locate *with* MTC slave\n";
662 mtcs->handle_locate (mmc_tc);
664 // cerr << "Locate without MTC slave\n";
665 request_locate (target_frame, false);
670 Session::mmc_shuttle (MIDI::MachineControl &mmc, float speed, bool forw)
672 if (!Config->get_mmc_control()) {
676 if (Config->get_shuttle_speed_threshold() >= 0 && speed > Config->get_shuttle_speed_threshold()) {
677 speed *= Config->get_shuttle_speed_factor();
681 request_transport_speed (speed);
683 request_transport_speed (-speed);
688 Session::mmc_record_enable (MIDI::MachineControl &mmc, size_t trk, bool enabled)
690 if (Config->get_mmc_control()) {
692 RouteList::iterator i;
693 boost::shared_ptr<RouteList> r = routes.reader();
695 for (i = r->begin(); i != r->end(); ++i) {
698 if ((at = dynamic_cast<AudioTrack*>((*i).get())) != 0) {
699 if (trk == at->remote_control_id()) {
700 at->set_record_enable (enabled, &mmc);
709 Session::send_full_time_code_in_another_thread ()
711 send_time_code_in_another_thread (true);
715 Session::send_midi_time_code_in_another_thread ()
717 send_time_code_in_another_thread (false);
721 Session::send_time_code_in_another_thread (bool full)
723 nframes_t two_smpte_frames_duration;
724 nframes_t quarter_frame_duration;
726 /* Duration of two smpte frames */
727 two_smpte_frames_duration = ((long) _frames_per_smpte_frame) << 1;
729 /* Duration of one quarter frame */
730 quarter_frame_duration = ((long) _frames_per_smpte_frame) >> 2;
732 if (_transport_frame < (outbound_mtc_smpte_frame + (next_quarter_frame_to_send * quarter_frame_duration)))
734 /* There is no work to do.
735 We throttle this here so that we don't overload
736 the transport thread with requests.
741 MIDIRequest* request = new MIDIRequest;
744 request->type = MIDIRequest::SendFullMTC;
746 request->type = MIDIRequest::SendMTC;
749 midi_requests.write (&request, 1);
754 Session::change_midi_ports ()
756 MIDIRequest* request = new MIDIRequest;
758 request->type = MIDIRequest::PortChange;
759 midi_requests.write (&request, 1);
764 Session::send_full_time_code ()
770 if (_mtc_port == 0 || !session_send_mtc) {
774 // Get smpte time for this transport frame
775 sample_to_smpte(_transport_frame, smpte, true /* use_offset */, false /* no subframes */);
777 // Check for negative smpte time and prepare for quarter frame transmission
778 if (smpte.negative) {
779 // Negative mtc is not defined, so sync slave to smpte zero.
780 // When _transport_frame gets there we will start transmitting quarter frames
786 smpte.negative = false;
787 smpte_to_sample( smpte, outbound_mtc_smpte_frame, true, false );
788 transmitting_smpte_time = smpte;
790 transmitting_smpte_time = smpte;
791 outbound_mtc_smpte_frame = _transport_frame;
792 if (((mtc_smpte_bits >> 5) != MIDI::MTC_25_FPS) && (transmitting_smpte_time.frames % 2)) {
793 // start MTC quarter frame transmission on an even frame
794 SMPTE::increment( transmitting_smpte_time );
795 outbound_mtc_smpte_frame += (nframes_t) _frames_per_smpte_frame;
799 // Compensate for audio latency
800 outbound_mtc_smpte_frame += _worst_output_latency;
802 next_quarter_frame_to_send = 0;
804 // Sync slave to the same smpte time as we are on (except if negative, see above)
812 msg[5] = mtc_smpte_bits | smpte.hours;
813 msg[6] = smpte.minutes;
814 msg[7] = smpte.seconds;
815 msg[8] = smpte.frames;
818 Glib::Mutex::Lock lm (midi_lock);
820 if (_mtc_port->midimsg (msg, sizeof (msg))) {
821 error << _("Session: could not send full MIDI time code") << endmsg;
831 Session::send_midi_time_code ()
833 if (_mtc_port == 0 || !session_send_mtc || transmitting_smpte_time.negative || (next_quarter_frame_to_send < 0) ) {
837 nframes_t two_smpte_frames_duration;
838 nframes_t quarter_frame_duration;
840 /* Duration of two smpte frames */
841 two_smpte_frames_duration = ((long) _frames_per_smpte_frame) << 1;
843 /* Duration of one quarter frame */
844 quarter_frame_duration = ((long) _frames_per_smpte_frame) >> 2;
846 while (_transport_frame >= (outbound_mtc_smpte_frame + (next_quarter_frame_to_send * quarter_frame_duration))) {
848 // Send quarter frames up to current time
850 Glib::Mutex::Lock lm (midi_lock);
852 switch(next_quarter_frame_to_send) {
854 mtc_msg[1] = 0x00 | (transmitting_smpte_time.frames & 0xf);
857 mtc_msg[1] = 0x10 | ((transmitting_smpte_time.frames & 0xf0) >> 4);
860 mtc_msg[1] = 0x20 | (transmitting_smpte_time.seconds & 0xf);
863 mtc_msg[1] = 0x30 | ((transmitting_smpte_time.seconds & 0xf0) >> 4);
866 mtc_msg[1] = 0x40 | (transmitting_smpte_time.minutes & 0xf);
869 mtc_msg[1] = 0x50 | ((transmitting_smpte_time.minutes & 0xf0) >> 4);
872 mtc_msg[1] = 0x60 | ((mtc_smpte_bits|transmitting_smpte_time.hours) & 0xf);
875 mtc_msg[1] = 0x70 | (((mtc_smpte_bits|transmitting_smpte_time.hours) & 0xf0) >> 4);
879 if (_mtc_port->midimsg (mtc_msg, 2)) {
880 error << string_compose(_("Session: cannot send quarter-frame MTC message (%1)"), strerror (errno))
886 // 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;
888 // Increment quarter frame counter
889 next_quarter_frame_to_send++;
891 if (next_quarter_frame_to_send >= 8) {
892 // Wrap quarter frame counter
893 next_quarter_frame_to_send = 0;
894 // Increment smpte time twice
895 SMPTE::increment( transmitting_smpte_time );
896 SMPTE::increment( transmitting_smpte_time );
897 // Re-calculate timing of first quarter frame
898 smpte_to_sample( transmitting_smpte_time, outbound_mtc_smpte_frame, true /* use_offset */, false );
899 // Compensate for audio latency
900 outbound_mtc_smpte_frame += _worst_output_latency;
907 /***********************************************************************
909 **********************************************************************/
912 Session::send_mmc_in_another_thread (MIDI::MachineControl::Command cmd, nframes_t target_frame)
914 MIDIRequest* request;
916 if (_mtc_port == 0 || !session_send_mmc) {
920 request = new MIDIRequest;
921 request->type = MIDIRequest::SendMMC;
922 request->mmc_cmd = cmd;
923 request->locate_frame = target_frame;
925 midi_requests.write (&request, 1);
930 Session::deliver_mmc (MIDI::MachineControl::Command cmd, nframes_t where)
932 using namespace MIDI;
936 if (_mmc_port == 0 || !session_send_mmc) {
940 mmc_buffer[nbytes++] = cmd;
942 // cerr << "delivering MMC, cmd = " << hex << (int) cmd << dec << endl;
945 case MachineControl::cmdLocate:
946 smpte_time_subframes (where, smpte);
948 mmc_buffer[nbytes++] = 0x6; // byte count
949 mmc_buffer[nbytes++] = 0x1; // "TARGET" subcommand
950 mmc_buffer[nbytes++] = smpte.hours;
951 mmc_buffer[nbytes++] = smpte.minutes;
952 mmc_buffer[nbytes++] = smpte.seconds;
953 mmc_buffer[nbytes++] = smpte.frames;
954 mmc_buffer[nbytes++] = smpte.subframes;
957 case MachineControl::cmdStop:
960 case MachineControl::cmdPlay:
961 /* always convert Play into Deferred Play */
962 mmc_buffer[4] = MachineControl::cmdDeferredPlay;
965 case MachineControl::cmdDeferredPlay:
968 case MachineControl::cmdRecordStrobe:
971 case MachineControl::cmdRecordExit:
974 case MachineControl::cmdRecordPause:
983 mmc_buffer[nbytes++] = 0xf7; // terminate SysEx/MMC message
985 Glib::Mutex::Lock lm (midi_lock);
987 if (_mmc_port->write (mmc_buffer, nbytes) != nbytes) {
988 error << string_compose(_("MMC: cannot send command %1%2%3"), &hex, cmd, &dec) << endmsg;
994 Session::mmc_step_timeout ()
999 gettimeofday (&now, 0);
1001 timersub (&now, &last_mmc_step, &diff);
1002 diff_usecs = diff.tv_sec * 1000000 + diff.tv_usec;
1004 if (diff_usecs > 1000000.0 || fabs (_transport_speed) < 0.0000001) {
1005 /* too long or too slow, stop transport */
1006 request_transport_speed (0.0);
1007 step_queued = false;
1011 if (diff_usecs < 250000.0) {
1012 /* too short, just keep going */
1018 request_transport_speed (_transport_speed * 0.75);
1024 Session::send_midi_message (MIDI::Port * port, MIDI::eventType ev, MIDI::channel_t ch, MIDI::EventTwoBytes data)
1026 // in another thread, really
1028 MIDIRequest* request = new MIDIRequest;
1030 request->type = MIDIRequest::SendMessage;
1031 request->port = port;
1034 request->data = data;
1036 midi_requests.write (&request, 1);
1037 poke_midi_thread ();
1041 Session::deliver_midi (MIDI::Port * port, MIDI::byte* buf, int32_t bufsize)
1043 // in another thread, really
1045 MIDIRequest* request = new MIDIRequest;
1047 request->type = MIDIRequest::Deliver;
1048 request->port = port;
1050 request->size = bufsize;
1052 midi_requests.write (&request, 1);
1053 poke_midi_thread ();
1057 Session::deliver_midi_message (MIDI::Port * port, MIDI::eventType ev, MIDI::channel_t ch, MIDI::EventTwoBytes data)
1059 if (port == 0 || ev == MIDI::none) {
1063 midi_msg[0] = (ev & 0xF0) | (ch & 0xF);
1064 midi_msg[1] = data.controller_number;
1065 midi_msg[2] = data.value;
1067 port->write (midi_msg, 3);
1071 Session::deliver_data (MIDI::Port * port, MIDI::byte* buf, int32_t size)
1074 port->write (buf, size);
1077 /* this is part of the semantics of the Deliver request */
1082 /*---------------------------------------------------------------------------
1084 ---------------------------------------------------------------------------*/
1087 Session::start_midi_thread ()
1089 if (pipe (midi_request_pipe)) {
1090 error << string_compose(_("Cannot create transport request signal pipe (%1)"), strerror (errno)) << endmsg;
1094 if (fcntl (midi_request_pipe[0], F_SETFL, O_NONBLOCK)) {
1095 error << string_compose(_("UI: cannot set O_NONBLOCK on " "signal read pipe (%1)"), strerror (errno)) << endmsg;
1099 if (fcntl (midi_request_pipe[1], F_SETFL, O_NONBLOCK)) {
1100 error << string_compose(_("UI: cannot set O_NONBLOCK on " "signal write pipe (%1)"), strerror (errno)) << endmsg;
1104 if (pthread_create_and_store ("transport", &midi_thread, 0, _midi_thread_work, this)) {
1105 error << _("Session: could not create transport thread") << endmsg;
1109 // pthread_detach (midi_thread);
1115 Session::terminate_midi_thread ()
1118 MIDIRequest* request = new MIDIRequest;
1121 request->type = MIDIRequest::Quit;
1123 midi_requests.write (&request, 1);
1124 poke_midi_thread ();
1126 pthread_join (midi_thread, &status);
1131 Session::poke_midi_thread ()
1135 if (write (midi_request_pipe[1], &c, 1) != 1) {
1136 error << string_compose(_("cannot send signal to midi thread! (%1)"), strerror (errno)) << endmsg;
1141 Session::_midi_thread_work (void* arg)
1143 pthread_setcancelstate (PTHREAD_CANCEL_ENABLE, 0);
1144 pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, 0);
1146 ((Session *) arg)->midi_thread_work ();
1151 Session::midi_thread_work ()
1153 MIDIRequest* request;
1154 struct pollfd pfd[4];
1158 struct sched_param rtparam;
1161 vector<MIDI::Port*> ports;
1163 PBD::ThreadCreatedWithRequestSize (pthread_self(), X_("MIDI"), 2048);
1165 memset (&rtparam, 0, sizeof (rtparam));
1166 rtparam.sched_priority = 9; /* XXX should be relative to audio (JACK) thread */
1168 if ((x = pthread_setschedparam (pthread_self(), SCHED_FIFO, &rtparam)) != 0) {
1169 // do we care? not particularly.
1172 /* set up the port vector; 4 is the largest possible size for now */
1174 ports.push_back (0);
1175 ports.push_back (0);
1176 ports.push_back (0);
1177 ports.push_back (0);
1183 pfd[nfds].fd = midi_request_pipe[0];
1184 pfd[nfds].events = POLLIN|POLLHUP|POLLERR;
1187 /* if we are using MMC control, we obviously have to listen
1188 on the appropriate port.
1191 if (Config->get_mmc_control() && _mmc_port && _mmc_port->selectable() >= 0) {
1192 pfd[nfds].fd = _mmc_port->selectable();
1193 pfd[nfds].events = POLLIN|POLLHUP|POLLERR;
1194 ports[nfds] = _mmc_port;
1198 /* if MTC is being handled on a different port from MMC
1199 or we are not handling MMC at all, poll
1203 if (_mtc_port && (_mtc_port != _mmc_port || !Config->get_mmc_control()) && _mtc_port->selectable() >= 0) {
1204 pfd[nfds].fd = _mtc_port->selectable();
1205 pfd[nfds].events = POLLIN|POLLHUP|POLLERR;
1206 ports[nfds] = _mtc_port;
1210 if (_midi_port && (_midi_port != _mmc_port || !Config->get_mmc_control()) && (_midi_port != _mtc_port) && _midi_port->selectable() >= 0) {
1211 pfd[nfds].fd = _midi_port->selectable();
1212 pfd[nfds].events = POLLIN|POLLHUP|POLLERR;
1213 ports[nfds] = _midi_port;
1217 if (!midi_timeouts.empty()) {
1218 timeout = 100; /* 10msecs */
1220 timeout = -1; /* if there is no data, we don't care */
1224 // cerr << "MIDI poll on " << nfds << " for " << timeout << endl;
1225 if (poll (pfd, nfds, timeout) < 0) {
1226 if (errno == EINTR) {
1227 /* gdb at work, perhaps */
1231 error << string_compose(_("MIDI thread poll failed (%1)"), strerror (errno)) << endmsg;
1235 // cerr << "MIDI thread wakes at " << get_cycles () << endl;
1240 /* check the transport request pipe */
1242 if (pfd[0].revents & ~POLLIN) {
1243 error << _("Error on transport thread request pipe") << endmsg;
1247 if (pfd[0].revents & POLLIN) {
1251 // cerr << "MIDI request FIFO ready\n";
1254 /* empty the pipe of all current requests */
1257 size_t nread = read (midi_request_pipe[0], &foo, sizeof (foo));
1260 if ((size_t) nread < sizeof (foo)) {
1265 } else if (nread == 0) {
1267 } else if (errno == EAGAIN) {
1270 fatal << _("Error reading from transport request pipe") << endmsg;
1275 while (midi_requests.read (&request, 1) == 1) {
1277 switch (request->type) {
1279 case MIDIRequest::SendFullMTC:
1280 // cerr << "send full MTC\n";
1281 send_full_time_code ();
1282 // cerr << "... done\n";
1285 case MIDIRequest::SendMTC:
1286 // cerr << "send qtr MTC\n";
1287 send_midi_time_code ();
1288 // cerr << "... done\n";
1291 case MIDIRequest::SendMMC:
1292 // cerr << "send MMC\n";
1293 deliver_mmc (request->mmc_cmd, request->locate_frame);
1294 // cerr << "... done\n";
1297 case MIDIRequest::SendMessage:
1298 // cerr << "send Message\n";
1299 deliver_midi_message (request->port, request->ev, request->chan, request->data);
1300 // cerr << "... done\n";
1303 case MIDIRequest::Deliver:
1304 // cerr << "deliver\n";
1305 deliver_data (_midi_port, request->buf, request->size);
1306 // cerr << "... done\n";
1309 case MIDIRequest::PortChange:
1310 /* restart poll with new ports */
1311 // cerr << "rebind\n";
1315 case MIDIRequest::Quit:
1317 pthread_exit_pbd (0);
1335 /* now read the rest of the ports */
1337 for (int p = 1; p < nfds; ++p) {
1338 if ((pfd[p].revents & ~POLLIN)) {
1339 // error << string_compose(_("Transport: error polling MIDI port %1 (revents =%2%3%4"), p, &hex, pfd[p].revents, &dec) << endmsg;
1343 if (pfd[p].revents & POLLIN) {
1345 midi_read (ports[p]);
1349 /* timeout driven */
1351 if (fds_ready < 2 && timeout != -1) {
1353 for (MidiTimeoutList::iterator i = midi_timeouts.begin(); i != midi_timeouts.end(); ) {
1355 MidiTimeoutList::iterator tmp;
1360 midi_timeouts.erase (i);