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.
30 #include <midi++/mmc.h>
31 #include <midi++/port.h>
32 #include <midi++/manager.h>
33 #include <pbd/error.h>
34 #include <glibmm/thread.h>
35 #include <pbd/pthread_utils.h>
37 #include <ardour/configuration.h>
38 #include <ardour/audioengine.h>
39 #include <ardour/session.h>
40 #include <ardour/audio_track.h>
41 #include <ardour/audio_diskstream.h>
42 #include <ardour/slave.h>
43 #include <ardour/cycles.h>
44 #include <ardour/smpte.h>
49 using namespace ARDOUR;
53 MachineControl::CommandSignature MMC_CommandSignature;
54 MachineControl::ResponseSignature MMC_ResponseSignature;
56 MultiAllocSingleReleasePool Session::MIDIRequest::pool ("midi", sizeof (Session::MIDIRequest), 1024);
59 Session::use_config_midi_ports ()
63 if (default_mmc_port) {
64 set_mmc_port (default_mmc_port->name());
69 if (default_mtc_port) {
70 set_mtc_port (default_mtc_port->name());
75 if (default_midi_port) {
76 set_midi_port (default_midi_port->name());
85 /***********************************************************************
87 **********************************************************************/
90 Session::set_mmc_control (bool yn)
93 if (mmc_control == yn) {
101 ControlChanged (MMCControl); /* EMIT SIGNAL */
105 Session::set_midi_control (bool yn)
108 if (midi_control == yn) {
116 ControlChanged (MidiControl); /* EMIT SIGNAL */
120 Session::set_send_mtc (bool yn)
122 /* set the persistent option value regardless */
124 send_midi_timecode = yn;
127 /* only set the internal flag if we have
131 if (_mtc_port == 0 || send_mtc == yn) {
136 ControlChanged (SendMTC); /* EMIT SIGNAL */
140 Session::set_send_mmc (bool yn)
142 cerr << "set send mmc " << yn << endl;
144 if (_mmc_port == 0) {
149 if (send_midi_machine_control == yn) {
154 /* only set the internal flag if we have
163 /* set the persistent option value regardless */
165 send_midi_machine_control = yn;
168 ControlChanged (SendMMC); /* EMIT SIGNAL */
172 Session::set_midi_feedback (bool yn)
177 Session::get_midi_feedback () const
183 Session::get_send_mtc () const
189 Session::get_send_mmc () const
195 Session::set_mtc_port (string port_tag)
199 if (port_tag.length() == 0) {
201 if (_slave && ((ms = dynamic_cast<MTC_Slave*> (_slave)) != 0)) {
202 error << _("Ardour is slaved to MTC - port cannot be reset") << endmsg;
206 if (_mtc_port == 0) {
216 if ((port = MIDI::Manager::instance()->port (port_tag)) == 0) {
217 error << string_compose (_("unknown port %1 requested for MTC"), port_tag) << endl;
223 if (_slave && ((ms = dynamic_cast<MTC_Slave*> (_slave)) != 0)) {
227 Config->set_mtc_port_name (port_tag);
230 MTC_PortChanged(); /* EMIT SIGNAL */
231 change_midi_ports ();
237 Session::set_mmc_port (string port_tag)
239 if (port_tag.length() == 0) {
240 if (_mmc_port == 0) {
249 if ((port = MIDI::Manager::instance()->port (port_tag)) == 0) {
259 mmc = new MIDI::MachineControl (*_mmc_port, 1.0,
260 MMC_CommandSignature,
261 MMC_ResponseSignature);
265 (mem_fun (*this, &Session::mmc_deferred_play));
266 mmc->DeferredPlay.connect
267 (mem_fun (*this, &Session::mmc_deferred_play));
269 (mem_fun (*this, &Session::mmc_stop));
270 mmc->FastForward.connect
271 (mem_fun (*this, &Session::mmc_fast_forward));
273 (mem_fun (*this, &Session::mmc_rewind));
275 (mem_fun (*this, &Session::mmc_pause));
276 mmc->RecordPause.connect
277 (mem_fun (*this, &Session::mmc_record_pause));
278 mmc->RecordStrobe.connect
279 (mem_fun (*this, &Session::mmc_record_strobe));
280 mmc->RecordExit.connect
281 (mem_fun (*this, &Session::mmc_record_exit));
283 (mem_fun (*this, &Session::mmc_locate));
285 (mem_fun (*this, &Session::mmc_step));
287 (mem_fun (*this, &Session::mmc_shuttle));
288 mmc->TrackRecordStatusChange.connect
289 (mem_fun (*this, &Session::mmc_record_enable));
291 /* also handle MIDI SPP because its so common */
293 _mmc_port->input()->start.connect (mem_fun (*this, &Session::spp_start));
294 _mmc_port->input()->contineu.connect (mem_fun (*this, &Session::spp_continue));
295 _mmc_port->input()->stop.connect (mem_fun (*this, &Session::spp_stop));
297 Config->set_mmc_port_name (port_tag);
300 MMC_PortChanged(); /* EMIT SIGNAL */
301 change_midi_ports ();
307 Session::set_midi_port (string port_tag)
309 if (port_tag.length() == 0) {
310 if (_midi_port == 0) {
319 if ((port = MIDI::Manager::instance()->port (port_tag)) == 0) {
325 /* XXX need something to forward this to control protocols ? or just
329 Config->set_midi_port_name (port_tag);
332 MIDI_PortChanged(); /* EMIT SIGNAL */
333 change_midi_ports ();
339 Session::set_trace_midi_input (bool yn, MIDI::Port* port)
341 MIDI::Parser* input_parser;
344 if ((input_parser = port->input()) != 0) {
345 input_parser->trace (yn, &cout, "input: ");
350 if ((input_parser = _mmc_port->input()) != 0) {
351 input_parser->trace (yn, &cout, "input: ");
355 if (_mtc_port && _mtc_port != _mmc_port) {
356 if ((input_parser = _mtc_port->input()) != 0) {
357 input_parser->trace (yn, &cout, "input: ");
361 if (_midi_port && _midi_port != _mmc_port && _midi_port != _mtc_port ) {
362 if ((input_parser = _midi_port->input()) != 0) {
363 input_parser->trace (yn, &cout, "input: ");
368 Config->set_trace_midi_input (yn);
372 Session::set_trace_midi_output (bool yn, MIDI::Port* port)
374 MIDI::Parser* output_parser;
377 if ((output_parser = port->output()) != 0) {
378 output_parser->trace (yn, &cout, "output: ");
382 if ((output_parser = _mmc_port->output()) != 0) {
383 output_parser->trace (yn, &cout, "output: ");
387 if (_mtc_port && _mtc_port != _mmc_port) {
388 if ((output_parser = _mtc_port->output()) != 0) {
389 output_parser->trace (yn, &cout, "output: ");
393 if (_midi_port && _midi_port != _mmc_port && _midi_port != _mtc_port ) {
394 if ((output_parser = _midi_port->output()) != 0) {
395 output_parser->trace (yn, &cout, "output: ");
401 Config->set_trace_midi_output (yn);
405 Session::get_trace_midi_input(MIDI::Port *port)
407 MIDI::Parser* input_parser;
409 if ((input_parser = port->input()) != 0) {
410 return input_parser->tracing();
415 if ((input_parser = _mmc_port->input()) != 0) {
416 return input_parser->tracing();
421 if ((input_parser = _mtc_port->input()) != 0) {
422 return input_parser->tracing();
427 if ((input_parser = _midi_port->input()) != 0) {
428 return input_parser->tracing();
437 Session::get_trace_midi_output(MIDI::Port *port)
439 MIDI::Parser* output_parser;
441 if ((output_parser = port->output()) != 0) {
442 return output_parser->tracing();
447 if ((output_parser = _mmc_port->output()) != 0) {
448 return output_parser->tracing();
453 if ((output_parser = _mtc_port->output()) != 0) {
454 return output_parser->tracing();
459 if ((output_parser = _midi_port->output()) != 0) {
460 return output_parser->tracing();
470 Session::setup_midi_control ()
472 outbound_mtc_smpte_frame = 0;
473 next_quarter_frame_to_send = 0;
475 /* setup the MMC buffer */
477 mmc_buffer[0] = 0xf0; // SysEx
478 mmc_buffer[1] = 0x7f; // Real Time SysEx ID for MMC
479 mmc_buffer[2] = 0x7f; // "broadcast" device ID
480 mmc_buffer[3] = 0x6; // MCC
482 /* Set up the qtr frame message */
493 if (_mmc_port != 0) {
495 send_mmc = send_midi_machine_control;
503 if (_mtc_port != 0) {
505 send_mtc = send_midi_timecode;
515 Session::midi_read (MIDI::Port* port)
519 /* reading from the MIDI port activates the Parser
520 that in turn generates signals that we care
521 about. the port is already set to NONBLOCK so that
522 can read freely here.
527 // cerr << "+++ READ ON " << port->name() << endl;
529 int nread = port->read (buf, sizeof (buf));
531 // cerr << "-- READ (" << nread << " ON " << port->name() << endl;
534 if ((size_t) nread < sizeof (buf)) {
539 } else if (nread == 0) {
541 } else if (errno == EAGAIN) {
544 fatal << string_compose(_("Error reading from MIDI port %1"), port->name()) << endmsg;
554 Session::spp_start (Parser& ignored)
556 if (mmc_control && (_slave_type != MTC)) {
557 request_transport_speed (1.0);
562 Session::spp_continue (Parser& ignored)
568 Session::spp_stop (Parser& ignored)
576 Session::mmc_deferred_play (MIDI::MachineControl &mmc)
578 if (mmc_control && (_slave_type != MTC)) {
579 request_transport_speed (1.0);
584 Session::mmc_record_pause (MIDI::MachineControl &mmc)
587 maybe_enable_record();
592 Session::mmc_record_strobe (MIDI::MachineControl &mmc)
597 /* record strobe does an implicit "Play" command */
599 if (_transport_speed != 1.0) {
601 /* start_transport() will move from Enabled->Recording, so we
602 don't need to do anything here except enable recording.
603 its not the same as maybe_enable_record() though, because
604 that *can* switch to Recording, which we do not want.
607 save_state ("", true);
609 g_atomic_int_set (&_record_status, Enabled);
610 RecordStateChanged (); /* EMIT SIGNAL */
612 request_transport_speed (1.0);
621 Session::mmc_record_exit (MIDI::MachineControl &mmc)
624 disable_record (false);
629 Session::mmc_stop (MIDI::MachineControl &mmc)
637 Session::mmc_pause (MIDI::MachineControl &mmc)
641 /* We support RECORD_PAUSE, so the spec says that
642 we must interpret PAUSE like RECORD_PAUSE if
646 if (actively_recording()) {
647 maybe_enable_record ();
654 static bool step_queued = false;
657 Session::mmc_step (MIDI::MachineControl &mmc, int steps)
664 struct timeval diff = { 0, 0 };
666 gettimeofday (&now, 0);
668 timersub (&now, &last_mmc_step, &diff);
670 gettimeofday (&now, 0);
671 timersub (&now, &last_mmc_step, &diff);
673 if (last_mmc_step.tv_sec != 0 && (diff.tv_usec + (diff.tv_sec * 1000000)) < _engine.usecs_per_cycle()) {
677 double diff_secs = diff.tv_sec + (diff.tv_usec / 1000000.0);
678 double cur_speed = (((steps * 0.5) * smpte_frames_per_second) / diff_secs) / smpte_frames_per_second;
680 if (_transport_speed == 0 || cur_speed * _transport_speed < 0) {
681 /* change direction */
682 step_speed = cur_speed;
684 step_speed = (0.6 * step_speed) + (0.4 * cur_speed);
690 cerr << "delta = " << diff_secs
691 << " ct = " << _transport_speed
692 << " steps = " << steps
693 << " new speed = " << cur_speed
694 << " speed = " << step_speed
698 request_transport_speed (step_speed);
702 midi_timeouts.push_back (mem_fun (*this, &Session::mmc_step_timeout));
708 Session::mmc_rewind (MIDI::MachineControl &mmc)
711 request_transport_speed(-8.0f);
716 Session::mmc_fast_forward (MIDI::MachineControl &mmc)
719 request_transport_speed(8.0f);
724 Session::mmc_locate (MIDI::MachineControl &mmc, const MIDI::byte* mmc_tc)
730 jack_nframes_t target_frame;
733 smpte.hours = mmc_tc[0] & 0xf;
734 smpte.minutes = mmc_tc[1];
735 smpte.seconds = mmc_tc[2];
736 smpte.frames = mmc_tc[3];
738 // Also takes smpte offset into account:
739 smpte_to_sample( smpte, target_frame, true /* use_offset */, false /* use_subframes */ );
741 if (target_frame > max_frames) {
742 target_frame = max_frames;
745 /* Some (all?) MTC/MMC devices do not send a full MTC frame
746 at the end of a locate, instead sending only an MMC
747 locate command. This causes the current position
748 of an MTC slave to become out of date. Catch this.
751 MTC_Slave* mtcs = dynamic_cast<MTC_Slave*> (_slave);
754 // cerr << "Locate *with* MTC slave\n";
755 mtcs->handle_locate (mmc_tc);
757 // cerr << "Locate without MTC slave\n";
758 request_locate (target_frame, false);
763 Session::mmc_shuttle (MIDI::MachineControl &mmc, float speed, bool forw)
765 cerr << "MMC shuttle, speed = " << speed << endl;
771 if (shuttle_speed_threshold >= 0 && speed > shuttle_speed_threshold) {
772 speed *= shuttle_speed_factor;
775 cerr << "requested MMC control speed = " << speed << endl;
778 request_transport_speed (speed);
780 request_transport_speed (-speed);
785 Session::mmc_record_enable (MIDI::MachineControl &mmc, size_t trk, bool enabled)
789 RouteList::iterator i;
790 boost::shared_ptr<RouteList> r = routes.reader();
792 for (i = r->begin(); i != r->end(); ++i) {
795 if ((at = dynamic_cast<AudioTrack*>((*i).get())) != 0) {
796 if (trk == at->remote_control_id()) {
797 at->set_record_enable (enabled, &mmc);
807 Session::change_midi_ports ()
810 MIDIRequest* request = new MIDIRequest;
812 request->type = MIDIRequest::PortChange;
813 midi_requests.write (&request, 1);
818 /** Send MTC Full Frame message (complete SMPTE time) for the start of this cycle.
819 * This resets the MTC code, the next quarter frame message that is sent will be
820 * the first one with the beginning of this cycle as the new start point.
822 * Audio thread only, realtime safe. MIDI::Manager::cycle_start must
823 * have been called with the appropriate nframes parameter this cycle.
826 Session::send_full_time_code(jack_nframes_t nframes)
828 /* This function could easily send at a given frame offset, but would
829 * that be useful? Does ardour do sub-block accurate locating? [DR] */
834 _send_smpte_update = false;
836 if (_mtc_port == 0 || !send_mtc) {
840 // Get smpte time for this transport frame
841 sample_to_smpte(_transport_frame, smpte, true /* use_offset */, false /* no subframes */);
843 transmitting_smpte_time = smpte;
844 outbound_mtc_smpte_frame = _transport_frame;
846 // I don't understand this bit yet.. [DR]
847 if (((mtc_smpte_bits >> 5) != MIDI::MTC_25_FPS) && (transmitting_smpte_time.frames % 2)) {
848 // start MTC quarter frame transmission on an even frame
849 SMPTE::increment( transmitting_smpte_time );
850 outbound_mtc_smpte_frame += (jack_nframes_t) _frames_per_smpte_frame;
853 // Compensate for audio latency
854 outbound_mtc_smpte_frame += _worst_output_latency;
856 next_quarter_frame_to_send = 0;
858 // Sync slave to the same SMPTE time as we are on
866 msg[5] = mtc_smpte_bits | smpte.hours;
867 msg[6] = smpte.minutes;
868 msg[7] = smpte.seconds;
869 msg[8] = smpte.frames;
871 cerr << "MTC: Sending full time code at " << outbound_mtc_smpte_frame << endl;
873 // Send message at offset 0, sent time is for the start of this cycle
874 if (!_mtc_port->midimsg (msg, sizeof (msg), 0)) {
875 error << _("Session: could not send full MIDI time code") << endmsg;
883 /** Sends MTC (quarter-frame) messages for this cycle.
884 * Must be called exactly once per cycle from the audio thread. Realtime safe.
885 * This function assumes the state of full SMPTE is sane, eg. the slave is
886 * expecting quarter frame messages and has the right frame of reference (any
887 * full MTC SMPTE time messages that needed to be sent should have been sent
888 * earlier already this cycle by send_full_time_code)
891 Session::send_midi_time_code_for_cycle(jack_nframes_t nframes)
893 assert (next_quarter_frame_to_send >= 0);
894 assert (next_quarter_frame_to_send <= 7);
896 if (next_quarter_frame_to_send < 0)
898 printf("Negative????\n");
901 if (_mtc_port == 0 || !send_mtc || transmitting_smpte_time.negative
902 /*|| (next_quarter_frame_to_send < 0)*/ ) {
903 //printf("(MTC) Not sending MTC\n");
907 /* Duration of one quarter frame */
908 jack_nframes_t quarter_frame_duration = ((long) _frames_per_smpte_frame) >> 2;
910 //cerr << "(MTC) TR: " << _transport_frame << " - SF: " << outbound_mtc_smpte_frame
911 //<< " - NQ: " << next_quarter_frame_to_send << " - FD" << quarter_frame_duration << endl;
913 // FIXME: this should always be true
914 //assert((outbound_mtc_smpte_frame + (next_quarter_frame_to_send * quarter_frame_duration))
915 // > _transport_frame);
918 // Send quarter frames for this cycle
919 while (_transport_frame + nframes > (outbound_mtc_smpte_frame +
920 (next_quarter_frame_to_send * quarter_frame_duration))) {
922 //cerr << "(MTC) Next frame to send: " << next_quarter_frame_to_send << endl;
924 switch (next_quarter_frame_to_send) {
926 mtc_msg[1] = 0x00 | (transmitting_smpte_time.frames & 0xf);
929 mtc_msg[1] = 0x10 | ((transmitting_smpte_time.frames & 0xf0) >> 4);
932 mtc_msg[1] = 0x20 | (transmitting_smpte_time.seconds & 0xf);
935 mtc_msg[1] = 0x30 | ((transmitting_smpte_time.seconds & 0xf0) >> 4);
938 mtc_msg[1] = 0x40 | (transmitting_smpte_time.minutes & 0xf);
941 mtc_msg[1] = 0x50 | ((transmitting_smpte_time.minutes & 0xf0) >> 4);
944 mtc_msg[1] = 0x60 | ((mtc_smpte_bits|transmitting_smpte_time.hours) & 0xf);
947 mtc_msg[1] = 0x70 | (((mtc_smpte_bits|transmitting_smpte_time.hours) & 0xf0) >> 4);
951 const jack_nframes_t msg_time = (outbound_mtc_smpte_frame
952 + (quarter_frame_duration * next_quarter_frame_to_send));
954 // This message must fall within this block or something is broken
955 assert(msg_time >= _transport_frame);
956 assert(msg_time < _transport_frame + nframes);
958 jack_nframes_t out_stamp = msg_time - _transport_frame;
959 assert(out_stamp < nframes);
961 if (!_mtc_port->midimsg (mtc_msg, 2, out_stamp)) {
962 error << string_compose(_("Session: cannot send quarter-frame MTC message (%1)"), strerror (errno))
967 /*cerr << "(MTC) SMPTE: " << transmitting_smpte_time.hours
968 << ":" << transmitting_smpte_time.minutes
969 << ":" << transmitting_smpte_time.seconds
970 << ":" << transmitting_smpte_time.frames
971 << ", qfm = " << next_quarter_frame_to_send
972 << ", stamp = " << out_stamp
973 << ", delta = " << _transport_frame + out_stamp - last_time << endl;*/
975 // Increment quarter frame counter
976 next_quarter_frame_to_send++;
978 if (next_quarter_frame_to_send >= 8) {
979 // Wrap quarter frame counter
980 next_quarter_frame_to_send = 0;
981 // Increment smpte time twice
982 SMPTE::increment( transmitting_smpte_time );
983 SMPTE::increment( transmitting_smpte_time );
984 // Re-calculate timing of first quarter frame
985 //smpte_to_sample( transmitting_smpte_time, outbound_mtc_smpte_frame, true /* use_offset */, false );
986 outbound_mtc_smpte_frame += 8 * quarter_frame_duration;
987 // Compensate for audio latency
988 outbound_mtc_smpte_frame += _worst_output_latency;
995 /***********************************************************************
997 **********************************************************************/
1000 Session::send_mmc_in_another_thread (MIDI::MachineControl::Command cmd, jack_nframes_t target_frame)
1002 MIDIRequest* request;
1004 if (_mtc_port == 0 || !send_mmc) {
1008 request = new MIDIRequest;
1009 request->type = MIDIRequest::SendMMC;
1010 request->mmc_cmd = cmd;
1011 request->locate_frame = target_frame;
1013 midi_requests.write (&request, 1);
1014 poke_midi_thread ();
1018 /** Send an MMC command at the given absolute timestamp (@a where).
1020 * This must be called in the process thread, and @a where must fall within
1021 * this process cycle or horrible things will happen.
1024 Session::deliver_mmc (MIDI::MachineControl::Command cmd, jack_nframes_t where)
1026 using namespace MIDI;
1030 if (_mmc_port == 0 || !send_mmc) {
1031 //cerr << "Not delivering MMC " << _mmc_port << " - " << send_mmc << endl;
1035 mmc_buffer[nbytes++] = cmd;
1037 //cerr << "delivering MMC, cmd = " << hex << (int) cmd << dec << endl;
1040 case MachineControl::cmdLocate:
1041 smpte_time_subframes (where, smpte);
1043 mmc_buffer[nbytes++] = 0x6; // byte count
1044 mmc_buffer[nbytes++] = 0x1; // "TARGET" subcommand
1045 mmc_buffer[nbytes++] = smpte.hours;
1046 mmc_buffer[nbytes++] = smpte.minutes;
1047 mmc_buffer[nbytes++] = smpte.seconds;
1048 mmc_buffer[nbytes++] = smpte.frames;
1049 mmc_buffer[nbytes++] = smpte.subframes;
1052 case MachineControl::cmdStop:
1055 case MachineControl::cmdPlay:
1056 /* always convert Play into Deferred Play */
1058 mmc_buffer[4] = MachineControl::cmdDeferredPlay;
1061 case MachineControl::cmdDeferredPlay:
1064 case MachineControl::cmdRecordStrobe:
1067 case MachineControl::cmdRecordExit:
1070 case MachineControl::cmdRecordPause:
1079 mmc_buffer[nbytes++] = 0xf7; // terminate SysEx/MMC message
1081 assert(where >= _transport_frame);
1083 // FIXME: timestamp correct? [DR]
1084 if (!_mmc_port->midimsg (mmc_buffer, sizeof (mmc_buffer), where - _transport_frame)) {
1085 error << string_compose(_("MMC: cannot send command %1%2%3"), &hex, cmd, &dec) << endmsg;
1087 cerr << "Sending MMC\n";
1093 Session::mmc_step_timeout ()
1096 struct timeval diff;
1098 gettimeofday (&now, 0);
1100 timersub (&now, &last_mmc_step, &diff);
1101 diff_usecs = diff.tv_sec * 1000000 + diff.tv_usec;
1103 if (diff_usecs > 1000000.0 || fabs (_transport_speed) < 0.0000001) {
1104 /* too long or too slow, stop transport */
1105 request_transport_speed (0.0);
1106 step_queued = false;
1110 if (diff_usecs < 250000.0) {
1111 /* too short, just keep going */
1117 request_transport_speed (_transport_speed * 0.75);
1123 Session::send_midi_message (MIDI::Port * port, MIDI::eventType ev, MIDI::channel_t ch, MIDI::EventTwoBytes data)
1125 // in another thread, really
1127 MIDIRequest* request = new MIDIRequest;
1129 request->type = MIDIRequest::SendMessage;
1130 request->port = port;
1133 request->data = data;
1135 midi_requests.write (&request, 1);
1136 poke_midi_thread ();
1141 Session::deliver_midi (MIDI::Port * port, MIDI::byte* buf, int32_t bufsize)
1143 // in another thread, really
1145 MIDIRequest* request = new MIDIRequest;
1147 request->type = MIDIRequest::Deliver;
1148 request->port = port;
1150 request->size = bufsize;
1152 midi_requests.write (&request, 1);
1153 poke_midi_thread ();
1159 This is aaalll gone.
1163 Session::deliver_midi_message (MIDI::Port * port, MIDI::eventType ev, MIDI::channel_t ch, MIDI::EventTwoBytes data)
1165 if (port == 0 || ev == MIDI::none) {
1169 midi_msg[0] = (ev & 0xF0) | (ch & 0xF);
1170 midi_msg[1] = data.controller_number;
1171 midi_msg[2] = data.value;
1173 port->write (midi_msg, 3);
1177 Session::deliver_data (MIDI::Port * port, MIDI::byte* buf, int32_t size)
1180 port->write (buf, size);
1183 /* this is part of the semantics of the Deliver request */
1190 /*---------------------------------------------------------------------------
1192 ---------------------------------------------------------------------------*/
1196 Session::start_midi_thread ()
1198 if (pipe (midi_request_pipe)) {
1199 error << string_compose(_("Cannot create transport request signal pipe (%1)"), strerror (errno)) << endmsg;
1203 if (fcntl (midi_request_pipe[0], F_SETFL, O_NONBLOCK)) {
1204 error << string_compose(_("UI: cannot set O_NONBLOCK on " "signal read pipe (%1)"), strerror (errno)) << endmsg;
1208 if (fcntl (midi_request_pipe[1], F_SETFL, O_NONBLOCK)) {
1209 error << string_compose(_("UI: cannot set O_NONBLOCK on " "signal write pipe (%1)"), strerror (errno)) << endmsg;
1213 if (pthread_create_and_store ("transport", &midi_thread, 0, _midi_thread_work, this)) {
1214 error << _("Session: could not create transport thread") << endmsg;
1218 // pthread_detach (midi_thread);
1224 Session::terminate_midi_thread ()
1226 MIDIRequest* request = new MIDIRequest;
1229 request->type = MIDIRequest::Quit;
1231 midi_requests.write (&request, 1);
1232 poke_midi_thread ();
1234 pthread_join (midi_thread, &status);
1238 Session::poke_midi_thread ()
1242 if (write (midi_request_pipe[1], &c, 1) != 1) {
1243 error << string_compose(_("cannot send signal to midi thread! (%1)"), strerror (errno)) << endmsg;
1248 Session::_midi_thread_work (void* arg)
1250 pthread_setcancelstate (PTHREAD_CANCEL_ENABLE, 0);
1251 pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, 0);
1253 ((Session *) arg)->midi_thread_work ();
1258 Session::midi_thread_work ()
1260 MIDIRequest* request;
1261 struct pollfd pfd[4];
1265 struct sched_param rtparam;
1268 vector<MIDI::Port*> ports;
1270 PBD::ThreadCreatedWithRequestSize (pthread_self(), X_("MIDI"), 2048);
1272 memset (&rtparam, 0, sizeof (rtparam));
1273 rtparam.sched_priority = 9; /* XXX should be relative to audio (JACK) thread */
1275 if ((x = pthread_setschedparam (pthread_self(), SCHED_FIFO, &rtparam)) != 0) {
1276 // do we care? not particularly.
1279 /* set up the port vector; 4 is the largest possible size for now */
1281 ports.push_back (0);
1282 ports.push_back (0);
1283 ports.push_back (0);
1284 ports.push_back (0);
1290 pfd[nfds].fd = midi_request_pipe[0];
1291 pfd[nfds].events = POLLIN|POLLHUP|POLLERR;
1294 /* if we are using MMC control, we obviously have to listen
1295 on the appropriate port.
1298 if (mmc_control && _mmc_port && _mmc_port->selectable() >= 0) {
1299 pfd[nfds].fd = _mmc_port->selectable();
1300 pfd[nfds].events = POLLIN|POLLHUP|POLLERR;
1301 ports[nfds] = _mmc_port;
1305 /* if MTC is being handled on a different port from MMC
1306 or we are not handling MMC at all, poll
1310 if (_mtc_port && (_mtc_port != _mmc_port || !mmc_control) && _mtc_port->selectable() >= 0) {
1311 pfd[nfds].fd = _mtc_port->selectable();
1312 pfd[nfds].events = POLLIN|POLLHUP|POLLERR;
1313 ports[nfds] = _mtc_port;
1317 if (_midi_port && (_midi_port != _mmc_port || !mmc_control) && (_midi_port != _mtc_port) && _midi_port->selectable() >= 0) {
1318 pfd[nfds].fd = _midi_port->selectable();
1319 pfd[nfds].events = POLLIN|POLLHUP|POLLERR;
1320 ports[nfds] = _midi_port;
1324 if (!midi_timeouts.empty()) {
1325 timeout = 100; /* 10msecs */
1327 timeout = -1; /* if there is no data, we don't care */
1331 // cerr << "MIDI poll on " << nfds << " for " << timeout << endl;
1332 if (poll (pfd, nfds, timeout) < 0) {
1333 if (errno == EINTR) {
1334 /* gdb at work, perhaps */
1338 error << string_compose(_("MIDI thread poll failed (%1)"), strerror (errno)) << endmsg;
1342 // cerr << "MIDI thread wakes at " << get_cycles () << endl;
1347 /* check the transport request pipe */
1349 if (pfd[0].revents & ~POLLIN) {
1350 error << _("Error on transport thread request pipe") << endmsg;
1354 if (pfd[0].revents & POLLIN) {
1358 // cerr << "MIDI request FIFO ready\n";
1361 /* empty the pipe of all current requests */
1364 size_t nread = read (midi_request_pipe[0], &foo, sizeof (foo));
1367 if ((size_t) nread < sizeof (foo)) {
1372 } else if (nread == 0) {
1374 } else if (errno == EAGAIN) {
1377 fatal << _("Error reading from transport request pipe") << endmsg;
1382 while (midi_requests.read (&request, 1) == 1) {
1384 switch (request->type) {
1386 case MIDIRequest::SendFullMTC:
1387 // cerr << "send full MTC\n";
1388 send_full_time_code ();
1389 // cerr << "... done\n";
1392 case MIDIRequest::SendMTC:
1393 // cerr << "send qtr MTC\n";
1394 send_midi_time_code ();
1395 // cerr << "... done\n";
1398 case MIDIRequest::SendMMC:
1399 // cerr << "send MMC\n";
1400 deliver_mmc (request->mmc_cmd, request->locate_frame);
1401 // cerr << "... done\n";
1404 case MIDIRequest::SendMessage:
1405 // cerr << "send Message\n";
1406 deliver_midi_message (request->port, request->ev, request->chan, request->data);
1407 // cerr << "... done\n";
1410 case MIDIRequest::Deliver:
1411 // cerr << "deliver\n";
1412 deliver_data (_midi_port, request->buf, request->size);
1413 // cerr << "... done\n";
1416 case MIDIRequest::PortChange:
1417 /* restart poll with new ports */
1418 // cerr << "rebind\n";
1422 case MIDIRequest::Quit:
1424 pthread_exit_pbd (0);
1442 /* now read the rest of the ports */
1444 for (int p = 1; p < nfds; ++p) {
1445 if ((pfd[p].revents & ~POLLIN)) {
1446 // error << string_compose(_("Transport: error polling MIDI port %1 (revents =%2%3%4"), p, &hex, pfd[p].revents, &dec) << endmsg;
1450 if (pfd[p].revents & POLLIN) {
1452 midi_read (ports[p]);
1456 /* timeout driven */
1458 if (fds_ready < 2 && timeout != -1) {
1460 for (MidiTimeoutList::iterator i = midi_timeouts.begin(); i != midi_timeouts.end(); ) {
1462 MidiTimeoutList::iterator tmp;
1467 midi_timeouts.erase (i);
1478 Session::get_mmc_control () const
1484 Session::get_midi_control () const
1486 return midi_control;