add lv2ui support
[goodguy/history.git] / cinelerra-5.1 / cinelerra / pluginlv2config.C
1 #ifdef HAVE_LV2
2
3 /*
4  * CINELERRA
5  * Copyright (C) 2018 GG
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20  *
21  */
22
23 #include "arraylist.h"
24 #include "cstrdup.h"
25 #include "language.h"
26 #include "pluginlv2config.h"
27
28 #include <ctype.h>
29 #include <string.h>
30
31 PluginLV2UriTable::PluginLV2UriTable()
32 {
33         set_array_delete();
34 }
35
36 PluginLV2UriTable::~PluginLV2UriTable()
37 {
38         remove_all_objects();
39 }
40
41 LV2_URID PluginLV2UriTable::map(const char *uri)
42 {
43         mLock locker(uri_table_lock);
44         for( int i=0; i<size(); ++i )
45                 if( !strcmp(uri, get(i)) ) return i+1;
46         append(cstrdup(uri));
47         return size();
48 }
49
50 const char *PluginLV2UriTable::unmap(LV2_URID urid)
51 {
52         mLock locker(uri_table_lock);
53         int idx = urid - 1;
54         return idx>=0 && idx<size() ? get(idx) : 0;
55 }
56
57 PluginLV2Client_OptName:: PluginLV2Client_OptName(PluginLV2Client_Opt *opt)
58 {
59         this->opt = opt;
60         set_text(opt->get_name());
61 }
62
63 PluginLV2Client_OptValue::PluginLV2Client_OptValue(PluginLV2Client_Opt *opt)
64 {
65         this->opt = opt;
66         update();
67 }
68
69 int PluginLV2Client_OptValue::update()
70 {
71         char val[BCSTRLEN];
72         sprintf(val, "%f", opt->get_value());
73         if( !strcmp(val, get_text()) ) return 0;
74         set_text(val);
75         return 1;
76 }
77
78
79 PluginLV2Client_Opt::PluginLV2Client_Opt(PluginLV2ClientConfig *conf, int idx)
80 {
81         this->conf = conf;
82         this->idx = idx;
83         item_name = new PluginLV2Client_OptName(this);
84         item_value = new PluginLV2Client_OptValue(this);
85 }
86
87 PluginLV2Client_Opt::~PluginLV2Client_Opt()
88 {
89         delete item_name;
90         delete item_value;
91 }
92
93 float PluginLV2Client_Opt::get_value()
94 {
95         return conf->ctls[idx];
96 }
97
98 const char *PluginLV2Client_Opt::get_symbol()
99 {
100         return conf->syms[idx];
101 }
102
103 void PluginLV2Client_Opt::set_value(float v)
104 {
105         conf->ctls[idx] = v;
106 }
107
108 int PluginLV2Client_Opt::update(float v)
109 {
110         set_value(v);
111         return item_value->update();
112 }
113
114 const char *PluginLV2Client_Opt::get_name()
115 {
116         return conf->names[idx];
117 }
118
119 PluginLV2ClientConfig::PluginLV2ClientConfig()
120 {
121         names = 0;
122         syms = 0;
123         mins = 0;
124         maxs = 0;
125         ctls = 0;
126         nb_ports = 0;
127 }
128
129 PluginLV2ClientConfig::~PluginLV2ClientConfig()
130 {
131         reset();
132         remove_all_objects();
133 }
134
135 void PluginLV2ClientConfig::reset()
136 {
137         for( int i=0; i<nb_ports; ++i ) {
138                 delete [] names[i];
139                 delete [] syms[i];
140         }
141         delete [] names; names = 0;
142         delete [] mins;  mins = 0;
143         delete [] maxs;  maxs = 0;
144         delete [] ctls;  ctls = 0;
145         nb_ports = 0;
146 }
147
148
149 int PluginLV2ClientConfig::equivalent(PluginLV2ClientConfig &that)
150 {
151         PluginLV2ClientConfig &conf = *this;
152         for( int i=0; i<that.size(); ++i ) {
153                 PluginLV2Client_Opt *topt = conf[i], *vopt = that[i];
154                 if( !EQUIV(topt->get_value(), vopt->get_value()) ) return 0;
155         }
156         return 1;
157 }
158
159 void PluginLV2ClientConfig::copy_from(PluginLV2ClientConfig &that)
160 {
161         if( nb_ports != that.nb_ports ) {
162                 reset();
163                 nb_ports = that.nb_ports;
164                 names = new const char *[nb_ports];
165                 syms = new const char *[nb_ports];
166                 for( int i=0; i<nb_ports; ++i ) names[i] = syms[i] = 0;
167                 mins  = new float[nb_ports];
168                 maxs  = new float[nb_ports];
169                 ctls  = new float[nb_ports];
170         }
171         for( int i=0; i<nb_ports; ++i ) {
172                 delete [] names[i];  names[i] = cstrdup(that.names[i]);
173                 delete [] syms[i];   syms[i] = cstrdup(that.syms[i]);
174                 mins[i] = that.mins[i];
175                 maxs[i] = that.maxs[i];
176                 ctls[i] = that.ctls[i];
177         }
178         remove_all_objects();
179         for( int i=0; i<that.size(); ++i ) {
180                 append(new PluginLV2Client_Opt(this, that[i]->idx));
181         }
182 }
183
184 void PluginLV2ClientConfig::interpolate(PluginLV2ClientConfig &prev, PluginLV2ClientConfig &next,
185         int64_t prev_frame, int64_t next_frame, int64_t current_frame)
186 {
187         copy_from(prev);
188 }
189
190 void PluginLV2ClientConfig::init_lv2(const LilvPlugin *lilv)
191 {
192         reset();
193         nb_ports = lilv_plugin_get_num_ports(lilv);
194         names = new const char *[nb_ports];
195         syms = new const char *[nb_ports];
196         mins  = new float[nb_ports];
197         maxs  = new float[nb_ports];
198         ctls  = new float[nb_ports];
199         lilv_plugin_get_port_ranges_float(lilv, mins, maxs, ctls);
200         for( int i=0; i<nb_ports; ++i ) {
201                 const LilvPort *lp = lilv_plugin_get_port_by_index(lilv, i);
202                 LilvNode *pnm = lilv_port_get_name(lilv, lp);
203                 names[i] = cstrdup(lilv_node_as_string(pnm));
204                 lilv_node_free(pnm);
205                 const LilvNode *sym = lilv_port_get_symbol(lilv, lp);
206                 syms[i] = cstrdup(lilv_node_as_string(sym));
207         }
208 }
209
210 int PluginLV2ClientConfig::update()
211 {
212         int ret = 0;
213         PluginLV2ClientConfig &conf = *this;
214         for( int i=0; i<size(); ++i ) {
215                 if( conf[i]->item_value->update() ) ++ret;
216         }
217         return ret;
218 }
219
220 void PluginLV2ClientConfig::dump(FILE *fp)
221 {
222         fprintf(fp, "Controls:\n");
223         for( int i=0; i<size(); ++i ) {
224                 fprintf(fp, " %3d. (%3d)  %-24s  %f\n",
225                         i, get(i)->idx, get(i)->get_symbol(), get(i)->get_value());
226         }
227         fprintf(fp, "Ports:\n");
228         for( int i=0; i<nb_ports; ++i ) {
229                 fprintf(fp, " %3d.  %-24s  %f  (%f - %f) %s\n",
230                         i, syms[i], ctls[i], mins[i], maxs[i], names[i]);
231         }
232 }
233
234 #endif /* HAVE_LV2 */