5 changed files with 393 additions and 3 deletions
@ -0,0 +1,2 @@
@@ -0,0 +1,2 @@
|
||||
# Musical Instrument Digital Interface |
||||
|
@ -0,0 +1,48 @@
@@ -0,0 +1,48 @@
|
||||
#!/usr/bin/perl -w |
||||
|
||||
my $port = 9001; |
||||
my $target = "localhost"; |
||||
|
||||
# ---------------------------------------------------------- |
||||
|
||||
use Net::OpenSoundControl::Client; |
||||
use Data::Dumper qw(Dumper); |
||||
use Getopt::Std; |
||||
|
||||
my $client; |
||||
my $verbose = 0; |
||||
|
||||
# ---------------------------------------------------------- |
||||
# |
||||
# MAIN |
||||
# |
||||
getopts('d:v', \%options); |
||||
|
||||
if (defined $options{"d"}) { |
||||
# print Dumper $options{"d"}; |
||||
($target, $port) = split /:/, $options{"d"}; |
||||
} |
||||
$verbose = 1 if (defined $options{"v"}); |
||||
|
||||
print "trashing ", $target, " on port ", $port, "\n"; |
||||
|
||||
$client = Net::OpenSoundControl::Client->new( |
||||
Name => "testkontrol", |
||||
Host => $target, Port => $port) |
||||
or die "Could not start client: $@\n"; |
||||
|
||||
print Dumper $client if $verbose; |
||||
|
||||
my ($foo, $knum, $kval); |
||||
|
||||
for ($foo=0; $foo<128; $foo++) { |
||||
$kval = int(128*rand()); |
||||
$knum = int(128*rand()); |
||||
|
||||
print "$knum -> $kval\n" if $verbose; |
||||
$client->send(['/kontrol/v', 'i', $knum, 'i', $kval]); |
||||
sleep(1); |
||||
} |
||||
|
||||
# ---------------------------------------------------------- |
||||
|
@ -0,0 +1,334 @@
@@ -0,0 +1,334 @@
|
||||
/*
|
||||
* SHOW BUTTONS |
||||
|
||||
*/ |
||||
|
||||
#include <stdio.h> |
||||
#include <stdlib.h> |
||||
#include <time.h> |
||||
#include <unistd.h> |
||||
#include <errno.h> |
||||
|
||||
#include <getopt.h> |
||||
#include <lo/lo.h> |
||||
|
||||
#include "functions/ncursefuncs.h" |
||||
|
||||
/* ----------------------------------------------------------------- */ |
||||
|
||||
#define LOCAL_PORT "9002" |
||||
#define NB_BUTTONS 24 |
||||
|
||||
int verbosity; |
||||
|
||||
typedef struct { |
||||
int type; |
||||
int value; |
||||
char texte[20]; |
||||
} Event; |
||||
|
||||
#define BUTTONS_EV 1 |
||||
#define XY_EV 2 |
||||
#define ID_EV 3 |
||||
|
||||
static int count; |
||||
static int pipefd[2]; |
||||
#define EVNT_RD (pipefd[0]) |
||||
#define EVNT_WR (pipefd[1]) |
||||
|
||||
unsigned char buttons[NB_BUTTONS]; |
||||
short xy_values[2]; |
||||
|
||||
|
||||
/* ----------------------------------------------------------------- */ |
||||
#define LINE0 8 /* vertical position of the top line */ |
||||
|
||||
int draw_buttons(unsigned char *states, int nbre, int unused) |
||||
{ |
||||
int idx, pos_c, pos_l; |
||||
char txt[20]; |
||||
|
||||
#if DEBUG_LEVEL |
||||
fprintf(stderr, "--> %s ( %p %d )\n", __func__, states, nbre); |
||||
#endif |
||||
|
||||
for (idx=0; idx<nbre; idx++) { |
||||
pos_c = 5 + ((idx % 8) * 9); |
||||
pos_l = LINE0 + ((idx / 8) * 5); |
||||
sprintf(txt, "%03d", idx); |
||||
draw_a_button(stdscr, pos_l, pos_c, txt, states[idx]); |
||||
} |
||||
|
||||
return 0; |
||||
} |
||||
/* ----------------------------------------------------------------- */ |
||||
int display_a_value(int lig, short value, char letter) |
||||
{ |
||||
char buffer[80], symbol; |
||||
int width, seuil, foo; |
||||
|
||||
sprintf(buffer, "%6d [", value); |
||||
mvaddstr(lig, 4, buffer); |
||||
|
||||
if (value < 0) symbol = '-'; |
||||
else symbol = '+'; |
||||
|
||||
width = 60; |
||||
seuil = (abs((int)value) * width) / 32767; |
||||
|
||||
#if DEBUG_LEVEL > 1 |
||||
fprintf(stderr, "in %s : value=%6d, seuil=%d\n", __func__, value, seuil); |
||||
#endif |
||||
|
||||
for (foo=0; foo<width; foo++) { |
||||
if (foo < seuil) mvaddch(lig, foo+12, symbol); |
||||
else mvaddch(lig, foo+12, ' '); |
||||
} |
||||
|
||||
refresh(); |
||||
|
||||
#if DEBUG_LEVEL > 1 |
||||
sprintf(buffer, "%s : %6d ", __func__, value); |
||||
blast_error_message(buffer, 0, 0); |
||||
#endif |
||||
|
||||
return 0; |
||||
} |
||||
/* ----------------------------------------------------------------- */ |
||||
int display_values(short *vals, int nbre, int ligne) |
||||
{ |
||||
int foo; |
||||
char buffer[80]; |
||||
|
||||
for (foo=0; foo<nbre; foo ++) { |
||||
display_a_value(ligne + foo, vals[foo], '?'); |
||||
} |
||||
|
||||
return 0; |
||||
} |
||||
/* ----------------------------------------------------------------- */ |
||||
int animation(int cycles, int speed) |
||||
{ |
||||
int foo; |
||||
short values[2]; |
||||
|
||||
#if DEBUG_LEVEL |
||||
fprintf(stderr, "entering %s ( %d %d )\n", __func__, cycles, speed); |
||||
#endif |
||||
|
||||
for (foo=0; foo<cycles; foo++) { |
||||
draw_buttons(buttons, NB_BUTTONS, 0); |
||||
display_values(values, 2, 2); |
||||
refresh(); |
||||
usleep(speed*1000); |
||||
|
||||
buttons[rand()%NB_BUTTONS] = rand() & 1; |
||||
values[0] += rand() % 320; |
||||
values[0] = abs(values[0]); |
||||
if (rand()%100 < 10) |
||||
values[1] = rand() % 32000; |
||||
|
||||
} |
||||
|
||||
/* may be we can make some cleanup after the show ? */ |
||||
|
||||
return 0; |
||||
} |
||||
/* ----------------------------------------------------------------- */ |
||||
int do_animation(int cycles, int speed) |
||||
{ |
||||
|
||||
(void)initcurses(); |
||||
animation(cycles, speed); |
||||
|
||||
sleep(2); |
||||
exit(0); |
||||
|
||||
return 0; |
||||
} |
||||
/* ----------------------------------------------------------------- */ |
||||
void error(int num, const char *msg, const char *path) |
||||
{ |
||||
fprintf(stderr, "liblo server error %d in path %s : %s\n", num, path, msg); |
||||
exit(1); |
||||
} |
||||
/* ----------------------------------------------------------------- */ |
||||
int xy_handler(const char *path, const char *types, lo_arg ** argv, |
||||
int argc, void *data, void *user_data) |
||||
{ |
||||
int x, y, foo; |
||||
Event evt; |
||||
|
||||
#if DEBUG_LEVEL |
||||
fprintf(stderr, "%s : %s %s %d %p\n", __func__, |
||||
path, types, argc, user_data); |
||||
#endif |
||||
|
||||
x = argv[0]->i; y = argv[1]->i; |
||||
/* may be we can bound-check that pair or values ? */ |
||||
|
||||
xy_values[0] = x; xy_values[1] = y; |
||||
|
||||
evt.type = XY_EV; evt.value = 0x55; |
||||
foo = write(EVNT_WR, &evt, sizeof(Event)); |
||||
if (sizeof(Event) != foo) { |
||||
fprintf(stderr, "%s : fifo error %d\n", __func__, errno); |
||||
exit(1); |
||||
} |
||||
count++; |
||||
|
||||
return 0; |
||||
} |
||||
/* ----------------------------------------------------------------- */ |
||||
int id_handler(const char *path, const char *types, lo_arg ** argv, |
||||
int argc, void *data, void *user_data) |
||||
{ |
||||
Event evt; |
||||
int foo; |
||||
|
||||
evt.type = ID_EV; evt.value = 0x55; |
||||
foo = write(EVNT_WR, &evt, sizeof(Event)); |
||||
if (sizeof(Event) != foo) { |
||||
fprintf(stderr, "%s : fifo error %d\n", __func__, errno); |
||||
exit(1); |
||||
} |
||||
|
||||
return 0; |
||||
} |
||||
/* ----------------------------------------------------------------- */ |
||||
int button_handler(const char *path, const char *types, lo_arg ** argv, |
||||
int argc, void *data, void *user_data) |
||||
{ |
||||
// char ligne[80];
|
||||
int button, state, foo; |
||||
Event evt; |
||||
|
||||
#if DEBUG_LEVEL |
||||
fprintf(stderr, "%s : %s %s %d %p\n", __func__, |
||||
path, types, argc, user_data); |
||||
#endif |
||||
|
||||
button = argv[0]->i; state = argv[1]->i; |
||||
|
||||
if (button<0 || button>=NB_BUTTONS) { |
||||
return 1; |
||||
} |
||||
|
||||
((unsigned char *)user_data)[button] = state; |
||||
|
||||
evt.type = BUTTONS_EV; evt.value = 0x55; |
||||
foo = write(EVNT_WR, &evt, sizeof(Event)); |
||||
if (sizeof(Event) != foo) { |
||||
fprintf(stderr, "%s : fifo error %d\n", __func__, errno); |
||||
exit(1); |
||||
} |
||||
|
||||
count++; |
||||
|
||||
return 0; |
||||
} |
||||
/* ----------------------------------------------------------------- */ |
||||
static void help(int k) |
||||
{ |
||||
puts("\t * showbuttons " __DATE__ " *"); |
||||
puts("\t-a\tshow animation"); |
||||
puts("\t-p\tlocal udp port ("LOCAL_PORT")"); |
||||
puts("\t-v\tenhance my verbosity"); |
||||
exit(0); |
||||
} |
||||
/* ----------------------------------------------------------------- */ |
||||
|
||||
int main(int argc, char *argv[]) |
||||
{ |
||||
int foo; |
||||
lo_server_thread st; |
||||
char *local_port = LOCAL_PORT; |
||||
int opt; |
||||
char ligne[81]; |
||||
long tdebut; |
||||
Event event; |
||||
|
||||
/* parsing command line options */ |
||||
while ((opt = getopt(argc, argv, "ahp:vE:C:")) != -1) { |
||||
switch (opt) { |
||||
case 'a': do_animation(200, 20); break; |
||||
case 'h': help(0); break; |
||||
case 'p': local_port = optarg; break; |
||||
case 'v': verbosity++; break; |
||||
default: exit(1); |
||||
} |
||||
} |
||||
|
||||
tdebut = time(NULL); |
||||
count = 0; |
||||
|
||||
/*
|
||||
* setup the inter-thread event synthetizer |
||||
*/ |
||||
foo = pipe(pipefd); |
||||
if (foo) { |
||||
perror("event synth"); |
||||
exit(1); |
||||
} |
||||
|
||||
/* set up the pretty screen user interface */ |
||||
foo = initcurses(); |
||||
sprintf(ligne, ":%s ", local_port); |
||||
foo = draw_main_screen(ligne, 0); |
||||
if (foo) { |
||||
endwin(); |
||||
fprintf(stderr, "main screen : err %d\n", foo); |
||||
exit(1); |
||||
} |
||||
|
||||
/* fireup the OSC liblo engine */ |
||||
st = lo_server_thread_new(local_port, error); |
||||
|
||||
#if DEBUG_LEVEL |
||||
fprintf(stderr, "Address of 'values' = %p\n", buttons); |
||||
#endif |
||||
|
||||
lo_server_thread_add_method(st, "/joystick/b", "ii", |
||||
button_handler, buttons); |
||||
lo_server_thread_add_method(st, "/joystick/xy", "ii", |
||||
xy_handler, NULL); |
||||
lo_server_thread_start(st); |
||||
|
||||
sprintf(ligne, "process %d on board, captain", getpid()); |
||||
blast_error_message(ligne, 0, 0); |
||||
sleep(1); |
||||
|
||||
for (;;) { |
||||
/* wait for un event from liblo threads */ |
||||
foo = read(EVNT_RD, &event, sizeof(Event)); |
||||
if (sizeof(Event) != foo) { /* FAILURE */ |
||||
perror("event fifo read error"); |
||||
exit(1); |
||||
} |
||||
|
||||
#if DEBUG_LEVEL |
||||
fprintf(stderr, "event %5d %8d %s\n", |
||||
event.type, event.value, event.texte); |
||||
#endif |
||||
|
||||
switch (event.type) { |
||||
case BUTTONS_EV: |
||||
draw_buttons(buttons, NB_BUTTONS, 0); |
||||
break; |
||||
case XY_EV: |
||||
display_values(xy_values, 2, 4); |
||||
break; |
||||
case ID_EV: |
||||
break; |
||||
default: |
||||
blast_error_message("bad event", 0, 0); |
||||
break; |
||||
} |
||||
} |
||||
|
||||
if (verbosity) |
||||
{ fprintf(stderr, "elapsed %ld s.\n", time(NULL)-tdebut); } |
||||
|
||||
return 0; |
||||
} |
||||
/* ----------------------------------------------------------------- */ |
Loading…
Reference in new issue