Add an option (-j) to set the Jack client name. Moreover, add equivalent directives for both the -j and -o options, so that they can also be set from the midizaprc file.
This commit is contained in:
parent
2b2d11ed3c
commit
3c95512b81
|
@ -6,11 +6,38 @@
|
||||||
|
|
||||||
# This program works pretty much like Eric Messick's shuttlepro program,
|
# This program works pretty much like Eric Messick's shuttlepro program,
|
||||||
# but it translates MIDI input rather than input events from the Contour
|
# but it translates MIDI input rather than input events from the Contour
|
||||||
# Design Shuttle devices. The program creates a Jack MIDI client named
|
# Design Shuttle devices. By default, the program creates a Jack MIDI
|
||||||
# "midizap" with a single input port, which you'll have to connect to
|
# client named "midizap" with a single input port, which you'll have to
|
||||||
# the MIDI controller that you want to use (e.g., using a patchbay
|
# connect to the MIDI controller that you want to use (e.g., using a
|
||||||
# program like qjackctl; non-Jack ALSA MIDI inputs can be accommodated
|
# patchbay program like qjackctl; non-Jack ALSA MIDI inputs can be
|
||||||
# using a2jmidid).
|
# accommodated using a2jmidid).
|
||||||
|
|
||||||
|
# Both the Jack client name and the number of (input and output) ports
|
||||||
|
# can be adjusted, either from the command line, using the -j and -o
|
||||||
|
# options (these always take priority), or by employing the following
|
||||||
|
# midizaprc directives. NOTE: These options only take effect
|
||||||
|
# immediately after program start, when the Jack client is initialized.
|
||||||
|
# If you edit them later, you need to restart the program, so that a new
|
||||||
|
# Jack client is created.
|
||||||
|
|
||||||
|
# The JACK_NAME directive is used to change the client name.
|
||||||
|
# (Uncomment the line and edit the name as needed.) This is useful,
|
||||||
|
# e.g., if you're running multiple instances of midizap using different
|
||||||
|
# configurations for different controllers, and you want to have them
|
||||||
|
# named appropriately so that they can be wired up more easily using the
|
||||||
|
# qjackctl patchbay.
|
||||||
|
|
||||||
|
#JACK_NAME "hello midizap"
|
||||||
|
|
||||||
|
# The number of ports given with the JACK_PORTS directive must be
|
||||||
|
# 1 or 2. It causes the given number of both input and output ports to
|
||||||
|
# be created. This option is useful if you want to translate MIDI
|
||||||
|
# messages, see the [MIDI] section below for details. Two input and
|
||||||
|
# output ports can be employed, e.g., if you also need to provide
|
||||||
|
# backward translations for controller feedback, see the [MIDI2] section
|
||||||
|
# below for an example.
|
||||||
|
|
||||||
|
#JACK_PORTS 2
|
||||||
|
|
||||||
# Other than the input being MIDI instead of the Shuttle's key and wheel
|
# Other than the input being MIDI instead of the Shuttle's key and wheel
|
||||||
# events, the program works exactly the same. Each section in the file
|
# events, the program works exactly the same. Each section in the file
|
||||||
|
|
|
@ -376,10 +376,11 @@ int
|
||||||
init_jack(JACK_SEQ* seq, uint8_t verbose)
|
init_jack(JACK_SEQ* seq, uint8_t verbose)
|
||||||
{
|
{
|
||||||
int err, k;
|
int err, k;
|
||||||
char portname[100];
|
char portname[100],
|
||||||
|
*client_name = seq->client_name?seq->client_name:"midizap";
|
||||||
|
|
||||||
if(verbose)printf("opening client...\n");
|
if(verbose)printf("opening client...\n");
|
||||||
seq->jack_client = jack_client_open("midizap", JackNullOption, NULL);
|
seq->jack_client = jack_client_open(client_name, JackNullOption, NULL);
|
||||||
|
|
||||||
if (seq->jack_client == NULL)
|
if (seq->jack_client == NULL)
|
||||||
{
|
{
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
|
|
||||||
typedef struct _jseq
|
typedef struct _jseq
|
||||||
{
|
{
|
||||||
|
char *client_name;
|
||||||
jack_ringbuffer_t **ringbuffer_out;
|
jack_ringbuffer_t **ringbuffer_out;
|
||||||
jack_ringbuffer_t **ringbuffer_in;
|
jack_ringbuffer_t **ringbuffer_in;
|
||||||
jack_client_t *jack_client;
|
jack_client_t *jack_client;
|
||||||
|
|
34
midizap.c
34
midizap.c
|
@ -23,7 +23,7 @@ typedef struct input_event EV;
|
||||||
Display *display;
|
Display *display;
|
||||||
|
|
||||||
JACK_SEQ seq;
|
JACK_SEQ seq;
|
||||||
int enable_jack_output = 0, debug_jack = 0;
|
int jack_num_outputs = 0, debug_jack = 0;
|
||||||
|
|
||||||
void
|
void
|
||||||
initdisplay(void)
|
initdisplay(void)
|
||||||
|
@ -70,7 +70,7 @@ static int16_t pbvalue[16] =
|
||||||
void
|
void
|
||||||
send_midi(uint8_t portno, int status, int data, int step, int incr, int index, int dir)
|
send_midi(uint8_t portno, int status, int data, int step, int incr, int index, int dir)
|
||||||
{
|
{
|
||||||
if (!enable_jack_output) return; // MIDI output not enabled
|
if (!jack_num_outputs) return; // MIDI output not enabled
|
||||||
uint8_t msg[3];
|
uint8_t msg[3];
|
||||||
int chan = status & 0x0f;
|
int chan = status & 0x0f;
|
||||||
msg[0] = status;
|
msg[0] = status;
|
||||||
|
@ -273,7 +273,7 @@ send_strokes(translation *tr, uint8_t portno, int status, int chan, int data,
|
||||||
int nkeys = 0;
|
int nkeys = 0;
|
||||||
stroke *s = fetch_stroke(tr, portno, status, chan, data, index, dir);
|
stroke *s = fetch_stroke(tr, portno, status, chan, data, index, dir);
|
||||||
|
|
||||||
if (!s && enable_jack_output) {
|
if (!s && jack_num_outputs) {
|
||||||
// fall back to default MIDI translation
|
// fall back to default MIDI translation
|
||||||
tr = default_midi_translation[portno];
|
tr = default_midi_translation[portno];
|
||||||
s = fetch_stroke(tr, portno, status, chan, data, index, dir);
|
s = fetch_stroke(tr, portno, status, chan, data, index, dir);
|
||||||
|
@ -603,11 +603,12 @@ handle_event(uint8_t *msg, uint8_t portno)
|
||||||
|
|
||||||
void help(char *progname)
|
void help(char *progname)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Usage: %s [-h] [-o[2]] [-r rcfile] [-d[rskj]]\n", progname);
|
fprintf(stderr, "Usage: %s [-h] [-o[2]] [-j name] [-r rcfile] [-d[rskmj]]\n", progname);
|
||||||
fprintf(stderr, "-h print this message\n");
|
fprintf(stderr, "-h print this message\n");
|
||||||
fprintf(stderr, "-o enable MIDI output (add 2 for a second pair of ports)\n");
|
fprintf(stderr, "-o enable MIDI output (add 2 for a second pair of ports)\n");
|
||||||
|
fprintf(stderr, "-j jack client name (default: midizap)\n");
|
||||||
fprintf(stderr, "-r config file name (default: MIDIZAP_CONFIG_FILE variable or ~/.midizaprc)\n");
|
fprintf(stderr, "-r config file name (default: MIDIZAP_CONFIG_FILE variable or ~/.midizaprc)\n");
|
||||||
fprintf(stderr, "-d debug (r = regex, s = strokes, k = keys, j = jack; default: all)\n");
|
fprintf(stderr, "-d debug (r = regex, s = strokes, k = keys, m = midi, j = jack; default: all)\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t quit = 0;
|
uint8_t quit = 0;
|
||||||
|
@ -623,25 +624,23 @@ void quitter()
|
||||||
#define CONF_FREQ 1
|
#define CONF_FREQ 1
|
||||||
#define MAX_COUNT (1000000/CONF_FREQ/POLL_INTERVAL)
|
#define MAX_COUNT (1000000/CONF_FREQ/POLL_INTERVAL)
|
||||||
|
|
||||||
int n_ports = 1;
|
|
||||||
|
|
||||||
int
|
int
|
||||||
main(int argc, char **argv)
|
main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
uint8_t msg[3];
|
uint8_t msg[3];
|
||||||
int opt, count = 0;
|
int opt, count = 0;
|
||||||
|
|
||||||
while ((opt = getopt(argc, argv, "ho::d::r:")) != -1) {
|
while ((opt = getopt(argc, argv, "ho::d::j:r:")) != -1) {
|
||||||
switch (opt) {
|
switch (opt) {
|
||||||
case 'h':
|
case 'h':
|
||||||
help(argv[0]);
|
help(argv[0]);
|
||||||
exit(0);
|
exit(0);
|
||||||
case 'o':
|
case 'o':
|
||||||
enable_jack_output = 1;
|
jack_num_outputs = 1;
|
||||||
if (optarg && *optarg) {
|
if (optarg && *optarg) {
|
||||||
const char *a = optarg;
|
const char *a = optarg;
|
||||||
if (*a == '2') {
|
if (*a == '2') {
|
||||||
n_ports = 2;
|
jack_num_outputs = 2;
|
||||||
} else if (*a && *a != '1') {
|
} else if (*a && *a != '1') {
|
||||||
fprintf(stderr, "%s: wrong port number (-o), must be 1 or 2\n", argv[0]);
|
fprintf(stderr, "%s: wrong port number (-o), must be 1 or 2\n", argv[0]);
|
||||||
fprintf(stderr, "Try -h for help.\n");
|
fprintf(stderr, "Try -h for help.\n");
|
||||||
|
@ -682,6 +681,9 @@ main(int argc, char **argv)
|
||||||
debug_jack = 1;
|
debug_jack = 1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case 'j':
|
||||||
|
jack_client_name = optarg;
|
||||||
|
break;
|
||||||
case 'r':
|
case 'r':
|
||||||
config_file_name = optarg;
|
config_file_name = optarg;
|
||||||
break;
|
break;
|
||||||
|
@ -698,14 +700,20 @@ main(int argc, char **argv)
|
||||||
|
|
||||||
initdisplay();
|
initdisplay();
|
||||||
|
|
||||||
seq.n_in = n_ports; seq.n_out = enable_jack_output?n_ports:0;
|
// Force the config file to be loaded initially, so that we pick up the Jack
|
||||||
|
// client name to be used (if not set from the command line). This cannot be
|
||||||
|
// changed later, so if you want to make changes to the client name in the
|
||||||
|
// config file take effect, you need to restart the program.
|
||||||
|
read_config_file();
|
||||||
|
|
||||||
|
seq.client_name = jack_client_name;
|
||||||
|
seq.n_in = jack_num_outputs>1?jack_num_outputs:1;
|
||||||
|
seq.n_out = jack_num_outputs;
|
||||||
if (!init_jack(&seq, debug_jack)) {
|
if (!init_jack(&seq, debug_jack)) {
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
signal(SIGINT, quitter);
|
signal(SIGINT, quitter);
|
||||||
// force the config file to be loaded initially
|
|
||||||
count = MAX_COUNT;
|
|
||||||
while (!quit) {
|
while (!quit) {
|
||||||
uint8_t portno;
|
uint8_t portno;
|
||||||
while (pop_midi(&seq, msg, &portno)) {
|
while (pop_midi(&seq, msg, &portno)) {
|
||||||
|
|
|
@ -93,5 +93,6 @@ extern int debug_regex, debug_strokes, debug_keys, debug_midi;
|
||||||
extern int default_debug_regex, default_debug_strokes, default_debug_keys,
|
extern int default_debug_regex, default_debug_strokes, default_debug_keys,
|
||||||
default_debug_midi;
|
default_debug_midi;
|
||||||
extern char *config_file_name;
|
extern char *config_file_name;
|
||||||
extern int enable_jack_output;
|
extern int jack_num_outputs;
|
||||||
extern int midi_octave;
|
extern int midi_octave;
|
||||||
|
extern char *jack_client_name;
|
||||||
|
|
23
readconfig.c
23
readconfig.c
|
@ -199,6 +199,8 @@ int debug_midi = 0;
|
||||||
|
|
||||||
int midi_octave = 0;
|
int midi_octave = 0;
|
||||||
|
|
||||||
|
char *jack_client_name = NULL;
|
||||||
|
|
||||||
char *
|
char *
|
||||||
allocate(size_t len)
|
allocate(size_t len)
|
||||||
{
|
{
|
||||||
|
@ -1211,6 +1213,27 @@ read_config_file(void)
|
||||||
debug_midi = 1;
|
debug_midi = 1;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (!strcmp(tok, "JACK_NAME")) {
|
||||||
|
char *a = token(NULL, &delim);
|
||||||
|
if (!jack_client_name) {
|
||||||
|
static char buf[100];
|
||||||
|
strncpy(buf, a, 100); buf[99] = 0; // just in case...
|
||||||
|
jack_client_name = buf;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!strcmp(tok, "JACK_PORTS")) {
|
||||||
|
char *a = token(NULL, &delim);
|
||||||
|
int k, n;
|
||||||
|
if (!jack_num_outputs) {
|
||||||
|
if (sscanf(a, "%d%n", &k, &n) == 1 && !a[n] && k>=1 && k<=2) {
|
||||||
|
jack_num_outputs = k;
|
||||||
|
} else {
|
||||||
|
fprintf(stderr, "invalid port number: %s, must be 1 or 2\n", a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (!strncmp(tok, "MIDI_OCTAVE", 11)) {
|
if (!strncmp(tok, "MIDI_OCTAVE", 11)) {
|
||||||
char *a = tok+11;
|
char *a = tok+11;
|
||||||
int k, n;
|
int k, n;
|
||||||
|
|
Loading…
Reference in New Issue