/*
- Copyright (C) 2000 Paul Barton-Davis
+ 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
#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;
}
void
-MachineControl::set_receive_device_id (byte id)
+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;
sysex_buf[3] != 0x7) { /* MMC Response */
return false;
}
-
+
return true;
}
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;
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;
}
}
#if 0
- cerr << "+++ MMC type "
+ cerr << "+++ MMC type "
<< hex
<< ((int) *mmc_msg)
<< dec
break;
}
- /* increase skiplen to cover the command byte and
+ /* increase skiplen to cover the command byte and
count byte (if it existed).
*/
len -= skiplen;
} while (len > 1); /* skip terminating EOX byte */
-}
+}
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" */
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]);
}
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;
bit 4: aux track b
the format of the message (its an MMC Masked Write) is:
-
+
0x41 Command Code
<count> byte count of following data
<name> byte value of the field being written
- <byte #> byte number of target byte in the
+ <byte #> byte number of target byte in the
bitmap being written to
<mask> ones in the mask indicate which bits will be changed
<data> 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
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
*/
bool val = (msg[2] & (1<<n));
-
+
switch (reg) {
case 0x4f:
trackRecordStatus[base_track+n] = val;
TrackRecordStatusChange (*this, base_track+n, val);
break;
-
+
case 0x62:
trackMute[base_track+n] = val;
TrackMuteChange (*this, base_track+n, val);
break;
}
- }
+ }
}
}
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"
}
int
-MachineControl::do_step (byte *msg, size_t /*msglen*/)
+MachineControl::do_step (MIDI::byte *msg, size_t /*msglen*/)
{
int steps = msg[2] & 0x3f;
}
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];
} else {
forward = true;
}
-
+
left_shift = (sh & 0x38);
integral = ((sh & 0x7) << left_shift) | (sm >> (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);
* @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;
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;
}
}
}
-MIDI::byte *
+MIDI::byte *
MachineControlCommand::fill_buffer (MachineControl* mmc, MIDI::byte* b) const
{
*b++ = 0xf0; // SysEx
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;