X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fmidi%2B%2B2%2Fmmc.cc;h=8a7e175cdde422a1a10255b486ea8b9ba5f50fc7;hb=eca27d82189c7509f7d010adad9ed3d83bccbf21;hp=1b8de40358914048cf2995253c2d03a048b0fc77;hpb=aaabaf5d3c8624f398809bb468e2b121a23abda0;p=ardour.git diff --git a/libs/midi++2/mmc.cc b/libs/midi++2/mmc.cc index 1b8de40358..8a7e175cdd 100644 --- a/libs/midi++2/mmc.cc +++ b/libs/midi++2/mmc.cc @@ -1,33 +1,35 @@ /* - Copyright (C) 2000 Paul Barton-Davis - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - $Id$ -*/ + * Copyright (C) 2000-2017 Paul Davis + * Copyright (C) 2009-2010 David Robillard + * Copyright (C) 2009-2012 Carl Hetherington + * Copyright (C) 2014-2015 Robin Gareus + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ #include #include -#include "timecode/time.h" +#include "temporal/time.h" +#include "temporal/bbt_time.h" + #include "pbd/error.h" + #include "midi++/mmc.h" #include "midi++/port.h" -#include "midi++/jack_midi_port.h" #include "midi++/parser.h" -#include "midi++/manager.h" #ifndef __INT_MAX__ // 'ssize_t' won't be defined yet typedef long ssize_t; @@ -37,6 +39,13 @@ using namespace std; using namespace MIDI; using namespace PBD; +/** + * As libtimecode is linked statically to libmidi++ this + * is necessary to pull in all the symbols from libtimecode + * so they are exported for other users of libtimecode. + */ +double tmp = Timecode::BBT_Time::ticks_per_beat; + static std::map mmc_cmd_map; static void build_mmc_cmd_map () { @@ -199,16 +208,21 @@ static void build_mmc_cmd_map () mmc_cmd_map.insert (newpair); } - -MachineControl::MachineControl (Manager* m, jack_client_t* jack) +MachineControl::MachineControl () { build_mmc_cmd_map (); _receive_device_id = 0x7f; _send_device_id = 0x7f; +} + +void +MachineControl::set_ports (MIDI::Port* ip, MIDI::Port* op) +{ + port_connections.drop_connections (); - _input_port = m->add_port (new JackMIDIPort ("MMC in", Port::IsInput, jack)); - _output_port = m->add_port (new JackMIDIPort ("MMC out", Port::IsOutput, jack)); + _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)); @@ -243,7 +257,7 @@ MachineControl::is_mmc (MIDI::byte *sysex_buf, size_t len) sysex_buf[3] != 0x7) { /* MMC Response */ return false; } - + return true; } @@ -271,7 +285,7 @@ MachineControl::process_mmc_message (Parser &, MIDI::byte *msg, size_t len) cerr << endl; #endif - if (msg[1] != 0x7f && msg[1] != _receive_device_id) { + if (_receive_device_id != 0x7f && msg[1] != 0x7f && msg[1] != _receive_device_id) { return; } @@ -294,7 +308,7 @@ MachineControl::process_mmc_message (Parser &, MIDI::byte *msg, size_t len) } #if 0 - cerr << "+++ MMC type " + cerr << "+++ MMC type " << hex << ((int) *mmc_msg) << dec @@ -434,7 +448,7 @@ MachineControl::process_mmc_message (Parser &, MIDI::byte *msg, size_t len) break; } - /* increase skiplen to cover the command byte and + /* increase skiplen to cover the command byte and count byte (if it existed). */ @@ -452,7 +466,7 @@ MachineControl::process_mmc_message (Parser &, MIDI::byte *msg, size_t len) len -= skiplen; } while (len > 1); /* skip terminating EOX byte */ -} +} int MachineControl::do_masked_write (MIDI::byte *msg, size_t len) @@ -460,7 +474,7 @@ MachineControl::do_masked_write (MIDI::byte *msg, size_t len) /* return the number of bytes "consumed" */ int retval = msg[1] + 2; /* bytes following + 2 */ - + switch (msg[2]) { case 0x4f: /* Track Record Ready Status */ write_track_status (&msg[3], len - 3, msg[2]); @@ -495,15 +509,15 @@ MachineControl::write_track_status (MIDI::byte *msg, size_t /*len*/, MIDI::byte bit 4: aux track b the format of the message (its an MMC Masked Write) is: - + 0x41 Command Code byte count of following data byte value of the field being written - byte number of target byte in the + byte number of target byte in the bitmap being written to ones in the mask indicate which bits will be changed new data for the byte being written - + by the time this code is executing, msg[0] is the byte number of the target byte. if its zero, we are writing to a special byte in the standard @@ -511,20 +525,20 @@ MachineControl::write_track_status (MIDI::byte *msg, size_t /*len*/, MIDI::byte special. hence the bits for tracks 1 + 2 are bits 5 and 6 of the first byte of the track bitmap. so: - - change track 1: msg[0] = 0; << first byte of track bitmap + + change track 1: msg[0] = 0; << first byte of track bitmap msg[1] = 0100000; << binary: bit 5 set - + change track 2: msg[0] = 0; << first byte of track bitmap msg[1] = 1000000; << binary: bit 6 set - + change track 3: msg[0] = 1; << second byte of track bitmap msg[1] = 0000001; << binary: bit 0 set - + the (msg[0] * 8) - 6 computation is an attempt to extract the value of the first track: ie. the one that would be indicated by bit 0 being set. - + so, if msg[0] = 0, msg[1] = 0100000 (binary), what happens is that base_track = -5, but by the time we check the correct bit, n = 5, and so the @@ -552,19 +566,19 @@ MachineControl::write_track_status (MIDI::byte *msg, size_t /*len*/, MIDI::byte */ bool val = (msg[2] & (1<> (7 - left_shift)); fractional = ((sm << left_shift) << 7) | sl; - shuttle_speed = integral + + shuttle_speed = integral + ((float)fractional / (1 << (14 - left_shift))); Shuttle (*this, shuttle_speed, forward); @@ -638,7 +652,7 @@ MachineControl::enable_send (bool yn) * @param c command. */ void -MachineControl::send (MachineControlCommand const & c) +MachineControl::send (MachineControlCommand const & c, timestamp_t when) { if (_output_port == 0 || !_enable_send) { // cerr << "Not delivering MMC " << _mmc->port() << " - " << session_send_mmc << endl; @@ -648,7 +662,7 @@ MachineControl::send (MachineControlCommand const & c) MIDI::byte buffer[32]; MIDI::byte* b = c.fill_buffer (this, buffer); - if (_output_port->midimsg (buffer, b - buffer, 0)) { + if (_output_port->midimsg (buffer, b - buffer, when)) { error << "MMC: cannot send command" << endmsg; } } @@ -684,7 +698,7 @@ MachineControlCommand::MachineControlCommand (Timecode::Time t) } -MIDI::byte * +MIDI::byte * MachineControlCommand::fill_buffer (MachineControl* mmc, MIDI::byte* b) const { *b++ = 0xf0; // SysEx @@ -697,7 +711,7 @@ MachineControlCommand::fill_buffer (MachineControl* mmc, MIDI::byte* b) const if (_command == MachineControl::cmdLocate) { *b++ = 0x6; // byte count *b++ = 0x1; // "TARGET" subcommand - *b++ = _time.hours; + *b++ = _time.hours % 24; *b++ = _time.minutes; *b++ = _time.seconds; *b++ = _time.frames;