1 /* control.c - interface to the controls of a jackspa plugin instance
2 * Copyright © 2013 Géraud Meyer <graud@gmx.com>
4 * This file is part of ng-jackspa.
6 * ng-jackspa is free software; you can redistribute it and/or modify it under
7 * the terms of the GNU General Public License version 2 as published by the
8 * Free Software Foundation.
10 * This program is distributed in the hope that it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15 * You should have received a copy of the GNU General Public License along
16 * with ng-jackspa. If not, see <http://www.gnu.org/licenses/>.
25 #include "interface.h"
27 LADSPA_Data
control_rounding(const control_t
*control
, LADSPA_Data val
)
29 if (control
->type
== JACKSPA_INT
|| control
->type
== JACKSPA_TOGGLE
)
30 return nearbyintf(val
);
34 void control_exchange(control_t
*control
)
38 *control
->val
= control
->sel
;
42 /* Initial config (command line switches) */
43 gchar
**control_inits
= NULL
;
44 gchar
**control_defaults
= NULL
;
45 gboolean
parse_inits(const gchar
*opt
, const gchar
*arg
,
46 gpointer data
, GError
**error
)
48 g_strfreev(control_inits
); /* discard a possible previous option */
49 control_inits
= g_strsplit(arg
, ":", -1);
52 gboolean
parse_defaults(const gchar
*opt
, const gchar
*arg
,
53 gpointer data
, GError
**error
)
55 g_strfreev(control_defaults
); /* discard a possible previous option */
56 control_defaults
= g_strsplit(arg
, ":", -1);
60 const GOptionEntry control_entries
[] =
62 /* long, short, flags, arg_type, arg_data, description, arg_description */
63 { "inits", 'i', 0, G_OPTION_ARG_CALLBACK
, parse_inits
,
64 "Colon separated list of initial values", "init_values" },
65 { "defaults", 'd', 0, G_OPTION_ARG_CALLBACK
, parse_defaults
,
66 "Colon separated list of default values", "default_values" },
76 /* Interpret the given command to obtain a value depending of the control
78 * Return 0 if the value was set, 1 if the command was to skip, -1 otherwise
79 * (invalid command or error) */
80 int control_set_value(LADSPA_Data
*val
, char *cmd
, control_t
*control
)
84 regmatch_t matches
[1];
85 const char *percent_r
="^%[0-9][0-9]$";
90 if (cmd
== NULL
|| !strcmp(cmd
, "")) /* skip */
92 else if (!strcmp(cmd
, "<")) /* min */
94 else if (!strcmp(cmd
, ">")) /* max */
96 else if (cmd
[0] == '%') { /* percentage */
97 if ((rc
= regcomp(®
, percent_r
, 0)) ) {
98 regerror(rc
, ®
, err
, sizeof(err
));
99 return (fprintf(stderr
, "regex compilation failed: %s\n", err
), -1);
101 if (regexec(®
, cmd
, 1, matches
, 0))
102 return (regfree(®
), -1);
103 *val
= (LADSPA_Data
)strtof(&cmd
[1], NULL
) / 100.0;
104 *val
= control_rounding
105 (control
, (1.0-*val
) * control
->min
+ *val
* control
->max
);
108 else if (!strcmp(cmd
, "d")) { /* default */
110 *val
= *control
->def
;
114 else if (!strcmp(cmd
, "a")) /* active */
115 *val
= *control
->val
;
116 else if (!strcmp(cmd
, "s")) /* selected */
119 buf
= (LADSPA_Data
)strtof(cmd
, &e
);
120 if (e
== cmd
|| *e
!= '\0')
128 /* Find the initial config of the control at index ctrl */
129 int control_set_init(control_init_t
*init
,
130 unsigned long ctrl
, control_t
*control
)
134 if (!(init
->ini
= malloc(sizeof(LADSPA_Data
))) )
136 rc
= control_set_value(init
->ini
, glib_strv_index(ctrl
, control_inits
), control
);
138 free(init
->ini
), init
->ini
= NULL
;
142 if (!(init
->def
= malloc(sizeof(LADSPA_Data
))) )
144 rc
= control_set_value(init
->def
, glib_strv_index(ctrl
, control_defaults
), control
);
146 free(init
->def
), init
->def
= NULL
;
153 int control_init(control_t
*control
, state_t
*state
, unsigned long port
,
156 control
->port
= port
;
157 control
->ctrl
= ctrl
;
158 control
->desc
= &state
->descriptor
->PortDescriptors
[port
];
159 control
->hint
= &state
->descriptor
->PortRangeHints
[port
];
160 LADSPA_PortRangeHintDescriptor descriptor
= control
->hint
->HintDescriptor
;
161 LADSPA_Data lower_bound
= control
->hint
->LowerBound
;
162 LADSPA_Data upper_bound
= control
->hint
->UpperBound
;
165 control
->name
= state
->port_names
[port
];
166 control
->val
= &state
->control_port_values
[port
];
168 /* control->min, control->max */
169 if (LADSPA_IS_HINT_SAMPLE_RATE(descriptor
)) {
170 int sample_rate
= jack_get_sample_rate(state
->jack_client
);
171 lower_bound
*= sample_rate
;
172 upper_bound
*= sample_rate
;
174 if ( LADSPA_IS_HINT_BOUNDED_BELOW(descriptor
) &&
175 LADSPA_IS_HINT_BOUNDED_ABOVE(descriptor
) )
177 control
->min
= lower_bound
;
178 control
->max
= upper_bound
;
180 else if (LADSPA_IS_HINT_BOUNDED_BELOW(descriptor
)) {
181 control
->min
= lower_bound
;
184 else if (LADSPA_IS_HINT_BOUNDED_ABOVE(descriptor
)) {
186 control
->max
= upper_bound
;
194 if (LADSPA_IS_HINT_HAS_DEFAULT(descriptor
)) {
195 control
->def
= (LADSPA_Data
*)malloc(sizeof(LADSPA_Data
));
197 return (fprintf(stderr
, "memory allocation error\n"), 1);
198 switch (descriptor
& LADSPA_HINT_DEFAULT_MASK
) {
199 case LADSPA_HINT_DEFAULT_MINIMUM
:
200 *control
->def
= lower_bound
;
202 case LADSPA_HINT_DEFAULT_LOW
:
203 *control
->def
= lower_bound
* 0.75 + upper_bound
* 0.25;
205 case LADSPA_HINT_DEFAULT_MIDDLE
:
206 *control
->def
= lower_bound
* 0.5 + upper_bound
* 0.5;
208 case LADSPA_HINT_DEFAULT_HIGH
:
209 *control
->def
= lower_bound
* 0.25 + upper_bound
* 0.75;
211 case LADSPA_HINT_DEFAULT_MAXIMUM
:
212 *control
->def
= upper_bound
;
214 case LADSPA_HINT_DEFAULT_0
:
217 case LADSPA_HINT_DEFAULT_1
:
220 case LADSPA_HINT_DEFAULT_100
:
221 *control
->def
= 100.0;
223 case LADSPA_HINT_DEFAULT_440
:
224 *control
->def
= 440.0;
227 fprintf(stderr
, "default not found\n");
228 free(control
->def
), control
->def
= NULL
;
234 /* Check the default */
236 if (*control
->def
< control
->min
) {
237 fprintf(stderr
, "default smaller than the minimum\n");
238 *control
->def
= control
->min
;
240 if (*control
->def
> control
->max
) {
241 fprintf(stderr
, "default greater than the maximum\n");
242 *control
->def
= control
->max
;
246 /* control->inc & Overrides */
247 if (LADSPA_IS_HINT_TOGGLED(descriptor
)) {
250 control
->inc
.fine
= 1.0;
251 control
->inc
.coarse
= 1.0;
252 control
->type
= JACKSPA_TOGGLE
;
253 if (control
->def
) *control
->def
= nearbyintf(*control
->def
);
255 else if (LADSPA_IS_HINT_INTEGER(descriptor
)) {
256 control
->min
= nearbyintf(control
->min
);
257 control
->max
= nearbyintf(control
->max
);
258 control
->inc
.fine
= 1.0;
259 control
->inc
.coarse
= 1.0;
260 control
->type
= JACKSPA_INT
;
261 if (control
->def
) *control
->def
= nearbyintf(*control
->def
);
264 control
->inc
.fine
= (control
->max
- control
->min
) / 500;
265 control
->inc
.coarse
= (control
->max
- control
->min
) / 50;
266 control
->type
= JACKSPA_FLOAT
;
270 if (control_set_init(&init
, ctrl
, control
) < 0)
271 return (fprintf(stderr
, "invalid initial value given\n"), 1);
274 control
->def
= (LADSPA_Data
*)malloc(sizeof(LADSPA_Data
));
276 return (fprintf(stderr
, "memory allocation error\n"), 1);
278 *control
->def
= *init
.def
;
281 /* control->sel, control->val */
283 control
->sel
= *control
->def
;
285 control
->sel
= control
->min
;
287 *control
->val
= *init
.ini
;
289 *control
->val
= control
->sel
;
291 free(init
.def
), free(init
.ini
);
295 int control_buildall(unsigned long *count
, controls_t
*controls
, state_t
*state
)
298 unsigned long p
, c
; /* loop variables for ports */
300 *count
= state
->num_control_ports
;
301 *controls
= (controls_t
)calloc(sizeof(control_t
*), (size_t)*count
);
303 return (fprintf(stderr
, "memory allocation error\n"), 1);
305 for (p
= 0, c
= 0; p
< state
->descriptor
->PortCount
; p
++)
306 if ( LADSPA_IS_PORT_INPUT(state
->descriptor
->PortDescriptors
[p
]) &&
307 LADSPA_IS_PORT_CONTROL(state
->descriptor
->PortDescriptors
[p
]) )
309 (*controls
)[c
] = (control_t
*)malloc(sizeof(control_t
));
311 return (fprintf(stderr
, "memory allocation error\n"), 1);
312 if (control_init((*controls
)[c
], state
, p
, c
))
320 void control_cleanupall(unsigned long count
, controls_t
*controls
)
322 while (count
) free((*controls
)[--count
]);