KORG microX utility.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

240 lines
5.1 KiB

/*
* asysex - A SysEx Utility
* Copyright (C) 2012,2016 Damien Goutte-Gattat
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <locale.h>
#include <getopt.h>
#include <err.h>
#include <sysex.h>
#include <hexio.h>
#define ASYSEX_MODE_QUERY 0x00
#define ASYSEX_MODE_INQUIRY 0x01
/* Globals. */
static midi_io_t *midi = NULL;
/* Help and informations about the program. */
static void
usage(int status)
{
puts("\
Usage: asysex [options]\n\
Read/write MIDI SysEx messages.\n");
puts("Options:\n\
-h, --help Display this help message.\n\
-v, --version Display the version message.\n\
");
puts("\
-p, --port PORT Specify MIDI port to use.\n\
");
puts("\
-I, --inquiry Identify the MIDI device and exit.\n\
");
puts("\
-r, --raw Write output in raw binary format.\n\
-H, --hex Write output in hex format. This is the\n\
default.\n\
");
printf("Report bugs to <%s>.\n", PACKAGE_BUGREPORT);
exit(status);
}
static void
info(void)
{
printf("\
asysex %s\n\
Copyright (C) 2012,2016 Damien Goutte-Gattat\n\
\n\
This program is released under the GNU General Public License.\n\
See the COPYING file or <http://www.gnu.org/licenses/gpl.html>.\n\
", VERSION);
exit(EXIT_SUCCESS);
}
/* Helper functions. */
static void
cleanup(void)
{
if ( midi ) {
midi_close(midi);
midi = NULL;
}
}
/* MIDI output functions. */
typedef void (*print_midi_fn_t)(FILE *, unsigned char *, size_t);
static void
print_midi_hex(FILE *out, unsigned char *buffer, size_t len)
{
static int n = 0;
fprinthd(out, buffer, len, n);
n += len;
}
static void
print_midi_raw(FILE *out, unsigned char *buffer, size_t len)
{
fwrite(buffer, 1, len, out);
}
/* Mode functions. */
static void
do_query(midi_io_t *midi, FILE *in, FILE *out, print_midi_fn_t print_midi)
{
unsigned char *query, reply[256];
ssize_t n;
query = NULL;
n = freadha(in, &query, NULL);
if ( n < 2 || query[0] != 0xF0 || query[n-1] != 0xF7 )
errx(EXIT_FAILURE, "invalid SysEx input (%lu)", 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");
print_midi(out, reply, n);
}
while ( n > 0 && reply[n-1] != 0xF7 );
fputc('\n', out);
}
static void
identify_device(midi_io_t *midi)
{
midi_device_id_t dev;
if ( sysex_identify(midi, &dev) <= 0 )
errx(EXIT_FAILURE, "cannot identify MIDI device");
printf("%s family %x, model %x, version %d.%d.%d.%d\n",
sysex_get_manufacturer(dev.manufacturer),
dev.family, dev.model,
dev.version & 0xFF,
(dev.version >> 8) & 0xFF,
(dev.version >> 16) & 0xFF,
(dev.version >> 24) & 0xFF);
}
/* Main function. */
int
main(int argc, char **argv)
{
char c;
const char *port;
int mode;
print_midi_fn_t print_midi;
struct option options[] = {
{ "help", 0, NULL, 'h' },
{ "version", 0, NULL, 'v' },
{ "port", 1, NULL, 'p' },
{ "inquiry", 0, NULL, 'I' },
{ "raw", 0, NULL, 'r' },
{ "hex", 0, NULL, 'H' },
{ NULL, 0, NULL, 0 }
};
setprogname(argv[0]);
setlocale(LC_ALL, "");
atexit(cleanup);
port = DEFAULT_MIDI_PORT;
mode = ASYSEX_MODE_QUERY;
print_midi = print_midi_hex;
while ( (c = getopt_long(argc, argv, "hvp:IrH", options, NULL)) != -1 ) {
switch ( c ) {
case 'h':
usage(EXIT_SUCCESS);
break;
case '?':
usage(EXIT_FAILURE);
break;
case 'v':
info();
break;
case 'p':
port = optarg;
break;
case 'I':
mode = ASYSEX_MODE_INQUIRY;
break;
case 'r':
print_midi = print_midi_raw;
break;
case 'H':
print_midi = print_midi_hex;
break;
}
}
if ( ! (midi = midi_open(port)) )
errx(EXIT_FAILURE, "cannot open MIDI port %s", port);
switch ( mode ) {
case ASYSEX_MODE_QUERY:
do_query(midi, stdin, stdout, print_midi);
break;
case ASYSEX_MODE_INQUIRY:
identify_device(midi);
break;
}
return EXIT_SUCCESS;
}