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);
145 Session::set_mmc_port (string port_tag)
147 MIDI::byte old_recv_device_id = 0;
148 MIDI::byte old_send_device_id = 0;
149 bool reset_id = false;
151 if (port_tag.length() == 0) {
152 if (_mmc_port == 0) {
161 if ((port = MIDI::Manager::instance()->port (port_tag)) == 0) {
168 old_recv_device_id = mmc->receive_device_id();
169 old_recv_device_id = mmc->send_device_id();
174 mmc = new MIDI::MachineControl (*_mmc_port, 1.0,
175 MMC_CommandSignature,
176 MMC_ResponseSignature);
179 mmc->set_receive_device_id (old_recv_device_id);
180 mmc->set_send_device_id (old_send_device_id);
184 (mem_fun (*this, &Session::mmc_deferred_play));
185 mmc->DeferredPlay.connect
186 (mem_fun (*this, &Session::mmc_deferred_play));
188 (mem_fun (*this, &Session::mmc_stop));
189 mmc->FastForward.connect
190 (mem_fun (*this, &Session::mmc_fast_forward));
192 (mem_fun (*this, &Session::mmc_rewind));
194 (mem_fun (*this, &Session::mmc_pause));
195 mmc->RecordPause.connect
196 (mem_fun (*this, &Session::mmc_record_pause));
197 mmc->RecordStrobe.connect
198 (mem_fun (*this, &Session::mmc_record_strobe));
199 mmc->RecordExit.connect
200 (mem_fun (*this, &Session::mmc_record_exit));
202 (mem_fun (*this, &Session::mmc_locate));
204 (mem_fun (*this, &Session::mmc_step));
206 (mem_fun (*this, &Session::mmc_shuttle));
207 mmc->TrackRecordStatusChange.connect
208 (mem_fun (*this, &Session::mmc_record_enable));
211 /* also handle MIDI SPP because its so common */
213 _mmc_port->input()->start.connect (mem_fun (*this, &Session::spp_start));
214 _mmc_port->input()->contineu.connect (mem_fun (*this, &Session::spp_continue));
215 _mmc_port->input()->stop.connect (mem_fun (*this, &Session::spp_stop));
217 Config->set_mmc_port_name (port_tag);
220 MMC_PortChanged(); /* EMIT SIGNAL */
221 change_midi_ports ();
227 Session::set_midi_port (string port_tag)
229 if (port_tag.length() == 0) {
230 if (_midi_port == 0) {
239 if ((port = MIDI::Manager::instance()->port (port_tag)) == 0) {
245 /* XXX need something to forward this to control protocols ? or just
249 Config->set_midi_port_name (port_tag);
252 MIDI_PortChanged(); /* EMIT SIGNAL */
253 change_midi_ports ();
259 Session::set_trace_midi_input (bool yn, MIDI::Port* port)
261 MIDI::Parser* input_parser;
264 if ((input_parser = port->input()) != 0) {
265 input_parser->trace (yn, &cout, "input: ");
270 if ((input_parser = _mmc_port->input()) != 0) {
271 input_parser->trace (yn, &cout, "input: ");
275 if (_mtc_port && _mtc_port != _mmc_port) {
276 if ((input_parser = _mtc_port->input()) != 0) {
277 input_parser->trace (yn, &cout, "input: ");
281 if (_midi_port && _midi_port != _mmc_port && _midi_port != _mtc_port ) {
282 if ((input_parser = _midi_port->input()) != 0) {
283 input_parser->trace (yn, &cout, "input: ");
288 Config->set_trace_midi_input (yn);
292 Session::set_trace_midi_output (bool yn, MIDI::Port* port)
294 MIDI::Parser* output_parser;
297 if ((output_parser = port->output()) != 0) {
298 output_parser->trace (yn, &cout, "output: ");
302 if ((output_parser = _mmc_port->output()) != 0) {
303 output_parser->trace (yn, &cout, "output: ");
307 if (_mtc_port && _mtc_port != _mmc_port) {
308 if ((output_parser = _mtc_port->output()) != 0) {
309 output_parser->trace (yn, &cout, "output: ");
313 if (_midi_port && _midi_port != _mmc_port && _midi_port != _mtc_port ) {
314 if ((output_parser = _midi_port->output()) != 0) {
315 output_parser->trace (yn, &cout, "output: ");
321 Config->set_trace_midi_output (yn);
325 Session::get_trace_midi_input(MIDI::Port *port)
327 MIDI::Parser* input_parser;
329 if ((input_parser = port->input()) != 0) {
330 return input_parser->tracing();
335 if ((input_parser = _mmc_port->input()) != 0) {
336 return input_parser->tracing();
341 if ((input_parser = _mtc_port->input()) != 0) {
342 return input_parser->tracing();
347 if ((input_parser = _midi_port->input()) != 0) {
348 return input_parser->tracing();
357 Session::get_trace_midi_output(MIDI::Port *port)
359 MIDI::Parser* output_parser;
361 if ((output_parser = port->output()) != 0) {
362 return output_parser->tracing();
367 if ((output_parser = _mmc_port->output()) != 0) {
368 return output_parser->tracing();
373 if ((output_parser = _mtc_port->output()) != 0) {
374 return output_parser->tracing();
379 if ((output_parser = _midi_port->output()) != 0) {
380 return output_parser->tracing();
390 Session::setup_midi_control ()
392 outbound_mtc_smpte_frame = 0;
393 next_quarter_frame_to_send = -1;
395 /* setup the MMC buffer */
397 mmc_buffer[0] = 0xf0; // SysEx
398 mmc_buffer[1] = 0x7f; // Real Time SysEx ID for MMC
399 mmc_buffer[2] = mmc->send_device_id();
400 mmc_buffer[3] = 0x6; // MCC
402 /* Set up the qtr frame message */
415 Session::midi_read (MIDI::Port* port)
419 /* reading from the MIDI port activates the Parser
420 that in turn generates signals that we care
421 about. the port is already set to NONBLOCK so that
422 can read freely here.
427 // cerr << "+++ READ ON " << port->name() << endl;
429 int nread = port->read (buf, sizeof (buf));
431 // cerr << "-- READ (" << nread << " ON " << port->name() << endl;
434 if ((size_t) nread < sizeof (buf)) {
439 } else if (nread == 0) {
441 } else if (errno == EAGAIN) {
444 fatal << string_compose(_("Error reading from MIDI port %1"), port->name()) << endmsg;
453 Session::spp_start (Parser& ignored)
455 if (Config->get_mmc_control() && (Config->get_slave_source() != MTC)) {
456 request_transport_speed (1.0);
461 Session::spp_continue (Parser& ignored)
467 Session::spp_stop (Parser& ignored)
469 if (Config->get_mmc_control()) {
475 Session::mmc_deferred_play (MIDI::MachineControl &mmc)
477 if (Config->get_mmc_control() && (Config->get_slave_source() != MTC)) {
478 request_transport_speed (1.0);
483 Session::mmc_record_pause (MIDI::MachineControl &mmc)
485 if (Config->get_mmc_control()) {
486 maybe_enable_record();
491 Session::mmc_record_strobe (MIDI::MachineControl &mmc)
493 if (!Config->get_mmc_control())
496 /* record strobe does an implicit "Play" command */
498 if (_transport_speed != 1.0) {
500 /* start_transport() will move from Enabled->Recording, so we
501 don't need to do anything here except enable recording.
502 its not the same as maybe_enable_record() though, because
503 that *can* switch to Recording, which we do not want.
506 save_state ("", true);
507 g_atomic_int_set (&_record_status, Enabled);
508 RecordStateChanged (); /* EMIT SIGNAL */
510 request_transport_speed (1.0);
519 Session::mmc_record_exit (MIDI::MachineControl &mmc)
521 if (Config->get_mmc_control()) {
522 disable_record (false);
527 Session::mmc_stop (MIDI::MachineControl &mmc)
529 if (Config->get_mmc_control()) {
535 Session::mmc_pause (MIDI::MachineControl &mmc)
537 if (Config->get_mmc_control()) {
539 /* We support RECORD_PAUSE, so the spec says that
540 we must interpret PAUSE like RECORD_PAUSE if
544 if (actively_recording()) {
545 maybe_enable_record ();
552 static bool step_queued = false;
555 Session::mmc_step (MIDI::MachineControl &mmc, int steps)
557 if (!Config->get_mmc_control()) {
562 struct timeval diff = { 0, 0 };
564 gettimeofday (&now, 0);
566 timersub (&now, &last_mmc_step, &diff);
568 gettimeofday (&now, 0);
569 timersub (&now, &last_mmc_step, &diff);
571 if (last_mmc_step.tv_sec != 0 && (diff.tv_usec + (diff.tv_sec * 1000000)) < _engine.usecs_per_cycle()) {
575 double diff_secs = diff.tv_sec + (diff.tv_usec / 1000000.0);
576 double cur_speed = (((steps * 0.5) * smpte_frames_per_second()) / diff_secs) / smpte_frames_per_second();
578 if (_transport_speed == 0 || cur_speed * _transport_speed < 0) {
579 /* change direction */
580 step_speed = cur_speed;
582 step_speed = (0.6 * step_speed) + (0.4 * cur_speed);
588 cerr << "delta = " << diff_secs
589 << " ct = " << _transport_speed
590 << " steps = " << steps
591 << " new speed = " << cur_speed
592 << " speed = " << step_speed
596 request_transport_speed (step_speed);
600 midi_timeouts.push_back (mem_fun (*this, &Session::mmc_step_timeout));
606 Session::mmc_rewind (MIDI::MachineControl &mmc)
608 if (Config->get_mmc_control()) {
609 request_transport_speed(-8.0f);
614 Session::mmc_fast_forward (MIDI::MachineControl &mmc)
616 if (Config->get_mmc_control()) {
617 request_transport_speed(8.0f);
622 Session::mmc_locate (MIDI::MachineControl &mmc, const MIDI::byte* mmc_tc)
624 if (!Config->get_mmc_control()) {
628 nframes_t target_frame;
631 smpte.hours = mmc_tc[0] & 0xf;
632 smpte.minutes = mmc_tc[1];
633 smpte.seconds = mmc_tc[2];
634 smpte.frames = mmc_tc[3];
635 smpte.rate = smpte_frames_per_second();
636 smpte.drop = smpte_drop_frames();
638 // Also takes smpte offset into account:
639 smpte_to_sample( smpte, target_frame, true /* use_offset */, false /* use_subframes */ );
641 if (target_frame > max_frames) {
642 target_frame = max_frames;
645 /* Some (all?) MTC/MMC devices do not send a full MTC frame
646 at the end of a locate, instead sending only an MMC
647 locate command. This causes the current position
648 of an MTC slave to become out of date. Catch this.
651 MTC_Slave* mtcs = dynamic_cast<MTC_Slave*> (_slave);
654 // cerr << "Locate *with* MTC slave\n";
655 mtcs->handle_locate (mmc_tc);
657 // cerr << "Locate without MTC slave\n";
658 request_locate (target_frame, false);
663 Session::mmc_shuttle (MIDI::MachineControl &mmc, float speed, bool forw)
665 if (!Config->get_mmc_control()) {
669 if (Config->get_shuttle_speed_threshold() >= 0 && speed > Config->get_shuttle_speed_threshold()) {
670 speed *= Config->get_shuttle_speed_factor();
674 request_transport_speed (speed);
676 request_transport_speed (-speed);
681 Session::mmc_record_enable (MIDI::MachineControl &mmc, size_t trk, bool enabled)
683 if (Config->get_mmc_control()) {
685 RouteList::iterator i;
686 boost::shared_ptr<RouteList> r = routes.reader();
688 for (i = r->begin(); i != r->end(); ++i) {
691 if ((at = dynamic_cast<AudioTrack*>((*i).get())) != 0) {
692 if (trk == at->remote_control_id()) {
693 at->set_record_enable (enabled, &mmc);
702 Session::send_full_time_code_in_another_thread ()
704 send_time_code_in_another_thread (true);
708 Session::send_midi_time_code_in_another_thread ()
710 send_time_code_in_another_thread (false);
714 Session::send_time_code_in_another_thread (bool full)
716 nframes_t two_smpte_frames_duration;
717 nframes_t quarter_frame_duration;
719 /* Duration of two smpte frames */
720 two_smpte_frames_duration = ((long) _frames_per_smpte_frame) << 1;
722 /* Duration of one quarter frame */
723 quarter_frame_duration = ((long) _frames_per_smpte_frame) >> 2;
725 if (_transport_frame < (outbound_mtc_smpte_frame + (next_quarter_frame_to_send * quarter_frame_duration)))
727 /* There is no work to do.
728 We throttle this here so that we don't overload
729 the transport thread with requests.
734 MIDIRequest* request = new MIDIRequest;
737 request->type = MIDIRequest::SendFullMTC;
739 request->type = MIDIRequest::SendMTC;
742 midi_requests.write (&request, 1);
747 Session::change_midi_ports ()
749 MIDIRequest* request = new MIDIRequest;
751 request->type = MIDIRequest::PortChange;
752 midi_requests.write (&request, 1);
757 Session::send_full_time_code ()
763 if (_mtc_port == 0 || !session_send_mtc) {
767 // Get smpte time for this transport frame
768 sample_to_smpte(_transport_frame, smpte, true /* use_offset */, false /* no subframes */);
770 // Check for negative smpte time and prepare for quarter frame transmission
771 if (smpte.negative) {
772 // Negative mtc is not defined, so sync slave to smpte zero.
773 // When _transport_frame gets there we will start transmitting quarter frames
779 smpte.negative = false;
780 smpte_to_sample( smpte, outbound_mtc_smpte_frame, true, false );
781 transmitting_smpte_time = smpte;
783 transmitting_smpte_time = smpte;
784 outbound_mtc_smpte_frame = _transport_frame;
785 if (((mtc_smpte_bits >> 5) != MIDI::MTC_25_FPS) && (transmitting_smpte_time.frames % 2)) {
786 // start MTC quarter frame transmission on an even frame
787 SMPTE::increment( transmitting_smpte_time );
788 outbound_mtc_smpte_frame += (nframes_t) _frames_per_smpte_frame;
792 // Compensate for audio latency
793 outbound_mtc_smpte_frame += _worst_output_latency;
795 next_quarter_frame_to_send = 0;
797 // Sync slave to the same smpte time as we are on (except if negative, see above)
805 msg[5] = mtc_smpte_bits | smpte.hours;
806 msg[6] = smpte.minutes;
807 msg[7] = smpte.seconds;
808 msg[8] = smpte.frames;
811 Glib::Mutex::Lock lm (midi_lock);
813 if (_mtc_port->midimsg (msg, sizeof (msg))) {
814 error << _("Session: could not send full MIDI time code") << endmsg;
824 Session::send_midi_time_code ()
826 if (_mtc_port == 0 || !session_send_mtc || transmitting_smpte_time.negative || (next_quarter_frame_to_send < 0) ) {
830 nframes_t two_smpte_frames_duration;
831 nframes_t quarter_frame_duration;
833 /* Duration of two smpte frames */
834 two_smpte_frames_duration = ((long) _frames_per_smpte_frame) << 1;
836 /* Duration of one quarter frame */
837 quarter_frame_duration = ((long) _frames_per_smpte_frame) >> 2;
839 while (_transport_frame >= (outbound_mtc_smpte_frame + (next_quarter_frame_to_send * quarter_frame_duration))) {
841 // Send quarter frames up to current time
843 Glib::Mutex::Lock lm (midi_lock);
845 switch(next_quarter_frame_to_send) {
847 mtc_msg[1] = 0x00 | (transmitting_smpte_time.frames & 0xf);
850 mtc_msg[1] = 0x10 | ((transmitting_smpte_time.frames & 0xf0) >> 4);
853 mtc_msg[1] = 0x20 | (transmitting_smpte_time.seconds & 0xf);
856 mtc_msg[1] = 0x30 | ((transmitting_smpte_time.seconds & 0xf0) >> 4);
859 mtc_msg[1] = 0x40 | (transmitting_smpte_time.minutes & 0xf);
862 mtc_msg[1] = 0x50 | ((transmitting_smpte_time.minutes & 0xf0) >> 4);
865 mtc_msg[1] = 0x60 | ((mtc_smpte_bits|transmitting_smpte_time.hours) & 0xf);
868 mtc_msg[1] = 0x70 | (((mtc_smpte_bits|transmitting_smpte_time.hours) & 0xf0) >> 4);
872 if (_mtc_port->midimsg (mtc_msg, 2)) {
873 error << string_compose(_("Session: cannot send quarter-frame MTC message (%1)"), strerror (errno))
879 // 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;
881 // Increment quarter frame counter
882 next_quarter_frame_to_send++;
884 if (next_quarter_frame_to_send >= 8) {
885 // Wrap quarter frame counter
886 next_quarter_frame_to_send = 0;
887 // Increment smpte time twice
888 SMPTE::increment( transmitting_smpte_time );
889 SMPTE::increment( transmitting_smpte_time );
890 // Re-calculate timing of first quarter frame
891 smpte_to_sample( transmitting_smpte_time, outbound_mtc_smpte_frame, true /* use_offset */, false );
892 // Compensate for audio latency
893 outbound_mtc_smpte_frame += _worst_output_latency;
900 /***********************************************************************
902 **********************************************************************/
905 Session::send_mmc_in_another_thread (MIDI::MachineControl::Command cmd, nframes_t target_frame)
907 MIDIRequest* request;
909 if (_mtc_port == 0 || !session_send_mmc) {
913 request = new MIDIRequest;
914 request->type = MIDIRequest::SendMMC;
915 request->mmc_cmd = cmd;
916 request->locate_frame = target_frame;
918 midi_requests.write (&request, 1);
923 Session::deliver_mmc (MIDI::MachineControl::Command cmd, nframes_t where)
925 using namespace MIDI;
929 if (_mmc_port == 0 || !session_send_mmc) {
933 mmc_buffer[nbytes++] = cmd;
935 // cerr << "delivering MMC, cmd = " << hex << (int) cmd << dec << endl;
938 case MachineControl::cmdLocate:
939 smpte_time_subframes (where, smpte);
941 mmc_buffer[nbytes++] = 0x6; // byte count
942 mmc_buffer[nbytes++] = 0x1; // "TARGET" subcommand
943 mmc_buffer[nbytes++] = smpte.hours;
944 mmc_buffer[nbytes++] = smpte.minutes;
945 mmc_buffer[nbytes++] = smpte.seconds;
946 mmc_buffer[nbytes++] = smpte.frames;
947 mmc_buffer[nbytes++] = smpte.subframes;
950 case MachineControl::cmdStop:
953 case MachineControl::cmdPlay:
954 /* always convert Play into Deferred Play */
955 mmc_buffer[4] = MachineControl::cmdDeferredPlay;
958 case MachineControl::cmdDeferredPlay:
961 case MachineControl::cmdRecordStrobe:
964 case MachineControl::cmdRecordExit:
967 case MachineControl::cmdRecordPause:
976 mmc_buffer[nbytes++] = 0xf7; // terminate SysEx/MMC message
978 Glib::Mutex::Lock lm (midi_lock);
980 if (_mmc_port->write (mmc_buffer, nbytes) != nbytes) {
981 error << string_compose(_("MMC: cannot send command %1%2%3"), &hex, cmd, &dec) << endmsg;
987 Session::mmc_step_timeout ()
992 gettimeofday (&now, 0);
994 timersub (&now, &last_mmc_step, &diff);
995 diff_usecs = diff.tv_sec * 1000000 + diff.tv_usec;
997 if (diff_usecs > 1000000.0 || fabs (_transport_speed) < 0.0000001) {
998 /* too long or too slow, stop transport */
999 request_transport_speed (0.0);
1000 step_queued = false;
1004 if (diff_usecs < 250000.0) {
1005 /* too short, just keep going */
1011 request_transport_speed (_transport_speed * 0.75);
1017 Session::send_midi_message (MIDI::Port * port, MIDI::eventType ev, MIDI::channel_t ch, MIDI::EventTwoBytes data)
1019 // in another thread, really
1021 MIDIRequest* request = new MIDIRequest;
1023 request->type = MIDIRequest::SendMessage;
1024 request->port = port;
1027 request->data = data;
1029 midi_requests.write (&request, 1);
1030 poke_midi_thread ();
1034 Session::deliver_midi (MIDI::Port * port, MIDI::byte* buf, int32_t bufsize)
1036 // in another thread, really
1038 MIDIRequest* request = new MIDIRequest;
1040 request->type = MIDIRequest::Deliver;
1041 request->port = port;
1043 request->size = bufsize;
1045 midi_requests.write (&request, 1);
1046 poke_midi_thread ();
1050 Session::deliver_midi_message (MIDI::Port * port, MIDI::eventType ev, MIDI::channel_t ch, MIDI::EventTwoBytes data)
1052 if (port == 0 || ev == MIDI::none) {
1056 midi_msg[0] = (ev & 0xF0) | (ch & 0xF);
1057 midi_msg[1] = data.controller_number;
1058 midi_msg[2] = data.value;
1060 port->write (midi_msg, 3);
1064 Session::deliver_data (MIDI::Port * port, MIDI::byte* buf, int32_t size)
1067 port->write (buf, size);
1070 /* this is part of the semantics of the Deliver request */
1075 /*---------------------------------------------------------------------------
1077 ---------------------------------------------------------------------------*/
1080 Session::start_midi_thread ()
1082 if (pipe (midi_request_pipe)) {
1083 error << string_compose(_("Cannot create transport request signal pipe (%1)"), strerror (errno)) << endmsg;
1087 if (fcntl (midi_request_pipe[0], F_SETFL, O_NONBLOCK)) {
1088 error << string_compose(_("UI: cannot set O_NONBLOCK on " "signal read pipe (%1)"), strerror (errno)) << endmsg;
1092 if (fcntl (midi_request_pipe[1], F_SETFL, O_NONBLOCK)) {
1093 error << string_compose(_("UI: cannot set O_NONBLOCK on " "signal write pipe (%1)"), strerror (errno)) << endmsg;
1097 if (pthread_create_and_store ("transport", &midi_thread, 0, _midi_thread_work, this)) {
1098 error << _("Session: could not create transport thread") << endmsg;
1102 // pthread_detach (midi_thread);
1108 Session::terminate_midi_thread ()
1111 MIDIRequest* request = new MIDIRequest;
1114 request->type = MIDIRequest::Quit;
1116 midi_requests.write (&request, 1);
1117 poke_midi_thread ();
1119 pthread_join (midi_thread, &status);
1124 Session::poke_midi_thread ()
1128 if (write (midi_request_pipe[1], &c, 1) != 1) {
1129 error << string_compose(_("cannot send signal to midi thread! (%1)"), strerror (errno)) << endmsg;
1134 Session::_midi_thread_work (void* arg)
1136 pthread_setcancelstate (PTHREAD_CANCEL_ENABLE, 0);
1137 pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, 0);
1139 ((Session *) arg)->midi_thread_work ();
1144 Session::midi_thread_work ()
1146 MIDIRequest* request;
1147 struct pollfd pfd[4];
1151 struct sched_param rtparam;
1154 vector<MIDI::Port*> ports;
1156 PBD::ThreadCreatedWithRequestSize (pthread_self(), X_("MIDI"), 2048);
1158 memset (&rtparam, 0, sizeof (rtparam));
1159 rtparam.sched_priority = 9; /* XXX should be relative to audio (JACK) thread */
1161 if ((x = pthread_setschedparam (pthread_self(), SCHED_FIFO, &rtparam)) != 0) {
1162 // do we care? not particularly.
1165 /* set up the port vector; 4 is the largest possible size for now */
1167 ports.push_back (0);
1168 ports.push_back (0);
1169 ports.push_back (0);
1170 ports.push_back (0);
1176 pfd[nfds].fd = midi_request_pipe[0];
1177 pfd[nfds].events = POLLIN|POLLHUP|POLLERR;
1180 /* if we are using MMC control, we obviously have to listen
1181 on the appropriate port.
1184 if (Config->get_mmc_control() && _mmc_port && _mmc_port->selectable() >= 0) {
1185 pfd[nfds].fd = _mmc_port->selectable();
1186 pfd[nfds].events = POLLIN|POLLHUP|POLLERR;
1187 ports[nfds] = _mmc_port;
1191 /* if MTC is being handled on a different port from MMC
1192 or we are not handling MMC at all, poll
1196 if (_mtc_port && (_mtc_port != _mmc_port || !Config->get_mmc_control()) && _mtc_port->selectable() >= 0) {
1197 pfd[nfds].fd = _mtc_port->selectable();
1198 pfd[nfds].events = POLLIN|POLLHUP|POLLERR;
1199 ports[nfds] = _mtc_port;
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;
1210 if (!midi_timeouts.empty()) {
1211 timeout = 100; /* 10msecs */
1213 timeout = -1; /* if there is no data, we don't care */
1217 // cerr << "MIDI poll on " << nfds << " for " << timeout << endl;
1218 if (poll (pfd, nfds, timeout) < 0) {
1219 if (errno == EINTR) {
1220 /* gdb at work, perhaps */
1224 error << string_compose(_("MIDI thread poll failed (%1)"), strerror (errno)) << endmsg;
1228 // cerr << "MIDI thread wakes at " << get_cycles () << endl;
1233 /* check the transport request pipe */
1235 if (pfd[0].revents & ~POLLIN) {
1236 error << _("Error on transport thread request pipe") << endmsg;
1240 if (pfd[0].revents & POLLIN) {
1244 // cerr << "MIDI request FIFO ready\n";
1247 /* empty the pipe of all current requests */
1250 size_t nread = read (midi_request_pipe[0], &foo, sizeof (foo));
1253 if ((size_t) nread < sizeof (foo)) {
1258 } else if (nread == 0) {
1260 } else if (errno == EAGAIN) {
1263 fatal << _("Error reading from transport request pipe") << endmsg;
1268 while (midi_requests.read (&request, 1) == 1) {
1270 switch (request->type) {
1272 case MIDIRequest::SendFullMTC:
1273 // cerr << "send full MTC\n";
1274 send_full_time_code ();
1275 // cerr << "... done\n";
1278 case MIDIRequest::SendMTC:
1279 // cerr << "send qtr MTC\n";
1280 send_midi_time_code ();
1281 // cerr << "... done\n";
1284 case MIDIRequest::SendMMC:
1285 // cerr << "send MMC\n";
1286 deliver_mmc (request->mmc_cmd, request->locate_frame);
1287 // cerr << "... done\n";
1290 case MIDIRequest::SendMessage:
1291 // cerr << "send Message\n";
1292 deliver_midi_message (request->port, request->ev, request->chan, request->data);
1293 // cerr << "... done\n";
1296 case MIDIRequest::Deliver:
1297 // cerr << "deliver\n";
1298 deliver_data (_midi_port, request->buf, request->size);
1299 // cerr << "... done\n";
1302 case MIDIRequest::PortChange:
1303 /* restart poll with new ports */
1304 // cerr << "rebind\n";
1308 case MIDIRequest::Quit:
1310 pthread_exit_pbd (0);
1328 /* now read the rest of the ports */
1330 for (int p = 1; p < nfds; ++p) {
1331 if ((pfd[p].revents & ~POLLIN)) {
1332 // error << string_compose(_("Transport: error polling MIDI port %1 (revents =%2%3%4"), p, &hex, pfd[p].revents, &dec) << endmsg;
1336 if (pfd[p].revents & POLLIN) {
1338 midi_read (ports[p]);
1342 /* timeout driven */
1344 if (fds_ready < 2 && timeout != -1) {
1346 for (MidiTimeoutList::iterator i = midi_timeouts.begin(); i != midi_timeouts.end(); ) {
1348 MidiTimeoutList::iterator tmp;
1353 midi_timeouts.erase (i);