1 /*
2 * Author: Harry van Haaren 2013
3 * harryhaaren@gmail.com
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
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.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19 #include <string>
20 #include <iostream>
21
22 #include <FL/x.H>
23
24 // include the URI and global data of this plugin
25 #include "ports.h"
26
27 // this is our custom widget include
28 #include "sorcer_widget.h"
29
30 // core spec include
31 #include "lv2/lv2plug.in/ns/lv2core/lv2.h"
32
33 // GUI
34 #include "lv2/lv2plug.in/ns/extensions/ui/ui.h"
35
36 using namespace std;
37
38 typedef struct {
39 SorcerUI* widget;
40
41 float sidechainAmp;
42
43 LV2UI_Write_Function write_function;
44 LV2UI_Controller controller;
45 } SorcerGUI;
46
instantiate(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)47 static LV2UI_Handle instantiate(const struct LV2UI_Descriptor * descriptor,
48 const char * plugin_uri,
49 const char * bundle_path,
50 LV2UI_Write_Function write_function,
51 LV2UI_Controller controller,
52 LV2UI_Widget * widget,
53 const LV2_Feature * const * features)
54 {
55 if (strcmp(plugin_uri, SORCER_URI) != 0) {
56 fprintf(stderr, "SORCER_URI error: this GUI does not support plugin with URI %s\n", plugin_uri);
57 return NULL;
58 }
59
60 SorcerGUI* self = (SorcerGUI*)malloc(sizeof(SorcerGUI));
61 if (self == NULL) return NULL;
62
63 self->controller = controller;
64 self->write_function = write_function;
65
66 void* parentXwindow = 0;
67 LV2UI_Resize* resize = NULL;
68
69 for (int i = 0; features[i]; ++i) {
70 if (!strcmp(features[i]->URI, LV2_UI__parent)) {
71 parentXwindow = features[i]->data;
72 } else if (!strcmp(features[i]->URI, LV2_UI__resize)) {
73 resize = (LV2UI_Resize*)features[i]->data;
74 }
75 }
76
77 // in case FLTK hasn't opened it yet
78 fl_open_display();
79
80 self->widget = new SorcerUI();
81
82 self->widget->window->border(0);
83 self->widget->subbass->X(0.5);
84
85 // write functions into the widget
86 self->widget->controller = controller;
87 self->widget->write_function = write_function;
88
89 // set host to change size of the window
90 if (resize)
91 {
92 resize->ui_resize(resize->handle, self->widget->getWidth(), self->widget->getHeight());
93 }
94 else
95 {
96 cout << "SorcerUI: Warning, host doesn't support resize extension.\n\
97 Please ask the developers of the host to support this extension. "<< endl;
98 }
99
100 fl_embed( self->widget->window, (Window)parentXwindow );
101
102
103 return (LV2UI_Handle)self;
104 }
105
106
107
cleanup(LV2UI_Handle ui)108 static void cleanup(LV2UI_Handle ui) {
109 SorcerGUI *pluginGui = (SorcerGUI *) ui;
110 delete pluginGui->widget;
111 free( pluginGui);
112 }
113
port_event(LV2UI_Handle ui,uint32_t port_index,uint32_t buffer_size,uint32_t format,const void * buffer)114 static void port_event(LV2UI_Handle ui,
115 uint32_t port_index,
116 uint32_t buffer_size,
117 uint32_t format,
118 const void * buffer)
119 {
120 SorcerGUI *self = (SorcerGUI *) ui;
121
122 if ( format == 0 )
123 {
124 float value = *(float *)buffer;
125 switch ( port_index )
126 {
127
128 case ADSR_ATTACK: {
129 self->widget->adsr->attack( value );
130 self->widget->attack->value( value );
131 } break;
132 case ADSR_DECAY: {
133 self->widget->adsr->decay( value );
134 self->widget->decay->value( value );
135 } break;
136 case ADSR_SUSTAIN: {
137 self->widget->adsr->sustain( value );
138 self->widget->sustain->value( value );
139 } break;
140 case ADSR_RELEASE: {
141 self->widget->adsr->release( value );
142 self->widget->release->value( value );
143 } break;
144
145 case VOLUME: {
146 self->widget->volume->value( value );
147 } break;
148 case OUTPUT_DB: {
149 float tmp = (1-(value / -96.f));
150 self->widget->volume->amplitude( tmp, tmp );
151 } break;
152
153 case COMPRESSOR_ATTACK: {
154 self->widget->compAttack->value( value );
155 } break;
156 case COMPRESSOR_RELEASE: {
157 self->widget->compRelease->value( value );
158 } break;
159 case COMPRESSOR_MAKEUP: {
160 self->widget->compMakeup->value( value );
161 } break;
162 case COMPRESSOR_THRESHOLD: {
163 self->widget->compThres->value( value );
164 } break;
165 case COMPRESSOR_ENABLE: {
166
167 self->widget->comp->set_active( value > 0.5 ? true : false );
168 } break;
169
170 case FILTER_CUTOFF: {
171 self->widget->filter->value( value );
172 self->widget->filterCutoff->value( value );
173 } break;
174 case LFO_TO_FILTER_RANGE: {
175 self->widget->filter->modulation( value );
176 self->widget->filterLfoMod->value( value );
177 } break;
178
179 case LFO_TO_WAVETABLE_1: {
180 self->widget->wave1->modulation( value );
181 self->widget->lfoToW1->value( value );
182 } break;
183 case LFO_TO_WAVETABLE_2: {
184 self->widget->wave2->modulation( value );
185 self->widget->lfoToW2->value( value );
186 } break;
187
188 case LFO_AMPLITUDE: {
189 self->widget->lfo->value( value );
190 self->widget->lfoAmp->value( value );
191 } break;
192 case LFO_FREQUENCY: {
193 self->widget->lfo->modulation( value );
194 self->widget->lfoSpeed->value( value );
195 } break;
196
197 case OSC_1_VOLUME: {
198 self->widget->wave1->Y( value );
199 } break;
200 case OSC_2_VOLUME: {
201 self->widget->wave2->Y( value );
202 } break;
203 case OSC_3_VOLUME: {
204 self->widget->subbass->Y( value );
205 } break;
206
207
208 case WAVETABLE_1_POS: {
209 self->widget->wave1->X( value );
210 } break;
211 case WAVETABLE_2_POS: {
212 self->widget->wave2->X( value );
213 } break;
214 }
215 }
216
217 return;
218 }
219
220
ui_show(LV2UI_Handle handle)221 static int ui_show(LV2UI_Handle handle)
222 {
223 SorcerGUI *self = (SorcerGUI *) handle;
224 self->widget->window->show();
225
226 return 0;
227 }
228
ui_hide(LV2UI_Handle handle)229 static int ui_hide(LV2UI_Handle handle)
230 {
231 SorcerGUI *self = (SorcerGUI *) handle;
232 self->widget->window->hide();
233
234 return 0;
235 }
236
237 static int
idle(LV2UI_Handle handle)238 idle(LV2UI_Handle handle)
239 {
240 SorcerGUI* self = (SorcerGUI*)handle;
241
242 self->widget->idle();
243
244 return 0;
245 }
246
247 static const void*
extension_data(const char * uri)248 extension_data(const char* uri)
249 {
250 static const LV2UI_Show_Interface show = { ui_show, ui_hide };
251 static const LV2UI_Idle_Interface idle_iface = { idle };
252
253 if (!strcmp(uri, LV2_UI__showInterface))
254 {
255 return (void*)&show;
256 }
257 else if (!strcmp(uri, LV2_UI__idleInterface))
258 {
259 return (void*)&idle_iface;
260 }
261 return NULL;
262 }
263
264 static LV2UI_Descriptor descriptors[] = {
265 {SORCER_UI_URI, instantiate, cleanup, port_event, extension_data}
266 };
267
lv2ui_descriptor(uint32_t index)268 const LV2UI_Descriptor * lv2ui_descriptor(uint32_t index)
269 {
270 if (index >= sizeof(descriptors) / sizeof(descriptors[0]))
271 {
272 return NULL;
273 }
274 return descriptors + index;
275 }
276