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);
608 g_atomic_int_set (&_record_status, Enabled);
609 RecordStateChanged (); /* EMIT SIGNAL */
611 request_transport_speed (1.0);
620 Session::mmc_record_exit (MIDI::MachineControl &mmc)
623 disable_record (false);
628 Session::mmc_stop (MIDI::MachineControl &mmc)
636 Session::mmc_pause (MIDI::MachineControl &mmc)
640 /* We support RECORD_PAUSE, so the spec says that
641 we must interpret PAUSE like RECORD_PAUSE if
645 if (actively_recording()) {
646 maybe_enable_record ();
653 static bool step_queued = false;
656 Session::mmc_step (MIDI::MachineControl &mmc, int steps)
663 struct timeval diff = { 0, 0 };
665 gettimeofday (&now, 0);
667 timersub (&now, &last_mmc_step, &diff);
669 gettimeofday (&now, 0);
670 timersub (&now, &last_mmc_step, &diff);
672 if (last_mmc_step.tv_sec != 0 && (diff.tv_usec + (diff.tv_sec * 1000000)) < _engine.usecs_per_cycle()) {
676 double diff_secs = diff.tv_sec + (diff.tv_usec / 1000000.0);
677 double cur_speed = (((steps * 0.5) * smpte_frames_per_second) / diff_secs) / smpte_frames_per_second;
679 if (_transport_speed == 0 || cur_speed * _transport_speed < 0) {
680 /* change direction */
681 step_speed = cur_speed;
683 step_speed = (0.6 * step_speed) + (0.4 * cur_speed);
689 cerr << "delta = " << diff_secs
690 << " ct = " << _transport_speed
691 << " steps = " << steps
692 << " new speed = " << cur_speed
693 << " speed = " << step_speed
697 request_transport_speed (step_speed);
701 midi_timeouts.push_back (mem_fun (*this, &Session::mmc_step_timeout));
707 Session::mmc_rewind (MIDI::MachineControl &mmc)
710 request_transport_speed(-8.0f);
715 Session::mmc_fast_forward (MIDI::MachineControl &mmc)
718 request_transport_speed(8.0f);
723 Session::mmc_locate (MIDI::MachineControl &mmc, const MIDI::byte* mmc_tc)
729 jack_nframes_t target_frame;
732 smpte.hours = mmc_tc[0] & 0xf;
733 smpte.minutes = mmc_tc[1];
734 smpte.seconds = mmc_tc[2];
735 smpte.frames = mmc_tc[3];
737 // Also takes smpte offset into account:
738 smpte_to_sample( smpte, target_frame, true /* use_offset */, false /* use_subframes */ );
740 if (target_frame > max_frames) {
741 target_frame = max_frames;
744 /* Some (all?) MTC/MMC devices do not send a full MTC frame
745 at the end of a locate, instead sending only an MMC
746 locate command. This causes the current position
747 of an MTC slave to become out of date. Catch this.
750 MTC_Slave* mtcs = dynamic_cast<MTC_Slave*> (_slave);
753 // cerr << "Locate *with* MTC slave\n";
754 mtcs->handle_locate (mmc_tc);
756 // cerr << "Locate without MTC slave\n";
757 request_locate (target_frame, false);
762 Session::mmc_shuttle (MIDI::MachineControl &mmc, float speed, bool forw)
764 cerr << "MMC shuttle, speed = " << speed << endl;
770 if (shuttle_speed_threshold >= 0 && speed > shuttle_speed_threshold) {
771 speed *= shuttle_speed_factor;
774 cerr << "requested MMC control speed = " << speed << endl;
777 request_transport_speed (speed);
779 request_transport_speed (-speed);
784 Session::mmc_record_enable (MIDI::MachineControl &mmc, size_t trk, bool enabled)
788 RouteList::iterator i;
789 boost::shared_ptr<RouteList> r = routes.reader();
791 for (i = r->begin(); i != r->end(); ++i) {
794 if ((at = dynamic_cast<AudioTrack*>((*i).get())) != 0) {
795 if (trk == at->remote_control_id()) {
796 at->set_record_enable (enabled, &mmc);
806 Session::change_midi_ports ()
809 MIDIRequest* request = new MIDIRequest;
811 request->type = MIDIRequest::PortChange;
812 midi_requests.write (&request, 1);
817 /** Send MTC Full Frame message (complete SMPTE time) for the start of this cycle.
818 * This resets the MTC code, the next quarter frame message that is sent will be
819 * the first one with the beginning of this cycle as the new start point.
821 * Audio thread only, realtime safe. MIDI::Manager::cycle_start must
822 * have been called with the appropriate nframes parameter this cycle.
825 Session::send_full_time_code(jack_nframes_t nframes)
827 /* This function could easily send at a given frame offset, but would
828 * that be useful? Does ardour do sub-block accurate locating? [DR] */
833 _send_smpte_update = false;
835 if (_mtc_port == 0 || !send_mtc) {
839 // Get smpte time for this transport frame
840 sample_to_smpte(_transport_frame, smpte, true /* use_offset */, false /* no subframes */);
842 transmitting_smpte_time = smpte;
843 outbound_mtc_smpte_frame = _transport_frame;
845 // I don't understand this bit yet.. [DR]
846 if (((mtc_smpte_bits >> 5) != MIDI::MTC_25_FPS) && (transmitting_smpte_time.frames % 2)) {
847 // start MTC quarter frame transmission on an even frame
848 SMPTE::increment( transmitting_smpte_time );
849 outbound_mtc_smpte_frame += (jack_nframes_t) _frames_per_smpte_frame;
852 // Compensate for audio latency
853 outbound_mtc_smpte_frame += _worst_output_latency;
855 next_quarter_frame_to_send = 0;
857 // Sync slave to the same SMPTE time as we are on
865 msg[5] = mtc_smpte_bits | smpte.hours;
866 msg[6] = smpte.minutes;
867 msg[7] = smpte.seconds;
868 msg[8] = smpte.frames;
870 cerr << "MTC: Sending full time code at " << outbound_mtc_smpte_frame << endl;
872 // Send message at offset 0, sent time is for the start of this cycle
873 if (!_mtc_port->midimsg (msg, sizeof (msg), 0)) {
874 error << _("Session: could not send full MIDI time code") << endmsg;
882 /** Sends MTC (quarter-frame) messages for this cycle.
883 * Must be called exactly once per cycle from the audio thread. Realtime safe.
884 * This function assumes the state of full SMPTE is sane, eg. the slave is
885 * expecting quarter frame messages and has the right frame of reference (any
886 * full MTC SMPTE time messages that needed to be sent should have been sent
887 * earlier already this cycle by send_full_time_code)
890 Session::send_midi_time_code_for_cycle(jack_nframes_t nframes)
892 assert (next_quarter_frame_to_send >= 0);
893 assert (next_quarter_frame_to_send <= 7);
895 if (next_quarter_frame_to_send < 0)
897 printf("Negative????\n");
900 if (_mtc_port == 0 || !send_mtc || transmitting_smpte_time.negative
901 /*|| (next_quarter_frame_to_send < 0)*/ ) {
902 //printf("(MTC) Not sending MTC\n");
906 /* Duration of one quarter frame */
907 jack_nframes_t quarter_frame_duration = ((long) _frames_per_smpte_frame) >> 2;
909 //cerr << "(MTC) TR: " << _transport_frame << " - SF: " << outbound_mtc_smpte_frame
910 //<< " - NQ: " << next_quarter_frame_to_send << " - FD" << quarter_frame_duration << endl;
912 // FIXME: this should always be true
913 //assert((outbound_mtc_smpte_frame + (next_quarter_frame_to_send * quarter_frame_duration))
914 // > _transport_frame);
917 // Send quarter frames for this cycle
918 while (_transport_frame + nframes > (outbound_mtc_smpte_frame +
919 (next_quarter_frame_to_send * quarter_frame_duration))) {
921 //cerr << "(MTC) Next frame to send: " << next_quarter_frame_to_send << endl;
923 switch (next_quarter_frame_to_send) {
925 mtc_msg[1] = 0x00 | (transmitting_smpte_time.frames & 0xf);
928 mtc_msg[1] = 0x10 | ((transmitting_smpte_time.frames & 0xf0) >> 4);
931 mtc_msg[1] = 0x20 | (transmitting_smpte_time.seconds & 0xf);
934 mtc_msg[1] = 0x30 | ((transmitting_smpte_time.seconds & 0xf0) >> 4);
937 mtc_msg[1] = 0x40 | (transmitting_smpte_time.minutes & 0xf);
940 mtc_msg[1] = 0x50 | ((transmitting_smpte_time.minutes & 0xf0) >> 4);
943 mtc_msg[1] = 0x60 | ((mtc_smpte_bits|transmitting_smpte_time.hours) & 0xf);
946 mtc_msg[1] = 0x70 | (((mtc_smpte_bits|transmitting_smpte_time.hours) & 0xf0) >> 4);
950 const jack_nframes_t msg_time = (outbound_mtc_smpte_frame
951 + (quarter_frame_duration * next_quarter_frame_to_send));
953 // This message must fall within this block or something is broken
954 assert(msg_time >= _transport_frame);
955 assert(msg_time < _transport_frame + nframes);
957 jack_nframes_t out_stamp = msg_time - _transport_frame;
958 assert(out_stamp < nframes);
960 if (!_mtc_port->midimsg (mtc_msg, 2, out_stamp)) {
961 error << string_compose(_("Session: cannot send quarter-frame MTC message (%1)"), strerror (errno))
966 /*cerr << "(MTC) SMPTE: " << transmitting_smpte_time.hours
967 << ":" << transmitting_smpte_time.minutes
968 << ":" << transmitting_smpte_time.seconds
969 << ":" << transmitting_smpte_time.frames
970 << ", qfm = " << next_quarter_frame_to_send
971 << ", stamp = " << out_stamp
972 << ", delta = " << _transport_frame + out_stamp - last_time << endl;*/
974 // Increment quarter frame counter
975 next_quarter_frame_to_send++;
977 if (next_quarter_frame_to_send >= 8) {
978 // Wrap quarter frame counter
979 next_quarter_frame_to_send = 0;
980 // Increment smpte time twice
981 SMPTE::increment( transmitting_smpte_time );
982 SMPTE::increment( transmitting_smpte_time );
983 // Re-calculate timing of first quarter frame
984 //smpte_to_sample( transmitting_smpte_time, outbound_mtc_smpte_frame, true /* use_offset */, false );
985 outbound_mtc_smpte_frame += 8 * quarter_frame_duration;
986 // Compensate for audio latency
987 outbound_mtc_smpte_frame += _worst_output_latency;
994 /***********************************************************************
996 **********************************************************************/
999 Session::send_mmc_in_another_thread (MIDI::MachineControl::Command cmd, jack_nframes_t target_frame)
1001 MIDIRequest* request;
1003 if (_mtc_port == 0 || !send_mmc) {
1007 request = new MIDIRequest;
1008 request->type = MIDIRequest::SendMMC;
1009 request->mmc_cmd = cmd;
1010 request->locate_frame = target_frame;
1012 midi_requests.write (&request, 1);
1013 poke_midi_thread ();
1017 /** Send an MMC command at the given absolute timestamp (@a where).
1019 * This must be called in the process thread, and @a where must fall within
1020 * this process cycle or horrible things will happen.
1023 Session::deliver_mmc (MIDI::MachineControl::Command cmd, jack_nframes_t where)
1025 using namespace MIDI;
1029 if (_mmc_port == 0 || !send_mmc) {
1030 //cerr << "Not delivering MMC " << _mmc_port << " - " << send_mmc << endl;
1034 mmc_buffer[nbytes++] = cmd;
1036 //cerr << "delivering MMC, cmd = " << hex << (int) cmd << dec << endl;
1039 case MachineControl::cmdLocate:
1040 smpte_time_subframes (where, smpte);
1042 mmc_buffer[nbytes++] = 0x6; // byte count
1043 mmc_buffer[nbytes++] = 0x1; // "TARGET" subcommand
1044 mmc_buffer[nbytes++] = smpte.hours;
1045 mmc_buffer[nbytes++] = smpte.minutes;
1046 mmc_buffer[nbytes++] = smpte.seconds;
1047 mmc_buffer[nbytes++] = smpte.frames;
1048 mmc_buffer[nbytes++] = smpte.subframes;
1051 case MachineControl::cmdStop:
1054 case MachineControl::cmdPlay:
1055 /* always convert Play into Deferred Play */
1057 mmc_buffer[4] = MachineControl::cmdDeferredPlay;
1060 case MachineControl::cmdDeferredPlay:
1063 case MachineControl::cmdRecordStrobe:
1066 case MachineControl::cmdRecordExit:
1069 case MachineControl::cmdRecordPause:
1078 mmc_buffer[nbytes++] = 0xf7; // terminate SysEx/MMC message
1080 assert(where >= _transport_frame);
1082 // FIXME: timestamp correct? [DR]
1083 if (!_mmc_port->midimsg (mmc_buffer, sizeof (mmc_buffer), where - _transport_frame)) {
1084 error << string_compose(_("MMC: cannot send command %1%2%3"), &hex, cmd, &dec) << endmsg;
1086 cerr << "Sending MMC\n";
1092 Session::mmc_step_timeout ()
1095 struct timeval diff;
1097 gettimeofday (&now, 0);
1099 timersub (&now, &last_mmc_step, &diff);
1100 diff_usecs = diff.tv_sec * 1000000 + diff.tv_usec;
1102 if (diff_usecs > 1000000.0 || fabs (_transport_speed) < 0.0000001) {
1103 /* too long or too slow, stop transport */
1104 request_transport_speed (0.0);
1105 step_queued = false;
1109 if (diff_usecs < 250000.0) {
1110 /* too short, just keep going */
1116 request_transport_speed (_transport_speed * 0.75);
1122 Session::send_midi_message (MIDI::Port * port, MIDI::eventType ev, MIDI::channel_t ch, MIDI::EventTwoBytes data)
1124 // in another thread, really
1126 MIDIRequest* request = new MIDIRequest;
1128 request->type = MIDIRequest::SendMessage;
1129 request->port = port;
1132 request->data = data;
1134 midi_requests.write (&request, 1);
1135 poke_midi_thread ();
1140 Session::deliver_midi (MIDI::Port * port, MIDI::byte* buf, int32_t bufsize)
1142 // in another thread, really
1144 MIDIRequest* request = new MIDIRequest;
1146 request->type = MIDIRequest::Deliver;
1147 request->port = port;
1149 request->size = bufsize;
1151 midi_requests.write (&request, 1);
1152 poke_midi_thread ();
1158 This is aaalll gone.
1162 Session::deliver_midi_message (MIDI::Port * port, MIDI::eventType ev, MIDI::channel_t ch, MIDI::EventTwoBytes data)
1164 if (port == 0 || ev == MIDI::none) {
1168 midi_msg[0] = (ev & 0xF0) | (ch & 0xF);
1169 midi_msg[1] = data.controller_number;
1170 midi_msg[2] = data.value;
1172 port->write (midi_msg, 3);
1176 Session::deliver_data (MIDI::Port * port, MIDI::byte* buf, int32_t size)
1179 port->write (buf, size);
1182 /* this is part of the semantics of the Deliver request */
1189 /*---------------------------------------------------------------------------
1191 ---------------------------------------------------------------------------*/
1195 Session::start_midi_thread ()
1197 if (pipe (midi_request_pipe)) {
1198 error << string_compose(_("Cannot create transport request signal pipe (%1)"), strerror (errno)) << endmsg;
1202 if (fcntl (midi_request_pipe[0], F_SETFL, O_NONBLOCK)) {
1203 error << string_compose(_("UI: cannot set O_NONBLOCK on " "signal read pipe (%1)"), strerror (errno)) << endmsg;
1207 if (fcntl (midi_request_pipe[1], F_SETFL, O_NONBLOCK)) {
1208 error << string_compose(_("UI: cannot set O_NONBLOCK on " "signal write pipe (%1)"), strerror (errno)) << endmsg;
1212 if (pthread_create_and_store ("transport", &midi_thread, 0, _midi_thread_work, this)) {
1213 error << _("Session: could not create transport thread") << endmsg;
1217 // pthread_detach (midi_thread);
1223 Session::terminate_midi_thread ()
1225 MIDIRequest* request = new MIDIRequest;
1228 request->type = MIDIRequest::Quit;
1230 midi_requests.write (&request, 1);
1231 poke_midi_thread ();
1233 pthread_join (midi_thread, &status);
1237 Session::poke_midi_thread ()
1241 if (write (midi_request_pipe[1], &c, 1) != 1) {
1242 error << string_compose(_("cannot send signal to midi thread! (%1)"), strerror (errno)) << endmsg;
1247 Session::_midi_thread_work (void* arg)
1249 pthread_setcancelstate (PTHREAD_CANCEL_ENABLE, 0);
1250 pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, 0);
1252 ((Session *) arg)->midi_thread_work ();
1257 Session::midi_thread_work ()
1259 MIDIRequest* request;
1260 struct pollfd pfd[4];
1264 struct sched_param rtparam;
1267 vector<MIDI::Port*> ports;
1269 PBD::ThreadCreatedWithRequestSize (pthread_self(), X_("MIDI"), 2048);
1271 memset (&rtparam, 0, sizeof (rtparam));
1272 rtparam.sched_priority = 9; /* XXX should be relative to audio (JACK) thread */
1274 if ((x = pthread_setschedparam (pthread_self(), SCHED_FIFO, &rtparam)) != 0) {
1275 // do we care? not particularly.
1278 /* set up the port vector; 4 is the largest possible size for now */
1280 ports.push_back (0);
1281 ports.push_back (0);
1282 ports.push_back (0);
1283 ports.push_back (0);
1289 pfd[nfds].fd = midi_request_pipe[0];
1290 pfd[nfds].events = POLLIN|POLLHUP|POLLERR;
1293 /* if we are using MMC control, we obviously have to listen
1294 on the appropriate port.
1297 if (mmc_control && _mmc_port && _mmc_port->selectable() >= 0) {
1298 pfd[nfds].fd = _mmc_port->selectable();
1299 pfd[nfds].events = POLLIN|POLLHUP|POLLERR;
1300 ports[nfds] = _mmc_port;
1304 /* if MTC is being handled on a different port from MMC
1305 or we are not handling MMC at all, poll
1309 if (_mtc_port && (_mtc_port != _mmc_port || !mmc_control) && _mtc_port->selectable() >= 0) {
1310 pfd[nfds].fd = _mtc_port->selectable();
1311 pfd[nfds].events = POLLIN|POLLHUP|POLLERR;
1312 ports[nfds] = _mtc_port;
1316 if (_midi_port && (_midi_port != _mmc_port || !mmc_control) && (_midi_port != _mtc_port) && _midi_port->selectable() >= 0) {
1317 pfd[nfds].fd = _midi_port->selectable();
1318 pfd[nfds].events = POLLIN|POLLHUP|POLLERR;
1319 ports[nfds] = _midi_port;
1323 if (!midi_timeouts.empty()) {
1324 timeout = 100; /* 10msecs */
1326 timeout = -1; /* if there is no data, we don't care */
1330 // cerr << "MIDI poll on " << nfds << " for " << timeout << endl;
1331 if (poll (pfd, nfds, timeout) < 0) {
1332 if (errno == EINTR) {
1333 /* gdb at work, perhaps */
1337 error << string_compose(_("MIDI thread poll failed (%1)"), strerror (errno)) << endmsg;
1341 // cerr << "MIDI thread wakes at " << get_cycles () << endl;
1346 /* check the transport request pipe */
1348 if (pfd[0].revents & ~POLLIN) {
1349 error << _("Error on transport thread request pipe") << endmsg;
1353 if (pfd[0].revents & POLLIN) {
1357 // cerr << "MIDI request FIFO ready\n";
1360 /* empty the pipe of all current requests */
1363 size_t nread = read (midi_request_pipe[0], &foo, sizeof (foo));
1366 if ((size_t) nread < sizeof (foo)) {
1371 } else if (nread == 0) {
1373 } else if (errno == EAGAIN) {
1376 fatal << _("Error reading from transport request pipe") << endmsg;
1381 while (midi_requests.read (&request, 1) == 1) {
1383 switch (request->type) {
1385 case MIDIRequest::SendFullMTC:
1386 // cerr << "send full MTC\n";
1387 send_full_time_code ();
1388 // cerr << "... done\n";
1391 case MIDIRequest::SendMTC:
1392 // cerr << "send qtr MTC\n";
1393 send_midi_time_code ();
1394 // cerr << "... done\n";
1397 case MIDIRequest::SendMMC:
1398 // cerr << "send MMC\n";
1399 deliver_mmc (request->mmc_cmd, request->locate_frame);
1400 // cerr << "... done\n";
1403 case MIDIRequest::SendMessage:
1404 // cerr << "send Message\n";
1405 deliver_midi_message (request->port, request->ev, request->chan, request->data);
1406 // cerr << "... done\n";
1409 case MIDIRequest::Deliver:
1410 // cerr << "deliver\n";
1411 deliver_data (_midi_port, request->buf, request->size);
1412 // cerr << "... done\n";
1415 case MIDIRequest::PortChange:
1416 /* restart poll with new ports */
1417 // cerr << "rebind\n";
1421 case MIDIRequest::Quit:
1423 pthread_exit_pbd (0);
1441 /* now read the rest of the ports */
1443 for (int p = 1; p < nfds; ++p) {
1444 if ((pfd[p].revents & ~POLLIN)) {
1445 // error << string_compose(_("Transport: error polling MIDI port %1 (revents =%2%3%4"), p, &hex, pfd[p].revents, &dec) << endmsg;
1449 if (pfd[p].revents & POLLIN) {
1451 midi_read (ports[p]);
1455 /* timeout driven */
1457 if (fds_ready < 2 && timeout != -1) {
1459 for (MidiTimeoutList::iterator i = midi_timeouts.begin(); i != midi_timeouts.end(); ) {
1461 MidiTimeoutList::iterator tmp;
1466 midi_timeouts.erase (i);
1477 Session::get_mmc_control () const
1483 Session::get_midi_control () const
1485 return midi_control;