2006-04-04 03:26:08 +00:00
|
|
|
#include <iostream>
|
2006-04-05 00:21:43 +00:00
|
|
|
#include <sys/time.h>
|
2006-04-04 03:26:08 +00:00
|
|
|
|
|
|
|
|
#include <pbd/pthread_utils.h>
|
|
|
|
|
|
|
|
|
|
#include <ardour/route.h>
|
2006-04-05 03:05:30 +00:00
|
|
|
#include <ardour/audio_track.h>
|
2006-04-04 03:26:08 +00:00
|
|
|
#include <ardour/session.h>
|
2006-04-05 03:05:30 +00:00
|
|
|
#include <ardour/location.h>
|
2006-04-04 03:26:08 +00:00
|
|
|
|
2006-04-05 00:21:43 +00:00
|
|
|
#include "tranzport_control_protocol.h"
|
|
|
|
|
|
2006-04-04 03:26:08 +00:00
|
|
|
using namespace ARDOUR;
|
|
|
|
|
using namespace std;
|
2006-04-05 03:05:30 +00:00
|
|
|
using namespace sigc;
|
2006-04-04 03:26:08 +00:00
|
|
|
|
|
|
|
|
#include "i18n.h"
|
|
|
|
|
|
|
|
|
|
TranzportControlProtocol::TranzportControlProtocol (Session& s)
|
|
|
|
|
: ControlProtocol (s, _("Tranzport"))
|
|
|
|
|
{
|
|
|
|
|
timeout = 60000;
|
|
|
|
|
buttonmask = 0;
|
|
|
|
|
_datawheel = 0;
|
|
|
|
|
_device_status = STATUS_OFFLINE;
|
|
|
|
|
udev = 0;
|
|
|
|
|
current_route = 0;
|
|
|
|
|
current_track_id = 0;
|
|
|
|
|
last_where = max_frames;
|
2006-04-05 03:05:30 +00:00
|
|
|
|
2006-04-05 00:21:43 +00:00
|
|
|
memset (next_screen, ' ', sizeof (next_screen));
|
|
|
|
|
memset (current_screen, ' ', sizeof (current_screen));
|
2006-04-05 03:05:30 +00:00
|
|
|
|
|
|
|
|
for (uint32_t i = 0; i < sizeof(lights)/sizeof(lights[0]); ++i) {
|
|
|
|
|
lights[i] = false;
|
|
|
|
|
}
|
2006-04-04 03:26:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TranzportControlProtocol::~TranzportControlProtocol ()
|
|
|
|
|
{
|
|
|
|
|
if (udev) {
|
2006-04-05 00:21:43 +00:00
|
|
|
lcd_clear ();
|
2006-04-04 03:26:08 +00:00
|
|
|
pthread_cancel_one (thread);
|
|
|
|
|
close ();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
TranzportControlProtocol::init ()
|
|
|
|
|
{
|
|
|
|
|
if (open ()) {
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
2006-04-05 00:21:43 +00:00
|
|
|
/* outbound thread */
|
|
|
|
|
|
|
|
|
|
init_thread ();
|
|
|
|
|
|
|
|
|
|
/* inbound thread */
|
|
|
|
|
|
|
|
|
|
pthread_create_and_store (X_("tranzport monitor"), &thread, 0, _thread_work, this);
|
2006-04-04 03:26:08 +00:00
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool
|
|
|
|
|
TranzportControlProtocol::active() const
|
|
|
|
|
{
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
TranzportControlProtocol::send_route_feedback (list<Route*>& routes)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
TranzportControlProtocol::send_global_feedback ()
|
|
|
|
|
{
|
2006-04-05 00:21:43 +00:00
|
|
|
show_transport_time ();
|
2006-04-04 03:26:08 +00:00
|
|
|
|
2006-04-05 03:05:30 +00:00
|
|
|
if (session.soloing()) {
|
|
|
|
|
light_on (LightAnysolo);
|
|
|
|
|
} else {
|
|
|
|
|
light_off (LightAnysolo);
|
|
|
|
|
}
|
|
|
|
|
|
2006-04-05 00:21:43 +00:00
|
|
|
flush_lcd ();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
TranzportControlProtocol::show_transport_time ()
|
|
|
|
|
{
|
|
|
|
|
jack_nframes_t where = session.transport_frame();
|
|
|
|
|
|
2006-04-04 03:26:08 +00:00
|
|
|
if (where != last_where) {
|
|
|
|
|
|
2006-04-05 00:21:43 +00:00
|
|
|
uint8_t label[12];
|
2006-04-04 03:26:08 +00:00
|
|
|
SMPTE_Time smpte;
|
2006-04-05 00:21:43 +00:00
|
|
|
char* ptr = (char *) label;
|
2006-04-04 03:26:08 +00:00
|
|
|
|
|
|
|
|
session.smpte_time (where, smpte);
|
2006-04-05 00:21:43 +00:00
|
|
|
memset (label, ' ', sizeof (label));
|
2006-04-04 03:26:08 +00:00
|
|
|
|
|
|
|
|
if (smpte.negative) {
|
|
|
|
|
sprintf (ptr, "-%02ld:", smpte.hours);
|
|
|
|
|
} else {
|
|
|
|
|
sprintf (ptr, " %02ld:", smpte.hours);
|
|
|
|
|
}
|
|
|
|
|
ptr += 4;
|
|
|
|
|
|
|
|
|
|
sprintf (ptr, "%02ld:", smpte.minutes);
|
|
|
|
|
ptr += 3;
|
|
|
|
|
|
|
|
|
|
sprintf (ptr, "%02ld:", smpte.seconds);
|
|
|
|
|
ptr += 3;
|
|
|
|
|
|
|
|
|
|
sprintf (ptr, "%02ld", smpte.frames);
|
|
|
|
|
ptr += 2;
|
|
|
|
|
|
2006-04-05 00:21:43 +00:00
|
|
|
write_clock (label);
|
2006-04-04 03:26:08 +00:00
|
|
|
|
|
|
|
|
last_where = where;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2006-04-05 00:21:43 +00:00
|
|
|
void
|
|
|
|
|
TranzportControlProtocol::write_clock (const uint8_t* label)
|
|
|
|
|
{
|
2006-04-05 03:05:30 +00:00
|
|
|
memcpy (&next_screen[1][8], &label[0], 4);
|
|
|
|
|
memcpy (&next_screen[1][12], &label[4], 4);
|
|
|
|
|
memcpy (&next_screen[1][16], &label[8], 4);
|
2006-04-05 00:21:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
TranzportControlProtocol::flush_lcd ()
|
|
|
|
|
{
|
|
|
|
|
if (memcmp (&next_screen[0][0], ¤t_screen[0][0], 4)) {
|
2006-04-05 03:05:30 +00:00
|
|
|
cerr << "diff 1\n";
|
2006-04-05 00:21:43 +00:00
|
|
|
lcd_write (0, &next_screen[0][0]);
|
|
|
|
|
}
|
|
|
|
|
if (memcmp (&next_screen[0][4], ¤t_screen[0][4], 4)) {
|
2006-04-05 03:05:30 +00:00
|
|
|
cerr << "diff 2\n";
|
|
|
|
|
lcd_write (1, &next_screen[0][4]);
|
2006-04-05 00:21:43 +00:00
|
|
|
}
|
|
|
|
|
if (memcmp (&next_screen[0][8], ¤t_screen[0][8], 4)) {
|
2006-04-05 03:05:30 +00:00
|
|
|
cerr << "diff 3\n";
|
|
|
|
|
lcd_write (2, &next_screen[0][8]);
|
2006-04-05 00:21:43 +00:00
|
|
|
}
|
|
|
|
|
if (memcmp (&next_screen[0][12], ¤t_screen[0][12], 4)) {
|
2006-04-05 03:05:30 +00:00
|
|
|
cerr << "diff 4\n";
|
|
|
|
|
lcd_write (3, &next_screen[0][12]);
|
2006-04-05 00:21:43 +00:00
|
|
|
}
|
|
|
|
|
if (memcmp (&next_screen[0][16], ¤t_screen[0][16], 4)) {
|
2006-04-05 03:05:30 +00:00
|
|
|
cerr << "diff 5\n";
|
|
|
|
|
lcd_write (4, &next_screen[0][16]);
|
2006-04-05 00:21:43 +00:00
|
|
|
}
|
|
|
|
|
if (memcmp (&next_screen[1][0], ¤t_screen[1][0], 4)) {
|
2006-04-05 03:05:30 +00:00
|
|
|
cerr << "diff 6\n";
|
|
|
|
|
lcd_write (5, &next_screen[1][0]);
|
2006-04-05 00:21:43 +00:00
|
|
|
}
|
|
|
|
|
if (memcmp (&next_screen[1][4], ¤t_screen[1][4], 4)) {
|
2006-04-05 03:05:30 +00:00
|
|
|
cerr << "diff 7\n";
|
|
|
|
|
lcd_write (6, &next_screen[1][4]);
|
2006-04-05 00:21:43 +00:00
|
|
|
}
|
|
|
|
|
if (memcmp (&next_screen[1][8], ¤t_screen[1][8], 4)) {
|
2006-04-05 03:05:30 +00:00
|
|
|
cerr << "diff 8\n";
|
|
|
|
|
lcd_write (7, &next_screen[1][8]);
|
2006-04-05 00:21:43 +00:00
|
|
|
}
|
|
|
|
|
if (memcmp (&next_screen[1][12], ¤t_screen[1][12], 4)) {
|
2006-04-05 03:05:30 +00:00
|
|
|
cerr << "diff 9\n";
|
|
|
|
|
lcd_write (8, &next_screen[1][12]);
|
2006-04-05 00:21:43 +00:00
|
|
|
}
|
|
|
|
|
if (memcmp (&next_screen[1][16], ¤t_screen[1][16], 4)) {
|
2006-04-05 03:05:30 +00:00
|
|
|
cerr << "diff 10\n";
|
|
|
|
|
lcd_write (9, &next_screen[1][16]);
|
2006-04-05 00:21:43 +00:00
|
|
|
}
|
|
|
|
|
|
2006-04-05 03:05:30 +00:00
|
|
|
/* copy the current state into the next state */
|
|
|
|
|
|
|
|
|
|
memcpy (next_screen, current_screen, sizeof (current_screen));
|
2006-04-05 00:21:43 +00:00
|
|
|
}
|
|
|
|
|
|
2006-04-04 03:26:08 +00:00
|
|
|
void*
|
|
|
|
|
TranzportControlProtocol::_thread_work (void* arg)
|
|
|
|
|
{
|
|
|
|
|
return static_cast<TranzportControlProtocol*>(arg)->thread_work ();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void*
|
|
|
|
|
TranzportControlProtocol::thread_work ()
|
|
|
|
|
{
|
2006-04-05 00:21:43 +00:00
|
|
|
PBD::ThreadCreated (pthread_self(), X_("tranzport monitor"));
|
2006-04-04 03:26:08 +00:00
|
|
|
|
|
|
|
|
while (true) {
|
|
|
|
|
if (read()) {
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
switch (_device_status) {
|
|
|
|
|
case STATUS_OFFLINE:
|
|
|
|
|
cerr << "offline\n";
|
|
|
|
|
break;
|
|
|
|
|
case STATUS_ONLINE:
|
2006-04-05 03:05:30 +00:00
|
|
|
case 0:
|
2006-04-04 03:26:08 +00:00
|
|
|
cerr << "online\n";
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
cerr << "unknown status\n";
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
2006-04-05 03:05:30 +00:00
|
|
|
if (_device_status == STATUS_ONLINE || _device_status == 0) {
|
2006-04-04 03:26:08 +00:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
while (true) {
|
|
|
|
|
if (read ()) {
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
TranzportControlProtocol::open ()
|
|
|
|
|
{
|
|
|
|
|
struct usb_bus *bus;
|
|
|
|
|
struct usb_device *dev;
|
|
|
|
|
|
|
|
|
|
usb_init();
|
|
|
|
|
usb_find_busses();
|
|
|
|
|
usb_find_devices();
|
|
|
|
|
|
|
|
|
|
for (bus = usb_busses; bus; bus = bus->next) {
|
|
|
|
|
|
|
|
|
|
for(dev = bus->devices; dev; dev = dev->next) {
|
|
|
|
|
if (dev->descriptor.idVendor != VENDORID)
|
|
|
|
|
continue;
|
|
|
|
|
if (dev->descriptor.idProduct != PRODUCTID)
|
|
|
|
|
continue;
|
|
|
|
|
return open_core (dev);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
error << _("Tranzport: no device detected") << endmsg;
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
TranzportControlProtocol::open_core (struct usb_device* dev)
|
|
|
|
|
{
|
|
|
|
|
if (!(udev = usb_open (dev))) {
|
|
|
|
|
error << _("Tranzport: cannot open USB transport") << endmsg;
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (usb_claim_interface (udev, 0) < 0) {
|
|
|
|
|
error << _("Tranzport: cannot claim USB interface") << endmsg;
|
|
|
|
|
usb_close (udev);
|
|
|
|
|
udev = 0;
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
TranzportControlProtocol::close ()
|
|
|
|
|
{
|
|
|
|
|
int ret = 0;
|
|
|
|
|
|
|
|
|
|
if (udev == 0) {
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (usb_release_interface (udev, 0) < 0) {
|
|
|
|
|
error << _("Tranzport: cannot release interface") << endmsg;
|
|
|
|
|
ret = -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (usb_close (udev)) {
|
|
|
|
|
error << _("Tranzport: cannot close device") << endmsg;
|
|
|
|
|
ret = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int
|
2006-04-05 00:21:43 +00:00
|
|
|
TranzportControlProtocol::write (uint8_t* cmd, uint32_t timeout_override)
|
2006-04-04 03:26:08 +00:00
|
|
|
{
|
|
|
|
|
int val;
|
2006-04-05 00:21:43 +00:00
|
|
|
|
|
|
|
|
val = usb_interrupt_write (udev, WRITE_ENDPOINT, (char*) cmd, 8, timeout_override ? timeout_override : timeout);
|
2006-04-04 03:26:08 +00:00
|
|
|
if (val < 0)
|
|
|
|
|
return val;
|
|
|
|
|
if (val != 8)
|
|
|
|
|
return -1;
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
TranzportControlProtocol::lcd_clear ()
|
|
|
|
|
{
|
|
|
|
|
lcd_write (0, " ");
|
|
|
|
|
lcd_write (1, " ");
|
|
|
|
|
lcd_write (2, " ");
|
|
|
|
|
lcd_write (3, " ");
|
|
|
|
|
lcd_write (4, " ");
|
|
|
|
|
lcd_write (5, " ");
|
|
|
|
|
lcd_write (6, " ");
|
|
|
|
|
lcd_write (7, " ");
|
|
|
|
|
lcd_write (8, " ");
|
|
|
|
|
lcd_write (9, " ");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
TranzportControlProtocol::lcd_write (uint8_t cell, const char* text)
|
|
|
|
|
{
|
|
|
|
|
uint8_t cmd[8];
|
|
|
|
|
|
|
|
|
|
if (cell > 9) {
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
cmd[0] = 0x00;
|
|
|
|
|
cmd[1] = 0x01;
|
|
|
|
|
cmd[2] = cell;
|
|
|
|
|
cmd[3] = text[0];
|
|
|
|
|
cmd[4] = text[1];
|
|
|
|
|
cmd[5] = text[2];
|
|
|
|
|
cmd[6] = text[3];
|
|
|
|
|
cmd[7] = 0x00;
|
|
|
|
|
|
2006-04-05 03:05:30 +00:00
|
|
|
if (write (cmd, 500) == 0) {
|
|
|
|
|
int row;
|
|
|
|
|
int col;
|
|
|
|
|
|
|
|
|
|
switch (cell) {
|
|
|
|
|
case 0:
|
|
|
|
|
row = 0;
|
|
|
|
|
col = 0;
|
|
|
|
|
break;
|
|
|
|
|
case 1:
|
|
|
|
|
row = 0;
|
|
|
|
|
col = 4;
|
|
|
|
|
break;
|
|
|
|
|
case 2:
|
|
|
|
|
row = 0;
|
|
|
|
|
col = 8;
|
|
|
|
|
break;
|
|
|
|
|
case 3:
|
|
|
|
|
row = 0;
|
|
|
|
|
col = 12;
|
|
|
|
|
break;
|
|
|
|
|
case 4:
|
|
|
|
|
row = 0;
|
|
|
|
|
col = 16;
|
|
|
|
|
break;
|
|
|
|
|
case 5:
|
|
|
|
|
row = 1;
|
|
|
|
|
col = 0;
|
|
|
|
|
break;
|
|
|
|
|
case 6:
|
|
|
|
|
row = 1;
|
|
|
|
|
col = 4;
|
|
|
|
|
break;
|
|
|
|
|
case 7:
|
|
|
|
|
row = 1;
|
|
|
|
|
col = 8;
|
|
|
|
|
break;
|
|
|
|
|
case 8:
|
|
|
|
|
row = 1;
|
|
|
|
|
col = 12;
|
|
|
|
|
break;
|
|
|
|
|
case 9:
|
|
|
|
|
row = 1;
|
|
|
|
|
col = 16;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
current_screen[row][col] = text[0];
|
|
|
|
|
current_screen[row][col+1] = text[1];
|
|
|
|
|
current_screen[row][col+2] = text[2];
|
|
|
|
|
current_screen[row][col+3] = text[3];
|
|
|
|
|
|
|
|
|
|
cerr << "stored " << text[0] << text[1] << text[2] << text[3] << " to " << row << ',' << col << endl;
|
2006-04-05 00:21:43 +00:00
|
|
|
|
2006-04-05 03:05:30 +00:00
|
|
|
return 0;
|
|
|
|
|
}
|
2006-04-05 00:21:43 +00:00
|
|
|
|
2006-04-05 03:05:30 +00:00
|
|
|
cerr << "failed to write text\n";
|
|
|
|
|
return -1;
|
2006-04-04 03:26:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
TranzportControlProtocol::light_on (LightID light)
|
|
|
|
|
{
|
|
|
|
|
uint8_t cmd[8];
|
|
|
|
|
|
2006-04-05 03:05:30 +00:00
|
|
|
if (!lights[light]) {
|
|
|
|
|
|
|
|
|
|
cmd[0] = 0x00;
|
|
|
|
|
cmd[1] = 0x00;
|
|
|
|
|
cmd[2] = light;
|
|
|
|
|
cmd[3] = 0x01;
|
|
|
|
|
cmd[4] = 0x00;
|
|
|
|
|
cmd[5] = 0x00;
|
|
|
|
|
cmd[6] = 0x00;
|
|
|
|
|
cmd[7] = 0x00;
|
2006-04-04 03:26:08 +00:00
|
|
|
|
2006-04-05 03:05:30 +00:00
|
|
|
if (write (cmd, 500) == 0) {
|
|
|
|
|
lights[light] = true;
|
|
|
|
|
return 0;
|
|
|
|
|
} else {
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
2006-04-04 03:26:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
TranzportControlProtocol::light_off (LightID light)
|
|
|
|
|
{
|
|
|
|
|
uint8_t cmd[8];
|
|
|
|
|
|
2006-04-05 03:05:30 +00:00
|
|
|
if (lights[light]) {
|
|
|
|
|
|
|
|
|
|
cmd[0] = 0x00;
|
|
|
|
|
cmd[1] = 0x00;
|
|
|
|
|
cmd[2] = light;
|
|
|
|
|
cmd[3] = 0x00;
|
|
|
|
|
cmd[4] = 0x00;
|
|
|
|
|
cmd[5] = 0x00;
|
|
|
|
|
cmd[6] = 0x00;
|
|
|
|
|
cmd[7] = 0x00;
|
2006-04-04 03:26:08 +00:00
|
|
|
|
2006-04-05 03:05:30 +00:00
|
|
|
if (write (cmd, 500) == 0) {
|
|
|
|
|
lights[light] = false;
|
|
|
|
|
return 0;
|
|
|
|
|
} else {
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
2006-04-04 03:26:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int
|
2006-04-05 00:21:43 +00:00
|
|
|
TranzportControlProtocol::read (uint32_t timeout_override)
|
2006-04-04 03:26:08 +00:00
|
|
|
{
|
|
|
|
|
uint8_t buf[8];
|
|
|
|
|
int val;
|
|
|
|
|
|
|
|
|
|
memset(buf, 0, 8);
|
2006-04-05 00:21:43 +00:00
|
|
|
again:
|
|
|
|
|
val = usb_interrupt_read(udev, READ_ENDPOINT, (char*) buf, 8, timeout_override ? timeout_override : timeout);
|
2006-04-04 03:26:08 +00:00
|
|
|
if (val < 0) {
|
|
|
|
|
return val;
|
|
|
|
|
}
|
|
|
|
|
if (val != 8) {
|
2006-04-05 00:21:43 +00:00
|
|
|
if (val == 0) {
|
|
|
|
|
goto again;
|
|
|
|
|
}
|
2006-04-04 03:26:08 +00:00
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
2006-04-05 03:05:30 +00:00
|
|
|
// printf("read: %02x %02x %02x %02x %02x %02x %02x %02x\n", buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], buf[7]);
|
2006-04-04 03:26:08 +00:00
|
|
|
|
|
|
|
|
uint32_t this_button_mask;
|
|
|
|
|
uint32_t button_changes;
|
|
|
|
|
|
|
|
|
|
_device_status = buf[1];
|
|
|
|
|
this_button_mask = 0;
|
|
|
|
|
this_button_mask |= buf[2] << 24;
|
|
|
|
|
this_button_mask |= buf[3] << 16;
|
|
|
|
|
this_button_mask |= buf[4] << 8;
|
|
|
|
|
this_button_mask |= buf[5];
|
|
|
|
|
_datawheel = buf[6];
|
|
|
|
|
|
|
|
|
|
button_changes = (this_button_mask ^ buttonmask);
|
|
|
|
|
buttonmask = this_button_mask;
|
|
|
|
|
|
|
|
|
|
if (button_changes & ButtonBattery) {
|
|
|
|
|
if (buttonmask & ButtonBattery) {
|
|
|
|
|
button_event_battery_press (buttonmask&ButtonShift);
|
|
|
|
|
} else {
|
|
|
|
|
button_event_battery_release (buttonmask&ButtonShift);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (button_changes & ButtonBacklight) {
|
|
|
|
|
if (buttonmask & ButtonBacklight) {
|
|
|
|
|
button_event_backlight_press (buttonmask&ButtonShift);
|
|
|
|
|
} else {
|
|
|
|
|
button_event_backlight_release (buttonmask&ButtonShift);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (button_changes & ButtonTrackLeft) {
|
|
|
|
|
if (buttonmask & ButtonTrackLeft) {
|
|
|
|
|
button_event_trackleft_press (buttonmask&ButtonShift);
|
|
|
|
|
} else {
|
|
|
|
|
button_event_trackleft_release (buttonmask&ButtonShift);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (button_changes & ButtonTrackRight) {
|
|
|
|
|
if (buttonmask & ButtonTrackRight) {
|
|
|
|
|
button_event_trackright_press (buttonmask&ButtonShift);
|
|
|
|
|
} else {
|
|
|
|
|
button_event_trackright_release (buttonmask&ButtonShift);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (button_changes & ButtonTrackRec) {
|
|
|
|
|
if (buttonmask & ButtonTrackRec) {
|
|
|
|
|
button_event_trackrec_press (buttonmask&ButtonShift);
|
|
|
|
|
} else {
|
|
|
|
|
button_event_trackrec_release (buttonmask&ButtonShift);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (button_changes & ButtonTrackMute) {
|
|
|
|
|
if (buttonmask & ButtonTrackMute) {
|
|
|
|
|
button_event_trackmute_press (buttonmask&ButtonShift);
|
|
|
|
|
} else {
|
|
|
|
|
button_event_trackmute_release (buttonmask&ButtonShift);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (button_changes & ButtonTrackSolo) {
|
|
|
|
|
if (buttonmask & ButtonTrackSolo) {
|
|
|
|
|
button_event_tracksolo_press (buttonmask&ButtonShift);
|
|
|
|
|
} else {
|
|
|
|
|
button_event_tracksolo_release (buttonmask&ButtonShift);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (button_changes & ButtonUndo) {
|
|
|
|
|
if (buttonmask & ButtonUndo) {
|
|
|
|
|
button_event_undo_press (buttonmask&ButtonShift);
|
|
|
|
|
} else {
|
|
|
|
|
button_event_undo_release (buttonmask&ButtonShift);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (button_changes & ButtonIn) {
|
|
|
|
|
if (buttonmask & ButtonIn) {
|
|
|
|
|
button_event_in_press (buttonmask&ButtonShift);
|
|
|
|
|
} else {
|
|
|
|
|
button_event_in_release (buttonmask&ButtonShift);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (button_changes & ButtonOut) {
|
|
|
|
|
if (buttonmask & ButtonOut) {
|
|
|
|
|
button_event_out_press (buttonmask&ButtonShift);
|
|
|
|
|
} else {
|
|
|
|
|
button_event_out_release (buttonmask&ButtonShift);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (button_changes & ButtonPunch) {
|
|
|
|
|
if (buttonmask & ButtonPunch) {
|
|
|
|
|
button_event_punch_press (buttonmask&ButtonShift);
|
|
|
|
|
} else {
|
|
|
|
|
button_event_punch_release (buttonmask&ButtonShift);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (button_changes & ButtonLoop) {
|
|
|
|
|
if (buttonmask & ButtonLoop) {
|
|
|
|
|
button_event_loop_press (buttonmask&ButtonShift);
|
|
|
|
|
} else {
|
|
|
|
|
button_event_loop_release (buttonmask&ButtonShift);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (button_changes & ButtonPrev) {
|
|
|
|
|
if (buttonmask & ButtonPrev) {
|
|
|
|
|
button_event_prev_press (buttonmask&ButtonShift);
|
|
|
|
|
} else {
|
|
|
|
|
button_event_prev_release (buttonmask&ButtonShift);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (button_changes & ButtonAdd) {
|
|
|
|
|
if (buttonmask & ButtonAdd) {
|
|
|
|
|
button_event_add_press (buttonmask&ButtonShift);
|
|
|
|
|
} else {
|
|
|
|
|
button_event_add_release (buttonmask&ButtonShift);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (button_changes & ButtonNext) {
|
|
|
|
|
if (buttonmask & ButtonNext) {
|
|
|
|
|
button_event_next_press (buttonmask&ButtonShift);
|
|
|
|
|
} else {
|
|
|
|
|
button_event_next_release (buttonmask&ButtonShift);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (button_changes & ButtonRewind) {
|
|
|
|
|
if (buttonmask & ButtonRewind) {
|
|
|
|
|
button_event_rewind_press (buttonmask&ButtonShift);
|
|
|
|
|
} else {
|
|
|
|
|
button_event_rewind_release (buttonmask&ButtonShift);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (button_changes & ButtonFastForward) {
|
|
|
|
|
if (buttonmask & ButtonFastForward) {
|
|
|
|
|
button_event_fastforward_press (buttonmask&ButtonShift);
|
|
|
|
|
} else {
|
|
|
|
|
button_event_fastforward_release (buttonmask&ButtonShift);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (button_changes & ButtonStop) {
|
|
|
|
|
if (buttonmask & ButtonStop) {
|
|
|
|
|
button_event_stop_press (buttonmask&ButtonShift);
|
|
|
|
|
} else {
|
|
|
|
|
button_event_stop_release (buttonmask&ButtonShift);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (button_changes & ButtonPlay) {
|
|
|
|
|
if (buttonmask & ButtonPlay) {
|
|
|
|
|
button_event_play_press (buttonmask&ButtonShift);
|
|
|
|
|
} else {
|
|
|
|
|
button_event_play_release (buttonmask&ButtonShift);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (button_changes & ButtonRecord) {
|
|
|
|
|
if (buttonmask & ButtonRecord) {
|
|
|
|
|
button_event_record_press (buttonmask&ButtonShift);
|
|
|
|
|
} else {
|
|
|
|
|
button_event_record_release (buttonmask&ButtonShift);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
TranzportControlProtocol::show_current_track ()
|
|
|
|
|
{
|
2006-04-05 03:05:30 +00:00
|
|
|
for (vector<sigc::connection>::iterator i = track_connections.begin(); i != track_connections.end(); ++i) {
|
|
|
|
|
(*i).disconnect ();
|
|
|
|
|
}
|
|
|
|
|
track_connections.clear ();
|
|
|
|
|
|
2006-04-04 03:26:08 +00:00
|
|
|
if (current_route == 0) {
|
|
|
|
|
char buf[5];
|
2006-04-05 03:05:30 +00:00
|
|
|
lcd_write (0, "----");
|
|
|
|
|
lcd_write (1, "----");
|
2006-04-04 03:26:08 +00:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
string name = current_route->name();
|
|
|
|
|
|
2006-04-05 03:05:30 +00:00
|
|
|
memcpy (&next_screen[0][0], name.substr (0, 4).c_str(), 4);
|
|
|
|
|
memcpy (&next_screen[0][4], name.substr (4, 4).c_str(), 4);
|
|
|
|
|
|
|
|
|
|
track_solo_changed (0);
|
|
|
|
|
track_mute_changed (0);
|
|
|
|
|
track_rec_changed (0);
|
|
|
|
|
|
|
|
|
|
track_connections.push_back (current_route->solo_changed.connect (mem_fun (*this, &TranzportControlProtocol::track_solo_changed)));
|
|
|
|
|
track_connections.push_back (current_route->mute_changed.connect (mem_fun (*this, &TranzportControlProtocol::track_mute_changed)));
|
|
|
|
|
track_connections.push_back (current_route->record_enable_changed.connect (mem_fun (*this, &TranzportControlProtocol::track_rec_changed)));
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
TranzportControlProtocol::track_solo_changed (void* ignored)
|
|
|
|
|
{
|
|
|
|
|
if (current_route->soloed()) {
|
|
|
|
|
light_on (LightTracksolo);
|
|
|
|
|
} else {
|
|
|
|
|
light_off (LightTracksolo);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
TranzportControlProtocol::track_mute_changed (void *ignored)
|
|
|
|
|
{
|
|
|
|
|
if (current_route->muted()) {
|
|
|
|
|
light_on (LightTrackmute);
|
|
|
|
|
} else {
|
|
|
|
|
light_off (LightTrackmute);
|
|
|
|
|
}
|
2006-04-04 03:26:08 +00:00
|
|
|
}
|
2006-04-05 03:05:30 +00:00
|
|
|
|
|
|
|
|
void
|
|
|
|
|
TranzportControlProtocol::track_rec_changed (void *ignored)
|
|
|
|
|
{
|
|
|
|
|
if (current_route->record_enabled()) {
|
|
|
|
|
light_on (LightTrackrec);
|
|
|
|
|
} else {
|
|
|
|
|
light_off (LightTrackrec);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2006-04-04 03:26:08 +00:00
|
|
|
|
|
|
|
|
void
|
|
|
|
|
TranzportControlProtocol::button_event_battery_press (bool shifted)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
TranzportControlProtocol::button_event_battery_release (bool shifted)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
TranzportControlProtocol::button_event_backlight_press (bool shifted)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
TranzportControlProtocol::button_event_backlight_release (bool shifted)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
TranzportControlProtocol::button_event_trackleft_press (bool shifted)
|
|
|
|
|
{
|
|
|
|
|
if (current_track_id == 0) {
|
|
|
|
|
current_track_id = session.nroutes() - 1;
|
|
|
|
|
} else {
|
|
|
|
|
current_track_id--;
|
|
|
|
|
}
|
2006-04-05 03:05:30 +00:00
|
|
|
|
|
|
|
|
while (current_track_id >= 0) {
|
|
|
|
|
if ((current_route = session.route_by_remote_id (current_track_id)) != 0) {
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
current_track_id--;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (current_track_id < 0) {
|
|
|
|
|
current_track_id = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
cerr << "current track = " << current_track_id << " route = " << current_route << endl;
|
2006-04-04 03:26:08 +00:00
|
|
|
|
|
|
|
|
show_current_track ();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
TranzportControlProtocol::button_event_trackleft_release (bool shifted)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
TranzportControlProtocol::button_event_trackright_press (bool shifted)
|
|
|
|
|
{
|
2006-04-05 03:05:30 +00:00
|
|
|
uint32_t limit = session.nroutes();
|
|
|
|
|
|
|
|
|
|
if (current_track_id == limit) {
|
2006-04-04 03:26:08 +00:00
|
|
|
current_track_id = 0;
|
|
|
|
|
} else {
|
|
|
|
|
current_track_id++;
|
|
|
|
|
}
|
2006-04-05 03:05:30 +00:00
|
|
|
|
|
|
|
|
while (current_track_id < limit) {
|
|
|
|
|
if ((current_route = session.route_by_remote_id (current_track_id)) != 0) {
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
current_track_id++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (current_track_id == limit) {
|
|
|
|
|
current_track_id = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
cerr << "current track = " << current_track_id << " route = " << current_route;
|
|
|
|
|
if (current_route) {
|
|
|
|
|
cerr << ' ' << current_route->name();
|
|
|
|
|
}
|
|
|
|
|
cerr << endl;
|
2006-04-04 03:26:08 +00:00
|
|
|
show_current_track ();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
TranzportControlProtocol::button_event_trackright_release (bool shifted)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
TranzportControlProtocol::button_event_trackrec_press (bool shifted)
|
|
|
|
|
{
|
2006-04-05 03:05:30 +00:00
|
|
|
if (current_route) {
|
|
|
|
|
AudioTrack* at = dynamic_cast<AudioTrack*>(current_route);
|
|
|
|
|
at->set_record_enable (!at->record_enabled(), this);
|
|
|
|
|
}
|
2006-04-04 03:26:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
TranzportControlProtocol::button_event_trackrec_release (bool shifted)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
TranzportControlProtocol::button_event_trackmute_press (bool shifted)
|
|
|
|
|
{
|
2006-04-05 03:05:30 +00:00
|
|
|
if (current_route) {
|
|
|
|
|
current_route->set_mute (!current_route->muted(), this);
|
|
|
|
|
}
|
2006-04-04 03:26:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
TranzportControlProtocol::button_event_trackmute_release (bool shifted)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
TranzportControlProtocol::button_event_tracksolo_press (bool shifted)
|
|
|
|
|
{
|
2006-04-05 03:05:30 +00:00
|
|
|
if (current_route) {
|
|
|
|
|
current_route->set_solo (!current_route->soloed(), this);
|
|
|
|
|
}
|
2006-04-04 03:26:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
TranzportControlProtocol::button_event_tracksolo_release (bool shifted)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
TranzportControlProtocol::button_event_undo_press (bool shifted)
|
|
|
|
|
{
|
2006-04-05 03:05:30 +00:00
|
|
|
if (shifted) {
|
|
|
|
|
session.redo (1);
|
|
|
|
|
} else {
|
|
|
|
|
session.undo (1);
|
|
|
|
|
}
|
2006-04-04 03:26:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
TranzportControlProtocol::button_event_undo_release (bool shifted)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
TranzportControlProtocol::button_event_in_press (bool shifted)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
TranzportControlProtocol::button_event_in_release (bool shifted)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
TranzportControlProtocol::button_event_out_press (bool shifted)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
TranzportControlProtocol::button_event_out_release (bool shifted)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
TranzportControlProtocol::button_event_punch_press (bool shifted)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
TranzportControlProtocol::button_event_punch_release (bool shifted)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
TranzportControlProtocol::button_event_loop_press (bool shifted)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
TranzportControlProtocol::button_event_loop_release (bool shifted)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
TranzportControlProtocol::button_event_prev_press (bool shifted)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
TranzportControlProtocol::button_event_prev_release (bool shifted)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
TranzportControlProtocol::button_event_add_press (bool shifted)
|
|
|
|
|
{
|
2006-04-05 03:05:30 +00:00
|
|
|
jack_nframes_t when = session.audible_frame();
|
|
|
|
|
session.locations()->add (new Location (when, when, _("unnamed"), Location::IsMark));
|
2006-04-04 03:26:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
TranzportControlProtocol::button_event_add_release (bool shifted)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
TranzportControlProtocol::button_event_next_press (bool shifted)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
TranzportControlProtocol::button_event_next_release (bool shifted)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
TranzportControlProtocol::button_event_rewind_press (bool shifted)
|
|
|
|
|
{
|
2006-04-05 03:05:30 +00:00
|
|
|
if (shifted) {
|
|
|
|
|
session.goto_start ();
|
|
|
|
|
} else {
|
|
|
|
|
session.request_transport_speed (-2.0f);
|
|
|
|
|
}
|
2006-04-04 03:26:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
TranzportControlProtocol::button_event_rewind_release (bool shifted)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
TranzportControlProtocol::button_event_fastforward_press (bool shifted)
|
|
|
|
|
{
|
2006-04-05 03:05:30 +00:00
|
|
|
if (shifted) {
|
|
|
|
|
session.goto_end();
|
|
|
|
|
} else {
|
|
|
|
|
session.request_transport_speed (2.0f);}
|
2006-04-04 03:26:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
TranzportControlProtocol::button_event_fastforward_release (bool shifted)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
TranzportControlProtocol::button_event_stop_press (bool shifted)
|
|
|
|
|
{
|
|
|
|
|
session.request_transport_speed (0.0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
TranzportControlProtocol::button_event_stop_release (bool shifted)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
TranzportControlProtocol::button_event_play_press (bool shifted)
|
|
|
|
|
{
|
|
|
|
|
session.request_transport_speed (1.0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
TranzportControlProtocol::button_event_play_release (bool shifted)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
TranzportControlProtocol::button_event_record_press (bool shifted)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
TranzportControlProtocol::button_event_record_release (bool shifted)
|
|
|
|
|
{
|
|
|
|
|
}
|