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>
43 #include <ardour/smpte.h>
48 using namespace ARDOUR;
52 MachineControl::CommandSignature MMC_CommandSignature;
53 MachineControl::ResponseSignature MMC_ResponseSignature;
55 MultiAllocSingleReleasePool Session::MIDIRequest::pool ("midi", sizeof (Session::MIDIRequest), 1024);
58 Session::use_config_midi_ports ()
62 if (default_mmc_port) {
63 set_mmc_port (default_mmc_port->name());
68 if (default_mtc_port) {
69 set_mtc_port (default_mtc_port->name());
74 if (default_midi_port) {
75 set_midi_port (default_midi_port->name());
84 /***********************************************************************
86 **********************************************************************/
89 Session::set_mtc_port (string port_tag)
92 MIDI::byte old_device_id = 0;
93 bool reset_id = false;
95 if (port_tag.length() == 0) {
105 if ((port = MIDI::Manager::instance()->port (port_tag)) == 0) {
112 old_device_id = mmc->device_id();
117 mmc = new MIDI::MachineControl (*_mmc_port, 1.0,
118 MMC_CommandSignature,
119 MMC_ResponseSignature);
122 mmc->set_device_id (old_device_id);
126 (mem_fun (*this, &Session::mmc_deferred_play));
127 mmc->DeferredPlay.connect
128 (mem_fun (*this, &Session::mmc_deferred_play));
130 (mem_fun (*this, &Session::mmc_stop));
131 mmc->FastForward.connect
132 (mem_fun (*this, &Session::mmc_fast_forward));
134 (mem_fun (*this, &Session::mmc_rewind));
136 (mem_fun (*this, &Session::mmc_pause));
137 mmc->RecordPause.connect
138 (mem_fun (*this, &Session::mmc_record_pause));
139 mmc->RecordStrobe.connect
140 (mem_fun (*this, &Session::mmc_record_strobe));
141 mmc->RecordExit.connect
142 (mem_fun (*this, &Session::mmc_record_exit));
144 (mem_fun (*this, &Session::mmc_locate));
146 (mem_fun (*this, &Session::mmc_step));
148 (mem_fun (*this, &Session::mmc_shuttle));
149 mmc->TrackRecordStatusChange.connect
150 (mem_fun (*this, &Session::mmc_record_enable));
153 /* also handle MIDI SPP because its so common */
155 _mmc_port->input()->start.connect (mem_fun (*this, &Session::spp_start));
156 _mmc_port->input()->contineu.connect (mem_fun (*this, &Session::spp_continue));
157 _mmc_port->input()->stop.connect (mem_fun (*this, &Session::spp_stop));
159 Config->set_mmc_port_name (port_tag);
162 MMC_PortChanged(); /* EMIT SIGNAL */
163 change_midi_ports ();
170 Session::set_mmc_device_id (uint32_t device_id)
173 mmc->set_device_id (device_id);
178 Session::set_mmc_port (string port_tag)
181 MIDI::byte old_device_id = 0;
182 bool reset_id = false;
184 if (port_tag.length() == 0) {
185 if (_mmc_port == 0) {
194 if ((port = MIDI::Manager::instance()->port (port_tag)) == 0) {
201 old_device_id = mmc->device_id();
206 mmc = new MIDI::MachineControl (*_mmc_port, 1.0,
207 MMC_CommandSignature,
208 MMC_ResponseSignature);
211 mmc->set_device_id (old_device_id);
215 (mem_fun (*this, &Session::mmc_deferred_play));
216 mmc->DeferredPlay.connect
217 (mem_fun (*this, &Session::mmc_deferred_play));
219 (mem_fun (*this, &Session::mmc_stop));
220 mmc->FastForward.connect
221 (mem_fun (*this, &Session::mmc_fast_forward));
223 (mem_fun (*this, &Session::mmc_rewind));
225 (mem_fun (*this, &Session::mmc_pause));
226 mmc->RecordPause.connect
227 (mem_fun (*this, &Session::mmc_record_pause));
228 mmc->RecordStrobe.connect
229 (mem_fun (*this, &Session::mmc_record_strobe));
230 mmc->RecordExit.connect
231 (mem_fun (*this, &Session::mmc_record_exit));
233 (mem_fun (*this, &Session::mmc_locate));
235 (mem_fun (*this, &Session::mmc_step));
237 (mem_fun (*this, &Session::mmc_shuttle));
238 mmc->TrackRecordStatusChange.connect
239 (mem_fun (*this, &Session::mmc_record_enable));
242 /* also handle MIDI SPP because its so common */
244 _mmc_port->input()->start.connect (mem_fun (*this, &Session::spp_start));
245 _mmc_port->input()->contineu.connect (mem_fun (*this, &Session::spp_continue));
246 _mmc_port->input()->stop.connect (mem_fun (*this, &Session::spp_stop));
248 Config->set_mmc_port_name (port_tag);
252 MMC_PortChanged(); /* EMIT SIGNAL */
253 change_midi_ports ();
259 Session::set_midi_port (string port_tag)
262 if (port_tag.length() == 0) {
263 if (_midi_port == 0) {
272 if ((port = MIDI::Manager::instance()->port (port_tag)) == 0) {
278 /* XXX need something to forward this to control protocols ? or just
282 Config->set_midi_port_name (port_tag);
286 MIDI_PortChanged(); /* EMIT SIGNAL */
287 change_midi_ports ();
293 Session::set_trace_midi_input (bool yn, MIDI::Port* port)
296 MIDI::Parser* input_parser;
299 if ((input_parser = port->input()) != 0) {
300 input_parser->trace (yn, &cout, "input: ");
305 if ((input_parser = _mmc_port->input()) != 0) {
306 input_parser->trace (yn, &cout, "input: ");
310 if (_mtc_port && _mtc_port != _mmc_port) {
311 if ((input_parser = _mtc_port->input()) != 0) {
312 input_parser->trace (yn, &cout, "input: ");
316 if (_midi_port && _midi_port != _mmc_port && _midi_port != _mtc_port ) {
317 if ((input_parser = _midi_port->input()) != 0) {
318 input_parser->trace (yn, &cout, "input: ");
324 Config->set_trace_midi_input (yn);
328 Session::set_trace_midi_output (bool yn, MIDI::Port* port)
331 MIDI::Parser* output_parser;
334 if ((output_parser = port->output()) != 0) {
335 output_parser->trace (yn, &cout, "output: ");
339 if ((output_parser = _mmc_port->output()) != 0) {
340 output_parser->trace (yn, &cout, "output: ");
344 if (_mtc_port && _mtc_port != _mmc_port) {
345 if ((output_parser = _mtc_port->output()) != 0) {
346 output_parser->trace (yn, &cout, "output: ");
350 if (_midi_port && _midi_port != _mmc_port && _midi_port != _mtc_port ) {
351 if ((output_parser = _midi_port->output()) != 0) {
352 output_parser->trace (yn, &cout, "output: ");
359 Config->set_trace_midi_output (yn);
363 Session::get_trace_midi_input(MIDI::Port *port)
366 MIDI::Parser* input_parser;
368 if ((input_parser = port->input()) != 0) {
369 return input_parser->tracing();
374 if ((input_parser = _mmc_port->input()) != 0) {
375 return input_parser->tracing();
380 if ((input_parser = _mtc_port->input()) != 0) {
381 return input_parser->tracing();
386 if ((input_parser = _midi_port->input()) != 0) {
387 return input_parser->tracing();
397 Session::get_trace_midi_output(MIDI::Port *port)
400 MIDI::Parser* output_parser;
402 if ((output_parser = port->output()) != 0) {
403 return output_parser->tracing();
408 if ((output_parser = _mmc_port->output()) != 0) {
409 return output_parser->tracing();
414 if ((output_parser = _mtc_port->output()) != 0) {
415 return output_parser->tracing();
420 if ((output_parser = _midi_port->output()) != 0) {
421 return output_parser->tracing();
432 Session::setup_midi_control ()
434 outbound_mtc_smpte_frame = 0;
435 next_quarter_frame_to_send = 0;
437 /* setup the MMC buffer */
439 mmc_buffer[0] = 0xf0; // SysEx
440 mmc_buffer[1] = 0x7f; // Real Time SysEx ID for MMC
441 mmc_buffer[2] = 0x7f; // "broadcast" device ID
442 mmc_buffer[3] = 0x6; // MCC
444 /* Set up the qtr frame message */
455 if (_mmc_port != 0) {
457 Config->set_send_mmc (session_send_mmc);
462 session_send_mmc = false;
465 if (_mtc_port != 0) {
467 Config->set_send_mtc (session_send_mtc);
470 session_send_mtc = false;
476 Session::midi_read (MIDI::Port* port)
480 /* reading from the MIDI port activates the Parser
481 that in turn generates signals that we care
482 about. the port is already set to NONBLOCK so that
483 can read freely here.
488 // cerr << "+++ READ ON " << port->name() << endl;
490 int nread = port->read (buf, sizeof (buf));
492 // cerr << "-- READ (" << nread << " ON " << port->name() << endl;
495 if ((size_t) nread < sizeof (buf)) {
500 } else if (nread == 0) {
502 } else if (errno == EAGAIN) {
505 fatal << string_compose(_("Error reading from MIDI port %1"), port->name()) << endmsg;
515 Session::spp_start (Parser& ignored)
517 if (Config->get_mmc_control() && (Config->get_slave_source() != MTC)) {
518 request_transport_speed (1.0);
523 Session::spp_continue (Parser& ignored)
529 Session::spp_stop (Parser& ignored)
531 if (Config->get_mmc_control()) {
537 Session::mmc_deferred_play (MIDI::MachineControl &mmc)
539 if (Config->get_mmc_control() && (Config->get_slave_source() != MTC)) {
540 request_transport_speed (1.0);
545 Session::mmc_record_pause (MIDI::MachineControl &mmc)
547 if (Config->get_mmc_control()) {
548 maybe_enable_record();
553 Session::mmc_record_strobe (MIDI::MachineControl &mmc)
555 if (!Config->get_mmc_control())
558 /* record strobe does an implicit "Play" command */
560 if (_transport_speed != 1.0) {
562 /* start_transport() will move from Enabled->Recording, so we
563 don't need to do anything here except enable recording.
564 its not the same as maybe_enable_record() though, because
565 that *can* switch to Recording, which we do not want.
568 save_state ("", true);
569 g_atomic_int_set (&_record_status, Enabled);
570 RecordStateChanged (); /* EMIT SIGNAL */
572 request_transport_speed (1.0);
581 Session::mmc_record_exit (MIDI::MachineControl &mmc)
583 if (Config->get_mmc_control()) {
584 disable_record (false);
589 Session::mmc_stop (MIDI::MachineControl &mmc)
591 if (Config->get_mmc_control()) {
597 Session::mmc_pause (MIDI::MachineControl &mmc)
599 if (Config->get_mmc_control()) {
601 /* We support RECORD_PAUSE, so the spec says that
602 we must interpret PAUSE like RECORD_PAUSE if
606 if (actively_recording()) {
607 maybe_enable_record ();
614 static bool step_queued = false;
617 Session::mmc_step (MIDI::MachineControl &mmc, int steps)
619 if (!Config->get_mmc_control()) {
624 struct timeval diff = { 0, 0 };
626 gettimeofday (&now, 0);
628 timersub (&now, &last_mmc_step, &diff);
630 gettimeofday (&now, 0);
631 timersub (&now, &last_mmc_step, &diff);
633 if (last_mmc_step.tv_sec != 0 && (diff.tv_usec + (diff.tv_sec * 1000000)) < _engine.usecs_per_cycle()) {
637 double diff_secs = diff.tv_sec + (diff.tv_usec / 1000000.0);
638 double cur_speed = (((steps * 0.5) * smpte_frames_per_second()) / diff_secs) / smpte_frames_per_second();
640 if (_transport_speed == 0 || cur_speed * _transport_speed < 0) {
641 /* change direction */
642 step_speed = cur_speed;
644 step_speed = (0.6 * step_speed) + (0.4 * cur_speed);
650 cerr << "delta = " << diff_secs
651 << " ct = " << _transport_speed
652 << " steps = " << steps
653 << " new speed = " << cur_speed
654 << " speed = " << step_speed
658 request_transport_speed (step_speed);
662 midi_timeouts.push_back (mem_fun (*this, &Session::mmc_step_timeout));
668 Session::mmc_rewind (MIDI::MachineControl &mmc)
670 if (Config->get_mmc_control()) {
671 request_transport_speed(-8.0f);
676 Session::mmc_fast_forward (MIDI::MachineControl &mmc)
678 if (Config->get_mmc_control()) {
679 request_transport_speed(8.0f);
684 Session::mmc_locate (MIDI::MachineControl &mmc, const MIDI::byte* mmc_tc)
686 if (!Config->get_mmc_control()) {
690 nframes_t target_frame;
693 smpte.hours = mmc_tc[0] & 0xf;
694 smpte.minutes = mmc_tc[1];
695 smpte.seconds = mmc_tc[2];
696 smpte.frames = mmc_tc[3];
697 smpte.rate = smpte_frames_per_second();
698 smpte.drop = smpte_drop_frames();
700 // Also takes smpte offset into account:
701 smpte_to_sample( smpte, target_frame, true /* use_offset */, false /* use_subframes */ );
703 if (target_frame > max_frames) {
704 target_frame = max_frames;
707 /* Some (all?) MTC/MMC devices do not send a full MTC frame
708 at the end of a locate, instead sending only an MMC
709 locate command. This causes the current position
710 of an MTC slave to become out of date. Catch this.
713 MTC_Slave* mtcs = dynamic_cast<MTC_Slave*> (_slave);
716 // cerr << "Locate *with* MTC slave\n";
717 mtcs->handle_locate (mmc_tc);
719 // cerr << "Locate without MTC slave\n";
720 request_locate (target_frame, false);
725 Session::mmc_shuttle (MIDI::MachineControl &mmc, float speed, bool forw)
727 if (!Config->get_mmc_control()) {
731 if (Config->get_shuttle_speed_threshold() >= 0 && speed > Config->get_shuttle_speed_threshold()) {
732 speed *= Config->get_shuttle_speed_factor();
736 request_transport_speed (speed);
738 request_transport_speed (-speed);
743 Session::mmc_record_enable (MIDI::MachineControl &mmc, size_t trk, bool enabled)
745 if (Config->get_mmc_control()) {
747 RouteList::iterator i;
748 boost::shared_ptr<RouteList> r = routes.reader();
750 for (i = r->begin(); i != r->end(); ++i) {
753 if ((at = dynamic_cast<AudioTrack*>((*i).get())) != 0) {
754 if (trk == at->remote_control_id()) {
755 at->set_record_enable (enabled, &mmc);
765 Session::change_midi_ports ()
768 MIDIRequest* request = new MIDIRequest;
770 request->type = MIDIRequest::PortChange;
771 midi_requests.write (&request, 1);
776 /** Send MTC Full Frame message (complete SMPTE time) for the start of this cycle.
777 * This resets the MTC code, the next quarter frame message that is sent will be
778 * the first one with the beginning of this cycle as the new start point.
780 * Audio thread only, realtime safe. MIDI::Manager::cycle_start must
781 * have been called with the appropriate nframes parameter this cycle.
784 Session::send_full_time_code(jack_nframes_t nframes)
786 /* This function could easily send at a given frame offset, but would
787 * that be useful? Does ardour do sub-block accurate locating? [DR] */
792 _send_smpte_update = false;
794 if (_mtc_port == 0 || !session_send_mtc) {
798 // Get smpte time for this transport frame
799 sample_to_smpte(_transport_frame, smpte, true /* use_offset */, false /* no subframes */);
801 transmitting_smpte_time = smpte;
802 outbound_mtc_smpte_frame = _transport_frame;
804 // I don't understand this bit yet.. [DR]
805 if (((mtc_smpte_bits >> 5) != MIDI::MTC_25_FPS) && (transmitting_smpte_time.frames % 2)) {
806 // start MTC quarter frame transmission on an even frame
807 SMPTE::increment( transmitting_smpte_time );
808 outbound_mtc_smpte_frame += (jack_nframes_t) _frames_per_smpte_frame;
811 // Compensate for audio latency
812 outbound_mtc_smpte_frame += _worst_output_latency;
814 next_quarter_frame_to_send = 0;
816 // Sync slave to the same SMPTE time as we are on
824 msg[5] = mtc_smpte_bits | smpte.hours;
825 msg[6] = smpte.minutes;
826 msg[7] = smpte.seconds;
827 msg[8] = smpte.frames;
829 cerr << "MTC: Sending full time code at " << outbound_mtc_smpte_frame << endl;
831 // Send message at offset 0, sent time is for the start of this cycle
832 if (!_mtc_port->midimsg (msg, sizeof (msg), 0)) {
833 error << _("Session: could not send full MIDI time code") << endmsg;
841 /** Sends MTC (quarter-frame) messages for this cycle.
842 * Must be called exactly once per cycle from the audio thread. Realtime safe.
843 * This function assumes the state of full SMPTE is sane, eg. the slave is
844 * expecting quarter frame messages and has the right frame of reference (any
845 * full MTC SMPTE time messages that needed to be sent should have been sent
846 * earlier already this cycle by send_full_time_code)
849 Session::send_midi_time_code_for_cycle(jack_nframes_t nframes)
851 assert (next_quarter_frame_to_send >= 0);
852 assert (next_quarter_frame_to_send <= 7);
854 if (next_quarter_frame_to_send < 0)
856 printf("Negative????\n");
859 if (_mtc_port == 0 || !session_send_mtc || transmitting_smpte_time.negative
860 /*|| (next_quarter_frame_to_send < 0)*/ ) {
861 //printf("(MTC) Not sending MTC\n");
865 /* Duration of one quarter frame */
866 jack_nframes_t quarter_frame_duration = ((long) _frames_per_smpte_frame) >> 2;
868 //cerr << "(MTC) TR: " << _transport_frame << " - SF: " << outbound_mtc_smpte_frame
869 //<< " - NQ: " << next_quarter_frame_to_send << " - FD" << quarter_frame_duration << endl;
871 // FIXME: this should always be true
872 //assert((outbound_mtc_smpte_frame + (next_quarter_frame_to_send * quarter_frame_duration))
873 // > _transport_frame);
876 // Send quarter frames for this cycle
877 while (_transport_frame + nframes > (outbound_mtc_smpte_frame +
878 (next_quarter_frame_to_send * quarter_frame_duration))) {
880 //cerr << "(MTC) Next frame to send: " << next_quarter_frame_to_send << endl;
882 switch (next_quarter_frame_to_send) {
884 mtc_msg[1] = 0x00 | (transmitting_smpte_time.frames & 0xf);
887 mtc_msg[1] = 0x10 | ((transmitting_smpte_time.frames & 0xf0) >> 4);
890 mtc_msg[1] = 0x20 | (transmitting_smpte_time.seconds & 0xf);
893 mtc_msg[1] = 0x30 | ((transmitting_smpte_time.seconds & 0xf0) >> 4);
896 mtc_msg[1] = 0x40 | (transmitting_smpte_time.minutes & 0xf);
899 mtc_msg[1] = 0x50 | ((transmitting_smpte_time.minutes & 0xf0) >> 4);
902 mtc_msg[1] = 0x60 | ((mtc_smpte_bits|transmitting_smpte_time.hours) & 0xf);
905 mtc_msg[1] = 0x70 | (((mtc_smpte_bits|transmitting_smpte_time.hours) & 0xf0) >> 4);
909 const jack_nframes_t msg_time = (outbound_mtc_smpte_frame
910 + (quarter_frame_duration * next_quarter_frame_to_send));
912 // This message must fall within this block or something is broken
913 assert(msg_time >= _transport_frame);
914 assert(msg_time < _transport_frame + nframes);
916 jack_nframes_t out_stamp = msg_time - _transport_frame;
917 assert(out_stamp < nframes);
919 if (!_mtc_port->midimsg (mtc_msg, 2, out_stamp)) {
920 error << string_compose(_("Session: cannot send quarter-frame MTC message (%1)"), strerror (errno))
925 /*cerr << "(MTC) SMPTE: " << transmitting_smpte_time.hours
926 << ":" << transmitting_smpte_time.minutes
927 << ":" << transmitting_smpte_time.seconds
928 << ":" << transmitting_smpte_time.frames
929 << ", qfm = " << next_quarter_frame_to_send
930 << ", stamp = " << out_stamp
931 << ", delta = " << _transport_frame + out_stamp - last_time << endl;*/
933 // Increment quarter frame counter
934 next_quarter_frame_to_send++;
936 if (next_quarter_frame_to_send >= 8) {
937 // Wrap quarter frame counter
938 next_quarter_frame_to_send = 0;
939 // Increment smpte time twice
940 SMPTE::increment( transmitting_smpte_time );
941 SMPTE::increment( transmitting_smpte_time );
942 // Re-calculate timing of first quarter frame
943 //smpte_to_sample( transmitting_smpte_time, outbound_mtc_smpte_frame, true /* use_offset */, false );
944 outbound_mtc_smpte_frame += 8 * quarter_frame_duration;
945 // Compensate for audio latency
946 outbound_mtc_smpte_frame += _worst_output_latency;
953 /***********************************************************************
955 **********************************************************************/
958 Session::send_mmc_in_another_thread (MIDI::MachineControl::Command cmd, nframes_t target_frame)
960 MIDIRequest* request;
962 if (_mtc_port == 0 || !session_send_mmc) {
966 request = new MIDIRequest;
967 request->type = MIDIRequest::SendMMC;
968 request->mmc_cmd = cmd;
969 request->locate_frame = target_frame;
971 midi_requests.write (&request, 1);
976 /** Send an MMC command at the given absolute timestamp (@a where).
978 * This must be called in the process thread, and @a where must fall within
979 * this process cycle or horrible things will happen.
982 Session::deliver_mmc (MIDI::MachineControl::Command cmd, nframes_t where)
984 using namespace MIDI;
988 if (_mmc_port == 0 || !session_send_mmc) {
989 //cerr << "Not delivering MMC " << _mmc_port << " - " << send_mmc << endl;
993 mmc_buffer[nbytes++] = cmd;
995 //cerr << "delivering MMC, cmd = " << hex << (int) cmd << dec << endl;
998 case MachineControl::cmdLocate:
999 smpte_time_subframes (where, smpte);
1001 mmc_buffer[nbytes++] = 0x6; // byte count
1002 mmc_buffer[nbytes++] = 0x1; // "TARGET" subcommand
1003 mmc_buffer[nbytes++] = smpte.hours;
1004 mmc_buffer[nbytes++] = smpte.minutes;
1005 mmc_buffer[nbytes++] = smpte.seconds;
1006 mmc_buffer[nbytes++] = smpte.frames;
1007 mmc_buffer[nbytes++] = smpte.subframes;
1010 case MachineControl::cmdStop:
1013 case MachineControl::cmdPlay:
1014 /* always convert Play into Deferred Play */
1016 mmc_buffer[4] = MachineControl::cmdDeferredPlay;
1019 case MachineControl::cmdDeferredPlay:
1022 case MachineControl::cmdRecordStrobe:
1025 case MachineControl::cmdRecordExit:
1028 case MachineControl::cmdRecordPause:
1037 mmc_buffer[nbytes++] = 0xf7; // terminate SysEx/MMC message
1039 assert(where >= _transport_frame);
1041 // FIXME: timestamp correct? [DR]
1042 if (!_mmc_port->midimsg (mmc_buffer, sizeof (mmc_buffer), where - _transport_frame)) {
1043 error << string_compose(_("MMC: cannot send command %1%2%3"), &hex, cmd, &dec) << endmsg;
1045 cerr << "Sending MMC\n";
1051 Session::mmc_step_timeout ()
1054 struct timeval diff;
1056 gettimeofday (&now, 0);
1058 timersub (&now, &last_mmc_step, &diff);
1059 diff_usecs = diff.tv_sec * 1000000 + diff.tv_usec;
1061 if (diff_usecs > 1000000.0 || fabs (_transport_speed) < 0.0000001) {
1062 /* too long or too slow, stop transport */
1063 request_transport_speed (0.0);
1064 step_queued = false;
1068 if (diff_usecs < 250000.0) {
1069 /* too short, just keep going */
1075 request_transport_speed (_transport_speed * 0.75);
1081 Session::send_midi_message (MIDI::Port * port, MIDI::eventType ev, MIDI::channel_t ch, MIDI::EventTwoBytes data)
1083 // in another thread, really
1085 MIDIRequest* request = new MIDIRequest;
1087 request->type = MIDIRequest::SendMessage;
1088 request->port = port;
1091 request->data = data;
1093 midi_requests.write (&request, 1);
1094 poke_midi_thread ();
1099 Session::deliver_midi (MIDI::Port * port, MIDI::byte* buf, int32_t bufsize)
1101 // in another thread, really
1103 MIDIRequest* request = new MIDIRequest;
1105 request->type = MIDIRequest::Deliver;
1106 request->port = port;
1108 request->size = bufsize;
1110 midi_requests.write (&request, 1);
1111 poke_midi_thread ();
1117 This is aaalll gone.
1121 Session::deliver_midi_message (MIDI::Port * port, MIDI::eventType ev, MIDI::channel_t ch, MIDI::EventTwoBytes data)
1123 if (port == 0 || ev == MIDI::none) {
1127 midi_msg[0] = (ev & 0xF0) | (ch & 0xF);
1128 midi_msg[1] = data.controller_number;
1129 midi_msg[2] = data.value;
1131 port->write (midi_msg, 3);
1135 Session::deliver_data (MIDI::Port * port, MIDI::byte* buf, int32_t size)
1138 port->write (buf, size);
1141 /* this is part of the semantics of the Deliver request */
1148 /*---------------------------------------------------------------------------
1150 ---------------------------------------------------------------------------*/
1154 Session::start_midi_thread ()
1156 if (pipe (midi_request_pipe)) {
1157 error << string_compose(_("Cannot create transport request signal pipe (%1)"), strerror (errno)) << endmsg;
1161 if (fcntl (midi_request_pipe[0], F_SETFL, O_NONBLOCK)) {
1162 error << string_compose(_("UI: cannot set O_NONBLOCK on " "signal read pipe (%1)"), strerror (errno)) << endmsg;
1166 if (fcntl (midi_request_pipe[1], F_SETFL, O_NONBLOCK)) {
1167 error << string_compose(_("UI: cannot set O_NONBLOCK on " "signal write pipe (%1)"), strerror (errno)) << endmsg;
1171 if (pthread_create_and_store ("transport", &midi_thread, 0, _midi_thread_work, this)) {
1172 error << _("Session: could not create transport thread") << endmsg;
1176 // pthread_detach (midi_thread);
1182 Session::terminate_midi_thread ()
1185 MIDIRequest* request = new MIDIRequest;
1188 request->type = MIDIRequest::Quit;
1190 midi_requests.write (&request, 1);
1191 poke_midi_thread ();
1193 pthread_join (midi_thread, &status);
1198 Session::poke_midi_thread ()
1202 if (write (midi_request_pipe[1], &c, 1) != 1) {
1203 error << string_compose(_("cannot send signal to midi thread! (%1)"), strerror (errno)) << endmsg;
1208 Session::_midi_thread_work (void* arg)
1210 pthread_setcancelstate (PTHREAD_CANCEL_ENABLE, 0);
1211 pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, 0);
1213 ((Session *) arg)->midi_thread_work ();
1218 Session::midi_thread_work ()
1220 MIDIRequest* request;
1221 struct pollfd pfd[4];
1225 struct sched_param rtparam;
1228 vector<MIDI::Port*> ports;
1230 PBD::ThreadCreatedWithRequestSize (pthread_self(), X_("MIDI"), 2048);
1232 memset (&rtparam, 0, sizeof (rtparam));
1233 rtparam.sched_priority = 9; /* XXX should be relative to audio (JACK) thread */
1235 if ((x = pthread_setschedparam (pthread_self(), SCHED_FIFO, &rtparam)) != 0) {
1236 // do we care? not particularly.
1239 /* set up the port vector; 4 is the largest possible size for now */
1241 ports.push_back (0);
1242 ports.push_back (0);
1243 ports.push_back (0);
1244 ports.push_back (0);
1250 pfd[nfds].fd = midi_request_pipe[0];
1251 pfd[nfds].events = POLLIN|POLLHUP|POLLERR;
1254 /* if we are using MMC control, we obviously have to listen
1255 on the appropriate port.
1258 if (Config->get_mmc_control() && _mmc_port && _mmc_port->selectable() >= 0) {
1259 pfd[nfds].fd = _mmc_port->selectable();
1260 pfd[nfds].events = POLLIN|POLLHUP|POLLERR;
1261 ports[nfds] = _mmc_port;
1265 /* if MTC is being handled on a different port from MMC
1266 or we are not handling MMC at all, poll
1270 if (_mtc_port && (_mtc_port != _mmc_port || !Config->get_mmc_control()) && _mtc_port->selectable() >= 0) {
1271 pfd[nfds].fd = _mtc_port->selectable();
1272 pfd[nfds].events = POLLIN|POLLHUP|POLLERR;
1273 ports[nfds] = _mtc_port;
1277 if (_midi_port && (_midi_port != _mmc_port || !Config->get_mmc_control()) && (_midi_port != _mtc_port) && _midi_port->selectable() >= 0) {
1278 pfd[nfds].fd = _midi_port->selectable();
1279 pfd[nfds].events = POLLIN|POLLHUP|POLLERR;
1280 ports[nfds] = _midi_port;
1284 if (!midi_timeouts.empty()) {
1285 timeout = 100; /* 10msecs */
1287 timeout = -1; /* if there is no data, we don't care */
1291 // cerr << "MIDI poll on " << nfds << " for " << timeout << endl;
1292 if (poll (pfd, nfds, timeout) < 0) {
1293 if (errno == EINTR) {
1294 /* gdb at work, perhaps */
1298 error << string_compose(_("MIDI thread poll failed (%1)"), strerror (errno)) << endmsg;
1302 // cerr << "MIDI thread wakes at " << get_cycles () << endl;
1307 /* check the transport request pipe */
1309 if (pfd[0].revents & ~POLLIN) {
1310 error << _("Error on transport thread request pipe") << endmsg;
1314 if (pfd[0].revents & POLLIN) {
1318 // cerr << "MIDI request FIFO ready\n";
1321 /* empty the pipe of all current requests */
1324 size_t nread = read (midi_request_pipe[0], &foo, sizeof (foo));
1327 if ((size_t) nread < sizeof (foo)) {
1332 } else if (nread == 0) {
1334 } else if (errno == EAGAIN) {
1337 fatal << _("Error reading from transport request pipe") << endmsg;
1342 while (midi_requests.read (&request, 1) == 1) {
1344 switch (request->type) {
1346 case MIDIRequest::SendFullMTC:
1347 // cerr << "send full MTC\n";
1348 send_full_time_code ();
1349 // cerr << "... done\n";
1352 case MIDIRequest::SendMTC:
1353 // cerr << "send qtr MTC\n";
1354 send_midi_time_code ();
1355 // cerr << "... done\n";
1358 case MIDIRequest::SendMMC:
1359 // cerr << "send MMC\n";
1360 deliver_mmc (request->mmc_cmd, request->locate_frame);
1361 // cerr << "... done\n";
1364 case MIDIRequest::SendMessage:
1365 // cerr << "send Message\n";
1366 deliver_midi_message (request->port, request->ev, request->chan, request->data);
1367 // cerr << "... done\n";
1370 case MIDIRequest::Deliver:
1371 // cerr << "deliver\n";
1372 deliver_data (_midi_port, request->buf, request->size);
1373 // cerr << "... done\n";
1376 case MIDIRequest::PortChange:
1377 /* restart poll with new ports */
1378 // cerr << "rebind\n";
1382 case MIDIRequest::Quit:
1384 pthread_exit_pbd (0);
1402 /* now read the rest of the ports */
1404 for (int p = 1; p < nfds; ++p) {
1405 if ((pfd[p].revents & ~POLLIN)) {
1406 // error << string_compose(_("Transport: error polling MIDI port %1 (revents =%2%3%4"), p, &hex, pfd[p].revents, &dec) << endmsg;
1410 if (pfd[p].revents & POLLIN) {
1412 midi_read (ports[p]);
1416 /* timeout driven */
1418 if (fds_ready < 2 && timeout != -1) {
1420 for (MidiTimeoutList::iterator i = midi_timeouts.begin(); i != midi_timeouts.end(); ) {
1422 MidiTimeoutList::iterator tmp;
1427 midi_timeouts.erase (i);