Browse Source

Add basic query mode

master
Damien Goutte-Gattat 9 years ago
parent
commit
c81a36c6ae
  1. 94
      src/asysex.c

94
src/asysex.c

@ -26,6 +26,7 @@
#include <getopt.h>
#include <sysex.h>
#include <xmem.h>
#define ASYSEX_MODE_QUERY 0x00
#define ASYSEX_MODE_INQUIRY 0x01
@ -88,6 +89,98 @@ cleanup(void)
}
}
static int
read_message_from_file(FILE *in, unsigned char **buffer, size_t *len)
{
int n, c;
size_t l;
char bytes[3];
enum { NEWLINE, COMMENT, HIGHCHAR, LOWCHAR } state;
n = 0;
bytes[2] = 0;
state = NEWLINE;
if ( len == NULL )
len = &l;
if ( *buffer == NULL )
*len = 0;
while ( (c = fgetc(in)) != EOF ) {
switch ( state ) {
case COMMENT:
if ( c == '\n' )
state = NEWLINE;
break;
case NEWLINE:
if ( c == '#' )
state = COMMENT;
/* Fall through */
case HIGHCHAR:
if ( isxdigit(c) ) {
bytes[0] = c;
state = LOWCHAR;
}
else if ( c == '\n' )
state = NEWLINE;
break;
case LOWCHAR:
if ( isxdigit(c) ) {
bytes[1] = c;
if ( n >= *len ) {
*len += 64;
*buffer = xrealloc(*buffer, *len);
}
*(*buffer + n++) = strtol(bytes, NULL, 16);
state = HIGHCHAR;
}
else if ( c == '\n' )
state = NEWLINE;
break;
}
}
return n;
}
static void
do_query(midi_io_t *midi, FILE *in, FILE *out)
{
unsigned char *query, reply[256];
size_t n;
int i, j;
query = NULL;
j = 0;
n = read_message_from_file(in, &query, NULL);
if ( n < 2 || query[0] != 0xF0 || query[n-1] != 0xF7 )
errx(EXIT_FAILURE, "invalid SysEx input (%d)", n);
if ( (n = midi_write(midi, query, n)) < 0 )
errx(EXIT_FAILURE, "cannot send MIDI data");
do {
if ( (n = sysex_read(midi, reply, sizeof(reply))) < 0 )
errx(EXIT_FAILURE, "cannot read MIDI data");
for ( i = 0; i < n; i++, j++ ) {
if ( j % 16 == 0 )
fprintf(out, "%s%08X:", j > 0 ? "\n" : "", j);
fprintf(out, " %s%02X", j % 8 == 0 ? " " : "", reply[i]);
}
}
while ( reply[n-1] != 0xF7 );
fputc('\n', out);
}
static void
identify_device(midi_io_t *midi)
{
@ -158,6 +251,7 @@ main(int argc, char **argv)
switch ( mode ) {
case ASYSEX_MODE_QUERY:
do_query(midi, stdin, stdout);
break;
case ASYSEX_MODE_INQUIRY:

Loading…
Cancel
Save