render effect segv, drag chkbox track coords, check mask active,
[goodguy/cinelerra.git] / cinelerra-5.1 / plugins / synthesizer / synthesizer.h
1
2 /*
3  * CINELERRA
4  * Copyright (C) 2010 Adam Williams <broadcast at earthling dot net>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
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
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  *
20  */
21
22 #ifndef SYNTHESIZER_H
23 #define SYNTHESIZER_H
24
25
26
27 #include "filexml.inc"
28 #include "guicast.h"
29 #include "mutex.h"
30 #include "pluginaclient.h"
31 #include "vframe.inc"
32
33
34 class Synth;
35 class SynthWindow;
36
37 // Frequency table for piano
38 float keyboard_freqs[] =
39 {
40         65.4064,
41         69.2957,
42         73.4162,
43         77.7817,
44         82.4069,
45         87.3071,
46         92.4986,
47         97.9989,
48         103.826,
49         110.000,
50         116.541,
51         123.471,
52
53         130.81,
54         138.59,
55         146.83,
56         155.56,
57         164.81,
58         174.61,
59         185.00,
60         196.00,
61         207.65,
62         220.00,
63         233.08,
64         246.94,
65
66         261.63,
67         277.18,
68         293.66,
69         311.13,
70         329.63,
71         349.23,
72         369.99,
73         392.00,
74         415.30,
75         440.00,
76         466.16,
77         493.88,
78
79
80
81         523.251,
82         554.365,
83         587.330,
84         622.254,
85         659.255,
86         698.456,
87         739.989,
88         783.991,
89         830.609,
90         880.000,
91         932.328,
92         987.767,
93
94         1046.50,
95         1108.73,
96         1174.66,
97         1244.51,
98         1318.51,
99         1396.91,
100         1479.98,
101         1567.98,
102         1661.22,
103         1760.00,
104         1864.66,
105         1975.53,
106
107         2093.00
108 };
109
110 #define MAX_FREQS 16
111 #define TOTALOSCILLATORS 1
112 #define OSCILLATORHEIGHT 40
113 #define TOTALNOTES ((int)(sizeof(keyboard_freqs) / sizeof(float)))
114 #define MIDDLE_C 24
115 #define FIRST_TITLE (MIDDLE_C - 12)
116 #define LAST_TITLE (MIDDLE_C + 12)
117 #define MARGIN 10
118
119 #define SINE 0
120 #define SAWTOOTH 1
121 #define SQUARE 2
122 #define TRIANGLE 3
123 #define PULSE 4
124 #define NOISE 5
125 #define DC    6
126
127
128 class SynthCanvas;
129 class SynthWaveForm;
130 class SynthBaseFreq;
131 class SynthFreqPot;
132 class SynthOscGUI;
133 class OscScroll;
134 class NoteScroll;
135 class SynthWetness;
136 class SynthNote;
137 class SynthMomentary;
138
139 class SynthWindow : public PluginClientWindow
140 {
141 public:
142         SynthWindow(Synth *synth);
143         ~SynthWindow();
144
145         void create_objects();
146         int resize_event(int w, int h);
147         void update_gui();
148         int waveform_to_text(char *text, int waveform);
149         void update_scrollbar();
150         void update_oscillators();
151         void update_notes();
152         void update_note_selection();
153         int keypress_event();
154         void update_blackkey(int number, int *current_title, int x, int y);
155         void update_whitekey(int number, int *current_title, int x, int y);
156
157
158         Synth *synth;
159         SynthCanvas *canvas;
160         SynthWetness *wetness;
161         SynthWaveForm *waveform;
162         SynthBaseFreq *base_freq;
163         SynthFreqPot *freqpot;
164         BC_SubWindow *osc_subwindow;
165         OscScroll *osc_scroll;
166         BC_SubWindow *note_subwindow;
167         NoteScroll *note_scroll;
168         ArrayList<SynthOscGUI*> oscillators;
169         SynthNote *notes[TOTALNOTES];
170         BC_Title *note_titles[TOTALNOTES];
171         BC_Title *note_instructions;
172         SynthMomentary *momentary;
173         VFrame *white_key[5];
174         VFrame *black_key[5];
175         int y1;
176         int y2;
177         int y3;
178         int text_white_margin;
179         int text_black_margin;
180 // Button press currently happening if > -1
181         int current_note;
182 // If we are stopping or starting notes in a drag
183         int starting_notes;
184 };
185
186 class SynthMomentary : public BC_CheckBox
187 {
188 public:
189         SynthMomentary(SynthWindow *window, int x, int y, char *text);
190         int handle_event();
191         SynthWindow *window;
192 };
193
194 class SynthNote : public BC_Toggle
195 {
196 public:
197         SynthNote(SynthWindow *window, VFrame **images, int number, int x, int y);
198         void start_note();
199         void stop_note();
200         int keypress_event();
201         int keyrelease_event();
202         int button_press_event();
203         int button_release_event();
204         int cursor_motion_event();
205         int draw_face(int flash, int flush);
206         int number;
207         int note_on;
208         SynthWindow *window;
209 };
210
211
212 class SynthOscGUILevel;
213 class SynthOscGUIPhase;
214 class SynthOscGUIFreq;
215
216 class SynthOscGUI
217 {
218 public:
219         SynthOscGUI(SynthWindow *window, int number);
220         ~SynthOscGUI();
221
222         void create_objects(int view_y);
223
224         SynthOscGUILevel *level;
225         SynthOscGUIPhase *phase;
226         SynthOscGUIFreq *freq;
227         BC_Title *title;
228
229         int number;
230         SynthWindow *window;
231 };
232
233 class SynthOscGUILevel : public BC_FPot
234 {
235 public:
236         SynthOscGUILevel(Synth *synth, SynthOscGUI *gui, int y);
237         ~SynthOscGUILevel();
238
239         int handle_event();
240
241         Synth *synth;
242         SynthOscGUI *gui;
243 };
244
245 class SynthOscGUIPhase : public BC_IPot
246 {
247 public:
248         SynthOscGUIPhase(Synth *synth, SynthOscGUI *gui, int y);
249         ~SynthOscGUIPhase();
250
251         int handle_event();
252
253         Synth *synth;
254         SynthOscGUI *gui;
255 };
256
257 class SynthOscGUIFreq : public BC_IPot
258 {
259 public:
260         SynthOscGUIFreq(Synth *synth, SynthOscGUI *gui, int y);
261         ~SynthOscGUIFreq();
262
263         int handle_event();
264
265         Synth *synth;
266         SynthOscGUI *gui;
267 };
268
269 class OscScroll : public BC_ScrollBar
270 {
271 public:
272         OscScroll(Synth *synth, SynthWindow *window, int x, int y, int h);
273         ~OscScroll();
274
275         int handle_event();
276
277         Synth *synth;
278         SynthWindow *window;
279 };
280
281 class NoteScroll : public BC_ScrollBar
282 {
283 public:
284         NoteScroll(Synth *synth, SynthWindow *window, int x, int y, int w);
285         ~NoteScroll();
286
287         int handle_event();
288
289         Synth *synth;
290         SynthWindow *window;
291 };
292
293 class SynthAddOsc : public BC_GenericButton
294 {
295 public:
296         SynthAddOsc(Synth *synth, SynthWindow *window, int x, int y);
297         ~SynthAddOsc();
298
299         int handle_event();
300
301         Synth *synth;
302         SynthWindow *window;
303 };
304
305
306 class SynthDelOsc : public BC_GenericButton
307 {
308 public:
309         SynthDelOsc(Synth *synth, SynthWindow *window, int x, int y);
310         ~SynthDelOsc();
311
312         int handle_event();
313
314         Synth *synth;
315         SynthWindow *window;
316 };
317
318 class SynthClear : public BC_GenericButton
319 {
320 public:
321         SynthClear(Synth *synth, int x, int y);
322         ~SynthClear();
323         int handle_event();
324         Synth *synth;
325 };
326
327 class SynthWaveForm : public BC_PopupMenu
328 {
329 public:
330         SynthWaveForm(Synth *synth, int x, int y, char *text);
331         ~SynthWaveForm();
332
333         void create_objects();
334         Synth *synth;
335 };
336
337 class SynthWaveFormItem : public BC_MenuItem
338 {
339 public:
340         SynthWaveFormItem(Synth *synth, char *text, int value);
341         ~SynthWaveFormItem();
342
343         int handle_event();
344
345         int value;
346         Synth *synth;
347 };
348
349 class SynthBaseFreq : public BC_TextBox
350 {
351 public:
352         SynthBaseFreq(Synth *synth, SynthWindow *window, int x, int y);
353         ~SynthBaseFreq();
354         int handle_event();
355         Synth *synth;
356         SynthFreqPot *freq_pot;
357         SynthWindow *window;
358 };
359
360 class SynthFreqPot : public BC_QPot
361 {
362 public:
363         SynthFreqPot(Synth *synth, SynthWindow *window, int x, int y);
364         ~SynthFreqPot();
365         int handle_event();
366         SynthWindow *window;
367         Synth *synth;
368         SynthBaseFreq *freq_text;
369 };
370
371 class SynthWetness : public BC_FPot
372 {
373 public:
374         SynthWetness(Synth *synth, int x, int y);
375         int handle_event();
376         Synth *synth;
377 };
378
379
380 class SynthCanvas : public BC_SubWindow
381 {
382 public:
383         SynthCanvas(Synth *synth,
384                 SynthWindow *window,
385                 int x,
386                 int y,
387                 int w,
388                 int h);
389         ~SynthCanvas();
390
391         int update();
392         Synth *synth;
393         SynthWindow *window;
394 };
395
396
397
398
399 // ======================= level calculations
400 class SynthLevelZero : public BC_MenuItem
401 {
402 public:
403         SynthLevelZero(Synth *synth);
404         ~SynthLevelZero();
405         int handle_event();
406         Synth *synth;
407 };
408
409 class SynthLevelMax : public BC_MenuItem
410 {
411 public:
412         SynthLevelMax(Synth *synth);
413         ~SynthLevelMax();
414         int handle_event();
415         Synth *synth;
416 };
417
418 class SynthLevelNormalize : public BC_MenuItem
419 {
420 public:
421         SynthLevelNormalize(Synth *synth);
422         ~SynthLevelNormalize();
423         int handle_event();
424         Synth *synth;
425 };
426
427 class SynthLevelSlope : public BC_MenuItem
428 {
429 public:
430         SynthLevelSlope(Synth *synth);
431         ~SynthLevelSlope();
432         int handle_event();
433         Synth *synth;
434 };
435
436 class SynthLevelRandom : public BC_MenuItem
437 {
438 public:
439         SynthLevelRandom(Synth *synth);
440         ~SynthLevelRandom();
441         int handle_event();
442         Synth *synth;
443 };
444
445 class SynthLevelInvert : public BC_MenuItem
446 {
447 public:
448         SynthLevelInvert(Synth *synth);
449         ~SynthLevelInvert();
450         int handle_event();
451         Synth *synth;
452 };
453
454 class SynthLevelSine : public BC_MenuItem
455 {
456 public:
457         SynthLevelSine(Synth *synth);
458         ~SynthLevelSine();
459         int handle_event();
460         Synth *synth;
461 };
462
463 // ============================ phase calculations
464
465 class SynthPhaseInvert : public BC_MenuItem
466 {
467 public:
468         SynthPhaseInvert(Synth *synth);
469         ~SynthPhaseInvert();
470         int handle_event();
471         Synth *synth;
472 };
473
474 class SynthPhaseZero : public BC_MenuItem
475 {
476 public:
477         SynthPhaseZero(Synth *synth);
478         ~SynthPhaseZero();
479         int handle_event();
480         Synth *synth;
481 };
482
483 class SynthPhaseSine : public BC_MenuItem
484 {
485 public:
486         SynthPhaseSine(Synth *synth);
487         ~SynthPhaseSine();
488         int handle_event();
489         Synth *synth;
490 };
491
492 class SynthPhaseRandom : public BC_MenuItem
493 {
494 public:
495         SynthPhaseRandom(Synth *synth);
496         ~SynthPhaseRandom();
497         int handle_event();
498         Synth *synth;
499 };
500
501
502 // ============================ freq calculations
503
504 class SynthFreqRandom : public BC_MenuItem
505 {
506 public:
507         SynthFreqRandom(Synth *synth);
508         ~SynthFreqRandom();
509         int handle_event();
510         Synth *synth;
511 };
512
513 class SynthFreqEnum : public BC_MenuItem
514 {
515 public:
516         SynthFreqEnum(Synth *synth);
517         ~SynthFreqEnum();
518         int handle_event();
519         Synth *synth;
520 };
521
522 class SynthFreqEven : public BC_MenuItem
523 {
524 public:
525         SynthFreqEven(Synth *synth);
526         ~SynthFreqEven();
527         int handle_event();
528         Synth *synth;
529 };
530
531 class SynthFreqOdd : public BC_MenuItem
532 {
533 public:
534         SynthFreqOdd(Synth *synth);
535         ~SynthFreqOdd();
536         int handle_event();
537         Synth *synth;
538 };
539
540 class SynthFreqFibonacci : public BC_MenuItem
541 {
542 public:
543         SynthFreqFibonacci(Synth *synth);
544         ~SynthFreqFibonacci();
545         int handle_event();
546         Synth *synth;
547 };
548
549 class SynthFreqPrime : public BC_MenuItem
550 {
551 public:
552         SynthFreqPrime(Synth *synth);
553         ~SynthFreqPrime();
554         int handle_event();
555         Synth *synth;
556 private:
557         float get_next_prime(float number);
558 };
559
560
561
562 class SynthOscillatorConfig
563 {
564 public:
565         SynthOscillatorConfig(int number);
566         ~SynthOscillatorConfig();
567
568         int equivalent(SynthOscillatorConfig &that);
569         void copy_from(SynthOscillatorConfig& that);
570         void reset();
571         void read_data(FileXML *file);
572         void save_data(FileXML *file);
573         int is_realtime();
574
575         float level;
576         float phase;
577         float freq_factor;
578         int number;
579 };
580
581
582
583 class SynthConfig
584 {
585 public:
586         SynthConfig();
587         ~SynthConfig();
588
589         int equivalent(SynthConfig &that);
590         void copy_from(SynthConfig &that);
591         void interpolate(SynthConfig &prev,
592                 SynthConfig &next,
593                 int64_t prev_frame,
594                 int64_t next_frame,
595                 int64_t current_frame);
596         void reset();
597
598         double wetness;
599 // base frequency for oscillators
600 // Freqs of 0 are unused.
601         double base_freq[MAX_FREQS];
602         int wavefunction;        // SINE, SAWTOOTH, etc
603         ArrayList<SynthOscillatorConfig*> oscillator_config;
604         int momentary_notes;
605 };
606
607
608 class Synth : public PluginAClient
609 {
610 public:
611         Synth(PluginServer *server);
612         ~Synth();
613
614
615         PLUGIN_CLASS_MEMBERS(SynthConfig)
616         int is_realtime();
617         int is_synthesis();
618         void read_data(KeyFrame *keyframe);
619         void save_data(KeyFrame *keyframe);
620         int process_realtime(int64_t size, Samples *input_ptr, Samples *output_ptr);
621
622
623
624
625 // Frequency is in the table of base_freqs
626         int freq_exists(double freq);
627 // Manage frequency table
628         void new_freq(double freq);
629         void delete_freq(double freq);
630         void delete_freqs();
631
632         void add_oscillator();
633         void delete_oscillator();
634         double get_total_power();
635         double get_oscillator_point(float x,
636                 double normalize_constant,
637                 int oscillator);
638         double solve_eqn(double *output,
639                 int length,
640                 double freq,
641                 double normalize_constant,
642                 int oscillator);
643         double get_point(float x, double normalize_constant);
644         double function_square(double x);
645         double function_pulse(double x);
646         double function_noise();
647         double function_sawtooth(double x);
648         double function_triangle(double x);
649         void reconfigure();
650         int overlay_synth(double freq,
651                 int64_t length,
652                 double *input,
653                 double *output);
654         void update_gui();
655         void reset();
656
657
658
659         int window_w, window_h;
660         int need_reconfigure;
661         DB db;
662 // Samples since last reconfiguration
663         int64_t waveform_sample;
664 };
665
666
667
668
669
670
671
672
673 #endif