1 /* -*- Mode: C ; c-basic-offset: 2 -*- */
2 /*****************************************************************************
4 * Copyright (C) 2006,2007,2008,2009 Nedko Arnaudov <nedko@arnaudov.name>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19 *****************************************************************************/
30 #include "lv2dynparam/lv2dynparam.h"
31 #include "lv2dynparam/plugin.h"
33 #include "zynadd_internal.h"
34 #include "zynadd_dynparam_value_changed_callbacks.h"
35 #include "zynadd_dynparam_forest_map_top.h"
36 #include "zynadd_dynparam_forest_map_voice.h"
38 #define LOG_LEVEL LOG_LEVEL_ERROR
42 zynadd_appear_parameter(
43 struct zynadd
* zynadd_ptr
,
44 struct zynadd_parameter
* parameter_ptr
)
46 lv2dynparam_plugin_group parent_group
;
49 "Appearing parameter \"%s\"/\"%s\" -> %p:%u",
50 parameter_ptr
->parent_ptr
? parameter_ptr
->parent_ptr
->name_ptr
: "",
51 parameter_ptr
->name_ptr
,
52 parameter_ptr
->addsynth_component
,
53 parameter_ptr
->addsynth_parameter
);
55 if (parameter_ptr
->parent_ptr
== NULL
)
61 parent_group
= parameter_ptr
->parent_ptr
->lv2group
;
64 switch (parameter_ptr
->type
)
66 case LV2DYNPARAM_PARAMETER_TYPE_BOOL
:
67 if (!lv2dynparam_plugin_param_boolean_add(
68 zynadd_ptr
->dynparams
,
70 parameter_ptr
->name_ptr
,
71 parameter_ptr
->hints_ptr
,
72 zyn_addsynth_get_bool_parameter(
73 parameter_ptr
->addsynth_component
,
74 parameter_ptr
->addsynth_parameter
),
75 zynadd_bool_parameter_changed
,
77 ¶meter_ptr
->lv2parameter
))
84 case LV2DYNPARAM_PARAMETER_TYPE_FLOAT
:
85 if (!lv2dynparam_plugin_param_float_add(
86 zynadd_ptr
->dynparams
,
88 parameter_ptr
->name_ptr
,
89 parameter_ptr
->hints_ptr
,
90 zyn_addsynth_get_float_parameter(
91 parameter_ptr
->addsynth_component
,
92 parameter_ptr
->addsynth_parameter
),
93 parameter_ptr
->map_element_ptr
->min
.fpoint
,
94 parameter_ptr
->map_element_ptr
->max
.fpoint
,
95 zynadd_float_parameter_changed
,
97 ¶meter_ptr
->lv2parameter
))
104 case LV2DYNPARAM_PARAMETER_TYPE_INT
:
105 if (!lv2dynparam_plugin_param_int_add(
106 zynadd_ptr
->dynparams
,
108 parameter_ptr
->name_ptr
,
109 parameter_ptr
->hints_ptr
,
110 zyn_addsynth_get_int_parameter(
111 parameter_ptr
->addsynth_component
,
112 parameter_ptr
->addsynth_parameter
),
113 parameter_ptr
->map_element_ptr
->min
.integer
,
114 parameter_ptr
->map_element_ptr
->max
.integer
,
115 zynadd_int_parameter_changed
,
117 ¶meter_ptr
->lv2parameter
))
124 case LV2DYNPARAM_PARAMETER_TYPE_ENUM
:
125 if (!lv2dynparam_plugin_param_enum_add(
126 zynadd_ptr
->dynparams
,
128 parameter_ptr
->name_ptr
,
129 parameter_ptr
->hints_ptr
,
130 parameter_ptr
->map_element_ptr
->min
.enum_values
,
131 parameter_ptr
->map_element_ptr
->max
.enum_values_count
,
132 zyn_addsynth_get_int_parameter(
133 parameter_ptr
->addsynth_component
,
134 parameter_ptr
->addsynth_parameter
),
135 zynadd_enum_parameter_changed
,
137 ¶meter_ptr
->lv2parameter
))
139 LOG_ERROR("lv2dynparam_plugin_param_enum_add() failed.");
150 /* create forest groups and parameters without exposing them */
152 zynadd_dynparam_forest_initializer_prepare(
153 struct zyn_forest_initializer
* forest_ptr
,
154 struct zyn_forest_map
* map_ptr
,
155 struct zynadd_group
* root_group_ptr
,
156 zyn_addsynth_component
* forest_components_array
,
157 struct zynadd
* zynadd_ptr
,
158 struct list_head
* groups_list_ptr
,
159 struct list_head
* parameters_list_ptr
)
162 struct zynadd_group
* group_ptr
;
163 struct zynadd_parameter
* parameter_ptr
;
165 LOG_DEBUG("Preparing forest with root \"%s\"/", root_group_ptr
== NULL
? "" : root_group_ptr
->name_ptr
);
167 forest_ptr
->map_ptr
= map_ptr
;
169 forest_ptr
->groups_count
= map_ptr
->groups_count
;
170 forest_ptr
->parameters_count
= map_ptr
->parameters_count
;
172 forest_ptr
->groups
= malloc(sizeof(struct zynadd_group
*) * forest_ptr
->groups_count
);
173 if (forest_ptr
->groups
== NULL
)
178 forest_ptr
->parameters
= malloc(sizeof(struct zynadd_parameter
*) * forest_ptr
->parameters_count
);
179 if (forest_ptr
->parameters
== NULL
)
181 goto fail_free_groups_array
;
184 for (i
= 0 ; i
< forest_ptr
->groups_count
; i
++)
186 LOG_DEBUG("Preparing group \"%s\"", forest_ptr
->map_ptr
->groups
[i
].name
);
188 group_ptr
= malloc(sizeof(struct zynadd_group
));
189 if (group_ptr
== NULL
)
191 goto fail_free_parameters_array
;
194 group_ptr
->name_ptr
= forest_ptr
->map_ptr
->groups
[i
].name
;
195 group_ptr
->hints_ptr
= &forest_ptr
->map_ptr
->groups
[i
].hints
;
196 group_ptr
->lv2group
= NULL
;
198 if (forest_ptr
->map_ptr
->groups
[i
].parent
== LV2DYNPARAM_GROUP_ROOT
)
200 group_ptr
->parent_ptr
= root_group_ptr
;
204 group_ptr
->parent_ptr
= forest_ptr
->groups
[forest_ptr
->map_ptr
->groups
[i
].parent
];
207 forest_ptr
->groups
[i
] = group_ptr
;
209 list_add_tail(&group_ptr
->siblings
, groups_list_ptr
);
212 for (i
= 0 ; i
< forest_ptr
->parameters_count
; i
++)
215 "Preparing parameter \"%s\"/\"%s\"",
216 forest_ptr
->map_ptr
->parameters
[i
].parent
== LV2DYNPARAM_GROUP_ROOT
?
217 (root_group_ptr
== NULL
?
219 root_group_ptr
->name_ptr
) :
220 forest_ptr
->groups
[forest_ptr
->map_ptr
->parameters
[i
].parent
]->name_ptr
,
221 forest_ptr
->map_ptr
->parameters
[i
].name
);
223 parameter_ptr
= malloc(sizeof(struct zynadd_parameter
));
224 if (parameter_ptr
== NULL
)
226 goto fail_free_parameters_array
;
229 if (forest_ptr
->map_ptr
->parameters
[i
].parent
== LV2DYNPARAM_GROUP_ROOT
)
231 parameter_ptr
->parent_ptr
= root_group_ptr
;
235 parameter_ptr
->parent_ptr
= forest_ptr
->groups
[forest_ptr
->map_ptr
->parameters
[i
].parent
];
238 forest_ptr
->parameters
[i
] = parameter_ptr
;
240 parameter_ptr
->synth_ptr
= zynadd_ptr
;
241 parameter_ptr
->addsynth_parameter
= forest_ptr
->map_ptr
->parameters
[i
].addsynth_parameter
;
242 parameter_ptr
->addsynth_component
= forest_components_array
[forest_ptr
->map_ptr
->parameters
[i
].addsynth_component
];
243 parameter_ptr
->scope
= forest_ptr
->map_ptr
->parameters
[i
].scope
;
244 parameter_ptr
->other_parameter
= NULL
;
245 parameter_ptr
->lv2parameter
= NULL
;
246 parameter_ptr
->name_ptr
= forest_ptr
->map_ptr
->parameters
[i
].name
;
247 parameter_ptr
->type
= forest_ptr
->map_ptr
->parameters
[i
].type
;
248 parameter_ptr
->hints_ptr
= &forest_ptr
->map_ptr
->parameters
[i
].hints
;
249 parameter_ptr
->map_element_ptr
= forest_ptr
->map_ptr
->parameters
+ i
;
251 list_add_tail(¶meter_ptr
->siblings
, parameters_list_ptr
);
254 /* set other_parameter when needed */
255 for (i
= 0 ; i
< forest_ptr
->parameters_count
; i
++)
257 if (forest_ptr
->map_ptr
->parameters
[i
].scope
== LV2DYNPARAM_PARAMETER_SCOPE_TYPE_HIDE_OTHER
||
258 forest_ptr
->map_ptr
->parameters
[i
].scope
== LV2DYNPARAM_PARAMETER_SCOPE_TYPE_SHOW_OTHER
)
260 forest_ptr
->parameters
[i
]->other_parameter
= forest_ptr
->parameters
[forest_ptr
->map_ptr
->parameters
[i
].scope_specific
];
266 fail_free_parameters_array
:
267 free(forest_ptr
->parameters
);
269 fail_free_groups_array
:
270 free(forest_ptr
->groups
);
277 zynadd_dynparam_forest_initializer_clear(
278 struct zyn_forest_initializer
* forest_ptr
)
280 free(forest_ptr
->groups
);
281 free(forest_ptr
->parameters
);
285 zynadd_dynparam_destroy_forests(
286 struct zynadd
* zynadd_ptr
)
288 struct list_head
* node_ptr
;
289 struct zynadd_group
* group_ptr
;
290 struct zynadd_parameter
* parameter_ptr
;
292 while (!list_empty(&zynadd_ptr
->parameters
))
294 node_ptr
= zynadd_ptr
->parameters
.next
;
295 parameter_ptr
= list_entry(node_ptr
, struct zynadd_parameter
, siblings
);
300 while (!list_empty(&zynadd_ptr
->groups
))
302 node_ptr
= zynadd_ptr
->groups
.next
;
303 group_ptr
= list_entry(node_ptr
, struct zynadd_group
, siblings
);
310 zynadd_dynparam_forests_appear(
311 struct zynadd
* zynadd_ptr
)
314 struct zynadd_group
* group_ptr
;
315 struct zynadd_parameter
* parameter_ptr
;
316 struct list_head
* node_ptr
;
318 list_for_each(node_ptr
, &zynadd_ptr
->groups
)
320 group_ptr
= list_entry(node_ptr
, struct zynadd_group
, siblings
);
322 LOG_DEBUG("Adding group \"%s\"", group_ptr
->name_ptr
);
324 if (!lv2dynparam_plugin_group_add(
325 zynadd_ptr
->dynparams
,
326 group_ptr
->parent_ptr
== NULL
? NULL
: group_ptr
->parent_ptr
->lv2group
,
328 group_ptr
->hints_ptr
,
329 &group_ptr
->lv2group
))
335 list_for_each(node_ptr
, &zynadd_ptr
->parameters
)
337 parameter_ptr
= list_entry(node_ptr
, struct zynadd_parameter
, siblings
);
339 LOG_DEBUG("Adding parameter \"%s\"", parameter_ptr
->name_ptr
);
341 if (parameter_ptr
->scope
== LV2DYNPARAM_PARAMETER_SCOPE_TYPE_SEMI
)
346 if (parameter_ptr
->scope
== LV2DYNPARAM_PARAMETER_SCOPE_TYPE_HIDE_OTHER
||
347 parameter_ptr
->scope
== LV2DYNPARAM_PARAMETER_SCOPE_TYPE_SHOW_OTHER
)
349 LOG_DEBUG("Apearing show/hide parameter \"%s\"", parameter_ptr
->name_ptr
);
350 assert(parameter_ptr
->type
== LV2DYNPARAM_PARAMETER_TYPE_BOOL
);
352 tmp_bool
= zyn_addsynth_get_bool_parameter(
353 parameter_ptr
->addsynth_component
,
354 parameter_ptr
->addsynth_parameter
);
356 if (!zynadd_appear_parameter(zynadd_ptr
, parameter_ptr
))
361 if ((parameter_ptr
->scope
== LV2DYNPARAM_PARAMETER_SCOPE_TYPE_HIDE_OTHER
&& !tmp_bool
) ||
362 (parameter_ptr
->scope
== LV2DYNPARAM_PARAMETER_SCOPE_TYPE_SHOW_OTHER
&& tmp_bool
))
364 LOG_DEBUG("Apearing semi parameter \"%s\"", parameter_ptr
->other_parameter
->name_ptr
);
365 if (!zynadd_appear_parameter(zynadd_ptr
, parameter_ptr
->other_parameter
))
374 assert(parameter_ptr
->scope
== LV2DYNPARAM_PARAMETER_SCOPE_TYPE_ALWAYS
);
376 if (!zynadd_appear_parameter(zynadd_ptr
, parameter_ptr
))
378 LOG_ERROR("zynadd_appear_parameter() failed.");
387 zynadd_dynparam_init(
388 struct zynadd
* zynadd_ptr
)
390 struct zyn_forest_initializer top_forest_initializer
;
391 struct zyn_forest_initializer voice_forest_initializer
;
394 char voice_group_names
[VOICES_COUNT
][20];
396 INIT_LIST_HEAD(&zynadd_ptr
->groups
);
397 INIT_LIST_HEAD(&zynadd_ptr
->parameters
);
399 for (i
= 0 ; i
< ZYNADD_GLOBAL_COMPONENTS_COUNT
; i
++)
401 zynadd_ptr
->synth_global_components
[i
] = zyn_addsynth_get_global_component(zynadd_ptr
->synth
, i
);
404 for (i
= 0 ; i
< VOICES_COUNT
; i
++)
406 for (j
= 0 ; j
< ZYNADD_VOICE_COMPONENTS_COUNT
; j
++)
408 LOG_DEBUG("Voice %u component %u", i
, j
);
409 zynadd_ptr
->synth_voice_components
[i
* ZYNADD_VOICE_COMPONENTS_COUNT
+ j
] = zyn_addsynth_get_voice_component(zynadd_ptr
->synth
, i
, j
);
410 LOG_DEBUG("Voice component %p", zynadd_ptr
->synth_voice_components
[i
* ZYNADD_VOICE_COMPONENTS_COUNT
+ j
]);
414 LOG_DEBUG("Preparing top forest...");
416 if (!zynadd_dynparam_forest_initializer_prepare(
417 &top_forest_initializer
,
420 zynadd_ptr
->synth_global_components
,
423 &zynadd_ptr
->parameters
))
425 goto fail_destroy_forests
;
428 LOG_DEBUG("Preparing voice forest...");
430 for (i
= 0 ; i
< VOICES_COUNT
; i
++)
432 sprintf(voice_group_names
[i
], "Voice %u", i
+ 1);
434 g_voice_forest_map
.groups
[0].name
= voice_group_names
[i
];
436 if (!zynadd_dynparam_forest_initializer_prepare(
437 &voice_forest_initializer
,
439 top_forest_initializer
.groups
[zynadd_top_forest_map_get_voices_group()],
440 zynadd_ptr
->synth_voice_components
+ i
* ZYNADD_VOICE_COMPONENTS_COUNT
,
443 &zynadd_ptr
->parameters
))
445 goto fail_clear_top_forest_initializer
;
449 if (!lv2dynparam_plugin_instantiate(
450 (LV2_Handle
)zynadd_ptr
,
451 zynadd_ptr
->host_features
,
453 &zynadd_ptr
->dynparams
))
455 goto fail_clear_voice_forest_initializer
;
458 if (!zynadd_dynparam_forests_appear(zynadd_ptr
))
460 goto fail_clean_dynparams
;
463 zynadd_dynparam_forest_initializer_clear(&voice_forest_initializer
);
464 zynadd_dynparam_forest_initializer_clear(&top_forest_initializer
);
468 fail_clean_dynparams
:
469 zynadd_dynparam_uninit(zynadd_ptr
);
471 fail_clear_voice_forest_initializer
:
472 zynadd_dynparam_forest_initializer_clear(&voice_forest_initializer
);
474 fail_clear_top_forest_initializer
:
475 zynadd_dynparam_forest_initializer_clear(&top_forest_initializer
);
477 fail_destroy_forests
:
478 zynadd_dynparam_destroy_forests(zynadd_ptr
);
484 zynadd_dynparam_uninit(struct zynadd
* zynadd_ptr
)
486 zynadd_dynparam_destroy_forests(zynadd_ptr
);
488 lv2dynparam_plugin_cleanup(zynadd_ptr
->dynparams
);