2 * Module wrapper methods.
4 * Copyright (C) 2001-2007 Krzysztof Foltman
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General
17 * Public License along with this program; if not, write to the
18 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
19 * Boston, MA 02111-1307, USA.
24 #include <calf/giface.h>
25 #include <calf/osctlnet.h>
28 using namespace calf_utils
;
29 using namespace calf_plugins
;
31 float parameter_properties::from_01(double value01
) const
33 double value
= dsp::clip(value01
, 0., 1.);
34 switch(flags
& PF_SCALEMASK
)
36 case PF_SCALE_DEFAULT
:
40 value
= min
+ (max
- min
) * value01
;
43 value
= min
+ (max
- min
) * value01
* value01
;
46 value
= min
* pow(double(max
/ min
), value01
);
49 if (value01
< 0.00001)
52 float rmin
= std::max(1.0f
/ 1024.0f
, min
);
53 value
= rmin
* pow(double(max
/ rmin
), value01
);
56 case PF_SCALE_LOG_INF
:
58 if (value01
> (step
- 1.0) / step
)
59 value
= FAKE_INFINITY
;
61 value
= min
* pow(double(max
/ min
), value01
* step
/ (step
- 1.0));
64 switch(flags
& PF_TYPEMASK
)
71 value
= (int)(value
+ 0.5);
73 value
= (int)(value
- 0.5);
79 double parameter_properties::to_01(float value
) const
81 switch(flags
& PF_SCALEMASK
)
83 case PF_SCALE_DEFAULT
:
87 return double(value
- min
) / (max
- min
);
89 return sqrt(double(value
- min
) / (max
- min
));
92 return log((double)value
) / log((double)max
/ min
);
93 case PF_SCALE_LOG_INF
:
94 if (IS_FAKE_INFINITY(value
))
98 return (step
- 1.0) * log((double)value
) / (step
* log((double)max
/ min
));
100 if (value
< 1.0 / 1024.0) // new bottom limit - 60 dB
102 double rmin
= std::max(1.0f
/ 1024.0f
, min
);
104 return log((double)value
) / log(max
/ rmin
);
108 float parameter_properties::get_increment() const
110 float increment
= 0.01;
112 increment
= 1.0 / (step
- 1);
114 if (step
> 0 && step
< 1)
117 if ((flags
& PF_TYPEMASK
) != PF_FLOAT
)
118 increment
= 1.0 / (max
- min
);
122 int parameter_properties::get_char_count() const
124 if ((flags
& PF_SCALEMASK
) == PF_SCALE_PERC
)
126 if ((flags
& PF_SCALEMASK
) == PF_SCALE_GAIN
) {
129 sprintf(buf
, "%0.0f dB", 6.0 * log(min
) / log(2));
131 sprintf(buf
, "%0.0f dB", 6.0 * log(max
) / log(2));
132 len
= std::max(len
, strlen(buf
)) + 2;
135 return std::max(to_string(min
).length(), std::max(to_string(max
).length(), to_string(min
+ (max
-min
) * 0.987654).length()));
138 std::string
parameter_properties::to_string(float value
) const
141 if ((flags
& PF_SCALEMASK
) == PF_SCALE_PERC
) {
142 sprintf(buf
, "%0.f%%", 100.0 * value
);
145 if ((flags
& PF_SCALEMASK
) == PF_SCALE_GAIN
) {
146 if (value
< 1.0 / 1024.0) // new bottom limit - 60 dB
147 return "-inf dB"; // XXXKF change to utf-8 infinity
148 sprintf(buf
, "%0.1f dB", 6.0 * log(value
) / log(2));
151 switch(flags
& PF_TYPEMASK
)
163 if ((flags
& PF_SCALEMASK
) == PF_SCALE_LOG_INF
&& IS_FAKE_INFINITY(value
))
164 sprintf(buf
, "+inf"); // XXXKF change to utf-8 infinity
166 sprintf(buf
, "%g", value
);
168 switch(flags
& PF_UNITMASK
) {
169 case PF_UNIT_DB
: return string(buf
) + " dB";
170 case PF_UNIT_HZ
: return string(buf
) + " Hz";
171 case PF_UNIT_SEC
: return string(buf
) + " s";
172 case PF_UNIT_MSEC
: return string(buf
) + " ms";
173 case PF_UNIT_CENTS
: return string(buf
) + " ct";
174 case PF_UNIT_SEMITONES
: return string(buf
) + "#";
175 case PF_UNIT_BPM
: return string(buf
) + " bpm";
176 case PF_UNIT_RPM
: return string(buf
) + " rpm";
177 case PF_UNIT_DEG
: return string(buf
) + " deg";
180 static const char *notes
= "C C#D D#E F F#G G#A A#B ";
181 int note
= (int)value
;
182 if (note
< 0 || note
> 127)
184 return string(notes
+ 2 * (note
% 12), 2) + i2s(note
/ 12 - 2);
191 void calf_plugins::plugin_ctl_iface::clear_preset() {
192 int param_count
= get_param_count();
193 for (int i
=0; i
< param_count
; i
++)
195 parameter_properties
&pp
= *get_param_props(i
);
196 if ((pp
.flags
& PF_TYPEMASK
) == PF_STRING
)
198 configure(pp
.short_name
, pp
.choices
? pp
.choices
[0] : "");
201 set_param_value(i
, pp
.def_value
);
205 const char *calf_plugins::load_gui_xml(const std::string
&plugin_id
)
208 return strdup(calf_utils::load_file((std::string(PKGLIBDIR
) + "/gui-" + plugin_id
+ ".xml").c_str()).c_str());
210 catch(file_exception e
)
216 bool calf_plugins::check_for_message_context_ports(parameter_properties
*parameters
, int count
)
218 for (int i
= count
- 1; i
>= 0; i
--)
220 if (parameters
[i
].flags
& PF_PROP_MSGCONTEXT
)
226 bool calf_plugins::check_for_string_ports(parameter_properties
*parameters
, int count
)
228 for (int i
= count
- 1; i
>= 0; i
--)
230 if ((parameters
[i
].flags
& PF_TYPEMASK
) == PF_STRING
)
232 if ((parameters
[i
].flags
& PF_TYPEMASK
) < PF_STRING
)
239 struct osc_cairo_control
: public cairo_iface
241 osctl::osc_inline_typed_strstream
&os
;
243 osc_cairo_control(osctl::osc_inline_typed_strstream
&_os
) : os(_os
) {}
244 virtual void set_source_rgba(float r
, float g
, float b
, float a
= 1.f
)
246 os
<< (uint32_t)LGI_SET_RGBA
<< r
<< g
<< b
<< a
;
248 virtual void set_line_width(float width
)
250 os
<< (uint32_t)LGI_SET_WIDTH
<< width
;
254 static void send_graph_via_osc(osctl::osc_client
&client
, const std::string
&address
, line_graph_iface
*graph
, std::vector
<int> ¶ms
)
256 osctl::osc_inline_typed_strstream os
;
257 osc_cairo_control
cairoctl(os
);
258 for (size_t i
= 0; i
< params
.size(); i
++)
260 int index
= params
[i
];
261 os
<< (uint32_t)LGI_GRAPH
;
262 os
<< (uint32_t)index
;
263 for (int j
= 0; ; j
++)
266 if (graph
->get_graph(index
, j
, data
, 128, &cairoctl
))
268 os
<< (uint32_t)LGI_SUBGRAPH
;
270 for (int p
= 0; p
< 128; p
++)
276 for (int j
= 0; ; j
++)
280 if (graph
->get_dot(index
, j
, x
, y
, size
, &cairoctl
))
281 os
<< (uint32_t)LGI_DOT
<< x
<< y
<< (uint32_t)size
;
285 for (int j
= 0; ; j
++)
288 bool vertical
= false;
290 if (graph
->get_gridline(index
, j
, pos
, vertical
, legend
, &cairoctl
))
291 os
<< (uint32_t)LGI_LEGEND
<< pos
<< (uint32_t)(vertical
? 1 : 0) << legend
;
295 os
<< (uint32_t)LGI_END_ITEM
;
297 os
<< (uint32_t)LGI_END
;
298 client
.send(address
, os
);
301 calf_plugins::dssi_feedback_sender::dssi_feedback_sender(const char *URI
, line_graph_iface
*_graph
, calf_plugins::parameter_properties
*props
, int num_params
)
304 client
= new osctl::osc_client
;
305 client
->bind("0.0.0.0", 0);
306 client
->set_url(URI
);
307 for (int i
= 0; i
< num_params
; i
++)
309 if (props
[i
].flags
& PF_PROP_GRAPH
)
310 indices
.push_back(i
);
314 void calf_plugins::dssi_feedback_sender::update()
316 send_graph_via_osc(*client
, "/lineGraph", graph
, indices
);
319 calf_plugins::dssi_feedback_sender::~dssi_feedback_sender()
321 // this would not be received by GUI's main loop because it's already been terminated
322 // client->send("/iQuit");