|
|
|
|
|
|
|
|
|
|
|
|
|
|
#define ZONE_COUNT 0x1e |
|
|
#define ZONE_COUNT 0x1e |
|
|
#define PORT_COUNT 196 |
|
|
#define PORT_COUNT 196 |
|
|
#define DISPLAY_COUNT 17 |
|
|
|
|
|
|
|
|
#define DISPLAY_COUNT 38 |
|
|
#define HDR 0xf0, 0x00, 0x00, 0x66, 0x05, 0x00 |
|
|
#define HDR 0xf0, 0x00, 0x00, 0x66, 0x05, 0x00 |
|
|
|
|
|
|
|
|
enum display_type { |
|
|
enum display_type { |
|
|
LABEL, |
|
|
LABEL, |
|
|
VPOT, |
|
|
VPOT, |
|
|
MAIN_DISPLAY |
|
|
|
|
|
|
|
|
MAIN_DISPLAY, |
|
|
|
|
|
TIMECODE, |
|
|
|
|
|
METER |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
/* enum vpot_mode { */ |
|
|
|
|
|
/* POINTER, */ |
|
|
|
|
|
/* CENTERED_FILL, */ |
|
|
|
|
|
/* FILL, */ |
|
|
|
|
|
/* WIDTH */ |
|
|
|
|
|
/* }; */ |
|
|
|
|
|
|
|
|
typedef struct { |
|
|
typedef struct { |
|
|
char zone; |
|
|
char zone; |
|
|
char port; |
|
|
char port; |
|
|
|
|
|
|
|
|
typedef struct { |
|
|
typedef struct { |
|
|
int type; |
|
|
int type; |
|
|
int id; |
|
|
int id; |
|
|
|
|
|
char state; |
|
|
void* io; |
|
|
void* io; |
|
|
} Hui_display_port_t; |
|
|
} Hui_display_port_t; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int argc, void *data, void *user_data); |
|
|
int argc, void *data, void *user_data); |
|
|
int osc_in_display_handler (const char *path, const char *types, lo_arg ** argv, |
|
|
int osc_in_display_handler (const char *path, const char *types, lo_arg ** argv, |
|
|
int argc, void *data, void *user_data); |
|
|
int argc, void *data, void *user_data); |
|
|
|
|
|
int osc_in_vpot_handler (const char *path, const char *types, lo_arg ** argv, |
|
|
|
|
|
int argc, void *data, void *user_data); |
|
|
|
|
|
int osc_in_meter_handler (const char *path, const char *types, lo_arg ** argv, |
|
|
|
|
|
int argc, void *data, void *user_data); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int main(int argc, char *argv[]) { |
|
|
int main(int argc, char *argv[]) { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int i; |
|
|
int i; |
|
|
int display_c = 0; |
|
|
int display_c = 0; |
|
|
|
|
|
|
|
|
|
|
|
// Labels |
|
|
for (i=0;i<9;i++) { |
|
|
for (i=0;i<9;i++) { |
|
|
Hui_display_port_t out = {LABEL,i,IOs}; |
|
|
|
|
|
|
|
|
Hui_display_port_t out = {LABEL, i, 0, IOs}; |
|
|
IOs->display_outs[display_c] = out; |
|
|
IOs->display_outs[display_c] = out; |
|
|
sprintf(address,"/label/%d",i); |
|
|
sprintf(address,"/label/%d",i); |
|
|
lo_server_thread_add_method(IOs->osc_in, |
|
|
lo_server_thread_add_method(IOs->osc_in, |
|
|
|
|
|
|
|
|
display_c++; |
|
|
display_c++; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Main display: |
|
|
for (i=0;i<8;i++) { |
|
|
for (i=0;i<8;i++) { |
|
|
Hui_display_port_t out = {MAIN_DISPLAY,i,IOs}; |
|
|
|
|
|
|
|
|
Hui_display_port_t out = {MAIN_DISPLAY, i, 0, IOs}; |
|
|
IOs->display_outs[display_c] = out; |
|
|
IOs->display_outs[display_c] = out; |
|
|
sprintf(address,"/main_display/%d",i); |
|
|
sprintf(address,"/main_display/%d",i); |
|
|
lo_server_thread_add_method(IOs->osc_in, |
|
|
lo_server_thread_add_method(IOs->osc_in, |
|
|
|
|
|
|
|
|
&IOs->display_outs[display_c]); |
|
|
&IOs->display_outs[display_c]); |
|
|
display_c++; |
|
|
display_c++; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Timecode |
|
|
|
|
|
Hui_display_port_t out = {TIMECODE, 0, 0, IOs}; |
|
|
|
|
|
IOs->display_outs[display_c] = out; |
|
|
|
|
|
sprintf(address,"/timecode"); |
|
|
|
|
|
lo_server_thread_add_method(IOs->osc_in, |
|
|
|
|
|
address, |
|
|
|
|
|
NULL, |
|
|
|
|
|
osc_in_display_handler, |
|
|
|
|
|
&IOs->display_outs[display_c]); |
|
|
|
|
|
display_c++; |
|
|
|
|
|
|
|
|
|
|
|
// Vpots |
|
|
|
|
|
for (i=0;i<12;i++) { |
|
|
|
|
|
Hui_display_port_t out = {VPOT, i, 0, IOs}; |
|
|
|
|
|
IOs->display_outs[display_c] = out; |
|
|
|
|
|
sprintf(address,"/vpot/%d",i+1); |
|
|
|
|
|
lo_server_thread_add_method(IOs->osc_in, |
|
|
|
|
|
address, |
|
|
|
|
|
NULL, |
|
|
|
|
|
osc_in_vpot_handler, |
|
|
|
|
|
&IOs->display_outs[display_c]); |
|
|
|
|
|
display_c++; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Meters |
|
|
|
|
|
for (i=0;i<8;i++) { |
|
|
|
|
|
Hui_display_port_t out = {METER, i, 0, IOs}; |
|
|
|
|
|
IOs->display_outs[display_c] = out; |
|
|
|
|
|
sprintf(address,"/meter/%d",i+1); |
|
|
|
|
|
lo_server_thread_add_method(IOs->osc_in, |
|
|
|
|
|
address, |
|
|
|
|
|
"ff", |
|
|
|
|
|
osc_in_meter_handler, |
|
|
|
|
|
&IOs->display_outs[display_c]); |
|
|
|
|
|
display_c++; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
int osc_in_meter_handler(const char *path, const char *types, lo_arg ** argv, |
|
|
|
|
|
int argc, void *data, void *user_data) { |
|
|
|
|
|
Hui_display_port_t* out = (Hui_display_port_t*)user_data; |
|
|
|
|
|
housicIO* IOs = (housicIO*) out->io; |
|
|
|
|
|
unsigned char message[3]; |
|
|
|
|
|
int i; |
|
|
|
|
|
char val; |
|
|
|
|
|
char side = 0; |
|
|
|
|
|
if (out->type == METER) { |
|
|
|
|
|
message[0] = 0xa0; |
|
|
|
|
|
message[1] = (0x0 | out->id); |
|
|
|
|
|
side = (char)argv[0]->f; |
|
|
|
|
|
if (side) { |
|
|
|
|
|
side = 0x10; |
|
|
|
|
|
} |
|
|
|
|
|
val = (char)argv[1]->f; |
|
|
|
|
|
if ( val <= 0xc) { |
|
|
|
|
|
message[2] = side | val; |
|
|
|
|
|
snd_rawmidi_write(IOs->midiout,message,3); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
int osc_in_vpot_handler(const char *path, const char *types, lo_arg ** argv, |
|
|
|
|
|
int argc, void *data, void *user_data) { |
|
|
|
|
|
Hui_display_port_t* out = (Hui_display_port_t*)user_data; |
|
|
|
|
|
housicIO* IOs = (housicIO*) out->io; |
|
|
|
|
|
unsigned char message[3]; |
|
|
|
|
|
int i; |
|
|
|
|
|
int size; |
|
|
|
|
|
|
|
|
|
|
|
if (out->type == VPOT) { |
|
|
|
|
|
size = 3; |
|
|
|
|
|
message[0] = 0xb0; |
|
|
|
|
|
for (i=0; i<argc; i++) { |
|
|
|
|
|
if (types[i] == 's') { |
|
|
|
|
|
// p: POINTER |
|
|
|
|
|
// c: CENTERED_FILL |
|
|
|
|
|
// f: FILL |
|
|
|
|
|
// w: WIDTH |
|
|
|
|
|
if (argv[i]->s == 'p' ) { |
|
|
|
|
|
out->state = (out->state & 0x0f) | 0x00; |
|
|
|
|
|
} else if (argv[i]->s == 'c' ) { |
|
|
|
|
|
out->state = (out->state & 0x0f) | 0x10; |
|
|
|
|
|
} else if (argv[i]->s == 'f' ) { |
|
|
|
|
|
out->state = (out->state & 0x0f) | 0x20; |
|
|
|
|
|
} else if (argv[i]->s == 'w' ) { |
|
|
|
|
|
out->state = (out->state & 0x0f) | 0x30; |
|
|
|
|
|
} |
|
|
|
|
|
} else if (types[i] == 'f') { |
|
|
|
|
|
if (argv[i]->f < 12) { |
|
|
|
|
|
out->state = ((unsigned char)argv[i]->f & 0x0f) | (out->state & 0xf0); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
message[1] = (0x10 | out->id); |
|
|
|
|
|
message[2] = out->state; |
|
|
|
|
|
snd_rawmidi_write(IOs->midiout,message,size); |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
int osc_in_display_handler(const char *path, const char *types, lo_arg ** argv, |
|
|
int osc_in_display_handler(const char *path, const char *types, lo_arg ** argv, |
|
|
|
|
|
|
|
|
int i; |
|
|
int i; |
|
|
int size; |
|
|
int size; |
|
|
char message[52] = {HDR}; |
|
|
char message[52] = {HDR}; |
|
|
|
|
|
|
|
|
|
|
|
char timecode[8]; |
|
|
|
|
|
|
|
|
if (out->type == LABEL) { |
|
|
if (out->type == LABEL) { |
|
|
size=13; |
|
|
size=13; |
|
|
message[6] = 0x10; |
|
|
message[6] = 0x10; |
|
|
|
|
|
|
|
|
for (i=0; i<10; i++) { |
|
|
for (i=0; i<10; i++) { |
|
|
message[8+i] = (val[i] > 0x10) ? val[i] & 0x7f : 0x20; |
|
|
message[8+i] = (val[i] > 0x10) ? val[i] & 0x7f : 0x20; |
|
|
} |
|
|
} |
|
|
|
|
|
} else if (out->type == TIMECODE) { |
|
|
|
|
|
size=0; |
|
|
|
|
|
message[6] = 0x11; |
|
|
|
|
|
printf("%s \n",types); |
|
|
|
|
|
for (i=0; i<argc; i++) { |
|
|
|
|
|
// size keeps track of how many digits have been entered |
|
|
|
|
|
// make sure we only read 8 digits |
|
|
|
|
|
if (types[i] == 'f' && size < 8) { |
|
|
|
|
|
timecode[size] = (unsigned char) argv[i]->f & 0xf; |
|
|
|
|
|
size++; |
|
|
|
|
|
} else if (types[i] == 's') { |
|
|
|
|
|
if (argv[i]->s == '.') { |
|
|
|
|
|
// a dot behind a digit has 5th bit set |
|
|
|
|
|
timecode[size-1] = timecode[size-1] + 0x10; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
for (i=0;i<size;i++) { |
|
|
|
|
|
// write timecode to message with a leading LSB |
|
|
|
|
|
// also LSB must be below 10 because it has no point (read doc) |
|
|
|
|
|
message[7+i] = i ? timecode[size-1-i]: timecode[size-1-i] & 0xf; |
|
|
|
|
|
} |
|
|
|
|
|
message[7+size] = 0xf7; |
|
|
|
|
|
size += 8; |
|
|
|
|
|
} else if (out->type == METER) { |
|
|
|
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
message[size-1] = 0xf7; |
|
|
message[size-1] = 0xf7; |
|
|
|
|
|
|
|
|
return 1; |
|
|
return 1; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
////////////////////////////// |
|
|
////////////////////////////// |
|
|
// |
|
|
// |
|
|
// osc_in_button_handler -- called when a button type message is |
|
|
// osc_in_button_handler -- called when a button type message is |
|
|
|
|
|
|
|
|
out_data |= out->port; |
|
|
out_data |= out->port; |
|
|
unsigned char message[6] = {0xb0,0x0c,out->zone,0xb0,0x2c,out_data}; |
|
|
unsigned char message[6] = {0xb0,0x0c,out->zone,0xb0,0x2c,out_data}; |
|
|
status = snd_rawmidi_write(IOs->midiout,message,6); |
|
|
status = snd_rawmidi_write(IOs->midiout,message,6); |
|
|
printf("%s - %x %x %x %x %x %x\n",path, |
|
|
|
|
|
message[0],message[1],message[2],message[3],message[4],message[5]); |
|
|
|
|
|
|
|
|
//printf("%s - %x %x %x %x %x %x\n",path, |
|
|
|
|
|
// message[0],message[1],message[2],message[3],message[4],message[5]); |
|
|
return 1; |
|
|
return 1; |
|
|
} |
|
|
} |
|
|
|
|
|
|