ソースを参照

all switches, rotaries and faders send to OSC now

master
コミット
13fcab0ded
1個のファイルの変更192行の追加16行の削除
  1. +192
    -16
      main.c

+ 192
- 16
main.c ファイルの表示

@@ -8,13 +8,38 @@
#include <alsa/asoundlib.h>
#include <pthread.h> /* for threading */
#include <lo/lo.h>
#include "mapping.h"
#include <unistd.h>

#define ZONE_COUNT 0x1e
#define PORT_COUNT 196
#define DISPLAY_COUNT 9

enum display_type {
LABEL,
VPOT
};

typedef struct {
char zone;
char port;
void* io;
} Hui_MIDI_port_t;

typedef struct {
int type;
int id;
void* io;
} Hui_display_port_t;

typedef struct {
snd_rawmidi_t* midiin;
snd_rawmidi_t* midiout;
lo_address osc_out;
lo_server_thread osc_in;
unsigned char hui_in_zone;
int hui_in_fader_hi[8];
Hui_MIDI_port_t MIDIouts[PORT_COUNT];
Hui_display_port_t display_outs[DISPLAY_COUNT];
} housicIO;

typedef struct {
@@ -22,6 +47,7 @@ typedef struct {
char* address;
} Item;


char *ZONES[] = {
"channel_strip_1",
"channel_strip_2",
@@ -55,7 +81,7 @@ char *ZONES[] = {
"misc"
};

char *BUTTONS[0x1e][8] = {
char *BUTTONS[ZONE_COUNT][8] = {
{"fader","select","mute","solo","auto","v-sel","insert","rec_rdy"},
{"fader","select","mute","solo","auto","v-sel","insert","rec_rdy"},
{"fader","select","mute","solo","auto","v-sel","insert","rec_rdy"},
@@ -88,38 +114,55 @@ char *BUTTONS[0x1e][8] = {
{"switch_1","switch_2","click","beep"}
};



// function declarations:
void alsa_error (const char *format, ...);
void* midiinfunction (void * arg);
void* ping (void * arg);
void midi_in_dispatch (void * arg, unsigned char * m);
void lo_error (int num, const char *m, const char *path);
int osc_in_handler (const char *path, const char *types, lo_arg ** argv,
int argc, void *data, void *user_data);
void hui_in_button (void *arg, unsigned char m);
void hui_in_scroll (void *arg, unsigned char port, unsigned char vv);
void hui_in_fader (void *arg, unsigned char fader, int val);
void osc_send (void *arg, Item el, float value);
void register_osc_receives();
void register_osc_receives(void *arg);
int osc_in_button_handler(const char *path, const char *types, lo_arg ** argv,
int argc, void *data, void *user_data);
int osc_in_label_handler (const char *path, const char *types, lo_arg ** argv,
int argc, void *data, void *user_data);


int main(int argc, char *argv[]) {
int status;
int mode = SND_RAWMIDI_SYNC;
pthread_t midiinthread;
lo_server_thread st = lo_server_thread_new("7770", lo_error);
housicIO IOs = {NULL,NULL,0,0};
pthread_t pingthread;
housicIO IOs = {NULL,NULL,0,NULL,0,{0,0,0,0,0,0,0,0},0};
IOs.osc_out = lo_address_new(NULL,"7771");
IOs.osc_in = lo_server_thread_new("7770", lo_error);
const char* portname = "virtual";

// MIDI
if ((status = snd_rawmidi_open(NULL, &IOs.midiout, portname, mode)) < 0) {
alsa_error("Problem opening MIDI output: %s", snd_strerror(status));
exit(1);
}
if ((status = snd_rawmidi_open(&IOs.midiin, NULL, portname, mode)) < 0) {
alsa_error("Problem opening MIDI input: %s", snd_strerror(status));
exit(1);
}
status = pthread_create(&pingthread,NULL, ping, &IOs);
status = pthread_create(&midiinthread, NULL, midiinfunction, &IOs);

// OSC
register_osc_receives();
lo_server_thread_add_method(st, NULL, NULL, osc_in_handler, NULL);
lo_server_thread_start(st);
register_osc_receives(&IOs);
//lo_server_thread_add_method(IOs.osc_in, NULL, NULL, osc_in_handler, NULL);
lo_server_thread_start(IOs.osc_in);
// wait for MIDI thread to end (will not happen)
pthread_join(midiinthread, NULL);
@@ -128,16 +171,103 @@ int main(int argc, char *argv[]) {
return 0;
}

//////////////////////////////
//
// ping -- It is important to send a ping in regular intervals. This
// will keep the HUI in online mode.
//
void *ping(void *arg) {
housicIO* IOs = (housicIO*)arg;
char message[] = {0x90,0x00,0x00};

while (1) {
sleep(1);
snd_rawmidi_write(IOs->midiout,message,3);
}
}


//////////////////////////////
//
// midiinfunction -- Thread function which waits around until a MIDI
// input byte arrives and then react correspondingly
//
void register_osc_receives() {
void register_osc_receives(void *arg) {
housicIO* IOs = (housicIO*)arg;
int zone_c;
int button_c;
char address[32];
int address_c = 0;

for (zone_c=0; zone_c<ZONE_COUNT; zone_c++) {
for (button_c=0; button_c<8; button_c++) {
if (BUTTONS[zone_c][button_c]) {
Hui_MIDI_port_t out = {zone_c,button_c,IOs};
IOs->MIDIouts[address_c] = out;
sprintf(address,"/%s/%s",ZONES[zone_c],BUTTONS[zone_c][button_c]);
lo_server_thread_add_method(IOs->osc_in,
address,
"i",
osc_in_button_handler,
&IOs->MIDIouts[address_c]);
address_c++;
}
}
}
int i;
int display_c = 0;
for (i=0;i<9;i++) {
Hui_display_port_t out = {LABEL,i,IOs};
IOs->display_outs[display_c] = out;
sprintf(address,"/label/%d",i);
lo_server_thread_add_method(IOs->osc_in,
address,
"s",
osc_in_label_handler,
&IOs->display_outs[display_c]);
display_c++;
}
}

int osc_in_label_handler(const char *path, const char *types, lo_arg ** argv,
int argc, void *data, void *user_data) {
char* val;

val = (char *)(lo_arg*) argv[0]->s;
printf("%s: %d: %x\n",types,argc, argv);
return 1;
}

//////////////////////////////
//
// osc_in_button_handler -- called when a button type message is
// received and should be sent to the HUI
//
int osc_in_button_handler(const char *path, const char *types, lo_arg ** argv,
int argc, void *data, void *user_data) {
Hui_MIDI_port_t* out = (Hui_MIDI_port_t*)user_data;
housicIO* IOs = (housicIO*) out->io;
char value;
int status;
// char message[6];
char out_data;
value = argv[0]->i;
out_data = value ? 0x40 : 0x00;
out_data |= out->port;
unsigned char message[6] = {0xb0,0x0c,out->zone,0xb0,0x2c,out_data};
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]);
return 1;
}


//////////////////////////////
//
// midiinfunction -- Thread function which waits around until a MIDI
@@ -161,7 +291,15 @@ void *midiinfunction(void *arg) {
for (i=1; i<=status;i++) {
message[3-i] = (unsigned char) buffer[status-i];
}

if (status==2) {
message[0] = 0xb0;
} else if(0) { // only for debugging
printf("%d: %x %x %x - %x %x %x\n", status,
buffer[0],buffer[1],buffer[2],
message[0], message[1], message[2]);
}
midi_in_dispatch(IOs,message);

fflush(stdout);
@@ -178,18 +316,56 @@ void *midiinfunction(void *arg) {

void midi_in_dispatch(void *arg, unsigned char *m) {
housicIO* IOs = (housicIO*)arg;
int fader_value;

if (m[0] == 0xb0) {
// received a CC message on MIDIchannel 1
if (m[1] == 0x0f) {
// received a zone select
IOs->hui_in_zone = m[2];
} else {
if (m[1] == 0x2f) {
// should always be true, if HUI is working.
hui_in_button(IOs,m[2]);
}
}
} else if (m[1] == 0x2f) { // switches
hui_in_button(IOs,m[2]);
} else if ((m[1] & 0xf0) == 0x40) { // V-pots:
hui_in_scroll(IOs,m[1] & 0xf, m[2]);
} else if (m[1] == 0x0d) { // jog wheel:
hui_in_scroll(IOs,0xd,m[2]);
} else if (m[1] < 0x08) { // fader Hi
IOs->hui_in_fader_hi[m[1]] = (int) m[2];
} else if ((m[1] & 0xf0) == 0x20) { // fader Lo
fader_value = (IOs->hui_in_fader_hi[m[1] & 0x0f] << 2) | (m[2] >> 5);
hui_in_fader(IOs,m[1] & 0x0f,fader_value);
}
}
}

//////////////////////////////
//
// hui_in_fader -- fader positions
//
void hui_in_fader(void *arg, unsigned char port, int val) {
housicIO* IOs = (housicIO*)arg;
char address[32];

sprintf(address, "/fader/%d", port + 1);
Item ee = {'f',address};
osc_send(IOs, ee, val);
}

//////////////////////////////
//
// hui_in_scroll -- user interacted with a button on the HUI
//
void hui_in_scroll(void *arg, unsigned char port, unsigned char vv) {
housicIO* IOs = (housicIO*)arg;
char address[32];

sprintf(address, "/vpot/%d", port + 1);
Item ee = {'s', address};
if (vv > 0x40) {
osc_send(IOs, ee, vv - 0x40);
} else if (vv < 0x40) {
osc_send(IOs, ee, -vv);
}
}


読み込み中…
キャンセル
保存