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_bounds
= NULL
;
44 gchar
**control_inits
= NULL
;
45 gchar
**control_defaults
= NULL
;
46 gboolean
parse_bounds(const gchar
*opt
, const gchar
*arg
,
47 gpointer data
, GError
**error
)
49 g_strfreev(control_bounds
); /* discard a possible previous option */
50 control_bounds
= g_strsplit(arg
, ":", -1);
53 gboolean
parse_inits(const gchar
*opt
, const gchar
*arg
,
54 gpointer data
, GError
**error
)
56 g_strfreev(control_inits
); /* discard a possible previous option */
57 control_inits
= g_strsplit(arg
, ":", -1);
60 gboolean
parse_defaults(const gchar
*opt
, const gchar
*arg
,
61 gpointer data
, GError
**error
)
63 g_strfreev(control_defaults
); /* discard a possible previous option */
64 control_defaults
= g_strsplit(arg
, ":", -1);
68 const GOptionEntry control_entries
[] =
70 /* long, short, flags, arg_type, arg_data, description, arg_description */
71 { "bounds", 'b', 0, G_OPTION_ARG_CALLBACK
, parse_bounds
,
72 "Colon separated list of multiplexed min/max values", "bound_values" },
73 { "inits", 'i', 0, G_OPTION_ARG_CALLBACK
, parse_inits
,
74 "Colon separated list of initial values", "init_values" },
75 { "defaults", 'd', 0, G_OPTION_ARG_CALLBACK
, parse_defaults
,
76 "Colon separated list of default values", "default_values" },
92 /* Interpret the given command to obtain a value depending of the control
94 * Return 0 if the value was set, 1 if the command was to skip, -1 otherwise
95 * (invalid command or error) */
96 int control_set_value(LADSPA_Data
*val
, char *cmd
, control_t
*control
)
100 regmatch_t matches
[1];
101 const char *percent_r
="^%[0-9][0-9]$";
106 if (cmd
== NULL
|| !strcmp(cmd
, "")) /* skip */
108 else if (!strcmp(cmd
, "<")) /* min */
110 else if (!strcmp(cmd
, ">")) /* max */
112 else if (cmd
[0] == '%') { /* percentage */
113 if ((rc
= regcomp(®
, percent_r
, 0)) ) {
114 regerror(rc
, ®
, err
, sizeof(err
));
115 return (fprintf(stderr
, "regex compilation failed: %s\n", err
), -1);
117 if (regexec(®
, cmd
, 1, matches
, 0))
118 return (regfree(®
), -1);
119 *val
= (LADSPA_Data
)strtof(&cmd
[1], NULL
) / 100.0;
120 *val
= control_rounding
121 (control
, (1.0-*val
) * control
->min
+ *val
* control
->max
);
124 else if (!strcmp(cmd
, "d")) { /* default */
126 *val
= *control
->def
;
130 else if (!strcmp(cmd
, "a")) /* active */
131 *val
= *control
->val
;
132 else if (!strcmp(cmd
, "s")) /* selected */
135 buf
= (LADSPA_Data
)strtof(cmd
, &e
);
136 if (e
== cmd
|| *e
!= '\0')
144 /* Find the initial config of the control at index ctrl */
145 int control_set_init(control_init_t
*init
,
146 unsigned long ctrl
, control_t
*control
)
150 rc
= control_set_value(&init
->min
, glib_strv_index(2*ctrl
, control_bounds
), control
);
151 init
->with_min
= rc
? 0 : 1;
152 if (rc
< 0) ret
= rc
;
153 rc
= control_set_value(&init
->max
, glib_strv_index(2*ctrl
+1, control_bounds
), control
);
154 init
->with_max
= rc
? 0 : 1;
155 if (rc
< 0) ret
= rc
;
157 rc
= control_set_value(&init
->ini
, glib_strv_index(ctrl
, control_inits
), control
);
158 init
->with_ini
= rc
? 0 : 1;
159 if (rc
< 0) ret
= rc
;
161 rc
= control_set_value(&init
->def
, glib_strv_index(ctrl
, control_defaults
), control
);
162 init
->with_def
= rc
? 0 : 1;
163 if (rc
< 0) ret
= rc
;
168 int control_init(control_t
*control
, state_t
*state
, unsigned long port
,
171 control
->port
= port
;
172 control
->ctrl
= ctrl
;
173 control
->desc
= &state
->descriptor
->PortDescriptors
[port
];
174 control
->hint
= &state
->descriptor
->PortRangeHints
[port
];
175 LADSPA_PortRangeHintDescriptor descriptor
= control
->hint
->HintDescriptor
;
176 LADSPA_Data lower_bound
= control
->hint
->LowerBound
;
177 LADSPA_Data upper_bound
= control
->hint
->UpperBound
;
180 control
->name
= state
->port_names
[port
];
181 control
->val
= &state
->control_port_values
[port
];
183 /* control->min, control->max */
184 if (LADSPA_IS_HINT_SAMPLE_RATE(descriptor
)) {
185 int sample_rate
= jack_get_sample_rate(state
->jack_client
);
186 lower_bound
*= sample_rate
;
187 upper_bound
*= sample_rate
;
189 if ( LADSPA_IS_HINT_BOUNDED_BELOW(descriptor
) &&
190 LADSPA_IS_HINT_BOUNDED_ABOVE(descriptor
) )
192 control
->min
= lower_bound
;
193 control
->max
= upper_bound
;
195 else if (LADSPA_IS_HINT_BOUNDED_BELOW(descriptor
)) {
196 control
->min
= lower_bound
;
199 else if (LADSPA_IS_HINT_BOUNDED_ABOVE(descriptor
)) {
201 control
->max
= upper_bound
;
209 if (LADSPA_IS_HINT_HAS_DEFAULT(descriptor
)) {
210 control
->def
= (LADSPA_Data
*)malloc(sizeof(LADSPA_Data
));
212 return (fprintf(stderr
, "memory allocation error\n"), 1);
213 switch (descriptor
& LADSPA_HINT_DEFAULT_MASK
) {
214 case LADSPA_HINT_DEFAULT_MINIMUM
:
215 *control
->def
= lower_bound
;
217 case LADSPA_HINT_DEFAULT_LOW
:
218 *control
->def
= lower_bound
* 0.75 + upper_bound
* 0.25;
220 case LADSPA_HINT_DEFAULT_MIDDLE
:
221 *control
->def
= lower_bound
* 0.5 + upper_bound
* 0.5;
223 case LADSPA_HINT_DEFAULT_HIGH
:
224 *control
->def
= lower_bound
* 0.25 + upper_bound
* 0.75;
226 case LADSPA_HINT_DEFAULT_MAXIMUM
:
227 *control
->def
= upper_bound
;
229 case LADSPA_HINT_DEFAULT_0
:
232 case LADSPA_HINT_DEFAULT_1
:
235 case LADSPA_HINT_DEFAULT_100
:
236 *control
->def
= 100.0;
238 case LADSPA_HINT_DEFAULT_440
:
239 *control
->def
= 440.0;
242 fprintf(stderr
, "default not found\n");
243 free(control
->def
), control
->def
= NULL
;
249 /* Check the default */
251 if (*control
->def
< control
->min
) {
252 fprintf(stderr
, "default smaller than the minimum\n");
253 *control
->def
= control
->min
;
255 if (*control
->def
> control
->max
) {
256 fprintf(stderr
, "default greater than the maximum\n");
257 *control
->def
= control
->max
;
261 /* control->inc & Overrides */
262 if (LADSPA_IS_HINT_TOGGLED(descriptor
)) {
265 control
->inc
.fine
= 1.0;
266 control
->inc
.coarse
= 1.0;
267 control
->type
= JACKSPA_TOGGLE
;
268 if (control
->def
) *control
->def
= nearbyintf(*control
->def
);
270 else if (LADSPA_IS_HINT_INTEGER(descriptor
)) {
271 control
->min
= nearbyintf(control
->min
);
272 control
->max
= nearbyintf(control
->max
);
273 control
->inc
.fine
= 1.0;
274 control
->inc
.coarse
= 1.0;
275 control
->type
= JACKSPA_INT
;
276 if (control
->def
) *control
->def
= nearbyintf(*control
->def
);
279 control
->inc
.fine
= (control
->max
- control
->min
) / 500;
280 control
->inc
.coarse
= (control
->max
- control
->min
) / 50;
281 control
->type
= JACKSPA_FLOAT
;
285 if (control_set_init(&init
, ctrl
, control
) < 0)
286 return (fprintf(stderr
, "invalid initial value given\n"), 1);
288 control
->min
= init
.min
;
290 control
->max
= init
.max
;
293 control
->def
= (LADSPA_Data
*)malloc(sizeof(LADSPA_Data
));
295 return (fprintf(stderr
, "memory allocation error\n"), 1);
297 *control
->def
= init
.def
;
300 /* control->sel, control->val */
302 control
->sel
= *control
->def
;
304 control
->sel
= control
->min
;
306 *control
->val
= init
.ini
;
308 *control
->val
= control
->sel
;
313 int control_buildall(unsigned long *count
, controls_t
*controls
, state_t
*state
)
316 unsigned long p
, c
; /* loop variables for ports */
318 *count
= state
->num_control_ports
;
319 *controls
= (controls_t
)calloc(sizeof(control_t
*), (size_t)*count
);
321 return (fprintf(stderr
, "memory allocation error\n"), 1);
323 for (p
= 0, c
= 0; p
< state
->descriptor
->PortCount
; p
++)
324 if ( LADSPA_IS_PORT_INPUT(state
->descriptor
->PortDescriptors
[p
]) &&
325 LADSPA_IS_PORT_CONTROL(state
->descriptor
->PortDescriptors
[p
]) )
327 (*controls
)[c
] = (control_t
*)malloc(sizeof(control_t
));
329 return (fprintf(stderr
, "memory allocation error\n"), 1);
330 if (control_init((*controls
)[c
], state
, p
, c
))
338 void control_cleanupall(unsigned long count
, controls_t
*controls
)
340 while (count
) free((*controls
)[--count
]);