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 /* see the interface .h file */
93 int control_set_value(LADSPA_Data
*val
, char *cmd
, control_t
*control
)
97 regmatch_t matches
[1];
98 const char *percent_r
="^%[0-9][0-9]$";
103 if (cmd
== NULL
|| !strcmp(cmd
, "")) /* skip */
105 else if (!strcmp(cmd
, "<")) /* min */
107 else if (!strcmp(cmd
, ">")) /* max */
109 else if (cmd
[0] == '%') { /* percentage */
110 if ((rc
= regcomp(®
, percent_r
, 0)) ) {
111 regerror(rc
, ®
, err
, sizeof(err
));
112 return (fprintf(stderr
, "regex compilation failed: %s\n", err
), -1);
114 if (regexec(®
, cmd
, 1, matches
, 0))
115 return (regfree(®
), -1);
116 *val
= (LADSPA_Data
)strtof(&cmd
[1], NULL
) / 100.0;
117 *val
= control_rounding
118 (control
, (1.0-*val
) * control
->min
+ *val
* control
->max
);
121 else if (!strcmp(cmd
, "d")) { /* default */
123 *val
= *control
->def
;
127 else if (!strcmp(cmd
, "a")) /* active */
128 *val
= *control
->val
;
129 else if (!strcmp(cmd
, "s")) /* selected */
132 buf
= (LADSPA_Data
)strtof(cmd
, &e
);
133 if (e
== cmd
|| *e
!= '\0')
141 /* Find the initial config of the control at index ctrl */
142 int control_set_init(control_init_t
*init
,
143 unsigned long ctrl
, control_t
*control
)
147 rc
= control_set_value(&init
->min
, glib_strv_index(2*ctrl
, control_bounds
), control
);
148 init
->with_min
= rc
? 0 : 1;
149 if (rc
< 0) ret
= rc
;
150 rc
= control_set_value(&init
->max
, glib_strv_index(2*ctrl
+1, control_bounds
), control
);
151 init
->with_max
= rc
? 0 : 1;
152 if (rc
< 0) ret
= rc
;
154 rc
= control_set_value(&init
->ini
, glib_strv_index(ctrl
, control_inits
), control
);
155 init
->with_ini
= rc
? 0 : 1;
156 if (rc
< 0) ret
= rc
;
158 rc
= control_set_value(&init
->def
, glib_strv_index(ctrl
, control_defaults
), control
);
159 init
->with_def
= rc
? 0 : 1;
160 if (rc
< 0) ret
= rc
;
165 int control_init(control_t
*control
, state_t
*state
, unsigned long port
,
168 control
->port
= port
;
169 control
->ctrl
= ctrl
;
170 control
->desc
= &state
->descriptor
->PortDescriptors
[port
];
171 control
->hint
= &state
->descriptor
->PortRangeHints
[port
];
172 LADSPA_PortRangeHintDescriptor descriptor
= control
->hint
->HintDescriptor
;
173 LADSPA_Data lower_bound
= control
->hint
->LowerBound
;
174 LADSPA_Data upper_bound
= control
->hint
->UpperBound
;
177 control
->name
= state
->port_names
[port
];
178 control
->val
= &state
->control_port_values
[port
];
180 /* control->min, control->max */
181 if (LADSPA_IS_HINT_SAMPLE_RATE(descriptor
)) {
182 int sample_rate
= jack_get_sample_rate(state
->jack_client
);
183 lower_bound
*= sample_rate
;
184 upper_bound
*= sample_rate
;
186 if ( LADSPA_IS_HINT_BOUNDED_BELOW(descriptor
) &&
187 LADSPA_IS_HINT_BOUNDED_ABOVE(descriptor
) )
189 control
->min
= lower_bound
;
190 control
->max
= upper_bound
;
192 else if (LADSPA_IS_HINT_BOUNDED_BELOW(descriptor
)) {
193 control
->min
= lower_bound
;
196 else if (LADSPA_IS_HINT_BOUNDED_ABOVE(descriptor
)) {
198 control
->max
= upper_bound
;
206 if (LADSPA_IS_HINT_HAS_DEFAULT(descriptor
)) {
207 control
->def
= (LADSPA_Data
*)malloc(sizeof(LADSPA_Data
));
209 return (fprintf(stderr
, "memory allocation error\n"), 1);
210 switch (descriptor
& LADSPA_HINT_DEFAULT_MASK
) {
211 case LADSPA_HINT_DEFAULT_MINIMUM
:
212 *control
->def
= lower_bound
;
214 case LADSPA_HINT_DEFAULT_LOW
:
215 *control
->def
= lower_bound
* 0.75 + upper_bound
* 0.25;
217 case LADSPA_HINT_DEFAULT_MIDDLE
:
218 *control
->def
= lower_bound
* 0.5 + upper_bound
* 0.5;
220 case LADSPA_HINT_DEFAULT_HIGH
:
221 *control
->def
= lower_bound
* 0.25 + upper_bound
* 0.75;
223 case LADSPA_HINT_DEFAULT_MAXIMUM
:
224 *control
->def
= upper_bound
;
226 case LADSPA_HINT_DEFAULT_0
:
229 case LADSPA_HINT_DEFAULT_1
:
232 case LADSPA_HINT_DEFAULT_100
:
233 *control
->def
= 100.0;
235 case LADSPA_HINT_DEFAULT_440
:
236 *control
->def
= 440.0;
239 fprintf(stderr
, "default not found\n");
240 free(control
->def
), control
->def
= NULL
;
246 /* Check the default */
248 if (*control
->def
< control
->min
) {
249 fprintf(stderr
, "default smaller than the minimum\n");
250 *control
->def
= control
->min
;
252 if (*control
->def
> control
->max
) {
253 fprintf(stderr
, "default greater than the maximum\n");
254 *control
->def
= control
->max
;
258 /* control->inc & Overrides */
259 if (LADSPA_IS_HINT_TOGGLED(descriptor
)) {
262 control
->inc
.fine
= 1.0;
263 control
->inc
.coarse
= 1.0;
264 control
->type
= JACKSPA_TOGGLE
;
265 if (control
->def
) *control
->def
= nearbyintf(*control
->def
);
267 else if (LADSPA_IS_HINT_INTEGER(descriptor
)) {
268 control
->min
= nearbyintf(control
->min
);
269 control
->max
= nearbyintf(control
->max
);
270 control
->inc
.fine
= 1.0;
271 control
->inc
.coarse
= 1.0;
272 control
->type
= JACKSPA_INT
;
273 if (control
->def
) *control
->def
= nearbyintf(*control
->def
);
276 control
->inc
.fine
= (control
->max
- control
->min
) / 500;
277 control
->inc
.coarse
= (control
->max
- control
->min
) / 50;
278 control
->type
= JACKSPA_FLOAT
;
282 if (control_set_init(&init
, ctrl
, control
) < 0)
283 return (fprintf(stderr
, "invalid initial value given\n"), 1);
285 control
->min
= init
.min
;
287 control
->max
= init
.max
;
290 control
->def
= (LADSPA_Data
*)malloc(sizeof(LADSPA_Data
));
292 return (fprintf(stderr
, "memory allocation error\n"), 1);
294 *control
->def
= init
.def
;
297 /* control->sel, control->val */
299 control
->sel
= *control
->def
;
301 control
->sel
= control
->min
;
303 *control
->val
= init
.ini
;
305 *control
->val
= control
->sel
;
310 void control_fini(control_t
*control
)
312 free(control
->def
), control
->def
= NULL
;
315 int control_buildall(unsigned long *count
, controls_t
*controls
, state_t
*state
)
318 unsigned long p
, c
; /* loop variables for ports */
320 *count
= state
->num_control_ports
;
321 *controls
= (controls_t
)calloc(sizeof(control_t
*), (size_t)*count
);
323 return (fprintf(stderr
, "memory allocation error\n"), 1);
325 for (p
= 0, c
= 0; p
< state
->descriptor
->PortCount
; p
++)
326 if ( LADSPA_IS_PORT_INPUT(state
->descriptor
->PortDescriptors
[p
]) &&
327 LADSPA_IS_PORT_CONTROL(state
->descriptor
->PortDescriptors
[p
]) )
329 (*controls
)[c
] = (control_t
*)malloc(sizeof(control_t
));
331 return (fprintf(stderr
, "memory allocation error\n"), 1);
332 if (control_init((*controls
)[c
], state
, p
, c
))
340 void control_cleanupall(unsigned long count
, controls_t
*controls
)
343 control_fini((*controls
)[--count
]);
344 free((*controls
)[count
]);