1 /*  SpiralSynth
2  *  Copyleft (C) 2000 David Griffiths <dave@pawfal.org>
3  *
4  *  This program is free software; you can redistribute it and/or modify
5  *  it under the terms of the GNU General Public License as published by
6  *  the Free Software Foundation; either version 2 of the License, or
7  *  (at your option) any later version.
8  *
9  *  This program is distributed in the hope that it will be useful,
10  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  *  GNU General Public License for more details.
13  *
14  *  You should have received a copy of the GNU General Public License
15  *  along with this program; if not, write to the Free Software
16  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17 */
18 
19 #include "OscillatorGUI.h"
20 
21 static unsigned char *image_Square[] = {
22 (unsigned char*)"20 20 2 1",
23 (unsigned char*)" \tc None",
24 (unsigned char*)".\tc #000000",
25 (unsigned char*)"                    ",
26 (unsigned char*)"                    ",
27 (unsigned char*)"     ......         ",
28 (unsigned char*)"     .    .         ",
29 (unsigned char*)"     .    .         ",
30 (unsigned char*)"     .    .         ",
31 (unsigned char*)"     .    .         ",
32 (unsigned char*)"     .    .         ",
33 (unsigned char*)"     .    .         ",
34 (unsigned char*)"     .    .         ",
35 (unsigned char*)"   ...    .    ...  ",
36 (unsigned char*)"          .    .    ",
37 (unsigned char*)"          .    .    ",
38 (unsigned char*)"          .    .    ",
39 (unsigned char*)"          .    .    ",
40 (unsigned char*)"          .    .    ",
41 (unsigned char*)"          .    .    ",
42 (unsigned char*)"          ......    ",
43 (unsigned char*)"                    ",
44 (unsigned char*)"                    "};
45 
46 static unsigned char *image_Noise[] = {
47 (unsigned char*)"20 20 2 1",
48 (unsigned char*)" \tc None",
49 (unsigned char*)".\tc #000000",
50 (unsigned char*)"                    ",
51 (unsigned char*)"                    ",
52 (unsigned char*)"                    ",
53 (unsigned char*)"                    ",
54 (unsigned char*)"            .       ",
55 (unsigned char*)"        .   .       ",
56 (unsigned char*)"        .  . .      ",
57 (unsigned char*)"        .  . .      ",
58 (unsigned char*)"       . . .  .     ",
59 (unsigned char*)"       . . .  .     ",
60 (unsigned char*)"   ... . . .  . ..  ",
61 (unsigned char*)"     . . . .  ..    ",
62 (unsigned char*)"     . . . .  .     ",
63 (unsigned char*)"     . .  .         ",
64 (unsigned char*)"      .   .         ",
65 (unsigned char*)"      .   .         ",
66 (unsigned char*)"      .   .         ",
67 (unsigned char*)"          .         ",
68 (unsigned char*)"                    ",
69 (unsigned char*)"                    "};
70 
71 static unsigned char *image_Saw[] = {
72 (unsigned char*)"20 20 2 1",
73 (unsigned char*)" \tc None",
74 (unsigned char*)".\tc #000000",
75 (unsigned char*)"                    ",
76 (unsigned char*)"                    ",
77 (unsigned char*)"         ..         ",
78 (unsigned char*)"         ..         ",
79 (unsigned char*)"        . .         ",
80 (unsigned char*)"        . .         ",
81 (unsigned char*)"       .  .         ",
82 (unsigned char*)"       .  .         ",
83 (unsigned char*)"      .   .         ",
84 (unsigned char*)"      .   .         ",
85 (unsigned char*)"   ...    .   ....  ",
86 (unsigned char*)"          .   .     ",
87 (unsigned char*)"          .  .      ",
88 (unsigned char*)"          .  .      ",
89 (unsigned char*)"          . .       ",
90 (unsigned char*)"          . .       ",
91 (unsigned char*)"          ..        ",
92 (unsigned char*)"          ..        ",
93 (unsigned char*)"                    ",
94 (unsigned char*)"                    "};
95 
OscillatorGUI(Oscillator * o)96 OscillatorGUI::OscillatorGUI(Oscillator *o):
97 pixmap_Square(image_Square),
98 pixmap_Noise(image_Noise),
99 pixmap_Saw(image_Saw)
100 {
101 	m_osc=o;
102 	if (!m_osc) cerr<<"WARNING: Oscillator not correctly set up"<<endl;
103 }
104 
CreateGUI(int xoff,int yoff,char * name)105 void OscillatorGUI::CreateGUI(int xoff, int yoff, char *name)
106 {
107 	 Fl_Group* o = GUIOscGroup = new Fl_Group(xoff, yoff, 245, 110, name);
108       o->type(1);
109 	  o->box(FL_UP_BOX);
110       o->labeltype(FL_ENGRAVED_LABEL);
111       o->align(FL_ALIGN_TOP_LEFT|FL_ALIGN_INSIDE);
112 	  o->user_data((void*)(this));
113 
114 	  ShapeSquare = new Fl_Check_Button(xoff+5, yoff+15, 55, 30);
115       ShapeSquare->type(102);
116       ShapeSquare->down_box(FL_DIAMOND_DOWN_BOX);
117       ShapeSquare->selection_color(SpiralInfo::GUI_COLOUR);
118       ShapeSquare->set();
119       pixmap_Square.label(ShapeSquare);
120 	  ShapeSquare->callback((Fl_Callback*)cb_Square);
121 
122 	  ShapeNoise = new Fl_Check_Button(xoff+5, yoff+65, 55, 30);
123       ShapeNoise->type(102);
124       ShapeNoise->down_box(FL_DIAMOND_DOWN_BOX);
125       ShapeNoise->selection_color(SpiralInfo::GUI_COLOUR);
126       pixmap_Noise.label(ShapeNoise);
127       ShapeNoise->callback((Fl_Callback*)cb_Noise);
128 
129 	  ShapeSaw = new Fl_Check_Button(xoff+5, yoff+40, 55, 30);
130       ShapeSaw->type(102);
131       ShapeSaw->down_box(FL_DIAMOND_DOWN_BOX);
132       ShapeSaw->selection_color(SpiralInfo::GUI_COLOUR);
133       pixmap_Saw.label(ShapeSaw);
134       ShapeSaw->callback((Fl_Callback*)cb_Saw);
135 
136 	  Freq = new Fl_Knob(xoff+122, yoff+22, 55, 55, "Octave");
137       Freq->color(SpiralInfo::GUI_COLOUR);
138 	  Freq->type(Fl_Knob::LINELIN);
139       Freq->labelsize(10);
140       Freq->maximum(6);
141       Freq->step(1);
142       Freq->value(3);
143 	  Freq->scaleticks(6);
144 	  Freq->cursor(50);
145 	  Freq->callback((Fl_Callback*)cb_Freq);
146 
147       FineTune = new Fl_Knob(xoff+188, yoff+2, 40, 40, "Fine Tune");
148       FineTune->color(SpiralInfo::GUI_COLOUR);
149 	  FineTune->type(Fl_Knob::LINELIN);
150       FineTune->labelsize(10);
151       FineTune->maximum(2.0);
152       FineTune->step(0.0001);
153       FineTune->value(1);
154 	  FineTune->callback((Fl_Callback*)cb_FineTune);
155 
156 	  ModAmount = new Fl_Knob(xoff+188, yoff+54, 40, 40, "Mod Depth");
157       ModAmount->color(SpiralInfo::GUI_COLOUR);
158 	  ModAmount->type(Fl_Knob::LINELIN);
159 	  ModAmount->labelsize(10);
160       ModAmount->maximum(0.1);
161       ModAmount->step(0.001);
162       ModAmount->value(0.01);
163       ModAmount->callback((Fl_Callback*)cb_ModAmount);
164 
165 	  PulseWidth = new Fl_Slider(xoff+60, yoff+20, 20, 70, "PW");
166 	  PulseWidth->type(4);
167 	  PulseWidth->selection_color(SpiralInfo::GUI_COLOUR);
168       PulseWidth->labelsize(10);
169 	  PulseWidth->maximum(1);
170       PulseWidth->step(0.01);
171       PulseWidth->value(0.5);
172       PulseWidth->callback((Fl_Callback*)cb_PulseWidth);
173 
174 	  SHLen = new Fl_Slider(xoff+80, yoff+20, 20, 70, "SH");
175 	  SHLen->type(4);
176 	  SHLen->selection_color(SpiralInfo::GUI_COLOUR);
177       SHLen->labelsize(10);
178 	  SHLen->maximum(0.2);
179       SHLen->step(0.001);
180       SHLen->value(0.1);
181       SHLen->callback((Fl_Callback*)cb_SHLen);
182 
183       Portmento = new Fl_Slider(xoff+100, yoff+20, 20, 70, "PM");
184 	  Portmento->type(4);
185 	  Portmento->selection_color(SpiralInfo::GUI_COLOUR);
186       Portmento->labelsize(10);
187 	  Portmento->maximum(1.0);
188       Portmento->step(0.001);
189       Portmento->value(0.9);
190       Portmento->callback((Fl_Callback*)cb_Portmento);
191 
192    o->end();
193 
194 }
195 
UpdateValues()196 void OscillatorGUI::UpdateValues()
197 {
198 	ShapeSquare->value(0);
199 	ShapeNoise->value(0);
200 	ShapeSaw->value(0);
201 
202 	switch (m_osc->GetType())
203 	{
204 		case Oscillator::SQUARE : ShapeSquare->value(1); break;
205 		case Oscillator::NOISE  : ShapeNoise->value(1); break;
206 		case Oscillator::SAW    : ShapeSaw->value(1); break;
207 		case Oscillator::NONE   : break;
208 	}
209 
210 	Freq->value(m_osc->GetOctave()+3);
211 	ModAmount->value(m_osc->GetModAmount());
212 	FineTune->value(m_osc->GetFineFreq());
213 	PulseWidth->value(m_osc->GetPulseWidth());
214 
215 	SHLen->value(0.2f-m_osc->GetSHLen());
216 
217 	if (m_osc->GetPortmento()==0)
218 	{
219 		Portmento->value(1.0f);
220 	}
221 	else Portmento->value(m_osc->GetPortmento()-0.001f);
222 }
223 
MidiPitchBend(int amount)224 void OscillatorGUI::MidiPitchBend(int amount)
225 {
226 	FineTune->value(amount/64.0f);
227 	m_osc->SetFineFreq(FineTune->value());
228 }
229 
230 //// Callbacks ////
231 
cb_Freq_i(Fl_Knob * o,void * v)232 inline void OscillatorGUI::cb_Freq_i(Fl_Knob* o, void* v)
233 { m_osc->SetOctave(o->value()-3); }
cb_Freq(Fl_Knob * o,void * v)234 void OscillatorGUI::cb_Freq(Fl_Knob* o, void* v)
235 { ((OscillatorGUI*)(o->parent()->user_data()))->cb_Freq_i(o,v); }
236 
cb_FineTune_i(Fl_Knob * o,void * v)237 inline void OscillatorGUI::cb_FineTune_i(Fl_Knob* o, void* v)
238 { m_osc->SetFineFreq(o->value()); }
cb_FineTune(Fl_Knob * o,void * v)239 void OscillatorGUI::cb_FineTune(Fl_Knob* o, void* v)
240 { ((OscillatorGUI*)(o->parent()->user_data()))->cb_FineTune_i(o,v); }
241 
cb_PulseWidth_i(Fl_Slider * o,void * v)242 inline void OscillatorGUI::cb_PulseWidth_i(Fl_Slider* o, void* v)
243 { m_osc->SetPulseWidth(o->value()); }
cb_PulseWidth(Fl_Slider * o,void * v)244 void OscillatorGUI::cb_PulseWidth(Fl_Slider* o, void* v)
245 { ((OscillatorGUI*)(o->parent()->user_data()))->cb_PulseWidth_i(o,v);}
246 
cb_Square_i(Fl_Check_Button * o,void * v)247 inline void OscillatorGUI::cb_Square_i(Fl_Check_Button* o, void* v)
248 { m_osc->SetType(Oscillator::SQUARE); }
cb_Square(Fl_Check_Button * o,void * v)249 void OscillatorGUI::cb_Square(Fl_Check_Button* o, void* v)
250 { ((OscillatorGUI*)(o->parent()->user_data()))->cb_Square_i(o,v); }
251 
cb_Saw_i(Fl_Check_Button * o,void * v)252 inline void OscillatorGUI::cb_Saw_i(Fl_Check_Button* o, void* v)
253 { m_osc->SetType(Oscillator::SAW); }
cb_Saw(Fl_Check_Button * o,void * v)254 void OscillatorGUI::cb_Saw(Fl_Check_Button* o, void* v)
255 { ((OscillatorGUI*)(o->parent()->user_data()))->cb_Saw_i(o,v); }
256 
cb_Noise_i(Fl_Check_Button * o,void * v)257 inline void OscillatorGUI::cb_Noise_i(Fl_Check_Button* o, void* v)
258 { m_osc->SetType(Oscillator::NOISE); }
cb_Noise(Fl_Check_Button * o,void * v)259 void OscillatorGUI::cb_Noise(Fl_Check_Button* o, void* v)
260 { ((OscillatorGUI*)(o->parent()->user_data()))->cb_Noise_i(o,v); }
261 
cb_SHLen_i(Fl_Slider * o,void * v)262 inline void OscillatorGUI::cb_SHLen_i(Fl_Slider* o, void* v)
263 { m_osc->SetSHLen(0.2f-o->value()); }
cb_SHLen(Fl_Slider * o,void * v)264 void OscillatorGUI::cb_SHLen(Fl_Slider* o, void* v)
265 { ((OscillatorGUI*)(o->parent()->user_data()))->cb_SHLen_i(o,v); }
266 
cb_ModAmount_i(Fl_Knob * o,void * v)267 inline void OscillatorGUI::cb_ModAmount_i(Fl_Knob* o, void* v)
268 { m_osc->SetModAmount(o->value()); }
cb_ModAmount(Fl_Knob * o,void * v)269 void OscillatorGUI::cb_ModAmount(Fl_Knob* o, void* v)
270 { ((OscillatorGUI*)(o->parent()->user_data()))->cb_ModAmount_i(o,v); }
271 
cb_Portmento_i(Fl_Slider * o,void * v)272 inline void OscillatorGUI::cb_Portmento_i(Fl_Slider* o, void* v)
273 {
274 if (o->value()==1.0f) m_osc->SetPortmento(0);
275 else m_osc->SetPortmento(o->value()+0.001f);
276 }
cb_Portmento(Fl_Slider * o,void * v)277 void OscillatorGUI::cb_Portmento(Fl_Slider* o, void* v)
278 { ((OscillatorGUI*)(o->parent()->user_data()))->cb_Portmento_i(o,v); }
279 
280 
281 /////////////////////////////////////////////////////////
282 
283 
LFOGUI(Oscillator * o)284 LFOGUI::LFOGUI(Oscillator *o) : OscillatorGUI(o)
285 {
286 }
287 
CreateGUI(int xoff,int yoff,char * name)288 void LFOGUI::CreateGUI(int xoff, int yoff, char *name)
289 {
290 	 Fl_Group* o = GUIOscGroup = new Fl_Group(xoff, yoff, 170, 110, name);
291       o->type(1);
292 	  o->box(FL_UP_BOX);
293       o->labeltype(FL_ENGRAVED_LABEL);
294       o->align(FL_ALIGN_TOP_LEFT|FL_ALIGN_INSIDE);
295 	  o->user_data((void*)(this));
296 
297 	  ShapeSquare = new Fl_Check_Button(xoff+5, yoff+15, 55, 30);
298       ShapeSquare->type(102);
299       ShapeSquare->down_box(FL_DIAMOND_DOWN_BOX);
300       ShapeSquare->selection_color(SpiralInfo::GUI_COLOUR);
301       ShapeSquare->set();
302       pixmap_Square.label(ShapeSquare);
303 	  ShapeSquare->callback((Fl_Callback*)cb_Square);
304 
305 	  ShapeNoise = new Fl_Check_Button(xoff+5, yoff+65, 55, 30);
306       ShapeNoise->type(102);
307       ShapeNoise->down_box(FL_DIAMOND_DOWN_BOX);
308       ShapeNoise->selection_color(SpiralInfo::GUI_COLOUR);
309       pixmap_Noise.label(ShapeNoise);
310       ShapeNoise->callback((Fl_Callback*)cb_Noise);
311 
312 	  ShapeSaw = new Fl_Check_Button(xoff+5, yoff+40, 55, 30);
313       ShapeSaw->type(102);
314       ShapeSaw->down_box(FL_DIAMOND_DOWN_BOX);
315       ShapeSaw->selection_color(SpiralInfo::GUI_COLOUR);
316       pixmap_Saw.label(ShapeSaw);
317       ShapeSaw->callback((Fl_Callback*)cb_Saw);
318 
319       FineTune = new Fl_Knob(xoff+118, yoff+30, 45, 45, "Frequency");
320       FineTune->color(SpiralInfo::GUI_COLOUR);
321 	  FineTune->type(Fl_Knob::LINELIN);
322       FineTune->labelsize(10);
323       FineTune->maximum(2.0);
324       FineTune->step(0.001);
325       FineTune->value(0.5);
326 	  FineTune->cursor(50);
327 	  FineTune->callback((Fl_Callback*)cb_FineTune);
328 
329 	  PulseWidth = new Fl_Slider(xoff+55, yoff+15, 20, 70, "PW");
330 	  PulseWidth->type(4);
331 	  PulseWidth->selection_color(SpiralInfo::GUI_COLOUR);
332       PulseWidth->labelsize(10);
333 	  PulseWidth->maximum(1);
334       PulseWidth->step(0.01);
335       PulseWidth->value(0.5);
336       PulseWidth->callback((Fl_Callback*)cb_PulseWidth);
337 
338 	  SHLen = new Fl_Slider(xoff+75, yoff+15, 20, 70, "SH");
339 	  SHLen->type(4);
340 	  SHLen->selection_color(SpiralInfo::GUI_COLOUR);
341       SHLen->labelsize(10);
342 	  SHLen->maximum(0.2);
343       SHLen->step(0.001);
344       SHLen->value(0.1);
345       SHLen->callback((Fl_Callback*)cb_SHLen);
346 
347 	  Volume = new Fl_Slider(xoff+95, yoff+15, 20, 70, "Depth");
348 	  Volume->type(4);
349 	  Volume->selection_color(SpiralInfo::GUI_COLOUR);
350       Volume->labelsize(10);
351 	  Volume->maximum(100);
352       Volume->step(1);
353       Volume->value(50);
354       Volume->callback((Fl_Callback*)cb_Volume);
355 
356       o->end();
357 
358 }
359 
UpdateValues()360 void LFOGUI::UpdateValues()
361 {
362 	ShapeSquare->value(0);
363 	ShapeNoise->value(0);
364 	ShapeSaw->value(0);
365 
366 	switch (m_osc->GetType())
367 	{
368 		case Oscillator::SQUARE : ShapeSquare->value(1); break;
369 		case Oscillator::NOISE  : ShapeNoise->value(1); break;
370 		case Oscillator::SAW    : ShapeSaw->value(1); break;
371 		case Oscillator::NONE   : break;
372 	}
373 
374 	FineTune->value(sqrt(m_osc->GetFineFreq()));
375 	PulseWidth->value(m_osc->GetPulseWidth());
376 	SHLen->value(0.2+m_osc->GetSHLen());
377 }
378 
cb_FineTune_i(Fl_Knob * o,void * v)379 inline void LFOGUI::cb_FineTune_i(Fl_Knob* o, void* v)
380 {
381 	float value=o->value();
382 	m_osc->SetFineFreq(value*value);
383 }
cb_FineTune(Fl_Knob * o,void * v)384 void LFOGUI::cb_FineTune(Fl_Knob* o, void* v)
385 { ((LFOGUI*)(o->parent()->user_data()))->cb_FineTune_i(o,v); }
386 
cb_Volume_i(Fl_Slider * o,void * v)387 inline void LFOGUI::cb_Volume_i(Fl_Slider* o, void* v)
388 { m_osc->SetVolume(0,100-o->value());}
cb_Volume(Fl_Slider * o,void * v)389 void LFOGUI::cb_Volume(Fl_Slider* o, void* v)
390 { ((LFOGUI*)(o->parent()->user_data()))->cb_Volume_i(o,v); }
391