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 *****************************************************************************/
29 #include "lv2dynparam/lv2dynparam.h"
30 #include "lv2dynparam/plugin.h"
32 #include "zynadd_internal.h"
33 #include "zynadd_dynparam_value_changed_callbacks.h"
34 #include "zynadd_dynparam_forest_map_top.h"
35 #include "zynadd_dynparam_forest_map_voice.h"
37 #define LOG_LEVEL LOG_LEVEL_ERROR
41 zynadd_appear_parameter(
42 struct zynadd
* zynadd_ptr
,
43 struct zynadd_parameter
* parameter_ptr
)
45 lv2dynparam_plugin_group parent_group
;
48 "Appearing parameter \"%s\"/\"%s\" -> %u",
49 parameter_ptr
->parent_ptr
? parameter_ptr
->parent_ptr
->name_ptr
: "",
50 parameter_ptr
->name_ptr
,
51 parameter_ptr
->addsynth_parameter
);
53 if (parameter_ptr
->parent_ptr
== NULL
)
59 parent_group
= parameter_ptr
->parent_ptr
->lv2group
;
62 switch (parameter_ptr
->type
)
64 case LV2DYNPARAM_PARAMETER_TYPE_BOOL
:
65 if (!lv2dynparam_plugin_param_boolean_add(
66 zynadd_ptr
->dynparams
,
68 parameter_ptr
->name_ptr
,
69 parameter_ptr
->hints_ptr
,
70 zyn_addsynth_get_bool_parameter(
71 parameter_ptr
->addsynth_component
,
72 parameter_ptr
->addsynth_parameter
),
73 zynadd_bool_parameter_changed
,
75 ¶meter_ptr
->lv2parameter
))
82 case LV2DYNPARAM_PARAMETER_TYPE_FLOAT
:
83 if (!lv2dynparam_plugin_param_float_add(
84 zynadd_ptr
->dynparams
,
86 parameter_ptr
->name_ptr
,
87 parameter_ptr
->hints_ptr
,
88 zyn_addsynth_get_float_parameter(
89 parameter_ptr
->addsynth_component
,
90 parameter_ptr
->addsynth_parameter
),
91 parameter_ptr
->map_element_ptr
->min
.fpoint
,
92 parameter_ptr
->map_element_ptr
->max
.fpoint
,
93 zynadd_float_parameter_changed
,
95 ¶meter_ptr
->lv2parameter
))
102 case LV2DYNPARAM_PARAMETER_TYPE_INT
:
103 if (!lv2dynparam_plugin_param_int_add(
104 zynadd_ptr
->dynparams
,
106 parameter_ptr
->name_ptr
,
107 parameter_ptr
->hints_ptr
,
108 zyn_addsynth_get_int_parameter(
109 parameter_ptr
->addsynth_component
,
110 parameter_ptr
->addsynth_parameter
),
111 parameter_ptr
->map_element_ptr
->min
.integer
,
112 parameter_ptr
->map_element_ptr
->max
.integer
,
113 zynadd_int_parameter_changed
,
115 ¶meter_ptr
->lv2parameter
))
122 case LV2DYNPARAM_PARAMETER_TYPE_ENUM
:
123 if (!lv2dynparam_plugin_param_enum_add(
124 zynadd_ptr
->dynparams
,
126 parameter_ptr
->name_ptr
,
127 parameter_ptr
->hints_ptr
,
128 parameter_ptr
->map_element_ptr
->min
.enum_values
,
129 parameter_ptr
->map_element_ptr
->max
.enum_values_count
,
130 zyn_addsynth_get_int_parameter(
131 parameter_ptr
->addsynth_component
,
132 parameter_ptr
->addsynth_parameter
),
133 zynadd_enum_parameter_changed
,
135 ¶meter_ptr
->lv2parameter
))
137 LOG_ERROR("lv2dynparam_plugin_param_enum_add() failed.");
148 /* create forest groups and parameters without exposing them */
150 zynadd_dynparam_forest_initializer_prepare(
151 struct zyn_forest_initializer
* forest_ptr
,
152 struct zyn_forest_map
* map_ptr
,
153 struct zynadd_group
* root_group_ptr
,
154 zyn_addsynth_component
* forest_components_array
,
155 struct zynadd
* zynadd_ptr
,
156 struct list_head
* groups_list_ptr
,
157 struct list_head
* parameters_list_ptr
)
160 struct zynadd_group
* group_ptr
;
161 struct zynadd_parameter
* parameter_ptr
;
163 LOG_DEBUG("Preparing forest with root \"%s\"/", root_group_ptr
== NULL
? "" : root_group_ptr
->name_ptr
);
165 forest_ptr
->map_ptr
= map_ptr
;
167 forest_ptr
->groups_count
= map_ptr
->groups_count
;
168 forest_ptr
->parameters_count
= map_ptr
->parameters_count
;
170 forest_ptr
->groups
= malloc(sizeof(struct zynadd_group
*) * forest_ptr
->groups_count
);
171 if (forest_ptr
->groups
== NULL
)
176 forest_ptr
->parameters
= malloc(sizeof(struct zynadd_parameter
*) * forest_ptr
->parameters_count
);
177 if (forest_ptr
->parameters
== NULL
)
179 goto fail_free_groups_array
;
182 for (i
= 0 ; i
< forest_ptr
->groups_count
; i
++)
184 LOG_DEBUG("Preparing group \"%s\"", forest_ptr
->map_ptr
->groups
[i
].name
);
186 group_ptr
= malloc(sizeof(struct zynadd_group
));
187 if (group_ptr
== NULL
)
189 goto fail_free_parameters_array
;
192 group_ptr
->name_ptr
= forest_ptr
->map_ptr
->groups
[i
].name
;
193 group_ptr
->hints_ptr
= &forest_ptr
->map_ptr
->groups
[i
].hints
;
194 group_ptr
->lv2group
= NULL
;
196 if (forest_ptr
->map_ptr
->groups
[i
].parent
== LV2DYNPARAM_GROUP_ROOT
)
198 group_ptr
->parent_ptr
= root_group_ptr
;
202 group_ptr
->parent_ptr
= forest_ptr
->groups
[forest_ptr
->map_ptr
->groups
[i
].parent
];
205 forest_ptr
->groups
[i
] = group_ptr
;
207 list_add_tail(&group_ptr
->siblings
, groups_list_ptr
);
210 for (i
= 0 ; i
< forest_ptr
->parameters_count
; i
++)
213 "Preparing parameter \"%s\"/\"%s\"",
214 forest_ptr
->map_ptr
->parameters
[i
].parent
== LV2DYNPARAM_GROUP_ROOT
?
215 (root_group_ptr
== NULL
?
217 root_group_ptr
->name_ptr
) :
218 forest_ptr
->groups
[forest_ptr
->map_ptr
->parameters
[i
].parent
]->name_ptr
,
219 forest_ptr
->map_ptr
->parameters
[i
].name
);
221 parameter_ptr
= malloc(sizeof(struct zynadd_parameter
));
222 if (parameter_ptr
== NULL
)
224 goto fail_free_parameters_array
;
227 if (forest_ptr
->map_ptr
->parameters
[i
].parent
== LV2DYNPARAM_GROUP_ROOT
)
229 parameter_ptr
->parent_ptr
= root_group_ptr
;
233 parameter_ptr
->parent_ptr
= forest_ptr
->groups
[forest_ptr
->map_ptr
->parameters
[i
].parent
];
236 forest_ptr
->parameters
[i
] = parameter_ptr
;
238 parameter_ptr
->synth_ptr
= zynadd_ptr
;
239 parameter_ptr
->addsynth_parameter
= forest_ptr
->map_ptr
->parameters
[i
].addsynth_parameter
;
240 parameter_ptr
->addsynth_component
= forest_components_array
[forest_ptr
->map_ptr
->parameters
[i
].addsynth_component
];
241 parameter_ptr
->scope
= forest_ptr
->map_ptr
->parameters
[i
].scope
;
242 parameter_ptr
->other_parameter
= NULL
;
243 parameter_ptr
->lv2parameter
= NULL
;
244 parameter_ptr
->name_ptr
= forest_ptr
->map_ptr
->parameters
[i
].name
;
245 parameter_ptr
->type
= forest_ptr
->map_ptr
->parameters
[i
].type
;
246 parameter_ptr
->hints_ptr
= &forest_ptr
->map_ptr
->parameters
[i
].hints
;
247 parameter_ptr
->map_element_ptr
= forest_ptr
->map_ptr
->parameters
+ i
;
249 list_add_tail(¶meter_ptr
->siblings
, parameters_list_ptr
);
252 /* set other_parameter when needed */
253 for (i
= 0 ; i
< forest_ptr
->parameters_count
; i
++)
255 if (forest_ptr
->map_ptr
->parameters
[i
].scope
== LV2DYNPARAM_PARAMETER_SCOPE_TYPE_HIDE_OTHER
||
256 forest_ptr
->map_ptr
->parameters
[i
].scope
== LV2DYNPARAM_PARAMETER_SCOPE_TYPE_SHOW_OTHER
)
258 forest_ptr
->parameters
[i
]->other_parameter
= forest_ptr
->parameters
[forest_ptr
->map_ptr
->parameters
[i
].scope_specific
];
264 fail_free_parameters_array
:
265 free(forest_ptr
->parameters
);
267 fail_free_groups_array
:
268 free(forest_ptr
->groups
);
275 zynadd_dynparam_forest_initializer_clear(
276 struct zyn_forest_initializer
* forest_ptr
)
278 free(forest_ptr
->groups
);
279 free(forest_ptr
->parameters
);
283 zynadd_dynparam_destroy_forests(
284 struct zynadd
* zynadd_ptr
)
286 struct list_head
* node_ptr
;
287 struct zynadd_group
* group_ptr
;
288 struct zynadd_parameter
* parameter_ptr
;
290 while (!list_empty(&zynadd_ptr
->parameters
))
292 node_ptr
= zynadd_ptr
->parameters
.next
;
293 parameter_ptr
= list_entry(node_ptr
, struct zynadd_parameter
, siblings
);
298 while (!list_empty(&zynadd_ptr
->groups
))
300 node_ptr
= zynadd_ptr
->groups
.next
;
301 group_ptr
= list_entry(node_ptr
, struct zynadd_group
, siblings
);
308 zynadd_dynparam_forests_appear(
309 struct zynadd
* zynadd_ptr
)
312 struct zynadd_group
* group_ptr
;
313 struct zynadd_parameter
* parameter_ptr
;
314 struct list_head
* node_ptr
;
316 list_for_each(node_ptr
, &zynadd_ptr
->groups
)
318 group_ptr
= list_entry(node_ptr
, struct zynadd_group
, siblings
);
320 LOG_DEBUG("Adding group \"%s\"", group_ptr
->name_ptr
);
322 if (!lv2dynparam_plugin_group_add(
323 zynadd_ptr
->dynparams
,
324 group_ptr
->parent_ptr
== NULL
? NULL
: group_ptr
->parent_ptr
->lv2group
,
326 group_ptr
->hints_ptr
,
327 &group_ptr
->lv2group
))
333 list_for_each(node_ptr
, &zynadd_ptr
->parameters
)
335 parameter_ptr
= list_entry(node_ptr
, struct zynadd_parameter
, siblings
);
337 LOG_DEBUG("Adding parameter \"%s\"", parameter_ptr
->name_ptr
);
339 if (parameter_ptr
->scope
== LV2DYNPARAM_PARAMETER_SCOPE_TYPE_SEMI
)
344 if (parameter_ptr
->scope
== LV2DYNPARAM_PARAMETER_SCOPE_TYPE_HIDE_OTHER
||
345 parameter_ptr
->scope
== LV2DYNPARAM_PARAMETER_SCOPE_TYPE_SHOW_OTHER
)
347 LOG_DEBUG("Apearing show/hide parameter \"%s\"", parameter_ptr
->name_ptr
);
348 assert(parameter_ptr
->type
== LV2DYNPARAM_PARAMETER_TYPE_BOOL
);
350 tmp_bool
= zyn_addsynth_get_bool_parameter(
351 parameter_ptr
->addsynth_component
,
352 parameter_ptr
->addsynth_parameter
);
354 if (!zynadd_appear_parameter(zynadd_ptr
, parameter_ptr
))
359 if ((parameter_ptr
->scope
== LV2DYNPARAM_PARAMETER_SCOPE_TYPE_HIDE_OTHER
&& !tmp_bool
) ||
360 (parameter_ptr
->scope
== LV2DYNPARAM_PARAMETER_SCOPE_TYPE_SHOW_OTHER
&& tmp_bool
))
362 LOG_DEBUG("Apearing semi parameter \"%s\"", parameter_ptr
->other_parameter
->name_ptr
);
363 if (!zynadd_appear_parameter(zynadd_ptr
, parameter_ptr
->other_parameter
))
372 assert(parameter_ptr
->scope
== LV2DYNPARAM_PARAMETER_SCOPE_TYPE_ALWAYS
);
374 if (!zynadd_appear_parameter(zynadd_ptr
, parameter_ptr
))
376 LOG_ERROR("zynadd_appear_parameter() failed.");
385 zynadd_dynparam_init(
386 struct zynadd
* zynadd_ptr
)
388 struct zyn_forest_initializer top_forest_initializer
;
389 struct zyn_forest_initializer voice_forest_initializer
;
392 INIT_LIST_HEAD(&zynadd_ptr
->groups
);
393 INIT_LIST_HEAD(&zynadd_ptr
->parameters
);
395 for (i
= 0 ; i
< ZYNADD_GLOBAL_COMPONENTS_COUNT
; i
++)
397 zynadd_ptr
->synth_global_components
[i
] = zyn_addsynth_get_global_component(zynadd_ptr
->synth
, i
);
400 for (i
= 0 ; i
< ZYNADD_VOICE_COMPONENTS_COUNT
; i
++)
402 zynadd_ptr
->synth_voice0_components
[i
] = zyn_addsynth_get_voice_component(zynadd_ptr
->synth
, 0, i
);
403 //LOG_DEBUG("Voice component %p", zynadd_ptr->synth_voice0_components[i]);
406 LOG_DEBUG("Preparing top forest...");
408 if (!zynadd_dynparam_forest_initializer_prepare(
409 &top_forest_initializer
,
412 zynadd_ptr
->synth_global_components
,
415 &zynadd_ptr
->parameters
))
417 goto fail_destroy_forests
;
420 LOG_DEBUG("Preparing voice forest...");
422 if (!zynadd_dynparam_forest_initializer_prepare(
423 &voice_forest_initializer
,
425 top_forest_initializer
.groups
[zynadd_top_forest_map_get_voices_group()],
426 zynadd_ptr
->synth_voice0_components
,
429 &zynadd_ptr
->parameters
))
431 goto fail_clear_top_forest_initializer
;
434 if (!lv2dynparam_plugin_instantiate(
435 (LV2_Handle
)zynadd_ptr
,
436 zynadd_ptr
->host_features
,
438 &zynadd_ptr
->dynparams
))
440 goto fail_clear_voice_forest_initializer
;
443 if (!zynadd_dynparam_forests_appear(zynadd_ptr
))
445 goto fail_clean_dynparams
;
448 zynadd_dynparam_forest_initializer_clear(&voice_forest_initializer
);
449 zynadd_dynparam_forest_initializer_clear(&top_forest_initializer
);
453 fail_clean_dynparams
:
454 zynadd_dynparam_uninit(zynadd_ptr
);
456 fail_clear_voice_forest_initializer
:
457 zynadd_dynparam_forest_initializer_clear(&voice_forest_initializer
);
459 fail_clear_top_forest_initializer
:
460 zynadd_dynparam_forest_initializer_clear(&top_forest_initializer
);
462 fail_destroy_forests
:
463 zynadd_dynparam_destroy_forests(zynadd_ptr
);
469 zynadd_dynparam_uninit(struct zynadd
* zynadd_ptr
)
471 zynadd_dynparam_destroy_forests(zynadd_ptr
);
473 lv2dynparam_plugin_cleanup(zynadd_ptr
->dynparams
);