13
0

Drop Frontier Tranzport surface - it has been dead for a decade

This commit is contained in:
Mads Kiilerich 2024-10-19 19:52:17 +02:00
parent 0d71876189
commit 38db12c9ea
66 changed files with 1 additions and 9438 deletions

View File

@ -623,7 +623,6 @@
osc open sound control osc open sound control
[use-plugin-own-gui] [use-plugin-own-gui]
plugins GUI editor prefer use own plugins GUI editor prefer use own
[use-tranzport]
[use-vst3] [use-vst3]
plugins vst3 plugins vst3
[use-windows-vst] [use-windows-vst]

View File

@ -89,8 +89,7 @@ CONFIG_VARIABLE (float, ltc_output_volume, "ltc-output-volume", 0.125893)
/* control surfaces */ /* control surfaces */
CONFIG_VARIABLE (uint32_t, feedback_interval_ms, "feedback-interval-ms", 100) CONFIG_VARIABLE (uint32_t, feedback_interval_ms, "feedback-interval-ms", 100)
CONFIG_VARIABLE (bool, use_tranzport, "use-tranzport", false)
CONFIG_VARIABLE (bool, auto_enable_surfaces, "auto-enable-surfaces", true) CONFIG_VARIABLE (bool, auto_enable_surfaces, "auto-enable-surfaces", true)
/* disk operations */ /* disk operations */

View File

@ -1,10 +0,0 @@
To build, type make
# make install and run
ir: install
rmmod tranzport
modprobe tranzport
# make install, run, and run tests
irt: ir

View File

@ -1,35 +0,0 @@
ifneq ($(KERNELRELEASE),)
obj-m := tranzport.o
tranzport-objs :=
else
KDIR := /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
MODDIR := $(DESTDIR)/lib/modules/$(shell uname -r)/kernel/sound/usb/misc
BINDIR := $(DESTDIR)/usr/local/bin
default::
$(MAKE) -Wall -C $(KDIR) SUBDIRS=$(PWD) modules
$(MAKE) -C tests
install-only:: default
mkdir -p $(MODDIR) $(BINDIR)
cp tranzport.ko $(MODDIR)
$(MAKE) -C tests install
install:: install-only
/sbin/depmod -a
+/sbin/rmmod tranzport
/sbin/modprobe tranzport
irt:: install
tranzport_tests.sh
clean::
rm -f core .*.cmd *.o *.ko *.mod.c Module.symvers *.bak .\#* *~
rm -rf .tmp_versions
$(MAKE) -C tests clean
endif

View File

@ -1,16 +0,0 @@
This directory contains the USB Tranzport Kernel driver for Linux.
At present it accepts reads/writes of 8 byte cmds to /dev/tranzport0 to control
the lights and screen.
Reads are possible. Wheel Compression does not currently account for button changes
It also has some sysfs hooks that are non-functional at the moment.
The API is closely tied to the ardour revision and WILL change.
A sysfs interface is PERFECT for simple userspace apps to do fun things with the
lights and screen. It's fairly lousy for handling input events and very lousy
for watching the state of the shuttle wheel.
In the end this is going to be driven by a midi layer

View File

@ -1,35 +0,0 @@
<HTML>
<HEAD>
<TITLE> TRANZPORT KEYCODES REFERENCE </TITLE>
</HEAD>
<BODY>
<H2> TRANZPORT KEYCODES REFERENCE </H2>
<H3>Footswitch</H3>
At least on every footswitch I've tried, the polarity appears to be wrong, in that the footswitch "up" position results
in 0100 being OR'd into the result. Pressing it down results in a 0, if no other keys are pressed. Releasing it results in 0100.
Every other key when up results in 0. This odd behavior would hopefully be controllable via a command to the tranzport,
but I don't have that, so dealing with footswitch events is weird.
So, seeing this bit enabled would be something like "HAVE_FOOTSWITCH INSTALLED", BE SMART ABOUT IT.
<H3>Special Key Combinations</H3>
<p>
In addition to the normal keycodes generated by the tranzport, it is possible to hit several combinations of keys and get a unique
result. Some are really weird. Perhaps the following assignments make sense:
</p><p>
<table><tr><th>PRESSING</th><th>RESULT</th><th>ASSIGNED TO</th></tr>
<tr><td>TRACKLEFT+TRACKRIGHT</td><td>TRACKLEFT+TRACKRIGHT</td><td>Master</td></tr>
<tr><td>SHIFT+TRACKLEFT+TRACKRIGHT</td><td>SHIFT+TRACKLEFT+TRACKRIGHT+UNDO</td><td>Show Bus Only Toggle</td></tr>
<tr><td>IN+OUT</td><td>IN+OUT</td><td>Zoom 100%</td></tr>
<tr><td>SHIFT+IN+OUT</td><td>SHIFT+IN+OUT+UNDO</td><td>Max Zoom</td></tr>
<tr><td>SHIFT+REW+FFW</td><td>SHIFT+REW+FFW+UNDO</td><td></td></tr>
<tr><td>RECORD+TRACKSOLO+FOOTSWITCHNOTDEPRESSED</td><td>RECORD+TRACKSOLO+BATTERY</td><td></td></tr>
<tr><td>PLAY+MUTE</td><td>PLAY+MUTE</td><td></td></tr>
</table>
</p>
</body>
</html>

View File

@ -1,23 +0,0 @@
# Some basic utilities for testing the tranzport's I/O
# eventually "tranzport" will become a flexible command
#
#
FILES:=tranzport tranzport_lights tranzport_tests.sh
BINDIR ?= $(DESTDIR)/usr/local/bin
all: tranzport tranzport_lights
tranzport: tranzport.c
gcc -g -Wall -o tranzport tranzport.c
tranzport_lights: tranzport_lights.c
gcc -g -Wall -o tranzport_lights tranzport_lights.c
clean::
rm -f core .*.cmd *.o *.ko *.mod.c Module.symvers *.bak .\#* *~
rm -rf .tmp_versions tranzport tranzport_lights
install::
cp $(FILES) $(BINDIR)

View File

@ -1,104 +0,0 @@
tranzport 0.1 <tranzport.sf.net>
oct 18, 2005
arthur@artcmusic.com
---
The Frontier Design Tranzport(tm) (www.frontierdesign.com) is a simple
wireless USB device. It is not a MIDI device. The document on their web
site "Tranzport(tm) Native Mode Interface Description" describes the
Tranzport(tm) as if it were a MIDI device, but this is implemented by their
Windows and Macintosh software drivers.
This code will allow you to use your Tranzport(tm) at a lower level of
abstraction. This code relies on libusb, which can be obtained from
libusb.sourceforge.net.
To compile the program, type "make". You should end up with a executable
called "tranzport". You'll probably have to run this program as root.
Using the program is straightforward. It will simply tell you which
buttons are being pressed and what not. If you press one of the buttons
with a light, the light will turn on. If you hold shift and press one of
the buttons with a light, the light will turn off. If you take out the
batteries to the device (or go out of range), it will tell you that the
device is offline. When you replace the batteries (or come back in
range), it should tell you it is back online.
Once you understand how everything works, you should be able to
incorporate it into your own setup however you wish.
This code was developed on a Linux machine, but (theoretically) it
should work on any system that is supported by libusb, since that is how
it communicates with the device.
Here are a few more details about the device:
There are two endpoints for communication with the device. All data
reads and writes are done in 8-byte segments.
One endpoint is for interrupt reads. This is used to read button data
from the device. It also supplies status information for when the device
goes out of range and comes back in range, loses power and regains
power, etc. The format of the data is:
00 ss bb bb bb bb dd 00 (hexadecimal)
where:
ss - status code, 01=online ff=offline
bb - button bits
dd - data wheel, 01-3f=forward 41-7f=backward
Please refer to the source code for a list of the button bits.
The other endpoint is for interrupt writes. This is used to toggle the
lights on the device, and to write data to the LCD.
There are 7 lights on the device. To turn a light on, send the following
sequence of bytes:
00 00 nn 01 00 00 00 00 (hexadecimal)
where nn is the light number.
To turn a light off:
00 00 nn 00 00 00 00 00 (hexadecimal)
Here is the list of lights:
00 Record
01 Track Rec
02 Track Mute
03 Track Solo
04 Any Solo
05 Loop
06 Punch
The size of the LCD is 20x2, and it is split into 10 cells, each cell
being 4 characters wide. The cells progress across, then down. To write
to the LCD, send the following sequence of bytes:
00 01 cc aa aa aa aa 00 (hexadecimal)
where:
cc - cell number
aa - ASCII code
Here is a list of the cells to clarify:
00 row 0, column 0-3
01 row 0, column 4-7
02 row 0, column 8-11
03 row 0, column 12-15
04 row 0, column 16-19
05 row 1, column 0-3
06 row 1, column 4-7
07 row 1, column 8-11
08 row 1, column 12-15
09 row 1, column 16-19
You should refer to the "Tranzport(tm) Native Mode Interface
Description" document for a listing of the ASCII codes the LCD uses.

View File

@ -1,375 +0,0 @@
/*
* tranzport 0.1 <tranzport.sf.net>
* oct 18, 2005
* arthur@artcmusic.com
*/
#include <stdarg.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <malloc.h>
#define VENDORID 0x165b
#define PRODUCTID 0x8101
#define READ_ENDPOINT 0x81
#define WRITE_ENDPOINT 0x02
enum {
LIGHT_RECORD = 0,
LIGHT_TRACKREC,
LIGHT_TRACKMUTE,
LIGHT_TRACKSOLO,
LIGHT_ANYSOLO,
LIGHT_LOOP,
LIGHT_PUNCH
};
#define BUTTONMASK_BATTERY 0x00004000
#define BUTTONMASK_BACKLIGHT 0x00008000
#define BUTTONMASK_TRACKLEFT 0x04000000
#define BUTTONMASK_TRACKRIGHT 0x40000000
#define BUTTONMASK_TRACKREC 0x00040000
#define BUTTONMASK_TRACKMUTE 0x00400000
#define BUTTONMASK_TRACKSOLO 0x00000400
#define BUTTONMASK_UNDO 0x80000000
#define BUTTONMASK_IN 0x02000000
#define BUTTONMASK_OUT 0x20000000
#define BUTTONMASK_PUNCH 0x00800000
#define BUTTONMASK_LOOP 0x00080000
#define BUTTONMASK_PREV 0x00020000
#define BUTTONMASK_ADD 0x00200000
#define BUTTONMASK_NEXT 0x00000200
#define BUTTONMASK_REWIND 0x01000000
#define BUTTONMASK_FASTFORWARD 0x10000000
#define BUTTONMASK_STOP 0x00010000
#define BUTTONMASK_PLAY 0x00100000
#define BUTTONMASK_RECORD 0x00000100
#define BUTTONMASK_SHIFT 0x08000000
#define STATUS_OFFLINE 0xff
#define STATUS_ONLINE 0x01
#define STATUS_OK 0x00
struct tranzport_s {
int *dev;
int udev;
};
typedef struct tranzport_s tranzport_t;
void log_entry(FILE *fp, char *format, va_list ap)
{
vfprintf(fp, format, ap);
fputc('\n', fp);
}
void log_error(char *format, ...)
{
va_list ap;
va_start(ap, format);
log_entry(stderr, format, ap);
va_end(ap);
}
void vlog_error(char *format, va_list ap)
{
log_entry(stderr, format, ap);
}
void die(char *format, ...)
{
va_list ap;
va_start(ap, format);
vlog_error(format, ap);
va_end(ap);
exit(1);
}
tranzport_t *open_tranzport_core()
{
tranzport_t *z;
int val;
z = malloc(sizeof(tranzport_t));
if (!z)
die("not enough memory");
memset(z, 0, sizeof(tranzport_t));
z->udev = open("/dev/tranzport0",O_RDWR);
if (z->udev < 1)
die("unable to open tranzport");
return z;
}
tranzport_t *open_tranzport()
{
return open_tranzport_core();
}
void close_tranzport(tranzport_t *z)
{
int val;
val = close(z->udev);
if (val < 0)
log_error("unable to release tranzport");
free(z);
}
int tranzport_write_core(tranzport_t *z, uint8_t *cmd, int timeout)
{
int val;
val = write(z->udev, cmd, 8);
if (val < 0)
return val;
if (val != 8)
return -1;
return 0;
}
int tranzport_lcdwrite(tranzport_t *z, uint8_t cell, char *text, int timeout)
{
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;
return tranzport_write_core(z, cmd, timeout);
}
int tranzport_lighton(tranzport_t *z, uint8_t light, int timeout)
{
uint8_t cmd[8];
cmd[0] = 0x00;
cmd[1] = 0x00;
cmd[2] = light;
cmd[3] = 0x01;
cmd[4] = 0x00;
cmd[5] = 0x00;
cmd[6] = 0x00;
cmd[7] = 0x00;
return tranzport_write_core(z, &cmd[0], timeout);
}
int tranzport_lightoff(tranzport_t *z, uint8_t light, int timeout)
{
uint8_t cmd[8];
cmd[0] = 0x00;
cmd[1] = 0x00;
cmd[2] = light;
cmd[3] = 0x00;
cmd[4] = 0x00;
cmd[5] = 0x00;
cmd[6] = 0x00;
cmd[7] = 0x00;
return tranzport_write_core(z, &cmd[0], timeout);
}
int tranzport_read(tranzport_t *z, uint8_t *status, uint32_t *buttons, uint8_t *datawheel, int timeout)
{
uint8_t buf[8];
int val;
memset(buf, 0xff, 8);
val = read(z->udev, buf, 8);
if (val < 0) {
printf("errno: %d\n",errno);
switch(errno) {
case ENOENT: ;
case ECONNRESET: ;
case ESHUTDOWN: printf("dying\n"); exit(1); break;
}
return val;
}
if (val != 8)
return -1;
/*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]);*/
*status = buf[1];
*buttons = 0;
*buttons |= buf[2] << 24;
*buttons |= buf[3] << 16;
*buttons |= buf[4] << 8;
*buttons |= buf[5];
*datawheel = buf[6];
return 0;
}
void lights_core(tranzport_t *z, uint32_t buttons, uint32_t buttonmask, uint8_t light)
{
if (buttons & buttonmask) {
if (buttons & BUTTONMASK_SHIFT) {
tranzport_lightoff(z, light, 10);
} else {
tranzport_lighton(z, light, 10);
}
}
}
void do_lights(tranzport_t *z, uint32_t buttons)
{
lights_core(z, buttons, BUTTONMASK_RECORD, LIGHT_RECORD);
lights_core(z, buttons, BUTTONMASK_TRACKREC, LIGHT_TRACKREC);
lights_core(z, buttons, BUTTONMASK_TRACKMUTE, LIGHT_TRACKMUTE);
lights_core(z, buttons, BUTTONMASK_TRACKSOLO, LIGHT_TRACKSOLO);
lights_core(z, buttons, BUTTONMASK_TRACKSOLO, LIGHT_ANYSOLO);
lights_core(z, buttons, BUTTONMASK_PUNCH, LIGHT_PUNCH);
lights_core(z, buttons, BUTTONMASK_LOOP, LIGHT_LOOP);
}
void buttons_core(tranzport_t *z, uint32_t buttons, uint32_t buttonmask, char *str)
{
if (buttons & buttonmask)
printf(" %s", str);
}
void do_buttons(tranzport_t *z, uint32_t buttons, uint8_t datawheel)
{
printf("buttons: %x ", buttons);
buttons_core(z, buttons, BUTTONMASK_BATTERY, "battery");
buttons_core(z, buttons, BUTTONMASK_BACKLIGHT, "backlight");
buttons_core(z, buttons, BUTTONMASK_TRACKLEFT, "trackleft");
buttons_core(z, buttons, BUTTONMASK_TRACKRIGHT, "trackright");
buttons_core(z, buttons, BUTTONMASK_TRACKREC, "trackrec");
buttons_core(z, buttons, BUTTONMASK_TRACKMUTE, "trackmute");
buttons_core(z, buttons, BUTTONMASK_TRACKSOLO, "tracksolo");
buttons_core(z, buttons, BUTTONMASK_UNDO, "undo");
buttons_core(z, buttons, BUTTONMASK_IN, "in");
buttons_core(z, buttons, BUTTONMASK_OUT, "out");
buttons_core(z, buttons, BUTTONMASK_PUNCH, "punch");
buttons_core(z, buttons, BUTTONMASK_LOOP, "loop");
buttons_core(z, buttons, BUTTONMASK_PREV, "prev");
buttons_core(z, buttons, BUTTONMASK_ADD, "add");
buttons_core(z, buttons, BUTTONMASK_NEXT, "next");
buttons_core(z, buttons, BUTTONMASK_REWIND, "rewind");
buttons_core(z, buttons, BUTTONMASK_FASTFORWARD, "fastforward");
buttons_core(z, buttons, BUTTONMASK_STOP, "stop");
buttons_core(z, buttons, BUTTONMASK_PLAY, "play");
buttons_core(z, buttons, BUTTONMASK_RECORD, "record");
buttons_core(z, buttons, BUTTONMASK_SHIFT, "shift");
if (datawheel)
printf(" datawheel=%02x", datawheel);
printf("\n");
}
void do_lcd(tranzport_t *z)
{
tranzport_lcdwrite(z, 0, " ", 10);
tranzport_lcdwrite(z, 1, "DISL", 10);
tranzport_lcdwrite(z, 2, "EXIA", 10);
tranzport_lcdwrite(z, 3, " FOR", 10);
tranzport_lcdwrite(z, 4, " ", 10);
tranzport_lcdwrite(z, 5, " ", 10);
tranzport_lcdwrite(z, 6, " CUR", 10);
tranzport_lcdwrite(z, 7, "E FO", 10);
tranzport_lcdwrite(z, 8, "UND ", 10);
tranzport_lcdwrite(z, 9, " ", 10);
}
void do_lcd2(tranzport_t *z)
{
tranzport_lcdwrite(z, 0, "THE ", 10);
tranzport_lcdwrite(z, 1, "TRAN", 10);
tranzport_lcdwrite(z, 2, "ZPOR", 10);
tranzport_lcdwrite(z, 3, "T RO", 10);
tranzport_lcdwrite(z, 4, " KS", 10);
tranzport_lcdwrite(z, 5, "AWES", 10);
tranzport_lcdwrite(z, 6, "OMEE", 10);
tranzport_lcdwrite(z, 7, "LEEE", 10);
tranzport_lcdwrite(z, 8, "UND ", 10);
tranzport_lcdwrite(z, 9, "GROK", 10);
}
int lights_off(tranzport_t *z) {
static int i = 0;
int j = 0;
for(;j<2; j++,i = (i+1) % 7) {
tranzport_lightoff(z, i, 10);
}
return 0;
}
int lights_on(tranzport_t *z) {
static int i = 0;
int j = 0;
for(;j<2; j++,i = (i+1) % 7) {
tranzport_lighton(z, i, 10);
}
return 0;
}
int main()
{
tranzport_t *z;
uint8_t status;
uint32_t buttons;
uint8_t datawheel;
int val;
z = open_tranzport();
do_lcd(z);
for(;;) {
// do_lcd(z);
lights_on(z);
// do_lcd2(z);
val = tranzport_read(z, &status, &buttons, &datawheel, 60000);
if (val < 0)
continue;
if (status == STATUS_OFFLINE) {
printf("offline: ");
continue;
}
if (status == STATUS_ONLINE) {
printf("online: ");
do_lcd(z);
}
if (status == STATUS_OK) {
printf("OK: ");
do_lcd(z);
}
// do_lights(z, buttons);
do_buttons(z, buttons, datawheel);
lights_off(z);
}
close_tranzport(z);
return 0;
}

View File

@ -1,361 +0,0 @@
/*
* tranzport 0.1 <tranzport.sf.net>
* oct 18, 2005
* arthur@artcmusic.com
*/
#include <stdarg.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <malloc.h>
#define VENDORID 0x165b
#define PRODUCTID 0x8101
#define READ_ENDPOINT 0x81
#define WRITE_ENDPOINT 0x02
enum {
LIGHT_RECORD = 0,
LIGHT_TRACKREC,
LIGHT_TRACKMUTE,
LIGHT_TRACKSOLO,
LIGHT_ANYSOLO,
LIGHT_LOOP,
LIGHT_PUNCH
};
#define BUTTONMASK_BATTERY 0x00004000
#define BUTTONMASK_BACKLIGHT 0x00008000
#define BUTTONMASK_TRACKLEFT 0x04000000
#define BUTTONMASK_TRACKRIGHT 0x40000000
#define BUTTONMASK_TRACKREC 0x00040000
#define BUTTONMASK_TRACKMUTE 0x00400000
#define BUTTONMASK_TRACKSOLO 0x00000400
#define BUTTONMASK_UNDO 0x80000000
#define BUTTONMASK_IN 0x02000000
#define BUTTONMASK_OUT 0x20000000
#define BUTTONMASK_PUNCH 0x00800000
#define BUTTONMASK_LOOP 0x00080000
#define BUTTONMASK_PREV 0x00020000
#define BUTTONMASK_ADD 0x00200000
#define BUTTONMASK_NEXT 0x00000200
#define BUTTONMASK_REWIND 0x01000000
#define BUTTONMASK_FASTFORWARD 0x10000000
#define BUTTONMASK_STOP 0x00010000
#define BUTTONMASK_PLAY 0x00100000
#define BUTTONMASK_RECORD 0x00000100
#define BUTTONMASK_SHIFT 0x08000000
#define STATUS_OFFLINE 0xff
#define STATUS_ONLINE 0x01
#define STATUS_OK 0x00
struct tranzport_s {
int *dev;
int udev;
};
typedef struct tranzport_s tranzport_t;
void log_entry(FILE *fp, char *format, va_list ap)
{
vfprintf(fp, format, ap);
fputc('\n', fp);
}
void log_error(char *format, ...)
{
va_list ap;
va_start(ap, format);
log_entry(stderr, format, ap);
va_end(ap);
}
void vlog_error(char *format, va_list ap)
{
log_entry(stderr, format, ap);
}
void die(char *format, ...)
{
va_list ap;
va_start(ap, format);
vlog_error(format, ap);
va_end(ap);
exit(1);
}
tranzport_t *open_tranzport_core()
{
tranzport_t *z;
int val;
z = malloc(sizeof(tranzport_t));
if (!z)
die("not enough memory");
memset(z, 0, sizeof(tranzport_t));
z->udev = open("/dev/tranzport0",O_RDWR);
if (!z->udev)
die("unable to open tranzport");
return z;
}
tranzport_t *open_tranzport()
{
return open_tranzport_core();
}
void close_tranzport(tranzport_t *z)
{
int val;
val = close(z->udev);
if (val < 0)
log_error("unable to release tranzport");
free(z);
}
int tranzport_write_core(tranzport_t *z, uint8_t *cmd, int timeout)
{
int val;
val = write(z->udev, cmd, 8);
if (val < 0)
return val;
if (val != 8)
return -1;
return 0;
}
int tranzport_lcdwrite(tranzport_t *z, uint8_t cell, char *text, int timeout)
{
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;
return tranzport_write_core(z, cmd, timeout);
}
int tranzport_lighton(tranzport_t *z, uint8_t light, int timeout)
{
uint8_t cmd[8];
cmd[0] = 0x00;
cmd[1] = 0x00;
cmd[2] = light;
cmd[3] = 0x01;
cmd[4] = 0x00;
cmd[5] = 0x00;
cmd[6] = 0x00;
cmd[7] = 0x00;
return tranzport_write_core(z, &cmd[0], timeout);
}
int tranzport_lightoff(tranzport_t *z, uint8_t light, int timeout)
{
uint8_t cmd[8];
cmd[0] = 0x00;
cmd[1] = 0x00;
cmd[2] = light;
cmd[3] = 0x00;
cmd[4] = 0x00;
cmd[5] = 0x00;
cmd[6] = 0x00;
cmd[7] = 0x00;
return tranzport_write_core(z, &cmd[0], timeout);
}
int tranzport_read(tranzport_t *z, uint8_t *status, uint32_t *buttons, uint8_t *datawheel, int timeout)
{
uint8_t buf[8];
int val;
memset(buf, 0xff, 8);
val = read(z->udev, buf, 8);
if (val < 0) {
// printf("errno: %d\n",errno);
return val;
}
if (val != 8)
return -1;
/*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]);*/
*status = buf[1];
*buttons = 0;
*buttons |= buf[2] << 24;
*buttons |= buf[3] << 16;
*buttons |= buf[4] << 8;
*buttons |= buf[5];
*datawheel = buf[6];
return 0;
}
void lights_core(tranzport_t *z, uint32_t buttons, uint32_t buttonmask, uint8_t light)
{
if (buttons & buttonmask) {
if (buttons & BUTTONMASK_SHIFT) {
tranzport_lightoff(z, light, 1000);
} else {
tranzport_lighton(z, light, 1000);
}
}
}
void do_lights(tranzport_t *z, uint32_t buttons)
{
lights_core(z, buttons, BUTTONMASK_RECORD, LIGHT_RECORD);
lights_core(z, buttons, BUTTONMASK_TRACKREC, LIGHT_TRACKREC);
lights_core(z, buttons, BUTTONMASK_TRACKMUTE, LIGHT_TRACKMUTE);
lights_core(z, buttons, BUTTONMASK_TRACKSOLO, LIGHT_TRACKSOLO);
lights_core(z, buttons, BUTTONMASK_TRACKSOLO, LIGHT_ANYSOLO);
lights_core(z, buttons, BUTTONMASK_PUNCH, LIGHT_PUNCH);
lights_core(z, buttons, BUTTONMASK_LOOP, LIGHT_LOOP);
}
void buttons_core(tranzport_t *z, uint32_t buttons, uint32_t buttonmask, char *str)
{
if (buttons & buttonmask)
printf(" %s", str);
}
void do_buttons(tranzport_t *z, uint32_t buttons, uint8_t datawheel)
{
printf("buttons: %x ", buttons);
buttons_core(z, buttons, BUTTONMASK_BATTERY, "battery");
buttons_core(z, buttons, BUTTONMASK_BACKLIGHT, "backlight");
buttons_core(z, buttons, BUTTONMASK_TRACKLEFT, "trackleft");
buttons_core(z, buttons, BUTTONMASK_TRACKRIGHT, "trackright");
buttons_core(z, buttons, BUTTONMASK_TRACKREC, "trackrec");
buttons_core(z, buttons, BUTTONMASK_TRACKMUTE, "trackmute");
buttons_core(z, buttons, BUTTONMASK_TRACKSOLO, "tracksolo");
buttons_core(z, buttons, BUTTONMASK_UNDO, "undo");
buttons_core(z, buttons, BUTTONMASK_IN, "in");
buttons_core(z, buttons, BUTTONMASK_OUT, "out");
buttons_core(z, buttons, BUTTONMASK_PUNCH, "punch");
buttons_core(z, buttons, BUTTONMASK_LOOP, "loop");
buttons_core(z, buttons, BUTTONMASK_PREV, "prev");
buttons_core(z, buttons, BUTTONMASK_ADD, "add");
buttons_core(z, buttons, BUTTONMASK_NEXT, "next");
buttons_core(z, buttons, BUTTONMASK_REWIND, "rewind");
buttons_core(z, buttons, BUTTONMASK_FASTFORWARD, "fastforward");
buttons_core(z, buttons, BUTTONMASK_STOP, "stop");
buttons_core(z, buttons, BUTTONMASK_PLAY, "play");
buttons_core(z, buttons, BUTTONMASK_RECORD, "record");
buttons_core(z, buttons, BUTTONMASK_SHIFT, "shift");
if (datawheel)
printf(" datawheel=%02x", datawheel);
printf("\n");
}
void do_lcd(tranzport_t *z)
{
tranzport_lcdwrite(z, 0, " ", 1000);
tranzport_lcdwrite(z, 1, "DISL", 1000);
tranzport_lcdwrite(z, 2, "EXIA", 1000);
tranzport_lcdwrite(z, 3, " FOR", 1000);
tranzport_lcdwrite(z, 4, " ", 1000);
tranzport_lcdwrite(z, 5, " ", 1000);
tranzport_lcdwrite(z, 6, " CUR", 1000);
tranzport_lcdwrite(z, 7, "E FO", 1000);
tranzport_lcdwrite(z, 8, "UND ", 1000);
tranzport_lcdwrite(z, 9, " ", 1000);
}
void do_lcd2(tranzport_t *z)
{
tranzport_lcdwrite(z, 0, "THE ", 1000);
tranzport_lcdwrite(z, 1, "TRAN", 1000);
tranzport_lcdwrite(z, 2, "ZPOR", 1000);
tranzport_lcdwrite(z, 3, "T RO", 1000);
tranzport_lcdwrite(z, 4, "KS ", 1000);
tranzport_lcdwrite(z, 5, "AWES", 1000);
tranzport_lcdwrite(z, 6, "OMEE", 1000);
tranzport_lcdwrite(z, 7, "LEEE", 1000);
tranzport_lcdwrite(z, 8, "WITH", 1000);
tranzport_lcdwrite(z, 9, "ARDO", 1000);
}
lights_off(tranzport_t *z) {
int i;
for(i=0;i<7;i++) {
tranzport_lightoff(z, i, 1000);
}
}
lights_on(tranzport_t *z) {
int i;
for(i=0;i<7;i++) {
tranzport_lighton(z, i, 1000);
}
}
int main()
{
tranzport_t *z;
uint8_t status;
uint32_t buttons;
uint8_t datawheel;
int val;
z = open_tranzport();
do_lcd(z);
for(;;) {
do_lcd(z);
lights_on(z);
do_lcd2(z);
lights_off(z);
// val = tranzport_read(z, &status, &buttons, &datawheel, 60000);
val = -1;
if (val < 0)
continue;
if (status == STATUS_OFFLINE) {
printf("offline: ");
continue;
}
if (status == STATUS_ONLINE) {
printf("online: ");
do_lcd(z);
}
do_lights(z, buttons);
do_buttons(z, buttons, datawheel);
}
close_tranzport(z);
return 0;
}

View File

@ -1,27 +0,0 @@
#!/bin/sh
echo "Testing lights"
tranzport_lights &
A=$!
sleep 30
kill $A
echo "Testing interleaved_reads/writes"
tranzport &
A=$!
sleep 30
kill $A
exit 0
# not done yet
echo "Testing_screen"
tranzport_screen &
A=$!
sleep 30
kill $A
echo "Testing_reads"
tranzport_read &
A=$!
sleep 30
kill $A

File diff suppressed because it is too large Load Diff

View File

@ -1,17 +0,0 @@
# Some basic utilities for testing the tranzport's I/O
# eventually "tranzport" will become a flexible command
#
#
all: tranzport tranzport_lights
tranzport: tranzport.c
gcc -g -Wall -o tranzport tranzport.c
tranzport_lights: tranzport_lights.c
gcc -g -Wall -o tranzport_lights tranzport_lights.c
clean::
rm -f core .*.cmd *.o *.ko *.mod.c Module.symvers *.bak .\#* *~
rm -rf .tmp_versions tranzport tranzport_lights

View File

@ -1,104 +0,0 @@
tranzport 0.1 <tranzport.sf.net>
oct 18, 2005
arthur@artcmusic.com
---
The Frontier Design Tranzport(tm) (www.frontierdesign.com) is a simple
wireless USB device. It is not a MIDI device. The document on their web
site "Tranzport(tm) Native Mode Interface Description" describes the
Tranzport(tm) as if it were a MIDI device, but this is implemented by their
Windows and Macintosh software drivers.
This code will allow you to use your Tranzport(tm) at a lower level of
abstraction. This code relies on libusb, which can be obtained from
libusb.sourceforge.net.
To compile the program, type "make". You should end up with a executable
called "tranzport". You'll probably have to run this program as root.
Using the program is straightforward. It will simply tell you which
buttons are being pressed and what not. If you press one of the buttons
with a light, the light will turn on. If you hold shift and press one of
the buttons with a light, the light will turn off. If you take out the
batteries to the device (or go out of range), it will tell you that the
device is offline. When you replace the batteries (or come back in
range), it should tell you it is back online.
Once you understand how everything works, you should be able to
incorporate it into your own setup however you wish.
This code was developed on a Linux machine, but (theoretically) it
should work on any system that is supported by libusb, since that is how
it communicates with the device.
Here are a few more details about the device:
There are two endpoints for communication with the device. All data
reads and writes are done in 8-byte segments.
One endpoint is for interrupt reads. This is used to read button data
from the device. It also supplies status information for when the device
goes out of range and comes back in range, loses power and regains
power, etc. The format of the data is:
00 ss bb bb bb bb dd 00 (hexadecimal)
where:
ss - status code, 01=online ff=offline
bb - button bits
dd - data wheel, 01-3f=forward 41-7f=backward
Please refer to the source code for a list of the button bits.
The other endpoint is for interrupt writes. This is used to toggle the
lights on the device, and to write data to the LCD.
There are 7 lights on the device. To turn a light on, send the following
sequence of bytes:
00 00 nn 01 00 00 00 00 (hexadecimal)
where nn is the light number.
To turn a light off:
00 00 nn 00 00 00 00 00 (hexadecimal)
Here is the list of lights:
00 Record
01 Track Rec
02 Track Mute
03 Track Solo
04 Any Solo
05 Loop
06 Punch
The size of the LCD is 20x2, and it is split into 10 cells, each cell
being 4 characters wide. The cells progress across, then down. To write
to the LCD, send the following sequence of bytes:
00 01 cc aa aa aa aa 00 (hexadecimal)
where:
cc - cell number
aa - ASCII code
Here is a list of the cells to clarify:
00 row 0, column 0-3
01 row 0, column 4-7
02 row 0, column 8-11
03 row 0, column 12-15
04 row 0, column 16-19
05 row 1, column 0-3
06 row 1, column 4-7
07 row 1, column 8-11
08 row 1, column 12-15
09 row 1, column 16-19
You should refer to the "Tranzport(tm) Native Mode Interface
Description" document for a listing of the ASCII codes the LCD uses.

View File

@ -1,347 +0,0 @@
/*
* tranzport 0.1 <tranzport.sf.net>
* oct 18, 2005
* arthur@artcmusic.com
*/
#include <stdarg.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <usb.h>
#define VENDORID 0x165b
#define PRODUCTID 0x8101
#define READ_ENDPOINT 0x81
#define WRITE_ENDPOINT 0x02
enum {
LIGHT_RECORD = 0,
LIGHT_TRACKREC,
LIGHT_TRACKMUTE,
LIGHT_TRACKSOLO,
LIGHT_ANYSOLO,
LIGHT_LOOP,
LIGHT_PUNCH
};
#define BUTTONMASK_BATTERY 0x00004000
#define BUTTONMASK_BACKLIGHT 0x00008000
#define BUTTONMASK_TRACKLEFT 0x04000000
#define BUTTONMASK_TRACKRIGHT 0x40000000
#define BUTTONMASK_TRACKREC 0x00040000
#define BUTTONMASK_TRACKMUTE 0x00400000
#define BUTTONMASK_TRACKSOLO 0x00000400
#define BUTTONMASK_UNDO 0x80000000
#define BUTTONMASK_IN 0x02000000
#define BUTTONMASK_OUT 0x20000000
#define BUTTONMASK_PUNCH 0x00800000
#define BUTTONMASK_LOOP 0x00080000
#define BUTTONMASK_PREV 0x00020000
#define BUTTONMASK_ADD 0x00200000
#define BUTTONMASK_NEXT 0x00000200
#define BUTTONMASK_REWIND 0x01000000
#define BUTTONMASK_FASTFORWARD 0x10000000
#define BUTTONMASK_STOP 0x00010000
#define BUTTONMASK_PLAY 0x00100000
#define BUTTONMASK_RECORD 0x00000100
#define BUTTONMASK_SHIFT 0x08000000
#define STATUS_OFFLINE 0xff
#define STATUS_ONLINE 0x01
struct tranzport_s {
struct usb_device *dev;
usb_dev_handle *udev;
};
typedef struct tranzport_s tranzport_t;
void log_entry(FILE *fp, char *format, va_list ap)
{
vfprintf(fp, format, ap);
fputc('\n', fp);
}
void log_error(char *format, ...)
{
va_list ap;
va_start(ap, format);
log_entry(stderr, format, ap);
va_end(ap);
}
void vlog_error(char *format, va_list ap)
{
log_entry(stderr, format, ap);
}
void die(char *format, ...)
{
va_list ap;
va_start(ap, format);
vlog_error(format, ap);
va_end(ap);
exit(1);
}
tranzport_t *open_tranzport_core(struct usb_device *dev)
{
tranzport_t *z;
int val;
z = malloc(sizeof(tranzport_t));
if (!z)
die("not enough memory");
memset(z, 0, sizeof(tranzport_t));
z->dev = dev;
z->udev = usb_open(z->dev);
if (!z->udev)
die("unable to open tranzport");
val = usb_claim_interface(z->udev, 0);
if (val < 0)
die("unable to claim tranzport");
return z;
}
tranzport_t *open_tranzport()
{
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_tranzport_core(dev);
}
}
die("can't find tranzport");
return 0;
}
void close_tranzport(tranzport_t *z)
{
int val;
val = usb_release_interface(z->udev, 0);
if (val < 0)
log_error("unable to release tranzport");
val = usb_close(z->udev);
if (val < 0)
log_error("unable to close tranzport");
free(z);
}
int tranzport_write_core(tranzport_t *z, uint8_t *cmd, int timeout)
{
int val;
val = usb_interrupt_write(z->udev, WRITE_ENDPOINT, cmd, 8, timeout);
if (val < 0)
return val;
if (val != 8)
return -1;
return 0;
}
int tranzport_lcdwrite(tranzport_t *z, uint8_t cell, char *text, int timeout)
{
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;
return tranzport_write_core(z, cmd, timeout);
}
int tranzport_lighton(tranzport_t *z, uint8_t light, int timeout)
{
uint8_t cmd[8];
cmd[0] = 0x00;
cmd[1] = 0x00;
cmd[2] = light;
cmd[3] = 0x01;
cmd[4] = 0x00;
cmd[5] = 0x00;
cmd[6] = 0x00;
cmd[7] = 0x00;
return tranzport_write_core(z, cmd, timeout);
}
int tranzport_lightoff(tranzport_t *z, uint8_t light, int timeout)
{
uint8_t cmd[8];
cmd[0] = 0x00;
cmd[1] = 0x00;
cmd[2] = light;
cmd[3] = 0x00;
cmd[4] = 0x00;
cmd[5] = 0x00;
cmd[6] = 0x00;
cmd[7] = 0x00;
return tranzport_write_core(z, cmd, timeout);
}
int tranzport_read(tranzport_t *z, uint8_t *status, uint32_t *buttons, uint8_t *datawheel, int timeout)
{
uint8_t buf[8];
int val;
memset(buf, 0, 8);
val = usb_interrupt_read(z->udev, READ_ENDPOINT, buf, 8, timeout);
if (val < 0)
return val;
if (val != 8)
return -1;
/*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]);*/
*status = buf[1];
*buttons = 0;
*buttons |= buf[2] << 24;
*buttons |= buf[3] << 16;
*buttons |= buf[4] << 8;
*buttons |= buf[5];
*datawheel = buf[6];
return 0;
}
void lights_core(tranzport_t *z, uint32_t buttons, uint32_t buttonmask, uint8_t light)
{
if (buttons & buttonmask) {
if (buttons & BUTTONMASK_SHIFT) {
tranzport_lightoff(z, light, 1000);
} else {
tranzport_lighton(z, light, 1000);
}
}
}
void do_lights(tranzport_t *z, uint32_t buttons)
{
lights_core(z, buttons, BUTTONMASK_RECORD, LIGHT_RECORD);
lights_core(z, buttons, BUTTONMASK_TRACKREC, LIGHT_TRACKREC);
lights_core(z, buttons, BUTTONMASK_TRACKMUTE, LIGHT_TRACKMUTE);
lights_core(z, buttons, BUTTONMASK_TRACKSOLO, LIGHT_TRACKSOLO);
lights_core(z, buttons, BUTTONMASK_TRACKSOLO, LIGHT_ANYSOLO);
lights_core(z, buttons, BUTTONMASK_PUNCH, LIGHT_PUNCH);
lights_core(z, buttons, BUTTONMASK_LOOP, LIGHT_LOOP);
}
void buttons_core(tranzport_t *z, uint32_t buttons, uint32_t buttonmask, char *str)
{
if (buttons & buttonmask)
printf(" %s", str);
}
void do_buttons(tranzport_t *z, uint32_t buttons, uint8_t datawheel)
{
printf("buttons:");
buttons_core(z, buttons, BUTTONMASK_BATTERY, "battery");
buttons_core(z, buttons, BUTTONMASK_BACKLIGHT, "backlight");
buttons_core(z, buttons, BUTTONMASK_TRACKLEFT, "trackleft");
buttons_core(z, buttons, BUTTONMASK_TRACKRIGHT, "trackright");
buttons_core(z, buttons, BUTTONMASK_TRACKREC, "trackrec");
buttons_core(z, buttons, BUTTONMASK_TRACKMUTE, "trackmute");
buttons_core(z, buttons, BUTTONMASK_TRACKSOLO, "tracksolo");
buttons_core(z, buttons, BUTTONMASK_UNDO, "undo");
buttons_core(z, buttons, BUTTONMASK_IN, "in");
buttons_core(z, buttons, BUTTONMASK_OUT, "out");
buttons_core(z, buttons, BUTTONMASK_PUNCH, "punch");
buttons_core(z, buttons, BUTTONMASK_LOOP, "loop");
buttons_core(z, buttons, BUTTONMASK_PREV, "prev");
buttons_core(z, buttons, BUTTONMASK_ADD, "add");
buttons_core(z, buttons, BUTTONMASK_NEXT, "next");
buttons_core(z, buttons, BUTTONMASK_REWIND, "rewind");
buttons_core(z, buttons, BUTTONMASK_FASTFORWARD, "fastforward");
buttons_core(z, buttons, BUTTONMASK_STOP, "stop");
buttons_core(z, buttons, BUTTONMASK_PLAY, "play");
buttons_core(z, buttons, BUTTONMASK_RECORD, "record");
buttons_core(z, buttons, BUTTONMASK_SHIFT, "shift");
if (datawheel)
printf(" datawheel=%02x", datawheel);
printf("\n");
}
void do_lcd(tranzport_t *z)
{
tranzport_lcdwrite(z, 0, " ", 1000);
tranzport_lcdwrite(z, 1, "DISL", 1000);
tranzport_lcdwrite(z, 2, "EXIA", 1000);
tranzport_lcdwrite(z, 3, " FOR", 1000);
tranzport_lcdwrite(z, 4, " ", 1000);
tranzport_lcdwrite(z, 5, " ", 1000);
tranzport_lcdwrite(z, 6, " CUR", 1000);
tranzport_lcdwrite(z, 7, "E FO", 1000);
tranzport_lcdwrite(z, 8, "UND ", 1000);
tranzport_lcdwrite(z, 9, " ", 1000);
}
int main()
{
tranzport_t *z;
uint8_t status;
uint32_t buttons;
uint8_t datawheel;
int val;
z = open_tranzport();
do_lcd(z);
for(;;) {
val = tranzport_read(z, &status, &buttons, &datawheel, 60000);
if (val < 0)
continue;
if (status == STATUS_OFFLINE) {
printf("offline\n");
continue;
}
if (status == STATUS_ONLINE) {
printf("online\n");
do_lcd(z);
}
do_lights(z, buttons);
do_buttons(z, buttons, datawheel);
}
close_tranzport(z);
return 0;
}

View File

@ -1,361 +0,0 @@
/*
* tranzport 0.1 <tranzport.sf.net>
* oct 18, 2005
* arthur@artcmusic.com
*/
#include <stdarg.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <malloc.h>
#define VENDORID 0x165b
#define PRODUCTID 0x8101
#define READ_ENDPOINT 0x81
#define WRITE_ENDPOINT 0x02
enum {
LIGHT_RECORD = 0,
LIGHT_TRACKREC,
LIGHT_TRACKMUTE,
LIGHT_TRACKSOLO,
LIGHT_ANYSOLO,
LIGHT_LOOP,
LIGHT_PUNCH
};
#define BUTTONMASK_BATTERY 0x00004000
#define BUTTONMASK_BACKLIGHT 0x00008000
#define BUTTONMASK_TRACKLEFT 0x04000000
#define BUTTONMASK_TRACKRIGHT 0x40000000
#define BUTTONMASK_TRACKREC 0x00040000
#define BUTTONMASK_TRACKMUTE 0x00400000
#define BUTTONMASK_TRACKSOLO 0x00000400
#define BUTTONMASK_UNDO 0x80000000
#define BUTTONMASK_IN 0x02000000
#define BUTTONMASK_OUT 0x20000000
#define BUTTONMASK_PUNCH 0x00800000
#define BUTTONMASK_LOOP 0x00080000
#define BUTTONMASK_PREV 0x00020000
#define BUTTONMASK_ADD 0x00200000
#define BUTTONMASK_NEXT 0x00000200
#define BUTTONMASK_REWIND 0x01000000
#define BUTTONMASK_FASTFORWARD 0x10000000
#define BUTTONMASK_STOP 0x00010000
#define BUTTONMASK_PLAY 0x00100000
#define BUTTONMASK_RECORD 0x00000100
#define BUTTONMASK_SHIFT 0x08000000
#define STATUS_OFFLINE 0xff
#define STATUS_ONLINE 0x01
#define STATUS_OK 0x00
struct tranzport_s {
int *dev;
int udev;
};
typedef struct tranzport_s tranzport_t;
void log_entry(FILE *fp, char *format, va_list ap)
{
vfprintf(fp, format, ap);
fputc('\n', fp);
}
void log_error(char *format, ...)
{
va_list ap;
va_start(ap, format);
log_entry(stderr, format, ap);
va_end(ap);
}
void vlog_error(char *format, va_list ap)
{
log_entry(stderr, format, ap);
}
void die(char *format, ...)
{
va_list ap;
va_start(ap, format);
vlog_error(format, ap);
va_end(ap);
exit(1);
}
tranzport_t *open_tranzport_core()
{
tranzport_t *z;
int val;
z = malloc(sizeof(tranzport_t));
if (!z)
die("not enough memory");
memset(z, 0, sizeof(tranzport_t));
z->udev = open("/dev/tranzport0",O_RDWR);
if (!z->udev)
die("unable to open tranzport");
return z;
}
tranzport_t *open_tranzport()
{
return open_tranzport_core();
}
void close_tranzport(tranzport_t *z)
{
int val;
val = close(z->udev);
if (val < 0)
log_error("unable to release tranzport");
free(z);
}
int tranzport_write_core(tranzport_t *z, uint8_t *cmd, int timeout)
{
int val;
val = write(z->udev, cmd, 8);
if (val < 0)
return val;
if (val != 8)
return -1;
return 0;
}
int tranzport_lcdwrite(tranzport_t *z, uint8_t cell, char *text, int timeout)
{
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;
return tranzport_write_core(z, cmd, timeout);
}
int tranzport_lighton(tranzport_t *z, uint8_t light, int timeout)
{
uint8_t cmd[8];
cmd[0] = 0x00;
cmd[1] = 0x00;
cmd[2] = light;
cmd[3] = 0x01;
cmd[4] = 0x00;
cmd[5] = 0x00;
cmd[6] = 0x00;
cmd[7] = 0x00;
return tranzport_write_core(z, &cmd[0], timeout);
}
int tranzport_lightoff(tranzport_t *z, uint8_t light, int timeout)
{
uint8_t cmd[8];
cmd[0] = 0x00;
cmd[1] = 0x00;
cmd[2] = light;
cmd[3] = 0x00;
cmd[4] = 0x00;
cmd[5] = 0x00;
cmd[6] = 0x00;
cmd[7] = 0x00;
return tranzport_write_core(z, &cmd[0], timeout);
}
int tranzport_read(tranzport_t *z, uint8_t *status, uint32_t *buttons, uint8_t *datawheel, int timeout)
{
uint8_t buf[8];
int val;
memset(buf, 0xff, 8);
val = read(z->udev, buf, 8);
if (val < 0) {
// printf("errno: %d\n",errno);
return val;
}
if (val != 8)
return -1;
/*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]);*/
*status = buf[1];
*buttons = 0;
*buttons |= buf[2] << 24;
*buttons |= buf[3] << 16;
*buttons |= buf[4] << 8;
*buttons |= buf[5];
*datawheel = buf[6];
return 0;
}
void lights_core(tranzport_t *z, uint32_t buttons, uint32_t buttonmask, uint8_t light)
{
if (buttons & buttonmask) {
if (buttons & BUTTONMASK_SHIFT) {
tranzport_lightoff(z, light, 1000);
} else {
tranzport_lighton(z, light, 1000);
}
}
}
void do_lights(tranzport_t *z, uint32_t buttons)
{
lights_core(z, buttons, BUTTONMASK_RECORD, LIGHT_RECORD);
lights_core(z, buttons, BUTTONMASK_TRACKREC, LIGHT_TRACKREC);
lights_core(z, buttons, BUTTONMASK_TRACKMUTE, LIGHT_TRACKMUTE);
lights_core(z, buttons, BUTTONMASK_TRACKSOLO, LIGHT_TRACKSOLO);
lights_core(z, buttons, BUTTONMASK_TRACKSOLO, LIGHT_ANYSOLO);
lights_core(z, buttons, BUTTONMASK_PUNCH, LIGHT_PUNCH);
lights_core(z, buttons, BUTTONMASK_LOOP, LIGHT_LOOP);
}
void buttons_core(tranzport_t *z, uint32_t buttons, uint32_t buttonmask, char *str)
{
if (buttons & buttonmask)
printf(" %s", str);
}
void do_buttons(tranzport_t *z, uint32_t buttons, uint8_t datawheel)
{
printf("buttons: %x ", buttons);
buttons_core(z, buttons, BUTTONMASK_BATTERY, "battery");
buttons_core(z, buttons, BUTTONMASK_BACKLIGHT, "backlight");
buttons_core(z, buttons, BUTTONMASK_TRACKLEFT, "trackleft");
buttons_core(z, buttons, BUTTONMASK_TRACKRIGHT, "trackright");
buttons_core(z, buttons, BUTTONMASK_TRACKREC, "trackrec");
buttons_core(z, buttons, BUTTONMASK_TRACKMUTE, "trackmute");
buttons_core(z, buttons, BUTTONMASK_TRACKSOLO, "tracksolo");
buttons_core(z, buttons, BUTTONMASK_UNDO, "undo");
buttons_core(z, buttons, BUTTONMASK_IN, "in");
buttons_core(z, buttons, BUTTONMASK_OUT, "out");
buttons_core(z, buttons, BUTTONMASK_PUNCH, "punch");
buttons_core(z, buttons, BUTTONMASK_LOOP, "loop");
buttons_core(z, buttons, BUTTONMASK_PREV, "prev");
buttons_core(z, buttons, BUTTONMASK_ADD, "add");
buttons_core(z, buttons, BUTTONMASK_NEXT, "next");
buttons_core(z, buttons, BUTTONMASK_REWIND, "rewind");
buttons_core(z, buttons, BUTTONMASK_FASTFORWARD, "fastforward");
buttons_core(z, buttons, BUTTONMASK_STOP, "stop");
buttons_core(z, buttons, BUTTONMASK_PLAY, "play");
buttons_core(z, buttons, BUTTONMASK_RECORD, "record");
buttons_core(z, buttons, BUTTONMASK_SHIFT, "shift");
if (datawheel)
printf(" datawheel=%02x", datawheel);
printf("\n");
}
void do_lcd(tranzport_t *z)
{
tranzport_lcdwrite(z, 0, " ", 1000);
tranzport_lcdwrite(z, 1, "DISL", 1000);
tranzport_lcdwrite(z, 2, "EXIA", 1000);
tranzport_lcdwrite(z, 3, " FOR", 1000);
tranzport_lcdwrite(z, 4, " ", 1000);
tranzport_lcdwrite(z, 5, " ", 1000);
tranzport_lcdwrite(z, 6, " CUR", 1000);
tranzport_lcdwrite(z, 7, "E FO", 1000);
tranzport_lcdwrite(z, 8, "UND ", 1000);
tranzport_lcdwrite(z, 9, " ", 1000);
}
void do_lcd2(tranzport_t *z)
{
tranzport_lcdwrite(z, 0, "THE ", 1000);
tranzport_lcdwrite(z, 1, "TRAN", 1000);
tranzport_lcdwrite(z, 2, "ZPOR", 1000);
tranzport_lcdwrite(z, 3, "T RO", 1000);
tranzport_lcdwrite(z, 4, " KS", 1000);
tranzport_lcdwrite(z, 5, "AWES", 1000);
tranzport_lcdwrite(z, 6, "OMEE", 1000);
tranzport_lcdwrite(z, 7, "LEEE", 1000);
tranzport_lcdwrite(z, 8, "UND ", 1000);
tranzport_lcdwrite(z, 9, "GROK", 1000);
}
lights_off(tranzport_t *z) {
int i;
for(i=0;i<7;i++) {
tranzport_lightoff(z, i, 1000);
}
}
lights_on(tranzport_t *z) {
int i;
for(i=0;i<7;i++) {
tranzport_lighton(z, i, 1000);
}
}
int main()
{
tranzport_t *z;
uint8_t status;
uint32_t buttons;
uint8_t datawheel;
int val;
z = open_tranzport();
do_lcd(z);
for(;;) {
do_lcd(z);
lights_on(z);
do_lcd2(z);
lights_off(z);
// val = tranzport_read(z, &status, &buttons, &datawheel, 60000);
val = -1;
if (val < 0)
continue;
if (status == STATUS_OFFLINE) {
printf("offline: ");
continue;
}
if (status == STATUS_ONLINE) {
printf("online: ");
do_lcd(z);
}
do_lights(z, buttons);
do_buttons(z, buttons, datawheel);
}
close_tranzport(z);
return 0;
}

View File

@ -1,66 +0,0 @@
/*
* Copyright (C) 2008-2015 Paul Davis <paul@linuxaudiosystems.com>
*
* 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 "control_protocol/control_protocol.h"
#include "tranzport_control_protocol.h"
using namespace ARDOUR;
ControlProtocol*
new_tranzport_protocol (ControlProtocolDescriptor* descriptor, Session* s)
{
TranzportControlProtocol* tcp = new TranzportControlProtocol (*s);
if (tcp->set_active (true)) {
delete tcp;
return 0;
}
return tcp;
}
void
delete_tranzport_protocol (ControlProtocolDescriptor* descriptor, ControlProtocol* cp)
{
delete cp;
}
bool
probe_tranzport_protocol (ControlProtocolDescriptor* descriptor)
{
return TranzportControlProtocol::probe();
}
static ControlProtocolDescriptor tranzport_descriptor = {
name : "Tranzport",
id : "uri://ardour.org/surfaces/tranzport:0",
module : 0,
probe : probe_tranzport_protocol,
initialize : new_tranzport_protocol,
destroy : delete_tranzport_protocol
};
extern "C" {
ControlProtocolDescriptor*
protocol_descriptor () {
return &tranzport_descriptor;
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,320 +0,0 @@
#ifndef ardour_tranzport_control_protocol_h
#define ardour_tranzport_control_protocol_h
#include <vector>
#include <sys/time.h>
#include <pthread.h>
#include <usb.h>
#include <glibmm/threads.h>
#include "ardour/types.h"
#include "control_protocol/control_protocol.h"
class TranzportControlProtocol : public ARDOUR::ControlProtocol
{
public:
TranzportControlProtocol (ARDOUR::Session&);
virtual ~TranzportControlProtocol();
int set_active (bool yn);
static bool probe ();
XMLNode& get_state () const;
int set_state (const XMLNode&);
private:
static const int VENDORID = 0x165b;
static const int PRODUCTID = 0x8101;
static const int READ_ENDPOINT = 0x81;
static const int WRITE_ENDPOINT = 0x02;
const static int STATUS_OFFLINE = 0xff;
const static int STATUS_ONLINE = 0x01;
const static uint8_t WheelDirectionThreshold = 0x3f;
enum LightID {
LightRecord = 0,
LightTrackrec,
LightTrackmute,
LightTracksolo,
LightAnysolo,
LightLoop,
LightPunch
};
enum ButtonID {
ButtonBattery = 0x00004000,
ButtonBacklight = 0x00008000,
ButtonTrackLeft = 0x04000000,
ButtonTrackRight = 0x40000000,
ButtonTrackRec = 0x00040000,
ButtonTrackMute = 0x00400000,
ButtonTrackSolo = 0x00000400,
ButtonUndo = 0x80000000,
ButtonIn = 0x02000000,
ButtonOut = 0x20000000,
ButtonPunch = 0x00800000,
ButtonLoop = 0x00080000,
ButtonPrev = 0x00020000,
ButtonAdd = 0x00200000,
ButtonNext = 0x00000200,
ButtonRewind = 0x01000000,
ButtonFastForward = 0x10000000,
ButtonStop = 0x00010000,
ButtonPlay = 0x00100000,
ButtonRecord = 0x00000100,
ButtonShift = 0x08000000
};
enum WheelShiftMode {
WheelShiftGain,
WheelShiftPan,
WheelShiftMaster,
WheelShiftMarker
};
enum WheelMode {
WheelTimeline,
WheelScrub,
WheelShuttle
};
// FIXME - look at gtk2_ardour for snap settings
enum WheelIncrement {
WheelIncrSlave,
WheelIncrScreen,
WheelIncrSample,
WheelIncrBeat,
WheelIncrBar,
WheelIncrSecond,
WheelIncrMinute
};
enum DisplayMode {
DisplayNormal,
DisplayRecording,
DisplayRecordingMeter,
DisplayBigMeter,
DisplayConfig,
DisplayBling,
DisplayBlingMeter
};
enum BlingMode {
BlingOff,
BlingKit,
BlingRotating,
BlingPairs,
BlingRows,
BlingFlashAll
};
pthread_t thread;
uint32_t buttonmask;
uint32_t timeout;
uint32_t inflight;
uint8_t _datawheel;
uint8_t _device_status;
uint32_t current_track_id;
WheelMode wheel_mode;
WheelShiftMode wheel_shift_mode;
DisplayMode display_mode;
BlingMode bling_mode;
WheelIncrement wheel_increment;
usb_dev_handle* udev;
ARDOUR::gain_t gain_fraction;
Glib::Threads::Mutex update_lock;
bool screen_invalid[2][20];
char screen_current[2][20];
char screen_pending[2][20];
char screen_flash[2][20];
bool lights_invalid[7];
bool lights_current[7];
bool lights_pending[7];
bool lights_flash[7];
uint32_t last_bars;
uint32_t last_beats;
uint32_t last_ticks;
bool last_negative;
uint32_t last_hrs;
uint32_t last_mins;
uint32_t last_secs;
uint32_t last_samples;
samplepos_t last_where;
ARDOUR::gain_t last_track_gain;
uint32_t last_meter_fill;
uint64_t last_wheel_motion;
int last_wheel_dir;
Glib::Mutex io_lock;
int open ();
int read (uint8_t *buf,uint32_t timeout_override = 0);
int write (uint8_t* cmd, uint32_t timeout_override = 0);
int write_noretry (uint8_t* cmd, uint32_t timeout_override = 0);
int close ();
int save(char *name = "default");
int load(char *name = "default");
void print (int row, int col, const char* text);
void print_noretry (int row, int col, const char* text);
int rtpriority_set(int priority = 52);
int rtpriority_unset(int priority = 0);
int open_core (struct usb_device*);
static void* _monitor_work (void* arg);
void* monitor_work ();
int process (uint8_t *);
int update_state();
void invalidate();
int flush();
// bool isuptodate(); // think on this. It seems futile to update more than 30/sec
// A screen is a cache of what should be on the lcd
void screen_init();
void screen_validate();
void screen_invalidate();
int screen_flush();
void screen_clear();
// bool screen_isuptodate(); // think on this -
// Commands to write to the lcd
int lcd_init();
bool lcd_damage();
bool lcd_isdamaged();
bool lcd_damage(int row, int col = 0, int length = 20);
bool lcd_isdamaged(int row, int col = 0, int length = 20);
int lcd_flush();
int lcd_write(uint8_t* cmd, uint32_t timeout_override = 0); // pedantic alias for write
void lcd_fill (uint8_t fill_char);
void lcd_clear ();
void lcd_print (int row, int col, const char* text);
void lcd_print_noretry (int row, int col, const char* text);
// Commands to write to the lights
// FIXME - on some devices lights can have intensity and colors
void lights_init();
void lights_validate();
void lights_invalidate();
void light_validate(LightID light);
void light_invalidate(LightID light);
int lights_flush();
int lights_write(uint8_t* cmd,uint32_t timeout_override = 0); // pedantic alias to write
// a cache of what should be lit
void lights_off ();
void lights_on ();
int light_set(LightID, bool offon = true);
int light_on (LightID);
int light_off (LightID);
// some modes for the lights, should probably be renamed
int lights_show_normal();
int lights_show_recording();
int lights_show_tempo();
int lights_show_bling();
void enter_big_meter_mode ();
void enter_normal_display_mode ();
void enter_config_mode();
void enter_recording_mode();
void enter_bling_mode();
void next_display_mode ();
void normal_update ();
void show_current_track ();
void show_track_gain ();
void show_transport_time ();
void show_bbt (samplepos_t where);
void show_smpte (samplepos_t where);
void show_wheel_mode ();
void show_gain ();
void show_pan ();
void show_meter ();
void datawheel ();
void scrub ();
void scroll ();
void shuttle ();
void config ();
void next_wheel_mode ();
void next_wheel_shift_mode ();
void set_current_track (ARDOUR::Route*);
void next_track ();
void prev_track ();
void step_gain_up ();
void step_gain_down ();
void step_pan_right ();
void step_pan_left ();
void button_event_battery_press (bool shifted);
void button_event_battery_release (bool shifted);
void button_event_backlight_press (bool shifted);
void button_event_backlight_release (bool shifted);
void button_event_trackleft_press (bool shifted);
void button_event_trackleft_release (bool shifted);
void button_event_trackright_press (bool shifted);
void button_event_trackright_release (bool shifted);
void button_event_trackrec_press (bool shifted);
void button_event_trackrec_release (bool shifted);
void button_event_trackmute_press (bool shifted);
void button_event_trackmute_release (bool shifted);
void button_event_tracksolo_press (bool shifted);
void button_event_tracksolo_release (bool shifted);
void button_event_undo_press (bool shifted);
void button_event_undo_release (bool shifted);
void button_event_in_press (bool shifted);
void button_event_in_release (bool shifted);
void button_event_out_press (bool shifted);
void button_event_out_release (bool shifted);
void button_event_punch_press (bool shifted);
void button_event_punch_release (bool shifted);
void button_event_loop_press (bool shifted);
void button_event_loop_release (bool shifted);
void button_event_prev_press (bool shifted);
void button_event_prev_release (bool shifted);
void button_event_add_press (bool shifted);
void button_event_add_release (bool shifted);
void button_event_next_press (bool shifted);
void button_event_next_release (bool shifted);
void button_event_rewind_press (bool shifted);
void button_event_rewind_release (bool shifted);
void button_event_fastforward_press (bool shifted);
void button_event_fastforward_release (bool shifted);
void button_event_stop_press (bool shifted);
void button_event_stop_release (bool shifted);
void button_event_play_press (bool shifted);
void button_event_play_release (bool shifted);
void button_event_record_press (bool shifted);
void button_event_record_release (bool shifted);
// new api
void button_event_mute (bool pressed, bool shifted);
};
#endif // ardour_tranzport_control_protocol_h

View File

@ -1,25 +0,0 @@
#!/usr/bin/env python
import os
def options(opt):
pass
def configure(conf):
pass
def build(bld):
# Generic MIDI
obj = bld(features = 'cxx cxxshlib')
obj.source = '''
generic_midi_control_protocol.cc
interface.cc
midicontrollable.cc
'''
obj.defines = [ 'PACKAGE="ardour_frontier"' ]
obj.defines += [ 'ARDOURSURFACE_DLL_EXPORTS' ]
obj.includes = ['.', './generic_midi']
obj.name = 'libgeneric_midi'
obj.target = 'generic_midi'
obj.uselib = 'XML OSX'
obj.use = 'libardour libardourcp'
obj.install_path = os.path.join(bld.env['LIBDIR'], 'surfaces')

View File

@ -1,90 +0,0 @@
I'm putting this here because I don't really have a place to put it, unless I create a web page and have a place to keep the code.
While doing some exaustive testing of my latest code (read - playing a ton of music) I have done some thinking about the ui, and decided that under apparent simplicity should lie complexity.
The "flash" screen idea I am going to drop, and replace it with the idea of a notify area being declared on each screen.
When the unit is idle, these messages will appear in that area statically. When the transport is running, these messages will still appear in that space, which is usually where the meter is. It's actually possible to rapidly flash the area between the competing writers and get a nifty faded effect. (I came across this idea accidentally when I had a pointer overrun)
Also certain things will update on top of each other, whatever was updated
last will stay on the screen. This is Pan/Gain primarily.
I need a way to get messages back into the tranzport. Example - I hit Undo, what was undone? Redo, same problem.
I've already found many uses for being able to control more than 1 track at a time, so I think that although I'm *usually* controlling one track at a time, being able to quickly access all tracks would be good.
Example - want to have meters for all tracks running and be able to control the
db/pan settings of the track I'm on....
What I am going to go with is multifold - but first my design goal: I want to do everything required for a solo musician wielding an instrument to NOT have to touch a keyboard or look at a big screen. When you are wrapped behind a bass, it's difficult to cope with that - but the tranzport is a great alternative.
Most screens will have *4* items on them.
There will be "display views" - which are more informational and bling oriented.
There will be "Track based views"- which basically do track specific things
There will be "interactive views",which basically allow for more input than output. They will do something to highlight the current selection.
Scroll wheel will select between values for a field. Track Next/Prev will move between fields. I would like to have a "No/Yes" option (hit record for yes? Stop for no?) but I'm still a little vague on that.
Things to do:
A) Hitting "Shift->Spacebar" will switch "views". There are ultimately going to be dozens of views. At present, there are only the "Normal" and "Big Meter" views.
Each view will change somewhat based on the state of the transport. Holding down shift for a second will switch to the "underlying display"....
Here's how the "normal" view looks today in my tree:
VIEW: NORMAL
Play Mode: Stopped
[Trackname[16]] [gain/pan[4]]
[Modes[9]] long smpte/bar counter]
Play Mode: Playing > 1.0 speed
[Trackname[16]] [gain/pan[4]]
[meter[16]] short smpte/bar counter]
Play Mode: Playing < 1.0
[Trackname[16]] [gain/pan[4]]
[meter[9]] long smpte/bar counter]
Play Mode: Recording
[Trackname[16]] [gain/pan[4]]
[meter[16]] short smpte/bar counter]
Other views (in order of development priority)
Marker Mode: Edit markers, setup loops and punch in points.
Config Mode: Load/Save settings, Load/Save project. Set wheel SnapTo
Loop Mode: Show track, raise layers to top for playback, editing, deletion, loop on and off, etc
It's possible that config mode will have a "MORE" field, or ways to move around the configuration (ffw/Play?)
(the first two are the two modes I most need personally. If you have a suggestion...)
Mastering Mode - display master and current track with meters and panner/db
Automation Mode - I really don't think I have the pixels for this
(I've already abstracted out the code to do most of these, but it's bling, I'm not going to bother much with it soon)
Quad Meter Mode
Inverted Meter mode (draws meters backwards)
Quad Inverted Meter mode (bling, but my car stereo has it, and it's cool)
10 8 bar meter mode
5 8 bar meter mode
I haven't written the panner yet, doing the stereo meter killed me.
From a development perspective I'm going to keep revising the code to make it more stable and merely tie the new mode modes to the "bling mode"s until they are ready for prime time. I should be able to put out releases once a week for a while.
A big help would be moving these items into a higher level of abstraction (revising the baseUI class).
In particular, I'd really like "slave" mode. Snapto increment is really important....
Here's an example of something that should be fairly easy to export to the Base::UI subclasses - the current state of the main keyboard's shift key.
That way, when shift is held down for a few seconds on the regular keyboard, I can see what's underneath the current tranzport display mode (I do like big meters) (Also, it's somewhat easier to hit shift on the main keyboard and play on the tranzport or the shuttle wheel, if that's what you are doing).
Should be fairly easy to tap into the gdk event for this but the "right way" to propagate this event into the class is beyond me.

View File

@ -1,6 +0,0 @@
BREAK APART DRIVER INTO SIMPLER CHUNKS - done
GET KERNEL DRIVER WORKING
GET TRIPLE THREADED DRIVER WORKING
STABLIZE THE API
ADOPT SOME CONVENTIONS FROM THE MACKIE
GET SAVING STATE WORKING

View File

@ -1,115 +0,0 @@
/*
* Copyright (C) 2006 Paul Davis
* Copyright (C) 2007 Michael Taht
*
* 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.
*
* */
/* The Bling class theoretically knows nothing about the device it's blinging
and depends on the overlying implementation to tell it about the format of the
device. Maybe this will become a template or people will inherit from it */
/* Bling is where all the bad, bad, marketing driven ideas go */
class bling {
public:
enum BlingMode {
BlingOff = 0,
BlingOn = 1,
BlingEnter = 2,
BlingExit = 4,
// Light Specific Stuff
BlingKit = 8,
BlingRotating = 16,
BlingPairs = 32,
BlingRows = 64,
BlingColumns = 128,
BlingFlashAllLights = 256,
// Screen Specific Stuff
// Slider Specific Stuff
BlingSliderMax,
BlingSliderMid,
BlingSliderMin,
// Random stuff
BlingRandomLight,
BlingRandomSlider,
BlingRandomScreen,
BlingAllSliders
};
bling();
~bling();
set(BlingMode);
unset(BlingMode);
run();
next();
prev();
msg(string&);
scrollmsg(string&);
protected:
// The as yet undefined "advanced_ui" class provides methods to find out at run time
// what the heck is what
BlingMode blingmode;
advancedUI *intf;
int last_light;
// I don't think these actually need to be part of the public definition of the class
enter();
exit();
rotate();
// etc
};
// make absolutely sure we have the pointer to the interface
// something like this
#define BLING_INTFA(a) (intf)? 0:intf->a
#define BLING_INTF(a) { if (intf) { intf->a; } else { return 0; } }
// Should any of these bother to return a status code?
bling::rotate() {
BLING_INTF(light(last_light,off));
last_light = BLING_INTFA(next_light(last_light));
BLING_INTF(light(last_light,on));
}
bling::enter() {
}
bling::exit() {
}
bling::flashall() {
}
bling::rows() {
}
bling::columns() {
}
bling::msg() {
}
bling::scrollmsg() {
}
// Based on the current bling mode, do whatever it is you are going to do
bling::run() {
}
// etc

View File

@ -1,380 +0,0 @@
/*
* Copyright (C) 2006 Paul Davis
* Copyright (C) 2007 Michael Taht
*
* 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.
*
* */
#include <tranzport_common.h>
#include <tranzport_control_protocol.h>
using namespace ARDOUR;
using namespace std;
using namespace sigc;
using namespace PBD;
#include "pbd/i18n.h"
#include <pbd/abstract_ui.cc>
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)
{
#if DEBUG_TRANZPORT
printf("backlight released, redrawing (and possibly crashing) display\n");
#endif
if (shifted) {
lcd_damage();
lcd_clear();
last_where += 1; /* force time redisplay */
last_track_gain = FLT_MAX;
}
}
void
TranzportControlProtocol::button_event_trackleft_press (bool shifted)
{
prev_track ();
// not really the right layer for this
if(display_mode == DisplayBigMeter) {
if (route_table[0] != 0) {
notify(route_get_name (0).substr (0, 15).c_str());
}
}
}
void
TranzportControlProtocol::button_event_trackleft_release (bool shifted)
{
}
void
TranzportControlProtocol::button_event_trackright_press (bool shifted)
{
next_track ();
// not really the right layer for this
if(display_mode == DisplayBigMeter) {
if (route_table[0] != 0) {
notify(route_get_name (0).substr (0, 15).c_str());
}
}
}
void
TranzportControlProtocol::button_event_trackright_release (bool shifted)
{
}
void
TranzportControlProtocol::button_event_trackrec_press (bool shifted)
{
if (shifted) {
toggle_all_rec_enables ();
} else {
route_set_rec_enable (0, !route_get_rec_enable (0));
}
}
void
TranzportControlProtocol::button_event_trackrec_release (bool shifted)
{
}
void
TranzportControlProtocol::button_event_trackmute_press (bool shifted)
{
if (shifted) {
// Mute ALL? Something useful when a phone call comes in. Mute master?
} else {
route_set_muted (0, !route_get_muted (0));
}
}
void
TranzportControlProtocol::button_event_trackmute_release (bool shifted)
{
}
void
TranzportControlProtocol::button_event_tracksolo_press (bool shifted)
{
#if DEBUG_TRANZPORT
printf("solo pressed\n");
#endif
if (display_mode == DisplayBigMeter) {
light_off (LightAnysolo);
return;
}
if (shifted) {
session->set_all_solo (!session->soloing());
} else {
route_set_soloed (0, !route_get_soloed (0));
}
}
void
TranzportControlProtocol::button_event_tracksolo_release (bool shifted)
{
#if DEBUG_TRANZPORT
printf("solo released\n");
#endif
}
void
TranzportControlProtocol::button_event_undo_press (bool shifted)
{
// undohistory->get_state(1);
//XMLNode&
//UndoHistory::get_state (uint32_t depth)
if (shifted) {
redo (); // someday flash the screen with what was redone
notify("Redone!!");
} else {
undo (); // someday flash the screen with what was undone
notify("Undone!!");
}
}
void
TranzportControlProtocol::button_event_undo_release (bool shifted)
{
}
void
TranzportControlProtocol::button_event_in_press (bool shifted)
{
if (shifted) {
toggle_punch_in ();
} else {
ControlProtocol::ZoomIn (); /* EMIT SIGNAL */
}
}
void
TranzportControlProtocol::button_event_in_release (bool shifted)
{
}
void
TranzportControlProtocol::button_event_out_press (bool shifted)
{
if (shifted) {
toggle_punch_out ();
} else {
ControlProtocol::ZoomOut (); /* EMIT SIGNAL */
}
}
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)
{
if (shifted) {
next_wheel_shift_mode ();
} else {
loop_toggle ();
}
}
void
TranzportControlProtocol::button_event_loop_release (bool shifted)
{
}
void
TranzportControlProtocol::button_event_prev_press (bool shifted)
{
if (shifted) {
ControlProtocol::ZoomToSession (); /* EMIT SIGNAL */
} else {
prev_marker ();
}
}
void
TranzportControlProtocol::button_event_prev_release (bool shifted)
{
}
// Note - add_marker should adhere to the snap to setting
// maybe session->audible_sample does that
void
TranzportControlProtocol::button_event_add_press (bool shifted)
{
add_marker ();
}
void
TranzportControlProtocol::button_event_add_release (bool shifted)
{
}
void
TranzportControlProtocol::button_event_next_press (bool shifted)
{
if (shifted) {
next_wheel_mode ();
} else {
next_marker ();
}
}
void
TranzportControlProtocol::button_event_next_release (bool shifted)
{
}
void
TranzportControlProtocol::button_event_rewind_press (bool shifted)
{
if (shifted) {
goto_start ();
} else {
rewind ();
}
}
void
TranzportControlProtocol::button_event_rewind_release (bool shifted)
{
}
void
TranzportControlProtocol::button_event_fastforward_press (bool shifted)
{
if (shifted) {
goto_end ();
} else {
ffwd ();
}
}
void
TranzportControlProtocol::button_event_fastforward_release (bool shifted)
{
}
void
TranzportControlProtocol::button_event_stop_press (bool shifted)
{
if (shifted) {
next_display_mode ();
} else {
transport_stop ();
}
}
void
TranzportControlProtocol::button_event_stop_release (bool shifted)
{
}
void
TranzportControlProtocol::button_event_play_press (bool shifted)
{
if (shifted) {
set_transport_speed (1.0f);
} else {
transport_play ();
}
}
void
TranzportControlProtocol::button_event_play_release (bool shifted)
{
}
void
TranzportControlProtocol::button_event_record_press (bool shifted)
{
if (shifted) {
save_state ();
} else {
rec_enable_toggle ();
}
}
void
TranzportControlProtocol::button_event_record_release (bool shifted)
{
}
void
TranzportControlProtocol::button_event_footswitch_press (bool shifted)
{
if (shifted) {
next_marker (); // think this through, we could also do punch in
} else {
prev_marker (); // think this through, we could also do punch in
}
}
void
TranzportControlProtocol::button_event_footswitch_release (bool shifted)
{
if(get_transport_speed() == 0.0)
{
transport_play ();
}
}
// Possible new api example
// tries harder to do the right thing if we somehow missed a button down event
// which currently happens... a lot.
void button_event_mute (bool pressed, bool shifted)
{
static int was_pressed = 0;
if((!pressed && !was_pressed) || pressed) {
was_pressed = 1;
}
was_pressed = 0;
}

View File

@ -1,21 +0,0 @@
/*
* Copyright (C) 2006 Paul Davis
* Copyright (C) 2007 Michael Taht
*
* 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.
*
* */
/* placeholder for button definitions for user edits like yes/no */

View File

@ -1,113 +0,0 @@
/*
* Copyright (C) 2006 Paul Davis
* Copyright (C) 2007 Michael Taht
*
* 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.
*
* */
#include "tranzport_control_protocol.h"
#define TRANZPORT_BUTTON_HANDLER(callback, button_arg) if (button_changes & button_arg) { \
if (buttonmask & button_arg) { \
callback##_press (buttonmask&ButtonShift); } else { callback##_release (buttonmask&ButtonShift); } }
int
TranzportControlProtocol::process (uint8_t* buf)
{
uint32_t this_button_mask;
uint32_t button_changes;
_device_status = buf[1];
#if DEBUG_TRANZPORT > 10
// Perhaps the device can go offline due to flow control, print command bits to see if we have anything interesting
if(_device_status == STATUS_ONLINE) {
printf("ONLINE : %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]);
}
if(_device_status == STATUS_OFFLINE) {
printf("OFFLINE : %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]);
}
if(_device_status != STATUS_OK) { return 1; }
#endif
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];
#if DEBUG_TRANZPORT_STATE > 1
// Is the state machine incomplete?
const unsigned int knownstates = 0x00004000|0x00008000|
0x04000000| 0x40000000| 0x00040000| 0x00400000|
0x00000400| 0x80000000| 0x02000000| 0x20000000|
0x00800000| 0x00080000| 0x00020000| 0x00200000|
0x00000200| 0x01000000| 0x10000000| 0x00010000|
0x00100000| 0x00000100| 0x08000000| 0x00001000;
std::bitset<32> bi(knownstates);
std::bitset<32> vi(this_button_mask);
// if an bi & vi == vi the same - it's a valid set
if(vi != (bi & vi)) {
printf("UNKNOWN STATE: %s also, datawheel= %d\n", vi.to_string().c_str(), _datawheel);
}
#endif
button_changes = (this_button_mask ^ buttonmask);
buttonmask = this_button_mask;
if (_datawheel) {
datawheel ();
}
// SHIFT + STOP + PLAY for bling mode?
// if (button_changes & ButtonPlay & ButtonStop) {
// bling_mode_toggle();
// } or something like that
TRANZPORT_BUTTON_HANDLER(button_event_battery,ButtonBattery);
TRANZPORT_BUTTON_HANDLER(button_event_backlight,ButtonBacklight);
TRANZPORT_BUTTON_HANDLER(button_event_trackleft,ButtonTrackLeft);
TRANZPORT_BUTTON_HANDLER(button_event_trackright,ButtonTrackRight);
TRANZPORT_BUTTON_HANDLER(button_event_trackrec,ButtonTrackRec);
TRANZPORT_BUTTON_HANDLER(button_event_trackmute,ButtonTrackMute);
TRANZPORT_BUTTON_HANDLER(button_event_tracksolo,ButtonTrackSolo);
TRANZPORT_BUTTON_HANDLER(button_event_undo,ButtonUndo);
TRANZPORT_BUTTON_HANDLER(button_event_in,ButtonIn);
TRANZPORT_BUTTON_HANDLER(button_event_out,ButtonOut);
TRANZPORT_BUTTON_HANDLER(button_event_punch,ButtonPunch);
TRANZPORT_BUTTON_HANDLER(button_event_loop,ButtonLoop);
TRANZPORT_BUTTON_HANDLER(button_event_prev,ButtonPrev);
TRANZPORT_BUTTON_HANDLER(button_event_add,ButtonAdd);
TRANZPORT_BUTTON_HANDLER(button_event_next,ButtonNext);
TRANZPORT_BUTTON_HANDLER(button_event_rewind,ButtonRewind);
TRANZPORT_BUTTON_HANDLER(button_event_fastforward,ButtonFastForward);
TRANZPORT_BUTTON_HANDLER(button_event_stop,ButtonStop);
TRANZPORT_BUTTON_HANDLER(button_event_play,ButtonPlay);
TRANZPORT_BUTTON_HANDLER(button_event_record,ButtonRecord);
TRANZPORT_BUTTON_HANDLER(button_event_footswitch,ButtonFootswitch);
return 0;
}

View File

@ -1,333 +0,0 @@
/*
* Copyright (C) 2006 Paul Davis
* Copyright (C) 2007 Michael Taht
*
* 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.
*
* */
#include <tranzport_common.h>
#include <tranzport_control_protocol.h>
using namespace ARDOUR;
using namespace std;
using namespace sigc;
using namespace PBD;
#include "pbd/i18n.h"
#include <pbd/abstract_ui.cc>
// HA, I don't need this anymore
#include <slider_gain.h>
// FIXME, flash recording light when recording and transport is moving
int TranzportControlProtocol::lights_show_recording()
{
return lights_show_normal();
}
void TranzportControlProtocol::show_bling() {
lights_show_bling();
screen_show_bling();
}
void TranzportControlProtocol::notify(const char *msg) {
last_notify=100;
if(strlen(msg) < 21) {
strcpy(last_notify_msg,msg);
} else {
strncpy(last_notify_msg,msg,16);
last_notify_msg[16] = '\n';
}
}
void TranzportControlProtocol::show_notify() {
// FIXME: Get width of the notify area somehow
if(last_notify==0) {
print(1,0," ");
last_notify=-1;
}
if(last_notify > 0) {
print(1,0,last_notify_msg);
--last_notify;
}
}
// Need more bling!
int TranzportControlProtocol::lights_show_bling()
{
switch (bling_mode) {
case BlingOff: break;
case BlingKit: break; // rotate rec/mute/solo/any solo back and forth
case BlingRotating: break; // switch between lights
case BlingPairs: break; // Show pairs of lights
case BlingRows: break; // light each row in sequence
case BlingFlashAll: break; // Flash everything randomly
case BlingEnter: lights_on(); // Show intro
case BlingExit:
lights_off();
break;
}
return 0;
}
int TranzportControlProtocol::screen_show_bling()
{
switch (bling_mode) {
case BlingOff: break;
case BlingKit: break; // rotate rec/mute/solo/any solo back and forth
case BlingRotating: break; // switch between lights
case BlingPairs: break; // Show pairs of lights
case BlingRows: break; // light each row in sequence
case BlingFlashAll: break; // Flash everything randomly
case BlingEnter: // Show intro
print(0,0,"!!Welcome to Ardour!");
print(1,0,"Peace through Music!");
break;
case BlingExit:
break;
}
return 0;
}
int TranzportControlProtocol::lights_show_normal()
{
/* Track only */
if (route_table[0]) {
std::shared_ptr<AudioTrack> at = std::dynamic_pointer_cast<AudioTrack> (route_table[0]);
lights_pending[LightTrackrec] = at && at->record_enabled();
lights_pending[LightTrackmute] = route_get_muted(0);
lights_pending[LightTracksolo] = route_get_soloed(0);
} else {
lights_pending[LightTrackrec] = false;
lights_pending[LightTracksolo] = false;
lights_pending[LightTrackmute] = false;
}
/* Global settings */
lights_pending[LightLoop] = session->get_play_loop();
lights_pending[LightPunch] = session->config.get_punch_in() || session->config.get_punch_out();
lights_pending[LightRecord] = session->get_record_enabled();
lights_pending[LightAnysolo] = session->soloing();
return 0;
}
int TranzportControlProtocol::lights_show_tempo()
{
// someday soon fiddle with the lights more sanely based on the tempo
return lights_show_normal();
}
int
TranzportControlProtocol::update_state ()
{
/* do the text and light updates */
switch (display_mode) {
case DisplayBigMeter:
lights_show_tempo();
show_meter ();
break;
case DisplayNormal:
lights_show_normal();
normal_update();
break;
case DisplayConfig:
break;
case DisplayRecording:
lights_show_recording();
normal_update();
break;
case DisplayRecordingMeter:
lights_show_recording();
show_meter();
break;
case DisplayBling:
show_bling();
break;
case DisplayBlingMeter:
lights_show_bling();
show_meter();
break;
}
show_notify();
return 0;
}
void
TranzportControlProtocol::prev_marker ()
{
Location *location = session->locations()->first_location_before (session->transport_sample());
if (location) {
session->request_locate (location->start());
notify(location->name().c_str());
} else {
session->goto_start ();
notify("START");
}
}
void
TranzportControlProtocol::next_marker ()
{
Location *location = session->locations()->first_location_after (session->transport_sample());
if (location) {
session->request_locate (location->start());
notify(location->name().c_str());
} else {
session->request_locate (session->current_end_sample());
notify("END ");
}
}
void
TranzportControlProtocol::show_current_track ()
{
char pad[COLUMNS];
char *v;
int len;
if (route_table[0] == 0) {
print (0, 0, "---------------");
last_track_gain = FLT_MAX;
} else {
strcpy(pad," ");
v = (char *)route_get_name (0).substr (0, 14).c_str();
if((len = strlen(v)) > 0) {
strncpy(pad,(char *)v,len);
}
print (0, 0, pad);
}
}
#if 0
void
TranzportControlProtocol::step_gain (float increment)
{
// FIXME: buttonstop is used elsewhere
if (buttonmask & ButtonStop) {
gain_fraction += 0.001*increment;
} else {
gain_fraction += 0.01*increment;
}
if (fabsf(gain_fraction) > 2.0) {
gain_fraction = 2.0*sign(gain_fraction);
}
route_set_gain (0, slider_position_to_gain (gain_fraction));
}
#endif
void
TranzportControlProtocol::step_gain_up ()
{
if (buttonmask & ButtonStop) {
gain_fraction += 0.001;
} else {
gain_fraction += 0.01;
}
if (gain_fraction > 2.0) {
gain_fraction = 2.0;
}
route_set_gain (0, slider_position_to_gain (gain_fraction));
}
void
TranzportControlProtocol::step_gain_down ()
{
if (buttonmask & ButtonStop) {
gain_fraction -= 0.001;
} else {
gain_fraction -= 0.01;
}
if (gain_fraction < 0.0) {
gain_fraction = 0.0;
}
route_set_gain (0, slider_position_to_gain (gain_fraction));
}
void
TranzportControlProtocol::next_track ()
{
ControlProtocol::next_track (current_track_id);
gain_fraction = gain_to_slider_position (route_get_effective_gain (0));
// notify("NextTrak"); // not needed til we have more modes
}
void
TranzportControlProtocol::prev_track ()
{
ControlProtocol::prev_track (current_track_id);
gain_fraction = gain_to_slider_position (route_get_effective_gain (0));
// notify("PrevTrak");
}
// This should kind of switch to using notify
// Was going to keep state around saying to retry or not
// haven't got to it yet, still not sure it's a good idea
void
TranzportControlProtocol::print (int row, int col, const char *text) {
print_noretry(row,col,text);
}
// -1 on failure
// 0 on no damage
// count of bit set on damage?
void
TranzportControlProtocol::print_noretry (int row, int col, const char *text)
{
uint32_t length = strlen (text);
if (row*COLUMNS+col+length > (ROWS*COLUMNS)) {
return;
}
// FIXME - be able to print the whole screen at a go.
uint32_t t,r,c;
std::bitset<ROWS*COLUMNS> mask(screen_invalid);
for(r = row, c = col, t = 0 ; t < length; c++,t++) {
screen_pending[r][c] = text[t];
mask[r*COLUMNS+c] = (screen_current[r][c] != screen_pending[r][c]);
}
screen_invalid = mask;
}
void TranzportControlProtocol::invalidate()
{
lcd_damage(); lights_invalidate(); screen_invalidate(); // one of these days lcds can be fine but screens not
}

View File

@ -1,295 +0,0 @@
/*
* Copyright (C) 2006 Paul Davis
* Copyright (C) 2007 Michael Taht
*
* 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.
*
*/
#include <tranzport_common.h>
#include <tranzport_control_protocol.h>
using namespace ARDOUR;
using namespace std;
using namespace sigc;
using namespace PBD;
#include "pbd/i18n.h"
#include <pbd/abstract_ui.cc>
void*
TranzportControlProtocol::_monitor_work (void* arg)
{
return static_cast<TranzportControlProtocol*>(arg)->monitor_work ();
}
TranzportControlProtocol::~TranzportControlProtocol ()
{
set_active (false);
}
int TranzportControlProtocol::rtpriority_set(int priority)
{
char *a = (char*) alloca(4096*2); a[0] = 'a'; a[4096] = 'b';
// Note - try SCHED_RR with a low limit
// - we don't care if we can't write everything this ms
// and it will help if we lose the device
if (set_thread_priority (SCHED_FIFO, priority)) {
PBD::info << string_compose (_("%1: thread not running with realtime scheduling."), name(), strerror (errno)) << endmsg;
return 1;
}
return 0;
}
// Running with realtime privs is bad when you have problems
int TranzportControlProtocol::rtpriority_unset(int priority)
{
struct sched_param rtparam;
int err;
memset (&rtparam, 0, sizeof (rtparam));
rtparam.sched_priority = priority;
if ((err = pthread_setschedparam (pthread_self(), SCHED_FIFO, &rtparam)) != 0) {
PBD::info << string_compose (_("%1: can't stop realtime scheduling (%2)"), name(), strerror (errno)) << endmsg;
return 1;
}
PBD::info << string_compose (_("%1: realtime scheduling stopped (%2)"), name(), strerror (errno)) << endmsg;
return 0;
}
int
TranzportControlProtocol::set_active (bool yn)
{
if (yn != _active) {
if (yn) {
if (open ()) {
return -1;
}
if (pthread_create_and_store (X_("tranzport monitor"), &thread, _monitor_work, this) == 0) {
_active = true;
} else {
return -1;
}
} else {
cerr << "Begin tranzport shutdown\n";
// if we got here due to an error, prettifying things will only make it worse
// And with threads involved, oh boy...
if(!(last_write_error || last_read_error)) {
bling_mode = BlingExit;
enter_bling_mode();
// thread FIXME - wait til all writes are done
for(int x = 0; (x < 20/MAX_TRANZPORT_INFLIGHT) && flush(); x++) { usleep(100); }
}
pthread_cancel_one (thread);
cerr << "Tranzport Thread dead\n";
close ();
_active = false;
cerr << "End tranzport shutdown\n";
}
}
return 0;
}
TranzportControlProtocol::TranzportControlProtocol (Session& s)
: ControlProtocol (s, X_("Tranzport"))
{
/* tranzport controls one track at a time */
set_route_table_size (1);
timeout = 6000; // what is this for?
buttonmask = 0;
_datawheel = 0;
_device_status = STATUS_OFFLINE;
udev = 0;
current_track_id = 0;
last_where = max_samples;
wheel_mode = WheelTimeline;
wheel_shift_mode = WheelShiftGain;
wheel_increment = WheelIncrScreen;
bling_mode = BlingEnter;
last_notify_msg[0] = '\0';
last_notify = 0;
timerclear (&last_wheel_motion);
last_wheel_dir = 1;
last_track_gain = FLT_MAX;
last_write_error = 0;
last_read_error = 0;
display_mode = DisplayBling;
gain_fraction = 0.0;
invalidate();
screen_init();
lights_init();
// FIXME: Wait til device comes online somewhere
// About 3 reads is enough
// enter_bling_mode();
}
void*
TranzportControlProtocol::monitor_work ()
{
uint8_t buf[8]; // = { 0,0,0,0,0,0,0,0 };
int val = 0, pending = 0;
bool first_time = true;
uint8_t offline = 0;
register_thread (X_("Tranzport"));
pthread_setcancelstate (PTHREAD_CANCEL_ENABLE, 0);
pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, 0);
rtpriority_set();
inflight=0;
//int intro = 20;
// wait for the device to come online
invalidate();
screen_init();
lights_init();
update_state();
// There has to be some specific command to enable the device!!
// while((val = read(buf,DEFAULT_USB_TIMEOUT*5)) == -110 && pending !=0) {
// pending = lights_flush(); // poke the device for a while
// }
// pending = 1;
// while(intro-- > 0 && pending != 0) {
// usleep(1000);
// pending = screen_flush(); // kinder, gentler init
// }
// usleep(1000);
// lights_on();
// while(flush()!=0) ;
// lights_off();
display_mode = DisplayNormal;
while (true) {
/* bInterval for this beastie is 10ms */
if (_device_status == STATUS_OFFLINE) {
first_time = true; offline++;
#if TRANZPORT_DEBUG > 3
if(offline == 1) {
cerr << "Transport has gone offline\n";
}
#endif
} else {
offline = 0; // hate writing this
}
unsigned int s = (last_write_error == 0) | ((last_read_error == 0) << 1);
switch (s) {
case 0: val = read(buf,DEFAULT_USB_TIMEOUT); break;
case 1: val = read(buf,DEFAULT_USB_TIMEOUT); break;
case 2: val = read(buf,DEFAULT_USB_TIMEOUT); break;
case 3: val = read(buf,DEFAULT_USB_TIMEOUT*2); break; // Hoo, boy, we're in trouble
default: break; // not reached
}
#if DEBUG_TRANZPORT_BITS > 9
if(_device_status != STATUS_OFFLINE && _device_status != STATUS_ONLINE && _device_status != STATUS_OK) {
printf("The device has more status bits than off or online: %d\n",_device_status);
}
#endif
#if DEBUG_TRANZPORT_BITS > 99
if (val != 8) {
printf("val = %d errno = %d\n",val,errno);
buf[0] = buf[1] = buf[2] = buf[3] =
buf[4] = buf[5] = buf[6] = buf[7] =
buf[8] = 0;
}
#endif
if(val == 8) {
last_write_error = 0;
process (buf);
}
#if DEBUG_TRANZPORT > 9
if(inflight > 1) printf("Inflight: %d\n", inflight);
#endif
if (_device_status == STATUS_ONLINE) {
if (first_time) {
invalidate();
lcd_clear ();
lights_off ();
first_time = false;
last_write_error = 0;
offline = 0;
pending = 3; // Give some time for the device to recover
}
#if DEBUG_TRANZPORT_BITS > 10
// Perhaps an online message indicates something
if(_device_status != buf[1]) {
printf("WTF- val: %d, device status != buf! %d != %d \n",val,_device_status,buf[1]); _device_status = buf[1];
}
#endif
}
#if DEBUG_TRANZPORT_BITS > 10
if(val == 8) {
if(_device_status == STATUS_ONLINE) {
printf("ONLINE : %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]);
}
if(_device_status == STATUS_OFFLINE) {
printf("OFFLINE : %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]);
}
if(_device_status == STATUS_OK) {
printf("OK : %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]);
}
}
#endif
/* update whatever needs updating */
if(last_write_error == 0 && (_device_status == STATUS_ONLINE || _device_status == STATUS_OK)) {
update_state ();
/* still struggling with a good means of exerting flow control without having to create threads */
// pending = flush();
if(pending == 0) {
pending = flush();
} else {
if(inflight > 0) {
pending = --inflight; // we just did a whole bunch of writes so wait
} else {
pending = 0;
}
}
}
// pending = 0;
}
return (void*) 0;
}

View File

@ -1,60 +0,0 @@
/*
* Copyright (C) 2006 Paul Davis
* Copyright (C) 2007 Michael Taht
*
* 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.
*
* */
#include "control_protocol/control_protocol.h"
#include "tranzport_control_protocol.h"
using namespace ARDOUR;
static ControlProtocol*
new_tranzport_protocol (Session* s)
{
TranzportControlProtocol* tcp = new TranzportControlProtocol (*s);
if (tcp->set_active (true)) {
delete tcp;
return 0;
}
return tcp;
}
static void
delete_tranzport_protocol (ControlProtocol* cp)
{
delete cp;
}
static ControlProtocolDescriptor tranzport_descriptor = {
/* name */ "Tranzport",
/* id */ "uri://ardour.org/surfaces/tranzport:0",
/* module */ 0,
/* available */ TranzportControlProtocol::available,
/* probe_port */ 0,
/* match usb */ 0,
/* initialize */ new_tranzport_protocol,
/* destroy */ delete_tranzport_protocol,
};
extern "C" ARDOURSURFACE_API ControlProtocolDescriptor* protocol_descriptor () { return &tranzport_descriptor; }

View File

@ -1,95 +0,0 @@
/*
* Copyright (C) 2006 Paul Davis
* Copyright (C) 2007 Michael Taht
*
* 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.
*
* */
/* The routines in here should know absolutely nothing about how io is actually done */
#include <tranzport_control_protocol.h>
int
TranzportControlProtocol::flush ()
{
int pending = 0;
// Always write the lights first
if(!(pending = lights_flush())) {
pending = screen_flush();
}
#if DEBUG_TRANZPORT_BITS > 9
int s;
if(s = (screen_invalid.count())) { // + lights_invalid.count())) {
printf("VALID : %s %s\n",
screen_invalid.to_string().c_str(),
lights_invalid.to_string().c_str());
printf("CURR : %s %s\n",
screen_invalid.to_string().c_str(),
lights_current.to_string().c_str());
printf("PENDING : %s %s\n",
screen_invalid.to_string().c_str(),
lights_pending.to_string().c_str());
#if DEBUG_TRANZPORT_BITS > 10
printf("invalid bits: %d\n",s);
#endif
}
#endif
return pending;
}
int
TranzportControlProtocol::lights_flush ()
{
std::bitset<LIGHTS> light_state;
light_state = lights_pending ^ lights_current;
if ( (light_state.none() || lights_invalid.none()))
{
return (0);
}
#if DEBUG_TRANZPORT_LIGHTS
printf("LPEND : %s\n", lights_pending.to_string().c_str());
printf("LCURR : %s\n", lights_current.to_string().c_str());
#endif
// if ever we thread reads/writes STATUS_OK will have to move into the loop
int i;
if ( _device_status == STATUS_OK || _device_status == STATUS_ONLINE) {
for (i = 0; i<LIGHTS; i++) {
if(light_state[i]) {
if(light_set ((LightID)i,lights_pending[i])) {
#if DEBUG_TRANZPORT_LIGHTS > 2
printf("Did %d light writes\n",i);
#endif
return light_state.count();
} else {
light_state[i] = 0;
}
}
}
}
light_state = lights_pending ^ lights_current;
#if DEBUG_TRANZPORT_LIGHTS > 2
printf("Did %d light writes, left: %d\n",i, light_state.count());
#endif
return light_state.count();
}

View File

@ -1,144 +0,0 @@
/*
* Copyright (C) 2006 Paul Davis
* Copyright (C) 2007 Michael Taht
*
* 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.
*
* */
#if HAVE_TRANZPORT_KERNEL_DRIVER
#include <fcntl.h>
#include <errno.h>
#include <poll.h>
#include "tranzport_control_protocol.h"
// Something like open(/dev/surface/tranzport/event) for reading and raw for writing) would be better in the long run
// Also support for multiple tranzports needs to be figured out
// And bulk reads/writes in general
bool
TranzportControlProtocol::probe ()
{
if((udev = ::open(TRANZPORT_DEVICE,O_RDWR))> 0) {
::close(udev);
return true;
}
error << _("Tranzport: Can't open device for Read/Write: ") << endmsg;
return false;
}
int
TranzportControlProtocol::open ()
{
if((udev=::open(TRANZPORT_DEVICE,O_RDWR))> 0) {
return(udev);
}
error << _("Tranzport: no device detected") << endmsg;
return udev;
}
int
TranzportControlProtocol::close ()
{
int ret = 0;
if (udev < 1) {
return 0;
}
if ((ret = ::close (udev)) != 0) {
error << _("Tranzport: cannot close device") << endmsg;
}
return ret;
}
// someday do buffered reads, presently this does blocking reads, which is bad...
int TranzportControlProtocol::read(uint8_t *buf, uint32_t timeout_override)
{
last_read_error = ::read (udev, (char *) buf, 8);
switch(errno) {
case -ENOENT:
case -ENXIO:
case -ECONNRESET:
case -ESHUTDOWN:
case -ENODEV:
cerr << "Tranzport disconnected, errno: " << last_read_error;
set_active(false);
break;
case -ETIMEDOUT: // This is not normal, but lets see what happened
cerr << "Tranzport read timed out, errno: " << last_read_error;
break;
default:
#if DEBUG_TRANZPORT
cerr << "Got an unknown error on read:" << last_read_error "\n";
#endif
break;
}
return last_read_error;
}
int
TranzportControlProtocol::write_noretry (uint8_t* cmd, uint32_t timeout_override)
{
// inflight is now taken care of by the driver, but...
if(inflight > MAX_TRANZPORT_INFLIGHT) { return (-1); }
int val = ::write (udev, (char*) cmd, 8);
if (val < 0 && val !=8) {
#if DEBUG_TRANZPORT
printf("write failed: %d\n", val);
#endif
last_write_error = errno;
switch(last_write_error) {
case -ENOENT:
case -ENXIO:
case -ECONNRESET:
case -ESHUTDOWN:
case -ENODEV:
cerr << "Tranzport disconnected, errno: " << last_write_error;
set_active(false);
break;
case -ETIMEDOUT: // This is not normal but
cerr << "Tranzport disconnected, errno: " << last_write_error;
break;
default:
#if DEBUG_TRANZPORT
cerr << "Got an unknown error on read:" << last_write_error "\n";
#endif
break;
}
return last_write_error;
}
last_write_error = 0;
++inflight;
return 0;
}
int
TranzportControlProtocol::write (uint8_t* cmd, uint32_t timeout_override)
{
return (write_noretry(cmd,timeout_override));
}
// FIXME - install poll semantics
#endif /* HAVE_TRANZPORT_KERNEL_DRIVER */

View File

@ -1,26 +0,0 @@
/*
* Copyright (C) 2006 Paul Davis
* Copyright (C) 2007 Michael Taht
*
* 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.
*
* */
/* io_midi: Implements reading and writing tranzport events via the normal
tranzport midi specification */
/* One day
#include <tranzport_control_protocol.h>
*/

View File

@ -1,232 +0,0 @@
/*
* Copyright (C) 2006 Paul Davis
* Copyright (C) 2007 Michael Taht
*
* 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.
*
* */
#include <iostream>
#define __STDC_FORMAT_MACROS
#include <inttypes.h>
#include <float.h>
#include <sys/time.h>
#include <errno.h>
#include <fcntl.h>
#include <tranzport_control_protocol.h>
#if !HAVE_TRANZPORT_KERNEL_DRIVER
using namespace ARDOUR;
using namespace std;
using namespace sigc;
using namespace PBD;
#include "pbd/i18n.h"
#include <pbd/abstract_ui.cc>
// I note that these usb specific open, close, probe, read routines are basically
// pure boilerplate and could easily be abstracted elsewhere
bool
TranzportControlProtocol::available ()
{
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 && dev->descriptor.idProduct == PRODUCTID) {
return true;
}
}
}
return false;
}
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);
}
}
cerr << _("Tranzport: no device detected") << endmsg;
return -1;
}
int
TranzportControlProtocol::open_core (struct usb_device* dev)
{
if (!(udev = usb_open (dev))) {
cerr << _("Tranzport: cannot open USB transport") << endmsg;
return -1;
}
if (usb_claim_interface (udev, 0) < 0) {
cerr << _("Tranzport: cannot claim USB interface") << endmsg;
usb_close (udev);
udev = 0;
return -1;
}
if (usb_set_configuration (udev, 1) < 0) {
cerr << _("Tranzport: cannot configure USB interface") << endmsg;
}
return 0;
}
int
TranzportControlProtocol::close ()
{
int ret = 0;
if (udev == 0) {
return 0;
}
if (usb_release_interface (udev, 0) < 0) {
cerr << _("Tranzport: cannot release interface") << endmsg;
ret = -1;
}
if (usb_close (udev)) {
cerr << _("Tranzport: cannot close device") << endmsg;
udev = 0;
ret = 0;
}
return ret;
}
int TranzportControlProtocol::read(uint8_t *buf, uint32_t timeout_override)
{
last_read_error = usb_interrupt_read (udev, READ_ENDPOINT, (char *) buf, 8, timeout_override);
switch(last_read_error) {
case -ENOENT:
case -ENXIO:
case -ECONNRESET:
case -ESHUTDOWN:
case -ENODEV:
cerr << "Tranzport disconnected, errno: " << last_read_error;
set_active(false);
case -ETIMEDOUT: // This is normal
break;
default:
#if DEBUG_TRANZPORT
cerr << "Got an unknown error on read:" << last_read_error "\n";
#endif
break;
}
return last_read_error;
}
int
TranzportControlProtocol::write_noretry (uint8_t* cmd, uint32_t timeout_override)
{
int val;
if(inflight > MAX_TRANZPORT_INFLIGHT) { return (-1); }
val = usb_interrupt_write (udev, WRITE_ENDPOINT, (char*) cmd, 8, timeout_override ? timeout_override : timeout);
if (val < 0 && val !=8) {
#if DEBUG_TRANZPORT
printf("usb_interrupt_write failed: %d\n", val);
#endif
last_write_error = val;
switch(last_write_error) {
case -ENOENT:
case -ENXIO:
case -ECONNRESET:
case -ESHUTDOWN:
case -ENODEV:
cerr << "Tranzport disconnected, errno: " << last_write_error;
set_active(false);
case -ETIMEDOUT: // This is normal
break;
default:
#if DEBUG_TRANZPORT
cerr << "Got an unknown error on read:" << last_write_error "\n";
#endif
break;
}
return val;
}
last_write_error = 0;
++inflight;
return 0;
}
int
TranzportControlProtocol::write (uint8_t* cmd, uint32_t timeout_override)
{
#if MAX_RETRY > 1
int val;
int retry = 0;
if(inflight > MAX_TRANZPORT_INFLIGHT) { return (-1); }
while((val = usb_interrupt_write (udev, WRITE_ENDPOINT, (char*) cmd, 8, timeout_override ? timeout_override : timeout))!=8 && retry++ < MAX_RETRY) {
printf("usb_interrupt_write failed, retrying: %d\n", val);
}
if (retry == MAX_RETRY) {
printf("Too many retries on a tranzport write, aborting\n");
}
if (val < 0) {
printf("usb_interrupt_write failed: %d\n", val);
return val;
}
if (val != 8) {
printf("usb_interrupt_write failed: %d\n", val);
return -1;
}
++inflight;
return 0;
#else
return (write_noretry(cmd,timeout_override));
#endif
}
#endif

View File

@ -1,120 +0,0 @@
/*
* Copyright (C) 2006 Paul Davis
* Copyright (C) 2007 Michael Taht
*
* 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.
*
* */
#include <tranzport_control_protocol.h>
// doing these functions made me realize that screen_invalid should be lcd_isdamaged FIXME soon
bool TranzportControlProtocol::lcd_damage()
{
screen_invalidate();
return true;
}
bool TranzportControlProtocol::lcd_damage (int row, int col, int length)
{
std::bitset<ROWS*COLUMNS> mask1(0);
// there's an intrinsic to do this fast, darn it, or I'm just sleepy
for (int i = 0; i < length; i++) { mask1[i] = 1; }
std::bitset<ROWS*COLUMNS> mask(mask1 << (row*COLUMNS+col));
screen_invalid |= mask;
return true;
}
// Still working on the layering, arguably screen_invalid should be lcd_invalid
// or vice versa
bool TranzportControlProtocol::lcd_isdamaged ()
{
if(screen_invalid.any()) {
#if DEBUG_TRANZPORT > 5
printf("LCD is damaged somewhere, should redraw it\n");
#endif
return true;
}
return false;
}
bool TranzportControlProtocol::lcd_isdamaged (int row, int col, int length)
{
// there's an intrinsic to do this fast, darn it
std::bitset<ROWS*COLUMNS> mask1(0);
for (int i = 0; i < length; i++) { mask1[i] = 1; }
std::bitset<ROWS*COLUMNS> mask(mask1 << (row*COLUMNS+col));
mask &= screen_invalid;
if(mask.any()) {
#if DEBUG_TRANZPORT > 5
printf("row: %d,col: %d is damaged, should redraw it\n", row,col);
#endif
return true;
}
return false;
}
// lcd_clear would be a separate function for a smart display
// here it does nothing, but for the sake of completeness it should
// probably write the lcd, and while I'm on the topic it should probably
// take a row, col, length argument....
void
TranzportControlProtocol::lcd_clear ()
{
}
// These lcd commands are not universally used yet and may drop out of the api
int
TranzportControlProtocol::lcd_flush ()
{
return 0;
}
int
TranzportControlProtocol::lcd_write(uint8_t* cmd, uint32_t timeout_override)
{
int result;
#if (DEBUG_TRANZPORT_SCREEN > 0)
printf("VALID : %s\n", (screen_invalid.to_string()).c_str());
#endif
if ((result = write(cmd,timeout_override))) {
#if DEBUG_TRANZPORT > 4
printf("usb screen update failed for some reason... why? \nresult, cmd and data were %d %02x %02x %02x %02x %02x %02x %02x %02x\n",
result, cmd[0],cmd[1],cmd[2], cmd[3], cmd[4], cmd[5],cmd[6],cmd[7]);
#endif
}
return result;
}
void
TranzportControlProtocol::lcd_fill (uint8_t fill_char)
{
}
void
TranzportControlProtocol::lcd_print (int row, int col, const char* text)
{
print(row,col,text);
}
void TranzportControlProtocol::lcd_print_noretry (int row, int col, const char* text)
{
print(row,col,text);
}

View File

@ -1,95 +0,0 @@
/*
* Copyright (C) 2006 Paul Davis
* Copyright (C) 2007 Michael Taht
*
* 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.
*
* */
#include <tranzport_control_protocol.h>
// Lights are buffered, and arguably these functions should be eliminated or inlined
void
TranzportControlProtocol::lights_on ()
{
lights_pending.set();
}
void
TranzportControlProtocol::lights_off ()
{
lights_pending.reset();
}
int
TranzportControlProtocol::light_on (LightID light)
{
lights_pending.set(light);
return 0;
}
int
TranzportControlProtocol::light_off (LightID light)
{
lights_pending.reset(light);
return 0;
}
void TranzportControlProtocol::lights_init()
{
lights_invalid.set();
lights_flash = lights_pending = lights_current.reset();
}
// Now that all this is bitsets, I don't see much
// need for these 4 to remain in the API
void TranzportControlProtocol::light_validate (LightID light)
{
lights_invalid.reset(light);
}
void TranzportControlProtocol::light_invalidate (LightID light)
{
lights_invalid.set(light);
}
void TranzportControlProtocol::lights_validate ()
{
lights_invalid.reset();
}
void TranzportControlProtocol::lights_invalidate ()
{
lights_invalid.set();
}
int
TranzportControlProtocol::light_set (LightID light, bool offon)
{
uint8_t cmd[8];
cmd[0] = 0x00; cmd[1] = 0x00; cmd[2] = light; cmd[3] = offon;
cmd[4] = 0x00; cmd[5] = 0x00; cmd[6] = 0x00; cmd[7] = 0x00;
if (write (cmd) == 0) {
lights_current[light] = offon;
lights_invalid.reset(light);
return 0;
} else {
return 1;
}
}

View File

@ -1,21 +0,0 @@
/*
* Copyright (C) 2006 Paul Davis
* Copyright (C) 2007 Michael Taht
*
* 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.
*
* */
/* Generic support for character based metering on a track */

View File

@ -1,107 +0,0 @@
/*
* Copyright (C) 2006 Paul Davis
* Copyright (C) 2007 Michael Taht
*
* 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.
*
* */
#include <tranzport_control_protocol.h>
void
TranzportControlProtocol::normal_update ()
{
show_current_track ();
show_transport_time ();
show_track_gain ();
show_wheel_mode ();
}
void
TranzportControlProtocol::next_display_mode ()
{
switch (display_mode) {
case DisplayNormal:
enter_big_meter_mode();
break;
case DisplayBigMeter:
enter_normal_display_mode();
break;
case DisplayRecording:
enter_normal_display_mode();
break;
case DisplayRecordingMeter:
enter_big_meter_mode();
break;
case DisplayConfig:
case DisplayBling:
case DisplayBlingMeter:
enter_normal_display_mode();
break;
}
}
// FIXME: There should be both enter and exits
// EXIT would erase the portions of the screen being written
// to.
/* not sure going macro crazy is a good idea
#define DECLARE_ENTER_MODE(mode,modename) void TranzportControlProtocol::enter_##mode##_mode() \{\screen_clear(); lights_off(); display_mode=Display##modename;\;
*/
void
TranzportControlProtocol::enter_recording_mode ()
{
screen_clear ();
lights_off ();
display_mode = DisplayRecording;
}
void
TranzportControlProtocol::enter_bling_mode ()
{
screen_clear ();
lights_off ();
display_mode = DisplayBling;
}
void
TranzportControlProtocol::enter_config_mode ()
{
lights_off ();
screen_clear ();
display_mode = DisplayConfig;
}
void
TranzportControlProtocol::enter_big_meter_mode ()
{
lights_off (); // it will clear the screen for you
last_meter_fill = 0;
display_mode = DisplayBigMeter;
}
void
TranzportControlProtocol::enter_normal_display_mode ()
{
lights_off ();
screen_clear ();
display_mode = DisplayNormal;
}

View File

@ -1,21 +0,0 @@
/*
* Copyright (C) 2006 Paul Davis
* Copyright (C) 2007 Michael Taht
*
* 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.
*
* */
/* placeholder for Marker Mode: Edit Markers, Setup Loops, and Punch in points */

View File

@ -1,21 +0,0 @@
/*
* Copyright (C) 2006 Paul Davis
* Copyright (C) 2007 Michael Taht
*
* 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.
*
* */
/* Placeholder for a tuner mode at some point */

View File

@ -1,34 +0,0 @@
/*
* Copyright (C) 2006 Paul Davis
* Copyright (C) 2007 Michael Taht
*
* 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.
*
*/
#include <tranzport_common.h>
#include <tranzport_control_protocol.h>
void
TranzportControlProtocol::step_pan_right ()
{
}
void
TranzportControlProtocol::step_pan_left ()
{
}

View File

@ -1,95 +0,0 @@
/*
* Copyright (C) 2006 Paul Davis
* Copyright (C) 2007 Michael Taht
*
* 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.
*
* */
#include <cstring>
#include <tranzport_control_protocol.h>
#include <cstring>
void
TranzportControlProtocol::screen_clear ()
{
const char *blank = " ";
print(0,0,blank);
print(1,0,blank);
}
void TranzportControlProtocol::screen_invalidate ()
{
screen_invalid.set();
for(int row = 0; row < ROWS; row++) {
for(int col = 0; col < COLUMNS; col++) {
screen_current[row][col] = 0x7f;
screen_pending[row][col] = ' ';
screen_flash[row][col] = ' ';
}
}
}
void TranzportControlProtocol::screen_validate ()
{
}
void TranzportControlProtocol::screen_init ()
{
screen_invalidate();
}
// FIXME: Switch to a column oriented flush to make the redraw of the
// meters look better
int
TranzportControlProtocol::screen_flush ()
{
int cell = 0, row=0, col_base, pending = 0;
const unsigned long CELL_BITS = 0x0F;
if ( _device_status == STATUS_OFFLINE) { return (-1); }
std::bitset<ROWS*COLUMNS> mask(CELL_BITS);
std::bitset<ROWS*COLUMNS> imask(CELL_BITS);
for(cell = 0; cell < 10 && pending == 0; cell++) {
mask = imask << (cell*4);
if((screen_invalid & mask).any()) {
/* something in this cell is different, so dump the cell to the device. */
#if DEBUG_TRANZPORT_SCREEN
printf("MASK : %s\n", mask.to_string().c_str());
#endif
if(cell > 4) { row = 1; } else { row = 0; }
col_base = (cell*4)%COLUMNS;
uint8_t cmd[8];
cmd[0] = 0x00;
cmd[1] = 0x01;
cmd[2] = cell;
cmd[3] = screen_pending[row][col_base];
cmd[4] = screen_pending[row][col_base+1];
cmd[5] = screen_pending[row][col_base+2];
cmd[6] = screen_pending[row][col_base+3];
cmd[7] = 0x00;
if((pending = lcd_write(cmd)) == 0) {
/* successful write: copy to current cached display */
screen_invalid &= mask.flip();
memcpy (&screen_current[row][col_base], &screen_pending[row][col_base], 4);
}
}
}
return pending;
}

View File

@ -1,399 +0,0 @@
/*
* Copyright (C) 2006 Paul Davis
* Copyright (C) 2007 Michael Taht
*
* 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.
*
* */
#include <iostream>
#include <algorithm>
#include <cmath>
#define __STDC_FORMAT_MACROS
#include <inttypes.h>
#include <float.h>
#include <sys/time.h>
#include <errno.h>
#include "pbd/pthread_utils.h"
#include "ardour/route.h"
#include "ardour/audio_track.h"
#include "ardour/session.h"
#include "ardour/tempo.h"
#include "ardour/location.h"
#include "ardour/dB.h"
#include "tranzport_control_protocol.h"
using namespace ARDOUR;
using namespace std;
using namespace sigc;
using namespace PBD;
#include "pbd/i18n.h"
#include "pbd/abstract_ui.cc"
float
log_meter (float db)
{
float def = 0.0f; /* Meter deflection %age */
if (db < -70.0f) return 0.0f;
if (db > 6.0f) return 1.0f;
if (db < -60.0f) {
def = (db + 70.0f) * 0.25f;
} else if (db < -50.0f) {
def = (db + 60.0f) * 0.5f + 2.5f;
} else if (db < -40.0f) {
def = (db + 50.0f) * 0.75f + 7.5f;
} else if (db < -30.0f) {
def = (db + 40.0f) * 1.5f + 15.0f;
} else if (db < -20.0f) {
def = (db + 30.0f) * 2.0f + 30.0f;
} else if (db < 6.0f) {
def = (db + 20.0f) * 2.5f + 50.0f;
}
/* 115 is the deflection %age that would be
when db=6.0. this is an arbitrary
endpoint for our scaling.
*/
return def/115.0f;
}
#define TRANZ_U 0x1 /* upper */
#define TRANZ_BL 0x2 /* lower left */
#define TRANZ_Q2 0x3 /* 2 quadrant block */
#define TRANZ_ULB 0x4 /* Upper + lower left */
#define TRANZ_L 0x5 /* lower */
#define TRANZ_UBL 0x6 /* upper left + bottom all */
#define TRANZ_Q4 0x7 /* 4 quadrant block */
#define TRANZ_UL 0x08 /* upper left */
// Shift Space - switches your "view"
// Currently defined views are:
// BigMeter
//
// Shift Record - SAVE SNAPSHOT
// Somewhere I was rewriting this
// Other meters
// Inverted - show meters "inside out" For example 4 meters covering 2 cells each, and the
//
// each 4 character cell could be an 8 bar meter = 10 meters!
// Dual Meter mode - master and current track
// We have 16 rows of pixels so we COULD do a vertical meter
// BEAT BLOCKS - For each beat, flash a 8 block (could use the center for vertical meters)
// Could have something generic that could handle up to /20 time
// Odd times could flash the whole top bar for the first beat
// Vertical Meter _ .colon - + ucolon A P R I H FULLBLACK
// MV@$%&*()-
// 3 char block rotating beat `\'/
// 1 char rotating beat {/\}
// 4 char in block rotating beat {/\}
// {\/)
void TranzportControlProtocol::show_mini_meter()
{
// FIXME - show the current marker in passing
const int meter_buf_size = 41;
static uint32_t last_meter_fill_l = 0;
static uint32_t last_meter_fill_r = 0;
uint32_t meter_size;
float speed = fabsf(get_transport_speed());
char buf[meter_buf_size];
if (speed == 1.0) {
meter_size = 32;
}
if (speed == 0.0) {
meter_size = 20; // not actually reached
}
if (speed > 0.0 && (speed < 1.0)) {
meter_size = 20; // may shrink more one day
}
if (speed > 1.0 && (speed < 2.0)) {
meter_size = 20;
}
if (speed >= 2.0) {
meter_size = 24;
}
// you only seem to get a route_table[0] == 0 on moving forward - bug in next_track?
if (route_table[0] == 0) {
// Principle of least surprise
print (1, 0, "NoAUDIO ");
return;
}
float level_l = route_get_peak_input_power (0, 0);
float fraction_l = log_meter (level_l);
// how to figure out if we are mono?
float level_r = route_get_peak_input_power (0, 1);
float fraction_r = log_meter (level_r);
uint32_t fill_left = (uint32_t) floor (fraction_l * ((int) meter_size));
uint32_t fill_right = (uint32_t) floor (fraction_r * ((int) meter_size));
if (fill_left == last_meter_fill_l && fill_right == last_meter_fill_r && !lcd_isdamaged(1,0,meter_size/2)) {
/* nothing to do */
return;
}
last_meter_fill_l = fill_left; last_meter_fill_r = fill_right;
// give some feedback when overdriving - override yellow and red lights
if (fraction_l > 0.96 || fraction_r > 0.96) {
light_on (LightLoop);
}
if (fraction_l == 1.0 || fraction_r == 1.0) {
light_on (LightTrackrec);
}
const uint8_t char_map[16] = { ' ', TRANZ_UL,
TRANZ_U, TRANZ_U,
TRANZ_BL, TRANZ_Q2,
TRANZ_Q2, TRANZ_ULB,
TRANZ_L, TRANZ_UBL,
' ',' ',
TRANZ_L, TRANZ_UBL,
TRANZ_Q4,TRANZ_Q4
};
unsigned int val,j,i;
for(j = 1, i = 0; i < meter_size/2; i++, j+=2) {
val = (fill_left >= j) | ((fill_left >= j+1) << 1) |
((fill_right >=j) << 2) | ((fill_right >= j+1) << 3);
buf[i] = char_map[val];
}
/* print() requires this */
buf[meter_size/2] = '\0';
print (1, 0, buf);
/* Add a peak bar, someday do falloff */
// char peak[2]; peak[0] = ' '; peak[1] = '\0';
// if(fraction_l == 1.0 || fraction_r == 1.0) peak[0] = 'P';
// print (1,8,peak); // Put a peak meter - P in if we peaked.
}
void
TranzportControlProtocol::show_meter ()
{
// you only seem to get a route_table[0] on moving forward - bug elsewhere
if (route_table[0] == 0) {
// Principle of least surprise
print (0, 0, "No audio to meter!!!");
print (1, 0, "Select another track");
return;
}
float level = route_get_peak_input_power (0, 0);
float fraction = log_meter (level);
/* Someday add a peak bar*/
/* we draw using a choice of a sort of double colon-like character ("::") or a single, left-aligned ":".
the screen is 20 chars wide, so we can display 40 different levels. compute the level,
then figure out how many "::" to fill. if the answer is odd, make the last one a ":"
*/
uint32_t fill = (uint32_t) floor (fraction * 40);
char buf[21];
uint32_t i;
if (fill == last_meter_fill) {
/* nothing to do */
return;
}
last_meter_fill = fill;
bool add_single_level = (fill % 2 != 0);
fill /= 2;
if (fraction > 0.96) {
light_on (LightLoop);
}
if (fraction == 1.0) {
light_on (LightTrackrec);
}
/* add all full steps */
for (i = 0; i < fill; ++i) {
buf[i] = 0x07; /* tranzport special code for 4 quadrant LCD block */
}
/* add a possible half-step */
if (i < 20 && add_single_level) {
buf[i] = 0x03; /* tranzport special code for 2 left quadrant LCD block */
++i;
}
/* fill rest with space */
for (; i < 20; ++i) {
buf[i] = ' ';
}
/* print() requires this */
buf[20] = '\0';
print (0, 0, buf);
print (1, 0, buf);
}
void
TranzportControlProtocol::show_bbt (samplepos_t where)
{
if (where != last_where) {
char buf[16];
Temporal::BBT_Time bbt;
// When recording or playing back < 1.0 speed do 1 or 2
// FIXME - clean up state machine & break up logic
// this has to co-operate with the mini-meter and
// this is NOT the right way.
session->tempo_map().bbt_time (where, bbt);
last_bars = bbt.bars;
last_beats = bbt.beats;
last_ticks = bbt.ticks;
last_where = where;
float speed = fabsf(get_transport_speed());
if (speed == 1.0) {
sprintf (buf, "%03" PRIu32 "%1" PRIu32, bbt.bars,bbt.beats); // switch to hex one day
print (1, 16, buf);
}
if (speed == 0.0) {
sprintf (buf, "%03" PRIu32 "|%1" PRIu32 "|%04" PRIu32, bbt.bars,bbt.beats,bbt.ticks);
print (1, 10, buf);
}
if (speed > 0.0 && (speed < 1.0)) {
sprintf (buf, "%03" PRIu32 "|%1" PRIu32 "|%04" PRIu32, bbt.bars,bbt.beats,bbt.ticks);
print (1, 10, buf);
}
if (speed > 1.0 && (speed < 2.0)) {
sprintf (buf, "%03" PRIu32 "|%1" PRIu32 "|%04" PRIu32, bbt.bars,bbt.beats,bbt.ticks);
print (1, 10, buf);
}
if (speed >= 2.0) {
sprintf (buf, "%03" PRIu32 "|%1" PRIu32 "|%02" PRIu32, bbt.bars,bbt.beats,bbt.ticks);
print (1, 12, buf);
}
TempoMap::Metric m (session->tempo_map().metric_at (where));
// the lights stop working well at above 100 bpm so don't bother
if(m.tempo().beats_per_minute() < 101.0 && (speed > 0.0)) {
// something else can reset these, so we need to
lights_pending[LightRecord] = false;
lights_pending[LightAnysolo] = false;
switch(last_beats) {
case 1: if(last_ticks < 250 || last_ticks >= 0) lights_pending[LightRecord] = true; break;
default: if(last_ticks < 250) lights_pending[LightAnysolo] = true;
}
}
}
}
void
TranzportControlProtocol::show_transport_time ()
{
show_bbt (session->transport_sample ());
}
void
TranzportControlProtocol::show_timecode (samplepos_t where)
{
if ((where != last_where) || lcd_isdamaged(1,9,10)) {
char buf[5];
Timecode::Time timecode;
session->timecode_time (where, timecode);
if (timecode.negative) {
sprintf (buf, "-%02" PRIu32 ":", timecode.hours);
} else {
sprintf (buf, " %02" PRIu32 ":", timecode.hours);
}
print (1, 8, buf);
sprintf (buf, "%02" PRIu32 ":", timecode.minutes);
print (1, 12, buf);
sprintf (buf, "%02" PRIu32 ":", timecode.seconds);
print (1, 15, buf);
sprintf (buf, "%02" PRIu32, timecode.frames);
print_noretry (1, 18, buf);
last_where = where;
}
}
void
TranzportControlProtocol::show_track_gain ()
{
// FIXME last_track gain has to become meter/track specific
if (route_table[0]) {
gain_t g = route_get_gain (0);
if ((g != last_track_gain) || lcd_isdamaged(0,12,8)) {
char buf[16];
snprintf (buf, sizeof (buf), "%6.1fdB", coefficient_to_dB (route_get_effective_gain (0)));
print (0, 12, buf);
last_track_gain = g;
}
} else {
print (0, 9, " ");
}
}

View File

@ -1,40 +0,0 @@
/*
* Copyright (C) 2006 Paul Davis
* Copyright (C) 2007 Michael Taht
*
* 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.
*
* */
#ifndef ardour_slider_gain
#define ardour_slider_gain
static inline double
gain_to_slider_position (ARDOUR::gain_t g)
{
if (g == 0) return 0;
return pow((6.0*log(g)/log(2.0)+192.0)/198.0, 8.0);
}
static inline ARDOUR::gain_t
slider_position_to_gain (double pos)
{
/* XXX Marcus writes: this doesn't seem right to me. but i don't have a better answer ... */
if (pos == 0.0) return 0;
return pow (2.0,(sqrt(sqrt(sqrt(pos)))*198.0-192.0)/6.0);
}
#endif

View File

@ -1,146 +0,0 @@
/*
* Copyright (C) 2006 Paul Davis
* Copyright (C) 2007 Michael Taht
*
* 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.
*
*/
#include <iostream>
#include <algorithm>
#include <cmath>
#define __STDC_FORMAT_MACROS
#include <inttypes.h>
#include <float.h>
#include <sys/time.h>
#include <errno.h>
#include "ardour/route.h"
#include "ardour/audio_track.h"
#include "ardour/session.h"
#include "ardour/location.h"
#include "ardour/dB.h"
using namespace ARDOUR;
using namespace std;
using namespace sigc;
using namespace PBD;
#include "pbd/i18n.h"
#include "pbd/abstract_ui.cc"
#include "tranzport_control_protocol.h"
// FIXME: How to handle multiple tranzports in a system?
XMLNode&
TranzportControlProtocol::get_state () const
{
return ControlProtocol::get_state();
}
int
TranzportControlProtocol::set_state (const XMLNode& node)
{
cout << "TranzportControlProtocol::set_state: active " << _active << endl;
int retval = 0;
// I think I want to make these strings rather than numbers
#if 0
// fetch current display mode
if ( node.property( X_("display_mode") ) != 0 )
{
string display = node.property( X_("display_mode") )->value();
try
{
set_active( true );
int32_t new_display = atoi( display.c_str() );
if ( display_mode != new_display ) display_mode = (DisplayMode)new_display;
}
catch ( exception & e )
{
cout << "exception in TranzportControlProtocol::set_state: " << e.what() << endl;
return -1;
}
}
if ( node.property( X_("wheel_mode") ) != 0 )
{
string wheel = node.property( X_("wheel_mode") )->value();
try
{
int32_t new_wheel = atoi( wheel.c_str() );
if ( wheel_mode != new_wheel ) wheel_mode = (WheelMode) new_wheel;
}
catch ( exception & e )
{
cout << "exception in TranzportControlProtocol::set_state: " << e.what() << endl;
return -1;
}
}
// fetch current bling mode
if ( node.property( X_("bling") ) != 0 )
{
string bling = node.property( X_("bling_mode") )->value();
try
{
int32_t new_bling = atoi( bling.c_str() );
if ( bling_mode != new_bling ) bling_mode = (BlingMode) new_bling;
}
catch ( exception & e )
{
cout << "exception in TranzportControlProtocol::set_state: " << e.what() << endl;
return -1;
}
}
#endif
return retval;
}
// These are intended for the day we have more options for tranzport modes
// And perhaps we could load up sessions this way, too
int
TranzportControlProtocol::save (char *name)
{
// Presently unimplemented
return 0;
}
int
TranzportControlProtocol::load (char *name)
{
// Presently unimplemented
return 0;
}
int
TranzportControlProtocol::save_config (char *name)
{
// Presently unimplemented
return 0;
}
int
TranzportControlProtocol::load_config (char *name)
{
// Presently unimplemented
return 0;
}

View File

@ -1,77 +0,0 @@
/*
* Copyright (C) 2006 Paul Davis
* Copyright (C) 2007 Michael Taht
*
* 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.
*
* */
/* This header file is basically where all the tranzport debuggable options go.
Try to only check it in with minimal debugging enabled so production
systems don't have to fiddle with it. */
/* Design notes: The tranzport is a unique device, basically a
20x2 character lcd gui with (almost) 22 shift keys and 8 blinking lights.
As such it has several unique constraints. In the libusb driver,
the device exerts flow control
by having a usb write fail. It is pointless to retry madly at that point,
the device is busy, and it's not going to become unbusy very quickly.
So writes need to be either "mandatory" or "unreliable", and therein
lies the rub, as the kernel can also drop writes, and missing an
interrupt in userspace is also generally bad.
However, the kernel driver retries writes for you and also buffers and
compresses incoming wheel events - it will rarely, if ever, drop data.
A more complex surface might have hundreds of lights and several displays.
mike@taht.net
*/
#ifndef ardour_tranzport_base
#define ardour_tranzport_base
#define DEFAULT_USB_TIMEOUT 10
#define MAX_RETRY 1
#define MAX_TRANZPORT_INFLIGHT 4
#define DEBUG_TRANZPORT 0
#ifndef HAVE_TRANZPORT_KERNEL_DRIVER
#define HAVE_TRANZPORT_KERNEL_DRIVER 0
#endif
#ifndef HAVE_TRANZPORT_MIDI_DRIVER
#define HAVE_TRANZPORT_MIDI_DRIVER 0
#endif
// for now, this is what the device is called
#define TRANZPORT_DEVICE "/dev/tranzport0"
#if DEBUG_TRANZPORT > 0
#define DEBUG_TRANZPORT_SCREEN 10
#define DEBUG_TRANZPORT_BITS 10
#define DEBUG_TRANZPORT_LIGHTS 10
#define DEBUG_TRANZPORT_STATE 10
#else
#define DEBUG_TRANZPORT 0
#define DEBUG_TRANZPORT_BITS 0
#define DEBUG_TRANZPORT_SCREEN 0
#define DEBUG_TRANZPORT_LIGHTS 0
#define DEBUG_TRANZPORT_STATE 0
#endif
#endif /* ardour_tranzport_base */

View File

@ -1,44 +0,0 @@
/*
* Copyright (C) 2006 Paul Davis
* Copyright (C) 2007 Michael Taht
*
* 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.
*
* */
/* The most common header files that the tranzport uses */
#ifndef ardour_tranzport_common
#define ardour_tranzport_common
#include <iostream>
#include <algorithm>
#include <cmath>
#define __STDC_FORMAT_MACROS
#include <inttypes.h>
#include <float.h>
#include <sys/time.h>
#include <errno.h>
#include "pbd/pthread_utils.h"
#include "ardour/route.h"
#include "ardour/audio_track.h"
#include "ardour/rc_configuration.h"
#include "ardour/tempo.h"
#include "ardour/location.h"
#include "ardour/dB.h"
#endif /* ardour_tranzport_common */

View File

@ -1,380 +0,0 @@
/*
Copyright (C) 2006 Paul Davis
Copyright (C) 2007 Mike Taht
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.
*/
#ifndef ardour_tranzport_control_protocol_h
#define ardour_tranzport_control_protocol_h
#include "tranzport_base.h"
#include <vector>
#include <bitset>
#include <sys/time.h>
#include <pthread.h>
#if !HAVE_TRANZPORT_KERNEL_DRIVER
#include <usb.h>
#endif
#include <glibmm/threads.h>
#include "ardour/types.h"
#include "control_protocol/control_protocol.h"
class TranzportControlProtocol : public ARDOUR::ControlProtocol
{
public:
TranzportControlProtocol (ARDOUR::Session&);
virtual ~TranzportControlProtocol();
int set_active (bool yn);
static bool available ();
XMLNode& get_state () const;
int set_state (const XMLNode&);
private:
static const int VENDORID = 0x165b;
static const int PRODUCTID = 0x8101;
static const int READ_ENDPOINT = 0x81;
static const int WRITE_ENDPOINT = 0x02;
const static int STATUS_OFFLINE = 0xff;
const static int STATUS_ONLINE = 0x01;
const static int STATUS_OK = 0x00;
const static int LIGHTS = 7;
const static int ROWS = 2;
const static int COLUMNS = 20;
const static uint8_t WheelDirectionThreshold = 0x7f;
enum LightID {
LightRecord = 0,
LightTrackrec,
LightTrackmute,
LightTracksolo,
LightAnysolo,
LightLoop,
LightPunch
};
enum ButtonID {
ButtonBattery = 0x00004000,
ButtonBacklight = 0x00008000,
ButtonTrackLeft = 0x04000000,
ButtonTrackRight = 0x40000000,
ButtonTrackRec = 0x00040000,
ButtonTrackMute = 0x00400000,
ButtonTrackSolo = 0x00000400,
ButtonUndo = 0x80000000,
ButtonIn = 0x02000000,
ButtonOut = 0x20000000,
ButtonPunch = 0x00800000,
ButtonLoop = 0x00080000,
ButtonPrev = 0x00020000,
ButtonAdd = 0x00200000,
ButtonNext = 0x00000200,
ButtonRewind = 0x01000000,
ButtonFastForward = 0x10000000,
ButtonStop = 0x00010000,
ButtonPlay = 0x00100000,
ButtonRecord = 0x00000100,
ButtonShift = 0x08000000,
ButtonFootswitch = 0x00001000
};
enum WheelShiftMode {
WheelShiftGain,
WheelShiftPan,
WheelShiftMaster,
WheelShiftMarker
};
enum WheelMode {
WheelTimeline,
WheelScrub,
WheelShuttle
};
// FIXME - look at gtk2_ardour for snap settings
enum WheelIncrement {
WheelIncrSlave,
WheelIncrScreen,
WheelIncrSample,
WheelIncrBeat,
WheelIncrBar,
WheelIncrSecond,
WheelIncrMinute
};
enum DisplayMode {
DisplayNormal,
DisplayRecording,
DisplayRecordingMeter,
DisplayBigMeter,
DisplayConfig,
DisplayBling,
DisplayBlingMeter
};
enum BlingMode {
BlingOff,
BlingKit,
BlingRotating,
BlingPairs,
BlingRows,
BlingFlashAll,
BlingEnter,
BlingExit
};
pthread_t thread;
#if HAVE_TRANZPORT_KERNEL_DRIVER
int udev;
#else
usb_dev_handle* udev;
#endif
int last_read_error;
uint32_t buttonmask;
uint32_t timeout;
uint32_t inflight;
uint32_t current_track_id;
int last_write_error;
uint8_t _datawheel;
uint8_t _device_status;
WheelMode wheel_mode;
WheelShiftMode wheel_shift_mode;
DisplayMode display_mode;
BlingMode bling_mode;
WheelIncrement wheel_increment;
ARDOUR::gain_t gain_fraction;
Glib::Threads::Mutex update_lock;
std::bitset<ROWS*COLUMNS> screen_invalid;
char screen_current[ROWS][COLUMNS];
char screen_pending[ROWS][COLUMNS];
char screen_flash[ROWS][COLUMNS];
std::bitset<LIGHTS> lights_invalid;
std::bitset<LIGHTS> lights_current;
std::bitset<LIGHTS> lights_pending;
std::bitset<LIGHTS> lights_flash;
int32_t last_notify;
char last_notify_msg[COLUMNS+1];
uint32_t last_bars;
uint32_t last_beats;
uint32_t last_ticks;
bool last_negative;
uint32_t last_hrs;
uint32_t last_mins;
uint32_t last_secs;
uint32_t last_samples;
samplepos_t last_where;
ARDOUR::gain_t last_track_gain;
uint32_t last_meter_fill;
struct timeval last_wheel_motion;
int last_wheel_dir;
Glib::Mutex io_lock;
int open ();
int read (uint8_t *buf,uint32_t timeout_override = 0);
int write (uint8_t* cmd, uint32_t timeout_override = 0);
int write_noretry (uint8_t* cmd, uint32_t timeout_override = 0);
int close ();
int save_config(char *name = "default");
int load_config(char *name = "default");
int save(char *name);
int load(char *name);
void print (int row, int col, const char* text);
void print_noretry (int row, int col, const char* text);
void notify(const char *msg);
#if HAVE_TRANZPORT_KERNEL_DRIVER
int rtpriority_set(int priority = 3); // we don't need serious rt privs anymore
#else
int rtpriority_set(int priority = 52);
#endif
int rtpriority_unset(int priority = 0);
// I hate changing the api to do either but until I have clean io class what can you do?
#if !HAVE_TRANZPORT_KERNEL_DRIVER
int open_core (struct usb_device*);
#endif
static void* _monitor_work (void* arg);
void* monitor_work ();
int process (uint8_t *);
int update_state();
void invalidate();
int flush();
// bool isuptodate(); // think on this. It seems futile to update more than 30/sec
// A screen is a cache of what should be on the lcd
void screen_init();
void screen_validate();
void screen_invalidate();
int screen_flush();
void screen_clear();
// bool screen_isuptodate(); // think on this -
int screen_show_bling();
// Commands to write to the lcd
int lcd_init();
bool lcd_damage();
bool lcd_isdamaged();
bool lcd_damage(int row, int col = 0, int length = COLUMNS);
bool lcd_isdamaged(int row, int col = 0, int length = COLUMNS);
int lcd_flush();
int lcd_write(uint8_t* cmd, uint32_t timeout_override = 0); // pedantic alias for write
void lcd_fill (uint8_t fill_char);
void lcd_clear ();
void lcd_print (int row, int col, const char* text);
void lcd_print_noretry (int row, int col, const char* text);
// Commands to write to the lights
// FIXME - on some devices lights can have intensity and colors
void lights_init();
void lights_validate();
void lights_invalidate();
void light_validate(LightID light);
void light_invalidate(LightID light);
int lights_flush();
int lights_write(uint8_t* cmd,uint32_t timeout_override = 0); // pedantic alias to write
// a cache of what should be lit
void lights_off ();
void lights_on ();
int light_set(LightID, bool offon = true);
int light_on (LightID);
int light_off (LightID);
// some modes for the lights, should probably be renamed
int lights_show_normal();
int lights_show_recording();
int lights_show_tempo();
int lights_show_bling();
void enter_big_meter_mode ();
void enter_normal_display_mode ();
void enter_config_mode();
void enter_recording_mode();
void enter_bling_mode();
void next_marker (); // basicui doesn't give me enough info
void prev_marker ();
void next_display_mode ();
void normal_update ();
void show_current_track ();
void show_track_gain ();
void show_transport_time ();
void show_bbt (samplepos_t where);
void show_timecode (samplepos_t where);
void show_wheel_mode ();
void show_gain ();
void show_pan ();
void show_meter ();
void show_mini_meter ();
void show_bling();
void show_notify();
void datawheel ();
void scrub ();
void scroll ();
void shuttle ();
void config ();
void next_wheel_mode ();
void next_wheel_shift_mode ();
void set_current_track (ARDOUR::Route*);
void next_track ();
void prev_track ();
void step_gain_up ();
void step_gain_down ();
void step_pan_right ();
void step_pan_left ();
void button_event_battery_press (bool shifted);
void button_event_battery_release (bool shifted);
void button_event_backlight_press (bool shifted);
void button_event_backlight_release (bool shifted);
void button_event_trackleft_press (bool shifted);
void button_event_trackleft_release (bool shifted);
void button_event_trackright_press (bool shifted);
void button_event_trackright_release (bool shifted);
void button_event_trackrec_press (bool shifted);
void button_event_trackrec_release (bool shifted);
void button_event_trackmute_press (bool shifted);
void button_event_trackmute_release (bool shifted);
void button_event_tracksolo_press (bool shifted);
void button_event_tracksolo_release (bool shifted);
void button_event_undo_press (bool shifted);
void button_event_undo_release (bool shifted);
void button_event_in_press (bool shifted);
void button_event_in_release (bool shifted);
void button_event_out_press (bool shifted);
void button_event_out_release (bool shifted);
void button_event_punch_press (bool shifted);
void button_event_punch_release (bool shifted);
void button_event_loop_press (bool shifted);
void button_event_loop_release (bool shifted);
void button_event_prev_press (bool shifted);
void button_event_prev_release (bool shifted);
void button_event_add_press (bool shifted);
void button_event_add_release (bool shifted);
void button_event_next_press (bool shifted);
void button_event_next_release (bool shifted);
void button_event_rewind_press (bool shifted);
void button_event_rewind_release (bool shifted);
void button_event_fastforward_press (bool shifted);
void button_event_fastforward_release (bool shifted);
void button_event_stop_press (bool shifted);
void button_event_stop_release (bool shifted);
void button_event_play_press (bool shifted);
void button_event_play_release (bool shifted);
void button_event_record_press (bool shifted);
void button_event_record_release (bool shifted);
void button_event_footswitch_press(bool shifted);
void button_event_footswitch_release (bool shifted);
// new api - still thinking about it
void button_event_mute (bool pressed, bool shifted);
};
#endif // ardour_tranzport_control_protocol_h

View File

@ -1,21 +0,0 @@
/*
* Copyright (C) 2006 Paul Davis
* Copyright (C) 2007 Michael Taht
*
* 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.
*
* */

View File

@ -1,21 +0,0 @@
/*
* Copyright (C) 2006 Paul Davis
* Copyright (C) 2007 Michael Taht
*
* 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.
*
* */

View File

@ -1,21 +0,0 @@
/*
* Copyright (C) 2006 Paul Davis
* Copyright (C) 2007 Michael Taht
*
* 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.
*
* */

View File

@ -1,21 +0,0 @@
/*
* Copyright (C) 2006 Paul Davis
* Copyright (C) 2007 Michael Taht
*
* 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.
*
* */

View File

@ -1,21 +0,0 @@
/*
* Copyright (C) 2006 Paul Davis
* Copyright (C) 2007 Michael Taht
*
* 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.
*
* */

View File

@ -1,21 +0,0 @@
/*
* Copyright (C) 2006 Paul Davis
* Copyright (C) 2007 Michael Taht
*
* 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.
*
* */
/* ultimately this view will let you: rotate layers (takes) on the currently selected track/region, do cross fades, and the like */

View File

@ -1,21 +0,0 @@
/*
* Copyright (C) 2006 Paul Davis
* Copyright (C) 2007 Michael Taht
*
* 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.
*
* */

View File

@ -1,21 +0,0 @@
/*
* Copyright (C) 2006 Paul Davis
* Copyright (C) 2007 Michael Taht
*
* 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.
*
* */

View File

@ -1,21 +0,0 @@
/*
* Copyright (C) 2006 Paul Davis
* Copyright (C) 2007 Michael Taht
*
* 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.
*
* */

View File

@ -1,21 +0,0 @@
/*
* Copyright (C) 2006 Paul Davis
* Copyright (C) 2007 Michael Taht
*
* 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.
*
* */

View File

@ -1,21 +0,0 @@
/*
* Copyright (C) 2006 Paul Davis
* Copyright (C) 2007 Michael Taht
*
* 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.
*
* */

View File

@ -1,21 +0,0 @@
/*
* Copyright (C) 2006 Paul Davis
* Copyright (C) 2007 Michael Taht
*
* 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.
*
* */

View File

@ -1,21 +0,0 @@
/*
* Copyright (C) 2006 Paul Davis
* Copyright (C) 2007 Michael Taht
*
* 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.
*
* */

View File

@ -1,21 +0,0 @@
/*
* Copyright (C) 2006 Paul Davis
* Copyright (C) 2007 Michael Taht
*
* 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.
*
* */

View File

@ -1,203 +0,0 @@
/*
* Copyright (C) 2006 Paul Davis
* Copyright (C) 2007 Michael Taht
*
* 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.
*
* */
#include <iostream>
#include <algorithm>
#include <cmath>
#define __STDC_FORMAT_MACROS
#include <inttypes.h>
#include <float.h>
#include <sys/time.h>
#include <errno.h>
#include "ardour/route.h"
#include "ardour/audio_track.h"
#include "ardour/session.h"
#include "ardour/location.h"
#include "ardour/dB.h"
using namespace ARDOUR;
using namespace std;
using namespace sigc;
using namespace PBD;
#include "pbd/i18n.h"
#include "pbd/abstract_ui.cc"
BaseUI::RequestType LEDChange = BaseUI::new_request_type ();
BaseUI::RequestType Print = BaseUI::new_request_type ();
BaseUI::RequestType SetCurrentTrack = BaseUI::new_request_type ();
#include "tranzport_control_protocol.h"
void
TranzportControlProtocol::datawheel ()
{
if ((buttonmask & ButtonTrackRight) || (buttonmask & ButtonTrackLeft)) {
/* track scrolling */
if (_datawheel < WheelDirectionThreshold) {
next_track ();
} else {
prev_track ();
}
last_wheel_motion = 0;
} else if ((buttonmask & ButtonPrev) || (buttonmask & ButtonNext)) {
if (_datawheel < WheelDirectionThreshold) {
next_marker ();
} else {
prev_marker ();
}
last_wheel_motion = 0;
} else if (buttonmask & ButtonShift) {
/* parameter control */
if (route_table[0]) {
switch (wheel_shift_mode) {
case WheelShiftGain:
if (_datawheel < WheelDirectionThreshold) {
step_gain_up ();
} else {
step_gain_down ();
}
break;
case WheelShiftPan:
if (_datawheel < WheelDirectionThreshold) {
step_pan_right ();
} else {
step_pan_left ();
}
break;
case WheelShiftMarker:
break;
case WheelShiftMaster:
break;
}
}
last_wheel_motion = 0;
} else {
switch (wheel_mode) {
case WheelTimeline:
scroll ();
break;
case WheelScrub:
scrub ();
break;
case WheelShuttle:
shuttle ();
break;
}
}
}
void
TranzportControlProtocol::scroll ()
{
float m = 1.0;
if (_datawheel < WheelDirectionThreshold) {
m = 1.0;
} else {
m = -1.0;
}
switch(wheel_increment) {
case WheelIncrScreen: ScrollTimeline (0.2*m); break;
case WheelIncrSlave:
case WheelIncrSample:
case WheelIncrBeat:
case WheelIncrBar:
case WheelIncrSecond:
case WheelIncrMinute:
default: break; // other modes unimplemented as yet
}
}
void
TranzportControlProtocol::scrub ()
{
float speed;
uint64_t now;
int dir;
now = g_get_monotonic_time();
if (_datawheel < WheelDirectionThreshold) {
dir = 1;
} else {
dir = -1;
}
if (dir != last_wheel_dir) {
/* changed direction, start over */
speed = 0.1f;
} else {
if (last_wheel_motion != 0) {
/* 10 clicks per second => speed == 1.0 */
speed = 100000.0f / (float) (now - last_wheel_motion)
} else {
/* start at half-speed and see where we go from there */
speed = 0.5f;
}
}
last_wheel_motion = now;
last_wheel_dir = dir;
set_transport_speed (speed * dir);
}
void
TranzportControlProtocol::shuttle ()
{
if (_datawheel < WheelDirectionThreshold) {
if (get_transport_speed() < 0) {
session->request_transport_speed (1.0);
} else {
session->request_transport_speed_nonzero (get_transport_speed() + 0.1);
}
} else {
if (session->get_transport_speed() > 0) {
session->request_transport_speed (-1.0);
} else {
session->request_transport_speed_nonzero (get_transport_speed() - 0.1);
}
}
session->request_roll ();
}

View File

@ -1,138 +0,0 @@
/*
* Copyright (C) 2006 Paul Davis
* Copyright (C) 2007 Michael Taht
*
* 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.
*
*/
#include <iostream>
#include <algorithm>
#include <cmath>
#define __STDC_FORMAT_MACROS
#include <inttypes.h>
#include <float.h>
#include <sys/time.h>
#include <errno.h>
#if HAVE_TRANZPORT_KERNEL_DRIVER
#include <fcntl.h>
#include <poll.h>
#endif
#include "pbd/pthread_utils.h"
#include "ardour/route.h"
#include "ardour/audio_track.h"
#include "ardour/tempo.h"
#include "ardour/location.h"
#include "ardour/dB.h"
#include "tranzport_control_protocol.h"
using namespace ARDOUR;
using namespace std;
using namespace sigc;
using namespace PBD;
#include "pbd/i18n.h"
#include <pbd/abstract_ui.cc>
void
TranzportControlProtocol::next_wheel_shift_mode ()
{
switch (wheel_shift_mode) {
case WheelShiftGain:
wheel_shift_mode = WheelShiftPan;
break;
case WheelShiftPan:
wheel_shift_mode = WheelShiftMaster;
break;
case WheelShiftMaster:
wheel_shift_mode = WheelShiftGain;
break;
case WheelShiftMarker: // Not done yet, disabled
wheel_shift_mode = WheelShiftGain;
break;
}
show_wheel_mode ();
}
void
TranzportControlProtocol::next_wheel_mode ()
{
switch (wheel_mode) {
case WheelTimeline:
wheel_mode = WheelScrub;
break;
case WheelScrub:
wheel_mode = WheelShuttle;
break;
case WheelShuttle:
wheel_mode = WheelTimeline;
}
show_wheel_mode ();
}
void
TranzportControlProtocol::show_wheel_mode ()
{
string text;
// if(get_transport_speed() != 0) {
// if session-transport_speed() < 1.0) show_big_bar/beat
// if ? greater. dont
if(get_transport_speed() != 0) {
show_mini_meter();
} else {
switch (wheel_mode) {
case WheelTimeline:
text = "Time";
break;
case WheelScrub:
text = "Scrb";
break;
case WheelShuttle:
text = "Shtl";
break;
}
switch (wheel_shift_mode) {
case WheelShiftGain:
text += ":Gain";
break;
case WheelShiftPan:
text += ":Pan ";
break;
case WheelShiftMaster:
text += ":Mstr";
break;
case WheelShiftMarker:
text += ":Mrkr";
break;
}
print (1, 0, text.c_str());
}
}

View File

@ -1,37 +0,0 @@
#!/usr/bin/env python
import os
def options(opt):
pass
def configure(conf):
pass
def build(bld):
obj = bld(features = 'cxx cxxshlib')
obj.source = '''
button_events.cc
buttons.cc
general.cc
init.cc
interface.cc
io.cc
io_usb.cc
lcd.cc
lights.cc
mode.cc
panner.cc
screen.cc
show.cc
state.cc
wheel.cc
wheel_modes.cc
'''
obj.defines = [ 'PACKAGE="ardour_tranzport"' ]
obj.defines += [ 'ARDOURSURFACE_DLL_EXPORTS' ]
obj.includes = ['.', './tranzport']
obj.name = 'libardour_tranzport'
obj.target = 'ardour_tranzport'
obj.uselib = 'XML OSX'
obj.use = 'libardour libardour_cp'
obj.install_path = os.path.join(bld.env['LIBDIR'], 'surfaces')

View File

@ -34,9 +34,6 @@ def configure(conf):
autowaf.set_recursive() autowaf.set_recursive()
#if Options.options.tranzport and conf.is_defined('HAVE_USB'):
# conf.define('BUILD_TRANZPORT', 1)
if conf.is_defined('HAVE_USB'): if conf.is_defined('HAVE_USB'):
children += [ 'push2' ] children += [ 'push2' ]
children += [ 'contourdesign' ] children += [ 'contourdesign' ]
@ -86,8 +83,6 @@ def build(bld):
if bld.is_defined('BUILD_WIIMOTE'): if bld.is_defined('BUILD_WIIMOTE'):
bld.recurse('wiimote') bld.recurse('wiimote')
if bld.is_defined('BUILD_TRANZPORT'):
bld.recurse('tranzport')
if bld.is_defined('HAVE_USB'): if bld.is_defined('HAVE_USB'):
bld.recurse('push2') bld.recurse('push2')
bld.recurse('contourdesign') bld.recurse('contourdesign')

View File

@ -900,8 +900,6 @@ def options(opt):
help="Run tests after build") help="Run tests after build")
opt.add_option('--single-tests', action='store_true', default=False, dest='single_tests', opt.add_option('--single-tests', action='store_true', default=False, dest='single_tests',
help="Build a single executable for each unit test") help="Build a single executable for each unit test")
#opt.add_option('--tranzport', action='store_true', default=False, dest='tranzport',
# help='Compile with support for Frontier Designs Tranzport (if libusb is available)')
opt.add_option('--maschine', action='store_true', default=False, dest='maschine', opt.add_option('--maschine', action='store_true', default=False, dest='maschine',
help='Compile with support for NI-Maschine') help='Compile with support for NI-Maschine')
opt.add_option('--generic', action='store_true', default=False, dest='generic', opt.add_option('--generic', action='store_true', default=False, dest='generic',
@ -1348,8 +1346,6 @@ int main () { __int128 x = 0; return 0; }
conf.env['RUN_TESTS'] = opts.run_tests conf.env['RUN_TESTS'] = opts.run_tests
if opts.single_tests: if opts.single_tests:
conf.env['SINGLE_TESTS'] = opts.single_tests conf.env['SINGLE_TESTS'] = opts.single_tests
#if opts.tranzport:
# conf.env['TRANZPORT'] = 1
if not opts.no_windows_vst: if not opts.no_windows_vst:
if Options.options.dist_target == 'mingw': if Options.options.dist_target == 'mingw':
conf.define('WINDOWS_VST_SUPPORT', 1) conf.define('WINDOWS_VST_SUPPORT', 1)
@ -1558,7 +1554,6 @@ const char* const ardour_config_info = "\\n\\
# write_config_text('Soundtouch', conf.is_defined('HAVE_SOUNDTOUCH')) # write_config_text('Soundtouch', conf.is_defined('HAVE_SOUNDTOUCH'))
write_config_text('Threaded WaveViews', not opts.no_threaded_waveviews) write_config_text('Threaded WaveViews', not opts.no_threaded_waveviews)
write_config_text('Translation', not opts.no_nls) write_config_text('Translation', not opts.no_nls)
# write_config_text('Tranzport', opts.tranzport)
write_config_text('Unit tests', conf.env['BUILD_TESTS']) write_config_text('Unit tests', conf.env['BUILD_TESTS'])
write_config_text('Use LLD linker', opts.use_lld) write_config_text('Use LLD linker', opts.use_lld)
write_config_text('VST3 support', conf.is_defined('VST3_SUPPORT')) write_config_text('VST3 support', conf.is_defined('VST3_SUPPORT'))