X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fmidi%2B%2B2%2Fmmc.cc;h=1b9481c9bf8127e1a89580ff4ebc6f78cc707c9f;hb=15cee60021eada542b2dae0fafbb3150fcaa5010;hp=603023010870ef618c2704d694a66713eb59517e;hpb=f450df300c9c057141a4caf79ff6dbfbf58492d9;p=ardour.git diff --git a/libs/midi++2/mmc.cc b/libs/midi++2/mmc.cc index 6030230108..1b9481c9bf 100644 --- a/libs/midi++2/mmc.cc +++ b/libs/midi++2/mmc.cc @@ -18,13 +18,21 @@ $Id$ */ +#include #include +#include "timecode/time.h" + #include "pbd/error.h" + #include "midi++/mmc.h" #include "midi++/port.h" #include "midi++/parser.h" +#ifndef __INT_MAX__ // 'ssize_t' won't be defined yet +typedef long ssize_t; +#endif + using namespace std; using namespace MIDI; using namespace PBD; @@ -191,43 +199,42 @@ static void build_mmc_cmd_map () mmc_cmd_map.insert (newpair); } - -MachineControl::MachineControl (Port &p, float /*version*/, - CommandSignature & /*csig*/, - ResponseSignature & /*rsig*/) - - : _port (p) +MachineControl::MachineControl () { - Parser *parser; - build_mmc_cmd_map (); - _receive_device_id = 0; + _receive_device_id = 0x7f; _send_device_id = 0x7f; - - if ((parser = _port.input()) != 0) { - parser->mmc.connect_same_thread (mmc_connection, boost::bind (&MachineControl::process_mmc_message, this, _1, _2, _3)); - } else { - warning << "MMC connected to a non-input port: useless!" - << endmsg; - } } void -MachineControl::set_receive_device_id (byte id) +MachineControl::set_ports (MIDI::Port* ip, MIDI::Port* op) +{ + port_connections.drop_connections (); + + _input_port = ip; + _output_port = op; + + _input_port->parser()->mmc.connect_same_thread (port_connections, boost::bind (&MachineControl::process_mmc_message, this, _1, _2, _3)); + _input_port->parser()->start.connect_same_thread (port_connections, boost::bind (&MachineControl::spp_start, this)); + _input_port->parser()->contineu.connect_same_thread (port_connections, boost::bind (&MachineControl::spp_continue, this)); + _input_port->parser()->stop.connect_same_thread (port_connections, boost::bind (&MachineControl::spp_stop, this)); +} + +void +MachineControl::set_receive_device_id (MIDI::byte id) { _receive_device_id = id & 0x7f; } void -MachineControl::set_send_device_id (byte id) +MachineControl::set_send_device_id (MIDI::byte id) { _send_device_id = id & 0x7f; } bool -MachineControl::is_mmc (byte *sysex_buf, size_t len) - +MachineControl::is_mmc (MIDI::byte *sysex_buf, size_t len) { if (len < 4 || len > 48) { return false; @@ -246,8 +253,7 @@ MachineControl::is_mmc (byte *sysex_buf, size_t len) } void -MachineControl::process_mmc_message (Parser &, byte *msg, size_t len) - +MachineControl::process_mmc_message (Parser &, MIDI::byte *msg, size_t len) { size_t skiplen; byte *mmc_msg; @@ -454,8 +460,7 @@ MachineControl::process_mmc_message (Parser &, byte *msg, size_t len) } int -MachineControl::do_masked_write (byte *msg, size_t len) - +MachineControl::do_masked_write (MIDI::byte *msg, size_t len) { /* return the number of bytes "consumed" */ @@ -481,7 +486,7 @@ MachineControl::do_masked_write (byte *msg, size_t len) } void -MachineControl::write_track_status (byte *msg, size_t /*len*/, byte reg) +MachineControl::write_track_status (MIDI::byte *msg, size_t /*len*/, MIDI::byte reg) { size_t n; ssize_t base_track; @@ -570,8 +575,7 @@ MachineControl::write_track_status (byte *msg, size_t /*len*/, byte reg) } int -MachineControl::do_locate (byte *msg, size_t /*msglen*/) - +MachineControl::do_locate (MIDI::byte *msg, size_t /*msglen*/) { if (msg[2] == 0) { warning << "MIDI::MMC: locate [I/F] command not supported" @@ -586,7 +590,7 @@ MachineControl::do_locate (byte *msg, size_t /*msglen*/) } int -MachineControl::do_step (byte *msg, size_t /*msglen*/) +MachineControl::do_step (MIDI::byte *msg, size_t /*msglen*/) { int steps = msg[2] & 0x3f; @@ -599,8 +603,7 @@ MachineControl::do_step (byte *msg, size_t /*msglen*/) } int -MachineControl::do_shuttle (byte *msg, size_t /*msglen*/) - +MachineControl::do_shuttle (MIDI::byte *msg, size_t /*msglen*/) { size_t forward; byte sh = msg[2]; @@ -630,3 +633,84 @@ MachineControl::do_shuttle (byte *msg, size_t /*msglen*/) return 0; } +void +MachineControl::enable_send (bool yn) +{ + _enable_send = yn; +} + +/** Send a MMC command to a the MMC port. + * @param c command. + */ +void +MachineControl::send (MachineControlCommand const & c) +{ + if (_output_port == 0 || !_enable_send) { + // cerr << "Not delivering MMC " << _mmc->port() << " - " << session_send_mmc << endl; + return; + } + + MIDI::byte buffer[32]; + MIDI::byte* b = c.fill_buffer (this, buffer); + + if (_output_port->midimsg (buffer, b - buffer, 0)) { + error << "MMC: cannot send command" << endmsg; + } +} + +void +MachineControl::spp_start () +{ + SPPStart (); /* EMIT SIGNAL */ +} + +void +MachineControl::spp_continue () +{ + SPPContinue (); /* EMIT SIGNAL */ +} + +void +MachineControl::spp_stop () +{ + SPPStop (); /* EMIT SIGNAL */ +} + +MachineControlCommand::MachineControlCommand (MachineControl::Command c) + : _command (c) +{ + +} + +MachineControlCommand::MachineControlCommand (Timecode::Time t) + : _command (MachineControl::cmdLocate) + , _time (t) +{ + +} + +MIDI::byte * +MachineControlCommand::fill_buffer (MachineControl* mmc, MIDI::byte* b) const +{ + *b++ = 0xf0; // SysEx + *b++ = 0x7f; // Real-time SysEx ID for MMC + *b++ = mmc->send_device_id(); + *b++ = 0x6; // MMC command + + *b++ = _command; + + if (_command == MachineControl::cmdLocate) { + *b++ = 0x6; // byte count + *b++ = 0x1; // "TARGET" subcommand + *b++ = _time.hours; + *b++ = _time.minutes; + *b++ = _time.seconds; + *b++ = _time.frames; + *b++ = _time.subframes; + } + + *b++ = 0xf7; + + return b; +} +