|
|
|
@ -34,6 +34,7 @@
|
|
|
|
|
#define MODE_STATUS 0x0 |
|
|
|
|
#define MODE_DATA_DUMP 0x1 |
|
|
|
|
#define MODE_DATA_LOAD 0x2 |
|
|
|
|
#define MODE_PROGRAM_LIST 0x4 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Globals. */ |
|
|
|
@ -60,6 +61,7 @@ Send/receive data to/from a connected microX synthesizer.\n");
|
|
|
|
|
|
|
|
|
|
puts("\
|
|
|
|
|
-s, --status Print device status (default).\n\
|
|
|
|
|
-L, --list-programs List all programs in all banks.\n\
|
|
|
|
|
-d, --dump-data ID Dump the specified slot.\n\
|
|
|
|
|
-l, --load-data ID Load program read from standard\n\
|
|
|
|
|
input into the specified slot.\n\
|
|
|
|
@ -150,6 +152,42 @@ print_microx_status(struct kmx_microx_status *s)
|
|
|
|
|
printf(" Current Controller: %d\n", s->ext_ctrl.current); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void |
|
|
|
|
do_list_programs(midi_io_t *midi) |
|
|
|
|
{ |
|
|
|
|
size_t n, len; |
|
|
|
|
unsigned char *reply, *cursor, bank, program; |
|
|
|
|
unsigned char query[] = { 0xF0, /* SysEx message begin */ |
|
|
|
|
0x42, /* Korg manufacturer ID */ |
|
|
|
|
0x30, /* Global channel */ |
|
|
|
|
0x7A, /* End of SysEx header */ |
|
|
|
|
0x1C, /* Program Parameter Dump Request */ |
|
|
|
|
0x00, /* Dump all programs */ |
|
|
|
|
0x00, /* Unused. */ |
|
|
|
|
0x00, /* Reserved */ |
|
|
|
|
0xF7 /* SysEx message end */ }; |
|
|
|
|
|
|
|
|
|
len = MICROX_PROGRAM_SIZE * MICROX_N_PROGRAM + 9; |
|
|
|
|
reply = xmalloc(len); |
|
|
|
|
|
|
|
|
|
if ( (n = midi_write(midi, query, sizeof(query))) < 0 ) |
|
|
|
|
errx(EXIT_FAILURE, "cannot dump data: %s", |
|
|
|
|
kmx_microx_error(midi, n)); |
|
|
|
|
|
|
|
|
|
if ( (n = kmx_microx_read_dump(midi, 0x4C, reply, len)) < 0 ) |
|
|
|
|
err(EXIT_FAILURE, "cannot read dump data: %s", |
|
|
|
|
kmx_microx_error(midi, n)); |
|
|
|
|
|
|
|
|
|
for ( cursor = reply, bank = 'A'; bank < 'F'; bank++ ) { |
|
|
|
|
for ( program = 0; program < 128; program++ ) { |
|
|
|
|
printf("%c%03d %.16s\n", bank, program, cursor); |
|
|
|
|
cursor += MICROX_PROGRAM_SIZE; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
free(reply); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
struct kmx_data_type |
|
|
|
|
{ |
|
|
|
|
enum kmx_microx_data_type code; |
|
|
|
@ -181,14 +219,15 @@ main(int argc, char **argv)
|
|
|
|
|
struct kmx_data_type *type; |
|
|
|
|
|
|
|
|
|
struct option options[] = { |
|
|
|
|
{ "help", 0, NULL, 'h' }, |
|
|
|
|
{ "version", 0, NULL, 'v' }, |
|
|
|
|
{ "port", 1, NULL, 'p' }, |
|
|
|
|
{ "status", 0, NULL, 's' }, |
|
|
|
|
{ "dump-data", 1, NULL, 'd' }, |
|
|
|
|
{ "load-data", 1, NULL, 'l' }, |
|
|
|
|
{ "data-type", 1, NULL, 't' }, |
|
|
|
|
{ NULL, 0, NULL, 0 } |
|
|
|
|
{ "help", 0, NULL, 'h' }, |
|
|
|
|
{ "version", 0, NULL, 'v' }, |
|
|
|
|
{ "port", 1, NULL, 'p' }, |
|
|
|
|
{ "status", 0, NULL, 's' }, |
|
|
|
|
{ "dump-data", 1, NULL, 'd' }, |
|
|
|
|
{ "load-data", 1, NULL, 'l' }, |
|
|
|
|
{ "data-type", 1, NULL, 't' }, |
|
|
|
|
{ "list-programs", 0, NULL, 'L' }, |
|
|
|
|
{ NULL, 0, NULL, 0 } |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
setprogname(argv[0]); |
|
|
|
@ -199,7 +238,7 @@ main(int argc, char **argv)
|
|
|
|
|
mode = MODE_STATUS; |
|
|
|
|
type = kmx_data_types; |
|
|
|
|
|
|
|
|
|
while ( (c = getopt_long(argc, argv, "hvp:sd:l:t:", |
|
|
|
|
while ( (c = getopt_long(argc, argv, "hvp:sd:l:t:L", |
|
|
|
|
options, NULL)) != -1 ) { |
|
|
|
|
switch ( c ) { |
|
|
|
|
case 'h': |
|
|
|
@ -242,6 +281,10 @@ main(int argc, char **argv)
|
|
|
|
|
if ( type->name == NULL ) |
|
|
|
|
errx(EXIT_FAILURE, "invalid data type: %s", optarg); |
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
case 'L': |
|
|
|
|
mode = MODE_PROGRAM_LIST; |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -288,6 +331,9 @@ main(int argc, char **argv)
|
|
|
|
|
errx(EXIT_FAILURE, "cannot load data: %s", |
|
|
|
|
kmx_microx_error(midi, n)); |
|
|
|
|
} |
|
|
|
|
else if ( mode == MODE_PROGRAM_LIST ) { |
|
|
|
|
do_list_programs(midi); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return EXIT_SUCCESS; |
|
|
|
|
} |
|
|
|
|