1 /*
2 
3     This LV2 extension provides phaser gui's
4 
5     (c) Fraser Stuart 2009
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., 675 Mass Ave, Cambridge, MA 02139, USA.
20 
21 */
22 
23 #include <stdlib.h>
24 #include <string.h>
25 #include <math.h>
26 #include <gtk/gtk.h>
27 #include <lv2.h>
28 #include "lv2_ui.h"
29 #include "widgets/widgets.h"
30 #include "widgets/knob.h"
31 #include "widgets/lamp.h"
32 #include "widgets/meter-peak.h"
33 #include "widgets/switch-toggle.h"
34 #include "../plugin/inv_phaser.h"
35 #include "inv_phaser_gui.h"
36 
37 
38 static LV2UI_Descriptor *IPhaserGuiDescriptor = NULL;
39 
40 typedef struct {
41 	GtkWidget	*windowContainer;
42 	GtkWidget	*heading;
43 	GtkWidget	*toggleBypass;
44 	GtkWidget	*meterIn;
45 	GtkWidget	*meterOut;
46 	GtkWidget	*knobCycle;
47 	GtkWidget	*knobPhase;
48 	GtkWidget	*lampL;
49 	GtkWidget	*lampR;
50 	GtkWidget	*knobWidth;
51 	GtkWidget	*knobDepth;
52 	GtkWidget	*toggleNoClip;
53 	GtkWidget	*lampNoClip;
54 
55 	gint		InChannels;
56 	gint		OutChannels;
57 	float 		bypass;
58 	float		cycle;
59 	float		phase;
60 	float		width;
61 	float		depth;
62 	float		noclip;
63 
64 	LV2UI_Write_Function 	write_function;
65 	LV2UI_Controller 	controller;
66 
67 } IPhaserGui;
68 
69 
70 
71 static LV2UI_Handle
instantiateIPhaserGui(const struct _LV2UI_Descriptor * descriptor,const char * plugin_uri,const char * bundle_path,LV2UI_Write_Function write_function,LV2UI_Controller controller,LV2UI_Widget * widget,const LV2_Feature * const * features)72 instantiateIPhaserGui(const struct _LV2UI_Descriptor* descriptor, const char* plugin_uri, const char* bundle_path, LV2UI_Write_Function write_function, LV2UI_Controller controller, LV2UI_Widget* widget, const LV2_Feature* const* features)
73 {
74 	IPhaserGui *pluginGui = (IPhaserGui *)malloc(sizeof(IPhaserGui));
75 	if(pluginGui==NULL)
76 		return NULL;
77 
78 	pluginGui->write_function = write_function;
79 	pluginGui->controller = controller;
80 
81 	GtkBuilder      *builder;
82 	GtkWidget       *window;
83 	GtkWidget	*tempObject;
84 
85 	char 		*file;
86 
87 	GError *err = NULL;
88 
89 	gtk_init (NULL,NULL);
90 
91 	builder = gtk_builder_new ();
92 	file = g_strdup_printf("%s/gtk/inv_phaser_gui.xml",bundle_path);
93 	gtk_builder_add_from_file (builder, file, &err);
94 	free(file);
95 
96 	window = GTK_WIDGET (gtk_builder_get_object (builder, "phaser_window"));
97 
98 	/* get pointers to some useful widgets from the design */
99 	pluginGui->windowContainer = GTK_WIDGET (gtk_builder_get_object (builder, "phaser_container"));
100 	pluginGui->heading = GTK_WIDGET (gtk_builder_get_object (builder, "label_heading"));
101 
102 	/* add custom widgets */
103 	tempObject=GTK_WIDGET (gtk_builder_get_object (builder, "alignment_bypass_toggle"));
104 	pluginGui->toggleBypass = inv_switch_toggle_new ();
105 	gtk_container_add (GTK_CONTAINER (tempObject), pluginGui->toggleBypass);
106 
107 	tempObject=GTK_WIDGET (gtk_builder_get_object (builder, "alignment_meter_in"));
108 	pluginGui->meterIn = inv_meter_new ();
109 	gtk_container_add (GTK_CONTAINER (tempObject), pluginGui->meterIn);
110 
111 	tempObject=GTK_WIDGET (gtk_builder_get_object (builder, "alignment_meter_out"));
112 	pluginGui->meterOut = inv_meter_new ();
113 	gtk_container_add (GTK_CONTAINER (tempObject), pluginGui->meterOut);
114 
115 	tempObject=GTK_WIDGET (gtk_builder_get_object (builder, "alignment_cycle_knob"));
116 	pluginGui->knobCycle = inv_knob_new ();
117 	gtk_container_add (GTK_CONTAINER (tempObject), pluginGui->knobCycle);
118 
119 	tempObject=GTK_WIDGET (gtk_builder_get_object (builder, "alignment_phase_knob"));
120 	pluginGui->knobPhase = inv_knob_new ();
121 	gtk_container_add (GTK_CONTAINER (tempObject), pluginGui->knobPhase);
122 
123 	tempObject=GTK_WIDGET (gtk_builder_get_object (builder, "alignment_l_lamp"));
124 	pluginGui->lampL = inv_lamp_new ();
125 	gtk_container_add (GTK_CONTAINER (tempObject), pluginGui->lampL);
126 
127 	tempObject=GTK_WIDGET (gtk_builder_get_object (builder, "alignment_r_lamp"));
128 	pluginGui->lampR = inv_lamp_new ();
129 	gtk_container_add (GTK_CONTAINER (tempObject), pluginGui->lampR);
130 
131 	tempObject=GTK_WIDGET (gtk_builder_get_object (builder, "alignment_width_knob"));
132 	pluginGui->knobWidth = inv_knob_new ();
133 	gtk_container_add (GTK_CONTAINER (tempObject), pluginGui->knobWidth);
134 
135 	tempObject=GTK_WIDGET (gtk_builder_get_object (builder, "alignment_depth_knob"));
136 	pluginGui->knobDepth = inv_knob_new ();
137 	gtk_container_add (GTK_CONTAINER (tempObject), pluginGui->knobDepth);
138 
139 	tempObject=GTK_WIDGET (gtk_builder_get_object (builder, "alignment_noclip_toggle"));
140 	pluginGui->toggleNoClip = inv_switch_toggle_new ();
141 	gtk_container_add (GTK_CONTAINER (tempObject), pluginGui->toggleNoClip);
142 
143 	tempObject=GTK_WIDGET (gtk_builder_get_object (builder, "alignment_noclip_lamp"));
144 	pluginGui->lampNoClip = inv_lamp_new ();
145 	gtk_container_add (GTK_CONTAINER (tempObject), pluginGui->lampNoClip);
146 
147 
148 	/* customise for the plugin */
149 	if(!strcmp(plugin_uri,IPHASER_MONO_URI))
150 	{
151 		gtk_label_set_markup (GTK_LABEL (pluginGui->heading), "<b>Stereo Phaser (mono in)</b>");
152 		pluginGui->InChannels	= 1;
153 	}
154 	if(!strcmp(plugin_uri,IPHASER_STEREO_URI))
155 	{
156 		gtk_label_set_markup (GTK_LABEL (pluginGui->heading), "<b>Stereo Phaser (stereo in)</b>");
157 		pluginGui->InChannels	= 2;
158 	}
159 	if(!strcmp(plugin_uri,IPHASER_SUM_URI))
160 	{
161 		gtk_label_set_markup (GTK_LABEL (pluginGui->heading), "<b>Stereo Phaser (sum L+R in)</b>");
162 		pluginGui->InChannels	= 1;
163 	}
164 
165 
166 	pluginGui->OutChannels	= 2;
167 	pluginGui->bypass	= 0.0;
168 	pluginGui->cycle	= 25.0;
169 	pluginGui->phase	= 45.0;
170 	pluginGui->width	= 10.5;
171 	pluginGui->depth	= 75.0;
172 	pluginGui->noclip	= 1.0;
173 
174 	inv_switch_toggle_set_bypass( INV_SWITCH_TOGGLE (pluginGui->toggleBypass), INV_PLUGIN_ACTIVE);
175 	inv_switch_toggle_set_value( INV_SWITCH_TOGGLE (pluginGui->toggleBypass), INV_SWITCH_TOGGLE_OFF, 0.0);
176 	inv_switch_toggle_set_colour(INV_SWITCH_TOGGLE (pluginGui->toggleBypass), INV_SWITCH_TOGGLE_OFF, 0.0, 1.0, 0.0);
177 	inv_switch_toggle_set_text(  INV_SWITCH_TOGGLE (pluginGui->toggleBypass), INV_SWITCH_TOGGLE_OFF, "Active");
178 	inv_switch_toggle_set_value( INV_SWITCH_TOGGLE (pluginGui->toggleBypass), INV_SWITCH_TOGGLE_ON,  1.0);
179 	inv_switch_toggle_set_colour(INV_SWITCH_TOGGLE (pluginGui->toggleBypass), INV_SWITCH_TOGGLE_ON,  1.0, 0.0, 0.0);
180 	inv_switch_toggle_set_text(  INV_SWITCH_TOGGLE (pluginGui->toggleBypass), INV_SWITCH_TOGGLE_ON,  "Bypassed");
181 	inv_switch_toggle_set_state( INV_SWITCH_TOGGLE (pluginGui->toggleBypass), INV_SWITCH_TOGGLE_OFF);
182 	inv_switch_toggle_set_tooltip(INV_SWITCH_TOGGLE (pluginGui->toggleBypass), "<span size=\"8000\"><b>Description:</b> This switch bypasses the plugin.\n<b>Usage:</b> Click to toggle between values.</span>");
183 	g_signal_connect_after(G_OBJECT(pluginGui->toggleBypass),"button-release-event",G_CALLBACK(on_inv_phaser_bypass_toggle_button_release),pluginGui);
184 
185 	inv_meter_set_bypass(INV_METER (pluginGui->meterIn),INV_PLUGIN_ACTIVE);
186 	inv_meter_set_mode(INV_METER (pluginGui->meterIn), INV_METER_DRAW_MODE_TOZERO);
187 	inv_meter_set_channels(INV_METER (pluginGui->meterIn), pluginGui->InChannels);
188 	inv_meter_set_LdB(INV_METER (pluginGui->meterIn),-90);
189 	inv_meter_set_RdB(INV_METER (pluginGui->meterIn),-90);
190 
191 	inv_meter_set_bypass(INV_METER (pluginGui->meterOut),INV_PLUGIN_ACTIVE);
192 	inv_meter_set_mode(INV_METER (pluginGui->meterOut), INV_METER_DRAW_MODE_TOZERO);
193 	inv_meter_set_channels(INV_METER (pluginGui->meterOut), pluginGui->OutChannels);
194 	inv_meter_set_LdB(INV_METER (pluginGui->meterOut),-90);
195 	inv_meter_set_RdB(INV_METER (pluginGui->meterOut),-90);
196 
197 	inv_knob_set_bypass(INV_KNOB (pluginGui->knobCycle),   INV_PLUGIN_ACTIVE);
198 	inv_knob_set_size(INV_KNOB (pluginGui->knobCycle),     INV_KNOB_SIZE_MEDIUM);
199 	inv_knob_set_curve(INV_KNOB (pluginGui->knobCycle),    INV_KNOB_CURVE_LOG);
200 	inv_knob_set_markings(INV_KNOB (pluginGui->knobCycle), INV_KNOB_MARKINGS_4);
201 	inv_knob_set_human(INV_KNOB (pluginGui->knobCycle));
202 	inv_knob_set_units(INV_KNOB (pluginGui->knobCycle),    "s");
203 	inv_knob_set_min(INV_KNOB (pluginGui->knobCycle),      0.5);
204 	inv_knob_set_max(INV_KNOB (pluginGui->knobCycle),      500.0);
205 	inv_knob_set_value(INV_KNOB (pluginGui->knobCycle),    pluginGui->cycle);
206 	inv_knob_set_tooltip(INV_KNOB (pluginGui->knobCycle), "<span size=\"8000\"><b>Description:</b> This knob sets the period of the LFO.\n<b>Usage:</b> Click and drag vertically to change value, hortizontally to change the sensitvity.</span>");
207 	g_signal_connect_after(G_OBJECT(pluginGui->knobCycle),"motion-notify-event",G_CALLBACK(on_inv_phaser_cycle_knob_motion),pluginGui);
208 
209 	inv_knob_set_bypass(INV_KNOB (pluginGui->knobPhase), INV_PLUGIN_ACTIVE);
210 	inv_knob_set_size(INV_KNOB (pluginGui->knobPhase), INV_KNOB_SIZE_MEDIUM);
211 	inv_knob_set_curve(INV_KNOB (pluginGui->knobPhase), INV_KNOB_CURVE_LINEAR);
212 	inv_knob_set_markings(INV_KNOB (pluginGui->knobPhase), INV_KNOB_MARKINGS_5);
213 	inv_knob_set_units(INV_KNOB (pluginGui->knobPhase), "");
214 	inv_knob_set_min(INV_KNOB (pluginGui->knobPhase), -180);
215 	inv_knob_set_max(INV_KNOB (pluginGui->knobPhase), 180);
216 	inv_knob_set_value(INV_KNOB (pluginGui->knobPhase), pluginGui->phase);
217 	inv_knob_set_tooltip(INV_KNOB (pluginGui->knobPhase), "<span size=\"8000\"><b>Description:</b> This knob sets the LFO cycle phase difference between the left and right channels.\n<b>Usage:</b> Click and drag vertically to change value, hortizontally to change the sensitvity.</span>");
218 	g_signal_connect_after(G_OBJECT(pluginGui->knobPhase),"motion-notify-event",G_CALLBACK(on_inv_phaser_phase_knob_motion),pluginGui);
219 
220 	inv_lamp_set_value(INV_LAMP (pluginGui->lampL),0.0);
221 	inv_lamp_set_scale(INV_LAMP (pluginGui->lampL),1.0);
222 	inv_lamp_set_tooltip(INV_LAMP (pluginGui->lampL), "<span size=\"8000\">This shows the resultant LFO on the left channel.</span>");
223 
224 	inv_lamp_set_value(INV_LAMP (pluginGui->lampR),0.0);
225 	inv_lamp_set_scale(INV_LAMP (pluginGui->lampR),1.0);
226 	inv_lamp_set_tooltip(INV_LAMP (pluginGui->lampR), "<span size=\"8000\">This shows the resultant LFO on the right channel.</span>");
227 
228 	inv_knob_set_bypass(INV_KNOB (pluginGui->knobWidth), INV_PLUGIN_ACTIVE);
229 	inv_knob_set_size(INV_KNOB (pluginGui->knobWidth), INV_KNOB_SIZE_MEDIUM);
230 	inv_knob_set_curve(INV_KNOB (pluginGui->knobWidth), INV_KNOB_CURVE_LINEAR);
231 	inv_knob_set_markings(INV_KNOB (pluginGui->knobWidth), INV_KNOB_MARKINGS_3);
232 	inv_knob_set_units(INV_KNOB (pluginGui->knobWidth), "ms");
233 	inv_knob_set_min(INV_KNOB (pluginGui->knobWidth), 1.0);
234 	inv_knob_set_max(INV_KNOB (pluginGui->knobWidth), 15.0);
235 	inv_knob_set_value(INV_KNOB (pluginGui->knobWidth), pluginGui->width);
236 	inv_knob_set_tooltip(INV_KNOB (pluginGui->knobWidth), "<span size=\"8000\"><b>Description:</b> This knob sets the maximum delay the LFO will cause (the miniumum delay is fixed to 0.1ms which will cancel a 10kHz signal) Larger maximum delays gives a lower cancellation frequency.\n<b>Usage:</b> Click and drag vertically to change value, hortizontally to change the sensitvity.</span>");
237 	g_signal_connect_after(G_OBJECT(pluginGui->knobWidth),"motion-notify-event",G_CALLBACK(on_inv_phaser_width_knob_motion),pluginGui);
238 
239 	inv_knob_set_bypass(INV_KNOB (pluginGui->knobDepth), INV_PLUGIN_ACTIVE);
240 	inv_knob_set_size(INV_KNOB (pluginGui->knobDepth), INV_KNOB_SIZE_MEDIUM);
241 	inv_knob_set_curve(INV_KNOB (pluginGui->knobDepth), INV_KNOB_CURVE_LINEAR);
242 	inv_knob_set_markings(INV_KNOB (pluginGui->knobDepth), INV_KNOB_MARKINGS_5);
243 	inv_knob_set_units(INV_KNOB (pluginGui->knobDepth), "%");
244 	inv_knob_set_min(INV_KNOB (pluginGui->knobDepth), 0.0);
245 	inv_knob_set_max(INV_KNOB (pluginGui->knobDepth), 100.0);
246 	inv_knob_set_value(INV_KNOB (pluginGui->knobDepth), pluginGui->depth);
247 	inv_knob_set_tooltip(INV_KNOB (pluginGui->knobDepth), "<span size=\"8000\"><b>Description:</b> This knob controls how much of the phased signal is blended back into the original. At 100% they are the same volume.\n<b>Usage:</b> Click and drag vertically to change value, hortizontally to change the sensitvity.</span>");
248 	g_signal_connect_after(G_OBJECT(pluginGui->knobDepth),"motion-notify-event",G_CALLBACK(on_inv_phaser_depth_knob_motion),pluginGui);
249 
250 	inv_switch_toggle_set_bypass( INV_SWITCH_TOGGLE (pluginGui->toggleNoClip), INV_PLUGIN_ACTIVE);
251 	inv_switch_toggle_set_value( INV_SWITCH_TOGGLE (pluginGui->toggleNoClip), INV_SWITCH_TOGGLE_OFF, 0.0);
252 	inv_switch_toggle_set_colour(INV_SWITCH_TOGGLE (pluginGui->toggleNoClip), INV_SWITCH_TOGGLE_OFF, 0.0, 1.0, 0.0);
253 	inv_switch_toggle_set_text(  INV_SWITCH_TOGGLE (pluginGui->toggleNoClip), INV_SWITCH_TOGGLE_OFF, "Off");
254 	inv_switch_toggle_set_value( INV_SWITCH_TOGGLE (pluginGui->toggleNoClip), INV_SWITCH_TOGGLE_ON,  1.0);
255 	inv_switch_toggle_set_colour(INV_SWITCH_TOGGLE (pluginGui->toggleNoClip), INV_SWITCH_TOGGLE_ON,  0.0, 1.0, 0.0);
256 	inv_switch_toggle_set_text(  INV_SWITCH_TOGGLE (pluginGui->toggleNoClip), INV_SWITCH_TOGGLE_ON,  "Active");
257 	inv_switch_toggle_set_state( INV_SWITCH_TOGGLE (pluginGui->toggleNoClip), INV_SWITCH_TOGGLE_ON);
258 	inv_switch_toggle_set_tooltip(INV_SWITCH_TOGGLE (pluginGui->toggleNoClip), "<span size=\"8000\"><b>Description:</b> This switch activates soft-clipping on the output. The soft clipping function outputs a value between -3dB and 0dB for input values between -3dB and +infinity.\n<b>Usage:</b> Click to toggle between values.</span>");
259 	g_signal_connect_after(G_OBJECT(pluginGui->toggleNoClip),"button-release-event",G_CALLBACK(on_inv_phaser_noclip_toggle_button_release),pluginGui);
260 
261 	inv_lamp_set_value(INV_LAMP (pluginGui->lampNoClip),0.0);
262 	inv_lamp_set_scale(INV_LAMP (pluginGui->lampNoClip),3.0);
263 	inv_lamp_set_tooltip(INV_LAMP (pluginGui->lampNoClip), "<span size=\"8000\">This glows when soft clipping is occurring.</span>");
264 
265 	/* strip the parent window from the design so the host can attach its own */
266 	gtk_widget_ref(pluginGui->windowContainer);
267 	gtk_container_remove(GTK_CONTAINER(window), pluginGui->windowContainer);
268 
269 	*widget = (LV2UI_Widget) pluginGui->windowContainer;
270 
271 	g_object_unref (G_OBJECT (builder));
272 
273 	/* return the instance */
274 	return pluginGui;
275 }
276 
277 
278 static void
cleanupIPhaserGui(LV2UI_Handle ui)279 cleanupIPhaserGui(LV2UI_Handle ui)
280 {
281 	return;
282 }
283 
284 
285 static void
port_eventIPhaserGui(LV2UI_Handle ui,uint32_t port,uint32_t buffer_size,uint32_t format,const void * buffer)286 port_eventIPhaserGui(LV2UI_Handle ui, uint32_t port, uint32_t buffer_size, uint32_t format, const void*  buffer)
287 {
288 	IPhaserGui *pluginGui = (IPhaserGui *)ui;
289 
290 	float value;
291 
292 	if(format==0)
293 	{
294 		value=* (float *) buffer;
295 		switch(port)
296 		{
297 			case IPHASER_BYPASS:
298 				pluginGui->bypass=value;
299 				if(value <= 0.0) {
300 					inv_switch_toggle_set_state(INV_SWITCH_TOGGLE (pluginGui->toggleBypass), INV_SWITCH_TOGGLE_OFF);
301 					inv_meter_set_bypass(         INV_METER         (pluginGui->meterIn),      INV_PLUGIN_ACTIVE);
302 					inv_meter_set_bypass(         INV_METER         (pluginGui->meterOut),     INV_PLUGIN_ACTIVE);
303 					inv_knob_set_bypass(          INV_KNOB          (pluginGui->knobCycle),    INV_PLUGIN_ACTIVE);
304 					inv_knob_set_bypass(          INV_KNOB          (pluginGui->knobPhase),    INV_PLUGIN_ACTIVE);
305 					inv_knob_set_bypass(          INV_KNOB          (pluginGui->knobWidth),    INV_PLUGIN_ACTIVE);
306 					inv_knob_set_bypass(          INV_KNOB          (pluginGui->knobDepth),    INV_PLUGIN_ACTIVE);
307 					inv_switch_toggle_set_bypass( INV_SWITCH_TOGGLE (pluginGui->toggleNoClip), INV_PLUGIN_ACTIVE);
308 				} else {
309 					inv_switch_toggle_set_state(INV_SWITCH_TOGGLE (pluginGui->toggleBypass), INV_SWITCH_TOGGLE_ON);
310 					inv_meter_set_bypass(         INV_METER         (pluginGui->meterIn),      INV_PLUGIN_BYPASS);
311 					inv_meter_set_bypass(         INV_METER         (pluginGui->meterOut),     INV_PLUGIN_BYPASS);
312 					inv_knob_set_bypass(          INV_KNOB          (pluginGui->knobCycle),    INV_PLUGIN_BYPASS);
313 					inv_knob_set_bypass(          INV_KNOB          (pluginGui->knobPhase),    INV_PLUGIN_BYPASS);
314 					inv_knob_set_bypass(          INV_KNOB          (pluginGui->knobWidth),    INV_PLUGIN_BYPASS);
315 					inv_knob_set_bypass(          INV_KNOB          (pluginGui->knobDepth),    INV_PLUGIN_BYPASS);
316 					inv_switch_toggle_set_bypass( INV_SWITCH_TOGGLE (pluginGui->toggleNoClip), INV_PLUGIN_BYPASS);
317 				}
318 				gtk_widget_queue_draw (pluginGui->windowContainer);
319 				break;
320 			case IPHASER_CYCLE:
321 				pluginGui->cycle=value;
322 				inv_knob_set_value(INV_KNOB (pluginGui->knobCycle), pluginGui->cycle);
323 				break;
324 			case IPHASER_PHASE:
325 				pluginGui->phase=value;
326 				inv_knob_set_value(INV_KNOB (pluginGui->knobPhase), pluginGui->phase);
327 				break;
328 			case IPHASER_WIDTH:
329 				pluginGui->width=value;
330 				inv_knob_set_value(INV_KNOB (pluginGui->knobWidth), pluginGui->width);
331 				break;
332 			case IPHASER_DEPTH:
333 				pluginGui->depth=value;
334 				inv_knob_set_value(INV_KNOB (pluginGui->knobDepth), pluginGui->depth);
335 				break;
336 			case IPHASER_METER_INL:
337 				inv_meter_set_LdB(INV_METER (pluginGui->meterIn),value);
338 				break;
339 			case IPHASER_METER_INR:
340 				if(pluginGui->InChannels==2) inv_meter_set_RdB(INV_METER (pluginGui->meterIn),value);
341 				break;
342 			case IPHASER_METER_OUTL:
343 				inv_meter_set_LdB(INV_METER (pluginGui->meterOut),value);
344 				break;
345 			case IPHASER_METER_OUTR:
346 				inv_meter_set_RdB(INV_METER (pluginGui->meterOut),value);
347 				break;
348 			case IPHASER_LAMP_L:
349 				inv_lamp_set_value(INV_LAMP (pluginGui->lampL),value);
350 				break;
351 			case IPHASER_LAMP_R:
352 				inv_lamp_set_value(INV_LAMP (pluginGui->lampR),value);
353 				break;
354 			case IPHASER_LAMP_NOCLIP:
355 				inv_lamp_set_value(INV_LAMP (pluginGui->lampNoClip),value);
356 				break;
357 		}
358 	}
359 }
360 
361 
362 static void
init()363 init()
364 {
365 	IPhaserGuiDescriptor =
366 	 (LV2UI_Descriptor *)malloc(sizeof(LV2UI_Descriptor));
367 
368 	IPhaserGuiDescriptor->URI 		= IPHASER_GUI_URI;
369 	IPhaserGuiDescriptor->instantiate 	= instantiateIPhaserGui;
370 	IPhaserGuiDescriptor->cleanup		= cleanupIPhaserGui;
371 	IPhaserGuiDescriptor->port_event	= port_eventIPhaserGui;
372 	IPhaserGuiDescriptor->extension_data 	= NULL;
373 
374 }
375 
376 
lv2ui_descriptor(uint32_t index)377 const LV2UI_Descriptor* lv2ui_descriptor(uint32_t index)
378 {
379 	if (!IPhaserGuiDescriptor) init();
380 
381 	switch (index) {
382 		case 0:
383 			return IPhaserGuiDescriptor;
384 	default:
385 		return NULL;
386 	}
387 }
388 
389 
390 /*****************************************************************************/
391 
392 static void
on_inv_phaser_bypass_toggle_button_release(GtkWidget * widget,GdkEvent * event,gpointer data)393 on_inv_phaser_bypass_toggle_button_release(GtkWidget *widget, GdkEvent *event, gpointer data)
394 {
395 
396 	IPhaserGui *pluginGui = (IPhaserGui *) data;
397 
398 	pluginGui->bypass=inv_switch_toggle_get_value(INV_SWITCH_TOGGLE (widget));
399 	(*pluginGui->write_function)(pluginGui->controller, IPHASER_BYPASS, 4, 0, &pluginGui->bypass);
400 	return;
401 }
402 
403 static void
on_inv_phaser_cycle_knob_motion(GtkWidget * widget,GdkEvent * event,gpointer data)404 on_inv_phaser_cycle_knob_motion(GtkWidget *widget, GdkEvent *event, gpointer data)
405 {
406 	IPhaserGui *pluginGui = (IPhaserGui *) data;
407 
408 	pluginGui->cycle=inv_knob_get_value(INV_KNOB (widget));
409 	(*pluginGui->write_function)(pluginGui->controller, IPHASER_CYCLE, 4, 0, &pluginGui->cycle);
410 	return;
411 }
412 
413 static void
on_inv_phaser_phase_knob_motion(GtkWidget * widget,GdkEvent * event,gpointer data)414 on_inv_phaser_phase_knob_motion(GtkWidget *widget, GdkEvent *event, gpointer data)
415 {
416 	IPhaserGui *pluginGui = (IPhaserGui *) data;
417 
418 	pluginGui->phase=inv_knob_get_value(INV_KNOB (widget));
419 	(*pluginGui->write_function)(pluginGui->controller, IPHASER_PHASE, 4, 0, &pluginGui->phase);
420 	return;
421 }
422 
423 static void
on_inv_phaser_width_knob_motion(GtkWidget * widget,GdkEvent * event,gpointer data)424 on_inv_phaser_width_knob_motion(GtkWidget *widget, GdkEvent *event, gpointer data)
425 {
426 	IPhaserGui *pluginGui = (IPhaserGui *) data;
427 
428 	pluginGui->width=inv_knob_get_value(INV_KNOB (widget));
429 	(*pluginGui->write_function)(pluginGui->controller, IPHASER_WIDTH, 4, 0, &pluginGui->width);
430 	return;
431 }
432 
433 static void
on_inv_phaser_depth_knob_motion(GtkWidget * widget,GdkEvent * event,gpointer data)434 on_inv_phaser_depth_knob_motion(GtkWidget *widget, GdkEvent *event, gpointer data)
435 {
436 	IPhaserGui *pluginGui = (IPhaserGui *) data;
437 
438 	pluginGui->depth=inv_knob_get_value(INV_KNOB (widget));
439 	(*pluginGui->write_function)(pluginGui->controller, IPHASER_DEPTH, 4, 0, &pluginGui->depth);
440 	return;
441 }
442 
443 static void
on_inv_phaser_noclip_toggle_button_release(GtkWidget * widget,GdkEvent * event,gpointer data)444 on_inv_phaser_noclip_toggle_button_release(GtkWidget *widget, GdkEvent *event, gpointer data)
445 {
446 
447 	IPhaserGui *pluginGui = (IPhaserGui *) data;
448 
449 	pluginGui->noclip=inv_switch_toggle_get_value(INV_SWITCH_TOGGLE (widget));
450 	(*pluginGui->write_function)(pluginGui->controller, IPHASER_NOCLIP, 4, 0, &pluginGui->noclip);
451 	return;
452 }
453