1 /*****************************************************************************
3 * This file is part of jack_mixer
5 * Copyright (C) 2006 Nedko Arnaudov <nedko@arnaudov.name>
6 * Copyright (C) 2009-2011 Frederic Peters <fpeters@0d.be>
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; version 2 of the License
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
21 *****************************************************************************/
24 * jack_mix_box is a most minimalistic jack mixer, a set of mono/sterero input
25 * channels, mixed to a single output channel, with the volume of the
26 * input channels controlled by MIDI control change (CC) codes.
39 #include "jack_mixer.h"
41 #define _(String) gettext(String)
44 bool keepRunning
= true;
49 const char* _usage
= _(
51 "jack_mix_box [-n <name>] [-p] [-s] [-v <dB>] MIDI_CC...\n"
53 "-h|--help print this help message\n"
54 "-n|--name set JACK client name\n"
55 "-p|--pickup enable MIDI pickup mode (default: jump-to-value)\n"
56 "-s|--stereo make all input channels stereo with left+right input\n"
57 "-v|--volume initial volume gain in dBFS (default 0.0, i.e. unity gain)\n"
59 "Each positional argument is interpreted as a MIDI Control Change number and\n"
60 "adds a mixer channel with one (mono) or left+right (stereo) inputs, whose\n"
61 "volume can be controlled via the given MIDI Control Change.\n"
63 "Send SIGUSR1 to the process to have the current volumes reported per input\n"
65 fputs(_usage
, stdout
);
72 channels_volumes_read(mixer
);
76 triggerShutDown(int sig
)
83 main(int argc
, char *argv
[])
85 jack_mixer_scale_t scale
;
86 jack_mixer_channel_t main_mix_channel
;
87 char *jack_cli_name
= NULL
;
90 enum midi_behavior_mode ePickup
= Jump_To_Value
;
91 double initialVolume
= 0.0f
; //in dbFS
94 localedir
= getenv("LOCALEDIR");
95 setlocale(LC_ALL
, "");
96 bindtextdomain("jack_mixer", localedir
!= NULL
? localedir
: LOCALEDIR
);
97 textdomain("jack_mixer");
101 static struct option long_options
[] =
103 {"name", required_argument
, 0, 'n'},
104 {"help", no_argument
, 0, 'h'},
105 {"pickup", no_argument
, 0, 'p'},
106 {"stereo", no_argument
, 0, 's'},
107 {"volume", required_argument
, 0, 'v'},
110 int option_index
= 0;
112 c
= getopt_long (argc
, argv
, "sphn:v:", long_options
, &option_index
);
118 jack_cli_name
= strdup(optarg
);
124 initialVolume
= strtod(optarg
, NULL
);
134 fprintf(stderr
, _("Unknown argument, aborting.\n"));
139 if (optind
== argc
) {
140 fputs(_("You must specify at least one input channel.\n"), stderr
);
144 scale
= scale_create();
145 scale_add_threshold(scale
, -70.0, 0.0);
146 scale_add_threshold(scale
, 0.0, 1.0);
147 scale_calculate_coefficients(scale
);
149 if (jack_cli_name
== NULL
) {
150 jack_cli_name
= strdup("jack_mix_box");
153 mixer
= create(jack_cli_name
, false);
155 fputs(jack_mixer_error_str(), stderr
);
158 main_mix_channel
= add_output_channel(mixer
, "MAIN", true, false);
159 channel_set_midi_scale(main_mix_channel
, scale
);
160 channel_volume_write(main_mix_channel
, 0.0);
161 set_midi_behavior_mode(mixer
, ePickup
);
164 while (optind
< argc
) {
166 jack_mixer_channel_t channel
;
169 channel_name
= malloc(15);
170 if (snprintf(channel_name
, 15, "Channel %d", channel_index
) >= 15) {
174 channel
= add_channel(mixer
, channel_name
, bStereo
);
175 if (channel
== NULL
) {
176 fprintf(stderr
, _("Failed to add channel %d, aborting.\n"), channel_index
);
179 channel_set_volume_midi_cc(channel
, atoi(argv
[optind
++]));
180 channel_set_midi_scale(channel
, scale
);
181 channel_volume_write(channel
, initialVolume
);
185 signal(SIGUSR1
, reportVolume
);
186 signal(SIGTERM
, triggerShutDown
);
187 signal(SIGHUP
, triggerShutDown
);
188 signal(SIGINT
, triggerShutDown
);
190 while (keepRunning
) {
191 usleep(500u * 1000u); //500msec
194 remove_channels(mixer
);
195 remove_output_channel(main_mix_channel
);
197 scale_destroy(scale
);