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