|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267 |
- /*
- * Programmer: Dominik Schmidt-Philipp <schmidt-philipp@kulturteknologi.no>
- * Filename: main.c
- *
- * Dedicated to seleomlivet
- *
- */
- #include <alsa/asoundlib.h>
- #include <pthread.h> /* for threading */
- #include <lo/lo.h>
- #include "mapping.h"
-
- typedef struct {
- snd_rawmidi_t* midiin;
- snd_rawmidi_t* midiout;
- lo_address osc_out;
- unsigned char hui_in_zone;
- } housicIO;
-
- typedef struct {
- char type;
- char* address;
- } Item;
-
- char *ZONES[] = {
- "channel_strip_1",
- "channel_strip_2",
- "channel_strip_3",
- "channel_strip_4",
- "channel_strip_5",
- "channel_strip_6",
- "channel_strip_7",
- "channel_strip_8",
- "keyboard_shortcuts",
- "window",
- "channel_selection",
- "assignment_1",
- "assignment_2",
- "cursor",
- "transport_main",
- "transport_add1",
- "transport_add2",
- "monitor_input",
- "monitor_output",
- "num_pad_1",
- "num_pad_2",
- "num_pad_3",
- "timecode",
- "auto_enable",
- "auto_mode",
- "status_group",
- "edit",
- "fn_keys",
- "parameter_edit",
- "misc"
- };
-
- char *BUTTONS[0x1e][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"},
- {"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"},
- {"fader","select","mute","solo","auto","v-sel","insert","rec_rdy"},
- {"fader","select","mute","solo","auto","v-sel","insert","rec_rdy"},
- {"ctrl","shift","editmode","undo","alt","option","edittool","save"},
- {"mix","edit","transprt","mem-loc","status","alt"},
- {"chan_left","bank_left","chanl_right","bank_right"},
- {"output","input","pan","send_e","send_d","send_c","send_b","send_a"},
- {"assign","default","suspend","shift","mute","bypass","recrdyall"},
- {"down","left","mode","right","up","scrub","shuttle"},
- {"talkback","rewind","fast_fwd","stop","play","record"},
- {"rtz","end","on_line","loop","quick_punch"},
- {"audition","pre","in","out","post"},
- {"input_3 ","input_2","input_1","mute","discrete"},
- {"output_3","output_2","output_1","dim","mono"},
- {"0","1","4","2","5",".","3","6"},
- {"enter","+"},
- {"7","8","9","-","clr","=","divide","*"},
- {"timecode","feet","beats","rudesolo"},
- {"plug_in","pan","fader","sendmute","send","mute"},
- {"trim","latch","read","off","write","touch"},
- {"phase","monitor","auto","suspend","create","group"},
- {"paste","cut","capture","delete","copy","separate"},
- {"f1","f2","f3","f4","f5","f6","f7","f8"},
- {"insert","assign","select_1","select_2","select_3","select_4","bypass","compare"},
- {"switch_1","switch_2","click","beep"}
- };
-
- // function declarations:
- void alsa_error (const char *format, ...);
- void* midiinfunction (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 osc_send (void *arg, Item el, float value);
- void register_osc_receives();
-
- 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};
- IOs.osc_out = lo_address_new(NULL,"7771");
-
- const char* portname = "virtual";
-
- // MIDI
- 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(&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);
-
- // wait for MIDI thread to end (will not happen)
- pthread_join(midiinthread, NULL);
-
-
- return 0;
- }
-
-
- //////////////////////////////
- //
- // midiinfunction -- Thread function which waits around until a MIDI
- // input byte arrives and then react correspondingly
- //
- void register_osc_receives() {
-
- }
-
- //////////////////////////////
- //
- // midiinfunction -- Thread function which waits around until a MIDI
- // input byte arrives and then react correspondingly
- //
-
- void *midiinfunction(void *arg) {
- housicIO* IOs = (housicIO*)arg;
- snd_rawmidi_t* midiin = IOs->midiin;
- int status;
- int i = 0;
- char buffer[3];
- unsigned char message[3];
-
- while (1) {
- if ((status = snd_rawmidi_read(midiin, buffer, 3)) < 0) {
- alsa_error("Problem reading MIDI input: %s", snd_strerror(status));
- }
-
- // in case of MIDI running status, value bytes need to not override status byte
- for (i=1; i<=status;i++) {
- message[3-i] = (unsigned char) buffer[status-i];
- }
-
- midi_in_dispatch(IOs,message);
-
- fflush(stdout);
- }
- }
-
-
-
- //////////////////////////////
- //
- // midi_in_dispatch -- Thread function which waits around until a MIDI
- // input byte arrives and then react correspondingly
- //
-
- void midi_in_dispatch(void *arg, unsigned char *m) {
- housicIO* IOs = (housicIO*)arg;
-
- 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]);
- }
- }
- }
- }
-
- //////////////////////////////
- //
- // hui_in_button -- user interacted with a button on the HUI
- //
- void hui_in_button(void *arg, unsigned char m) {
- housicIO* IOs = (housicIO*)arg;
- char address[32];
-
- char zone = IOs->hui_in_zone;
- int dir = m & 0xf0;
- int port = m & 0x0f;
-
- sprintf(address, "/%s/%s",ZONES[zone],BUTTONS[zone][port]);
- Item ee = {'b',address};
- if (dir == 0x40) {
- // down
- osc_send(IOs, ee, 1);
- } else if (dir == 0x00) {
- // up
- osc_send(IOs, ee, 0);
- }
- }
-
-
-
- //////////////////////////////
- //
- // osc_send --
- //
- void osc_send(void *arg, Item el, float value) {
- housicIO* IOs = (housicIO*)arg;
-
- lo_send(IOs->osc_out, el.address, "f", value );
- }
-
- //////////////////////////////
- //
- // osc_in_handler -- receive incoming OSC messages
- //
- int osc_in_handler (const char *path, const char *types, lo_arg ** argv,
- int argc, void *data, void *user_data) {
- int i;
-
- printf("path: <%s>\n", path);
- for (i = 0; i < argc; i++) {
- printf("arg %d '%c' ", i, types[i]);
- lo_arg_pp((lo_type)types[i], argv[i]);
- printf("\n");
- }
- printf("\n");
- fflush(stdout);
-
- return 1;
- }
-
- //////////////////////////////
- //
- // error -- print error message
- //
-
- void alsa_error(const char *format, ...) {
- va_list ap;
- va_start(ap, format);
- vfprintf(stderr, format, ap);
- va_end(ap);
- putc('\n', stderr);
- }
- void lo_error(int num, const char *msg, const char *path)
- {
- printf("liblo server error %d in path %s: %s\n", num, path, msg);
- fflush(stdout);
- }
|