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 _send_smpte_update = false;
767 if (_mtc_port == 0 || !session_send_mtc) {
771 // Get smpte time for this transport frame
772 sample_to_smpte(_transport_frame, smpte, true /* use_offset */, false /* no subframes */);
774 // Check for negative smpte time and prepare for quarter frame transmission
775 if (smpte.negative) {
776 // Negative mtc is not defined, so sync slave to smpte zero.
777 // When _transport_frame gets there we will start transmitting quarter frames
783 smpte.negative = false;
784 smpte_to_sample( smpte, outbound_mtc_smpte_frame, true, false );
785 transmitting_smpte_time = smpte;
787 transmitting_smpte_time = smpte;
788 outbound_mtc_smpte_frame = _transport_frame;
789 if (((mtc_smpte_bits >> 5) != MIDI::MTC_25_FPS) && (transmitting_smpte_time.frames % 2)) {
790 // start MTC quarter frame transmission on an even frame
791 SMPTE::increment( transmitting_smpte_time );
792 outbound_mtc_smpte_frame += (nframes_t) _frames_per_smpte_frame;
796 // Compensate for audio latency
797 outbound_mtc_smpte_frame += _worst_output_latency;
799 next_quarter_frame_to_send = 0;
801 // Sync slave to the same smpte time as we are on (except if negative, see above)
809 msg[5] = mtc_smpte_bits | smpte.hours;
810 msg[6] = smpte.minutes;
811 msg[7] = smpte.seconds;
812 msg[8] = smpte.frames;
815 Glib::Mutex::Lock lm (midi_lock);
817 if (_mtc_port->midimsg (msg, sizeof (msg))) {
818 error << _("Session: could not send full MIDI time code") << endmsg;
828 Session::send_midi_time_code ()
830 if (_mtc_port == 0 || !session_send_mtc || transmitting_smpte_time.negative || (next_quarter_frame_to_send < 0) ) {
834 /* Duration of one quarter frame */
835 nframes_t const quarter_frame_duration = ((long) _frames_per_smpte_frame) >> 2;
837 while (_transport_frame >= (outbound_mtc_smpte_frame + (next_quarter_frame_to_send * quarter_frame_duration))) {
839 // Send quarter frames up to current time
841 Glib::Mutex::Lock lm (midi_lock);
843 switch(next_quarter_frame_to_send) {
845 mtc_msg[1] = 0x00 | (transmitting_smpte_time.frames & 0xf);
848 mtc_msg[1] = 0x10 | ((transmitting_smpte_time.frames & 0xf0) >> 4);
851 mtc_msg[1] = 0x20 | (transmitting_smpte_time.seconds & 0xf);
854 mtc_msg[1] = 0x30 | ((transmitting_smpte_time.seconds & 0xf0) >> 4);
857 mtc_msg[1] = 0x40 | (transmitting_smpte_time.minutes & 0xf);
860 mtc_msg[1] = 0x50 | ((transmitting_smpte_time.minutes & 0xf0) >> 4);
863 mtc_msg[1] = 0x60 | ((mtc_smpte_bits|transmitting_smpte_time.hours) & 0xf);
866 mtc_msg[1] = 0x70 | (((mtc_smpte_bits|transmitting_smpte_time.hours) & 0xf0) >> 4);
870 if (_mtc_port->midimsg (mtc_msg, 2)) {
871 error << string_compose(_("Session: cannot send quarter-frame MTC message (%1)"), strerror (errno))
877 // 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;
879 // Increment quarter frame counter
880 next_quarter_frame_to_send++;
882 if (next_quarter_frame_to_send >= 8) {
883 // Wrap quarter frame counter
884 next_quarter_frame_to_send = 0;
885 // Increment smpte time twice
886 SMPTE::increment( transmitting_smpte_time );
887 SMPTE::increment( transmitting_smpte_time );
888 // Re-calculate timing of first quarter frame
889 smpte_to_sample( transmitting_smpte_time, outbound_mtc_smpte_frame, true /* use_offset */, false );
890 // Compensate for audio latency
891 outbound_mtc_smpte_frame += _worst_output_latency;
898 /***********************************************************************
900 **********************************************************************/
903 Session::send_mmc_in_another_thread (MIDI::MachineControl::Command cmd, nframes_t target_frame)
905 MIDIRequest* request;
907 if (_mtc_port == 0 || !session_send_mmc) {
911 request = new MIDIRequest;
912 request->type = MIDIRequest::SendMMC;
913 request->mmc_cmd = cmd;
914 request->locate_frame = target_frame;
916 midi_requests.write (&request, 1);
921 Session::deliver_mmc (MIDI::MachineControl::Command cmd, nframes_t where)
923 using namespace MIDI;
927 if (_mmc_port == 0 || !session_send_mmc) {
931 mmc_buffer[nbytes++] = cmd;
933 // cerr << "delivering MMC, cmd = " << hex << (int) cmd << dec << endl;
936 case MachineControl::cmdLocate:
937 smpte_time_subframes (where, smpte);
939 mmc_buffer[nbytes++] = 0x6; // byte count
940 mmc_buffer[nbytes++] = 0x1; // "TARGET" subcommand
941 mmc_buffer[nbytes++] = smpte.hours;
942 mmc_buffer[nbytes++] = smpte.minutes;
943 mmc_buffer[nbytes++] = smpte.seconds;
944 mmc_buffer[nbytes++] = smpte.frames;
945 mmc_buffer[nbytes++] = smpte.subframes;
948 case MachineControl::cmdStop:
951 case MachineControl::cmdPlay:
952 /* always convert Play into Deferred Play */
953 mmc_buffer[4] = MachineControl::cmdDeferredPlay;
956 case MachineControl::cmdDeferredPlay:
959 case MachineControl::cmdRecordStrobe:
962 case MachineControl::cmdRecordExit:
965 case MachineControl::cmdRecordPause:
974 mmc_buffer[nbytes++] = 0xf7; // terminate SysEx/MMC message
976 Glib::Mutex::Lock lm (midi_lock);
978 if (_mmc_port->write (mmc_buffer, nbytes) != nbytes) {
979 error << string_compose(_("MMC: cannot send command %1%2%3"), &hex, cmd, &dec) << endmsg;
985 Session::mmc_step_timeout ()
990 gettimeofday (&now, 0);
992 timersub (&now, &last_mmc_step, &diff);
993 diff_usecs = diff.tv_sec * 1000000 + diff.tv_usec;
995 if (diff_usecs > 1000000.0 || fabs (_transport_speed) < 0.0000001) {
996 /* too long or too slow, stop transport */
997 request_transport_speed (0.0);
1002 if (diff_usecs < 250000.0) {
1003 /* too short, just keep going */
1009 request_transport_speed (_transport_speed * 0.75);
1015 Session::send_midi_message (MIDI::Port * port, MIDI::eventType ev, MIDI::channel_t ch, MIDI::EventTwoBytes data)
1017 // in another thread, really
1019 MIDIRequest* request = new MIDIRequest;
1021 request->type = MIDIRequest::SendMessage;
1022 request->port = port;
1025 request->data = data;
1027 midi_requests.write (&request, 1);
1028 poke_midi_thread ();
1032 Session::deliver_midi (MIDI::Port * port, MIDI::byte* buf, int32_t bufsize)
1034 // in another thread, really
1036 MIDIRequest* request = new MIDIRequest;
1038 request->type = MIDIRequest::Deliver;
1039 request->port = port;
1041 request->size = bufsize;
1043 midi_requests.write (&request, 1);
1044 poke_midi_thread ();
1048 Session::deliver_midi_message (MIDI::Port * port, MIDI::eventType ev, MIDI::channel_t ch, MIDI::EventTwoBytes data)
1050 if (port == 0 || ev == MIDI::none) {
1054 midi_msg[0] = (ev & 0xF0) | (ch & 0xF);
1055 midi_msg[1] = data.controller_number;
1056 midi_msg[2] = data.value;
1058 port->write (midi_msg, 3);
1062 Session::deliver_data (MIDI::Port * port, MIDI::byte* buf, int32_t size)
1065 port->write (buf, size);
1068 /* this is part of the semantics of the Deliver request */
1073 /*---------------------------------------------------------------------------
1075 ---------------------------------------------------------------------------*/
1078 Session::start_midi_thread ()
1080 if (pipe (midi_request_pipe)) {
1081 error << string_compose(_("Cannot create transport request signal pipe (%1)"), strerror (errno)) << endmsg;
1085 if (fcntl (midi_request_pipe[0], F_SETFL, O_NONBLOCK)) {
1086 error << string_compose(_("UI: cannot set O_NONBLOCK on " "signal read pipe (%1)"), strerror (errno)) << endmsg;
1090 if (fcntl (midi_request_pipe[1], F_SETFL, O_NONBLOCK)) {
1091 error << string_compose(_("UI: cannot set O_NONBLOCK on " "signal write pipe (%1)"), strerror (errno)) << endmsg;
1095 if (pthread_create_and_store ("transport", &midi_thread, 0, _midi_thread_work, this)) {
1096 error << _("Session: could not create transport thread") << endmsg;
1100 // pthread_detach (midi_thread);
1106 Session::terminate_midi_thread ()
1109 MIDIRequest* request = new MIDIRequest;
1112 request->type = MIDIRequest::Quit;
1114 midi_requests.write (&request, 1);
1115 poke_midi_thread ();
1117 pthread_join (midi_thread, &status);
1122 Session::poke_midi_thread ()
1126 if (write (midi_request_pipe[1], &c, 1) != 1) {
1127 error << string_compose(_("cannot send signal to midi thread! (%1)"), strerror (errno)) << endmsg;
1132 Session::_midi_thread_work (void* arg)
1134 pthread_setcancelstate (PTHREAD_CANCEL_ENABLE, 0);
1135 pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, 0);
1137 ((Session *) arg)->midi_thread_work ();
1142 Session::midi_thread_work ()
1144 MIDIRequest* request;
1145 struct pollfd pfd[4];
1149 struct sched_param rtparam;
1152 vector<MIDI::Port*> ports;
1154 PBD::notify_gui_about_thread_creation (pthread_self(), X_("MIDI"), 2048);
1156 memset (&rtparam, 0, sizeof (rtparam));
1157 rtparam.sched_priority = 9; /* XXX should be relative to audio (JACK) thread */
1159 if ((x = pthread_setschedparam (pthread_self(), SCHED_FIFO, &rtparam)) != 0) {
1160 // do we care? not particularly.
1163 /* set up the port vector; 4 is the largest possible size for now */
1165 ports.push_back (0);
1166 ports.push_back (0);
1167 ports.push_back (0);
1168 ports.push_back (0);
1174 pfd[nfds].fd = midi_request_pipe[0];
1175 pfd[nfds].events = POLLIN|POLLHUP|POLLERR;
1178 /* if we are using MMC control, we obviously have to listen
1179 on the appropriate port.
1182 if (Config->get_mmc_control() && _mmc_port && _mmc_port->selectable() >= 0) {
1183 pfd[nfds].fd = _mmc_port->selectable();
1184 pfd[nfds].events = POLLIN|POLLHUP|POLLERR;
1185 ports[nfds] = _mmc_port;
1186 //cerr << "MIDI port " << nfds << " = MMC @ " << _mmc_port << endl;
1190 /* if MTC is being handled on a different port from MMC
1191 or we are not handling MMC at all, poll
1195 if (_mtc_port && (_mtc_port != _mmc_port || !Config->get_mmc_control()) && _mtc_port->selectable() >= 0) {
1196 pfd[nfds].fd = _mtc_port->selectable();
1197 pfd[nfds].events = POLLIN|POLLHUP|POLLERR;
1198 ports[nfds] = _mtc_port;
1199 //cerr << "MIDI port " << nfds << " = MTC @ " << _mtc_port << endl;
1203 if (_midi_port && (_midi_port != _mmc_port || !Config->get_mmc_control()) && (_midi_port != _mtc_port) && _midi_port->selectable() >= 0) {
1204 pfd[nfds].fd = _midi_port->selectable();
1205 pfd[nfds].events = POLLIN|POLLHUP|POLLERR;
1206 ports[nfds] = _midi_port;
1207 // cerr << "MIDI port " << nfds << " = MIDI @ " << _midi_port << endl;
1211 if (!midi_timeouts.empty()) {
1212 timeout = 100; /* 10msecs */
1214 timeout = -1; /* if there is no data, we don't care */
1218 // cerr << "MIDI poll on " << nfds << " for " << timeout << endl;
1219 if (poll (pfd, nfds, timeout) < 0) {
1220 if (errno == EINTR) {
1221 /* gdb at work, perhaps */
1225 error << string_compose(_("MIDI thread poll failed (%1)"), strerror (errno)) << endmsg;
1229 // cerr << "MIDI thread wakes at " << get_cycles () << endl;
1234 /* check the transport request pipe */
1236 if (pfd[0].revents & ~POLLIN) {
1237 error << _("Error on transport thread request pipe") << endmsg;
1241 if (pfd[0].revents & POLLIN) {
1245 // cerr << "MIDI request FIFO ready\n";
1248 /* empty the pipe of all current requests */
1251 size_t nread = read (midi_request_pipe[0], &foo, sizeof (foo));
1254 if ((size_t) nread < sizeof (foo)) {
1259 } else if (nread == 0) {
1261 } else if (errno == EAGAIN) {
1264 fatal << _("Error reading from transport request pipe") << endmsg;
1269 while (midi_requests.read (&request, 1) == 1) {
1271 switch (request->type) {
1273 case MIDIRequest::SendFullMTC:
1274 // cerr << "send full MTC\n";
1275 send_full_time_code ();
1276 // cerr << "... done\n";
1279 case MIDIRequest::SendMTC:
1280 // cerr << "send qtr MTC\n";
1281 send_midi_time_code ();
1282 // cerr << "... done\n";
1285 case MIDIRequest::SendMMC:
1286 // cerr << "send MMC\n";
1287 deliver_mmc (request->mmc_cmd, request->locate_frame);
1288 // cerr << "... done\n";
1291 case MIDIRequest::SendMessage:
1292 // cerr << "send Message\n";
1293 deliver_midi_message (request->port, request->ev, request->chan, request->data);
1294 // cerr << "... done\n";
1297 case MIDIRequest::Deliver:
1298 // cerr << "deliver\n";
1299 deliver_data (_midi_port, request->buf, request->size);
1300 // cerr << "... done\n";
1303 case MIDIRequest::PortChange:
1304 /* restart poll with new ports */
1305 // cerr << "rebind\n";
1309 case MIDIRequest::Quit:
1311 pthread_exit_pbd (0);
1329 /* now read the rest of the ports */
1331 for (int p = 1; p < nfds; ++p) {
1332 if ((pfd[p].revents & ~POLLIN)) {
1333 // error << string_compose(_("Transport: error polling MIDI port %1 (revents =%2%3%4"), p, &hex, pfd[p].revents, &dec) << endmsg;
1337 if (pfd[p].revents & POLLIN) {
1339 midi_read (ports[p]);
1343 /* timeout driven */
1345 if (fds_ready < 2 && timeout != -1) {
1347 for (MidiTimeoutList::iterator i = midi_timeouts.begin(); i != midi_timeouts.end(); ) {
1349 MidiTimeoutList::iterator tmp;
1354 midi_timeouts.erase (i);