1 #include "bcdisplayinfo.h"
6 #include "synthesizer.h"
13 #define _(String) gettext(String)
14 #define gettext_noop(String) String
15 #define N_(String) gettext_noop (String)
19 PluginClient* new_plugin(PluginServer *server)
21 return new Synth(server);
28 Synth::Synth(PluginServer *server)
29 : PluginAClient(server)
41 thread->window->set_done(0);
42 thread->completion.lock();
49 if(dsp_buffer) delete [] dsp_buffer;
52 VFrame* Synth::new_picon()
54 return new VFrame(picon_png);
58 char* Synth::plugin_title()
60 return _("Synthesizer");
71 int Synth::is_realtime()
76 int Synth::is_synthesis()
83 LOAD_CONFIGURATION_MACRO(Synth, SynthConfig)
88 int Synth::load_defaults()
90 char directory[BCTEXTLEN], string[BCTEXTLEN];
92 sprintf(directory, "%ssynthesizer.rc", BCASTDIR);
93 defaults = new Defaults(directory);
95 w = defaults->get("WIDTH", 380);
96 h = defaults->get("HEIGHT", 400);
98 config.wetness = defaults->get("WETNESS", 0);
99 config.base_freq = defaults->get("BASEFREQ", 440);
100 config.wavefunction = defaults->get("WAVEFUNCTION", 0);
102 int total_oscillators = defaults->get("OSCILLATORS", TOTALOSCILLATORS);
103 config.oscillator_config.remove_all_objects();
104 for(int i = 0; i < total_oscillators; i++)
106 config.oscillator_config.append(new SynthOscillatorConfig(i));
107 config.oscillator_config.values[i]->load_defaults(defaults);
114 void Synth::read_data(KeyFrame *keyframe)
117 // cause htal file to read directly from text
118 input.set_shared_string(keyframe->data, strlen(keyframe->data));
120 //printf("Synth::read_data %s\n", keyframe->data);
121 int result = 0, current_osc = 0, total_oscillators = 0;
124 result = input.read_tag();
128 if(input.tag.title_is("SYNTH"))
130 config.wetness = input.tag.get_property("WETNESS", config.wetness);
131 config.base_freq = input.tag.get_property("BASEFREQ", config.base_freq);
132 config.wavefunction = input.tag.get_property("WAVEFUNCTION", config.wavefunction);
133 total_oscillators = input.tag.get_property("OSCILLATORS", 0);
136 if(input.tag.title_is("OSCILLATOR"))
138 if(current_osc >= config.oscillator_config.total)
139 config.oscillator_config.append(new SynthOscillatorConfig(current_osc));
141 config.oscillator_config.values[current_osc]->read_data(&input);
147 while(config.oscillator_config.total > current_osc)
148 config.oscillator_config.remove_object();
151 void Synth::save_data(KeyFrame *keyframe)
154 // cause htal file to store data directly in text
155 output.set_shared_string(keyframe->data, MESSAGESIZE);
157 output.tag.set_title("SYNTH");
158 output.tag.set_property("WETNESS", config.wetness);
159 output.tag.set_property("BASEFREQ", config.base_freq);
160 output.tag.set_property("WAVEFUNCTION", config.wavefunction);
161 output.tag.set_property("OSCILLATORS", config.oscillator_config.total);
163 output.append_newline();
165 for(int i = 0; i < config.oscillator_config.total; i++)
167 config.oscillator_config.values[i]->save_data(&output);
170 output.terminate_string();
171 // data is now in *text
174 int Synth::save_defaults()
176 char string[BCTEXTLEN];
178 defaults->update("WIDTH", w);
179 defaults->update("HEIGHT", h);
180 defaults->update("WETNESS", config.wetness);
181 defaults->update("BASEFREQ", config.base_freq);
182 defaults->update("WAVEFUNCTION", config.wavefunction);
183 defaults->update("OSCILLATORS", config.oscillator_config.total);
185 for(int i = 0; i < config.oscillator_config.total; i++)
187 config.oscillator_config.values[i]->save_defaults(defaults);
194 int Synth::show_gui()
196 load_configuration();
198 thread = new SynthThread(this);
203 int Synth::set_string()
205 if(thread) thread->window->set_title(gui_string);
209 void Synth::raise_window()
213 thread->window->raise_window();
214 thread->window->flush();
218 void Synth::update_gui()
222 load_configuration();
223 thread->window->lock_window();
224 thread->window->update_gui();
225 thread->window->unlock_window();
230 void Synth::add_oscillator()
232 if(config.oscillator_config.total > 20) return;
234 config.oscillator_config.append(new SynthOscillatorConfig(config.oscillator_config.total - 1));
237 void Synth::delete_oscillator()
239 if(config.oscillator_config.total)
241 config.oscillator_config.remove_object();
246 double Synth::get_total_power()
250 if(config.wavefunction == DC) return 1.0;
252 for(int i = 0; i < config.oscillator_config.total; i++)
254 result += db.fromdb(config.oscillator_config.values[i]->level);
257 if(result == 0) result = 1; // prevent division by 0
262 double Synth::solve_eqn(double *output,
265 double normalize_constant,
268 SynthOscillatorConfig *config = this->config.oscillator_config.values[oscillator];
269 if(config->level <= INFINITYGAIN) return 0;
273 double power = this->db.fromdb(config->level) * normalize_constant;
274 double phase_offset = config->phase * this->period;
275 double x3 = x1 + phase_offset;
276 double x4 = x2 + phase_offset;
277 double period = this->period / config->freq_factor;
280 switch(this->config.wavefunction)
283 for(sample = (int)x1, x = x3; x < x4; x++, sample++)
285 output[sample] += power;
289 for(sample = (int)x1, x = x3; x < x4; x++, sample++)
291 output[sample] += sin(x / period * 2 * M_PI) * power;
295 for(sample = (int)x1, x = x3; x < x4; x++, sample++)
297 output[sample] += function_sawtooth(x / period) * power;
301 for(sample = (int)x1, x = x3; x < x4; x++, sample++)
303 output[sample] += function_square(x / period) * power;
307 for(sample = (int)x1, x = x3; x < x4; x++, sample++)
309 output[sample] += function_triangle(x / period) * power;
313 for(sample = (int)x1, x = x3; x < x4; x++, sample++)
315 output[sample] += function_pulse(x / period) * power;
319 for(sample = (int)x1, x = x3; x < x4; x++, sample++)
321 output[sample] += function_noise() * power;
327 double Synth::get_point(float x, double normalize_constant)
330 for(int i = 0; i < config.oscillator_config.total; i++)
331 result += get_oscillator_point(x, normalize_constant, i);
336 double Synth::get_oscillator_point(float x,
337 double normalize_constant,
340 SynthOscillatorConfig *config = this->config.oscillator_config.values[oscillator];
341 double power = db.fromdb(config->level) * normalize_constant;
342 switch(this->config.wavefunction)
348 return sin((x + config->phase) * config->freq_factor * 2 * M_PI) * power;
351 return function_sawtooth((x + config->phase) * config->freq_factor) * power;
354 return function_square((x + config->phase) * config->freq_factor) * power;
357 return function_triangle((x + config->phase) * config->freq_factor) * power;
360 return function_pulse((x + config->phase) * config->freq_factor) * power;
363 return function_noise() * power;
368 double Synth::function_square(double x)
370 x -= (int)x; // only fraction counts
371 return (x < .5) ? -1 : 1;
374 double Synth::function_pulse(double x)
376 x -= (int)x; // only fraction counts
377 return (x < .5) ? 0 : 1;
380 double Synth::function_noise()
382 return (double)(rand() % 65536 - 32768) / 32768;
385 double Synth::function_sawtooth(double x)
391 double Synth::function_triangle(double x)
394 return (x < .5) ? 1 - x * 4 : -3 + x * 4;
397 int Synth::process_realtime(int64_t size, double *input_ptr, double *output_ptr)
401 need_reconfigure |= load_configuration();
402 if(need_reconfigure) reconfigure();
404 double wetness = DB::fromdb(config.wetness);
405 if(EQUIV(config.wetness, INFINITYGAIN)) wetness = 0;
407 for(int j = 0; j < size; j++)
408 output_ptr[j] = input_ptr[j] * wetness;
410 int64_t fragment_len;
411 for(int64_t i = 0; i < size; i += fragment_len)
414 if(i + fragment_len > size) fragment_len = size - i;
416 //printf("Synth::process_realtime 1 %d %d %d\n", i, fragment_len, size);
417 fragment_len = overlay_synth(i, fragment_len, input_ptr, output_ptr);
418 //printf("Synth::process_realtime 2\n");
425 int Synth::overlay_synth(int64_t start, int64_t length, double *input, double *output)
427 if(waveform_sample + length > waveform_length)
428 length = waveform_length - waveform_sample;
430 //printf("Synth::overlay_synth 1 %d %d\n", length, waveform_length);
432 // calculate some more data
433 // only calculate what's needed to speed it up
434 if(waveform_sample + length > samples_rendered)
436 int64_t start = waveform_sample, end = waveform_sample + length;
437 for(int i = start; i < end; i++) dsp_buffer[i] = 0;
439 double normalize_constant = 1 / get_total_power();
440 for(int i = 0; i < config.oscillator_config.total; i++)
441 solve_eqn(dsp_buffer,
448 samples_rendered = end;
450 //printf("Synth::overlay_synth 2\n");
453 double *buffer_in = &input[start];
454 double *buffer_out = &output[start];
456 for(int i = 0; i < length; i++)
458 buffer_out[i] += dsp_buffer[waveform_sample++];
460 //printf("Synth::overlay_synth 3\n");
462 if(waveform_sample >= waveform_length) waveform_sample = 0;
467 void Synth::reconfigure()
469 need_reconfigure = 0;
473 delete [] dsp_buffer;
476 //printf("Synth::reconfigure 1 %d\n", PluginAClient::project_sample_rate);
477 waveform_length = PluginAClient::project_sample_rate;
478 period = (float)PluginAClient::project_sample_rate / config.base_freq;
479 dsp_buffer = new double[waveform_length + 1];
481 samples_rendered = 0; // do some calculations on the next process_realtime
505 SynthThread::SynthThread(Synth *synth)
513 SynthThread::~SynthThread()
518 void SynthThread::run()
521 window = new SynthWindow(synth,
522 info.get_abs_cursor_x() - 125,
523 info.get_abs_cursor_y() - 115);
524 window->create_objects();
525 int result = window->run_window();
527 // Last command executed in thread
528 if(result) synth->client_side_close();
541 SynthWindow::SynthWindow(Synth *synth, int x, int y)
542 : BC_Window(synth->gui_string,
556 SynthWindow::~SynthWindow()
560 int SynthWindow::create_objects()
563 add_subwindow(menu = new BC_MenuBar(0, 0, get_w()));
565 BC_Menu *levelmenu, *phasemenu, *harmonicmenu;
566 menu->add_menu(levelmenu = new BC_Menu(_("Level")));
567 menu->add_menu(phasemenu = new BC_Menu(_("Phase")));
568 menu->add_menu(harmonicmenu = new BC_Menu(_("Harmonic")));
570 levelmenu->add_item(new SynthLevelInvert(synth));
571 levelmenu->add_item(new SynthLevelMax(synth));
572 levelmenu->add_item(new SynthLevelRandom(synth));
573 levelmenu->add_item(new SynthLevelSine(synth));
574 levelmenu->add_item(new SynthLevelSlope(synth));
575 levelmenu->add_item(new SynthLevelZero(synth));
577 phasemenu->add_item(new SynthPhaseInvert(synth));
578 phasemenu->add_item(new SynthPhaseRandom(synth));
579 phasemenu->add_item(new SynthPhaseSine(synth));
580 phasemenu->add_item(new SynthPhaseZero(synth));
582 harmonicmenu->add_item(new SynthFreqEnum(synth));
583 harmonicmenu->add_item(new SynthFreqEven(synth));
584 harmonicmenu->add_item(new SynthFreqFibonacci(synth));
585 harmonicmenu->add_item(new SynthFreqOdd(synth));
586 harmonicmenu->add_item(new SynthFreqPrime(synth));
588 int x = 10, y = 30, i;
589 add_subwindow(new BC_Title(x, y, _("Waveform")));
591 add_subwindow(new BC_Title(x, y, _("Wave Function")));
594 add_subwindow(canvas = new SynthCanvas(synth, this, x, y, 230, 160));
598 char string[BCTEXTLEN];
599 waveform_to_text(string, synth->config.wavefunction);
601 add_subwindow(waveform = new SynthWaveForm(synth, x, y, string));
602 waveform->create_objects();
606 add_subwindow(new BC_Title(x, y, _("Base Frequency:")));
608 add_subwindow(base_freq = new SynthBaseFreq(synth, x, y));
610 add_subwindow(freqpot = new SynthFreqPot(synth, this, x, y - 10));
611 base_freq->freq_pot = freqpot;
612 freqpot->freq_text = base_freq;
615 add_subwindow(new BC_Title(x, y, _("Wetness:")));
616 add_subwindow(wetness = new SynthWetness(synth, x + 70, y - 10));
619 add_subwindow(new SynthClear(synth, x, y));
624 add_subwindow(new BC_Title(x, y, _("Level")));
626 add_subwindow(new BC_Title(x, y, _("Phase")));
628 add_subwindow(new BC_Title(x, y, _("Harmonic")));
633 add_subwindow(subwindow = new SynthSubWindow(synth, x, y, 265, get_h() - y));
635 add_subwindow(scroll = new SynthScroll(synth, this, x, y, get_h() - y));
639 add_subwindow(new SynthAddOsc(synth, this, x, y));
641 add_subwindow(new SynthDelOsc(synth, this, x, y));
644 update_oscillators();
651 int SynthWindow::close_event()
653 // Set result to 1 to indicate a client side close
658 int SynthWindow::resize_event(int w, int h)
660 clear_box(0, 0, w, h);
661 subwindow->reposition_window(subwindow->get_x(),
664 h - subwindow->get_y());
665 subwindow->clear_box(0, 0, subwindow->get_w(), subwindow->get_h());
666 scroll->reposition_window(scroll->get_x(),
668 h - scroll->get_y());
670 update_oscillators();
676 void SynthWindow::update_gui()
678 char string[BCTEXTLEN];
679 freqpot->update(synth->config.base_freq);
680 base_freq->update((int64_t)synth->config.base_freq);
681 wetness->update(synth->config.wetness);
682 waveform_to_text(string, synth->config.wavefunction);
683 waveform->set_text(string);
686 update_oscillators();
690 void SynthWindow::update_scrollbar()
692 scroll->update_length(synth->config.oscillator_config.total * OSCILLATORHEIGHT,
693 scroll->get_position(),
697 void SynthWindow::update_oscillators()
699 int i, y = -scroll->get_position();
703 // Add new oscillators
705 i < synth->config.oscillator_config.total;
709 SynthOscillatorConfig *config = synth->config.oscillator_config.values[i];
711 if(oscillators.total <= i)
713 oscillators.append(gui = new SynthOscGUI(this, i));
714 gui->create_objects(y);
718 gui = oscillators.values[i];
720 gui->title->reposition_window(gui->title->get_x(), y + 15);
722 gui->level->reposition_window(gui->level->get_x(), y);
723 gui->level->update(config->level);
725 gui->phase->reposition_window(gui->phase->get_x(), y);
726 gui->phase->update((int64_t)(config->phase * 360));
728 gui->freq->reposition_window(gui->freq->get_x(), y);
729 gui->freq->update((int64_t)(config->freq_factor));
731 y += OSCILLATORHEIGHT;
734 // Delete old oscillators
736 i < oscillators.total;
738 oscillators.remove_object();
742 int SynthWindow::waveform_to_text(char *text, int waveform)
746 case DC: sprintf(text, _("DC")); break;
747 case SINE: sprintf(text, _("Sine")); break;
748 case SAWTOOTH: sprintf(text, _("Sawtooth")); break;
749 case SQUARE: sprintf(text, _("Square")); break;
750 case TRIANGLE: sprintf(text, _("Triangle")); break;
751 case PULSE: sprintf(text, _("Pulse")); break;
752 case NOISE: sprintf(text, _("Noise")); break;
763 SynthOscGUI::SynthOscGUI(SynthWindow *window, int number)
765 this->window = window;
766 this->number = number;
769 SynthOscGUI::~SynthOscGUI()
777 int SynthOscGUI::create_objects(int y)
779 char text[BCTEXTLEN];
780 sprintf(text, "%d:", number + 1);
781 window->subwindow->add_subwindow(title = new BC_Title(10, y + 15, text));
783 window->subwindow->add_subwindow(level = new SynthOscGUILevel(window->synth, this, y));
784 window->subwindow->add_subwindow(phase = new SynthOscGUIPhase(window->synth, this, y));
785 window->subwindow->add_subwindow(freq = new SynthOscGUIFreq(window->synth, this, y));
792 SynthOscGUILevel::SynthOscGUILevel(Synth *synth, SynthOscGUI *gui, int y)
795 synth->config.oscillator_config.values[gui->number]->level,
803 SynthOscGUILevel::~SynthOscGUILevel()
807 int SynthOscGUILevel::handle_event()
809 SynthOscillatorConfig *config = synth->config.oscillator_config.values[gui->number];
810 config->level = get_value();
811 gui->window->canvas->update();
812 synth->send_configure_change();
818 SynthOscGUIPhase::SynthOscGUIPhase(Synth *synth, SynthOscGUI *gui, int y)
821 (int64_t)(synth->config.oscillator_config.values[gui->number]->phase * 360),
829 SynthOscGUIPhase::~SynthOscGUIPhase()
833 int SynthOscGUIPhase::handle_event()
835 SynthOscillatorConfig *config = synth->config.oscillator_config.values[gui->number];
836 config->phase = (float)get_value() / 360;
837 gui->window->canvas->update();
838 synth->send_configure_change();
844 SynthOscGUIFreq::SynthOscGUIFreq(Synth *synth, SynthOscGUI *gui, int y)
847 (int64_t)(synth->config.oscillator_config.values[gui->number]->freq_factor),
855 SynthOscGUIFreq::~SynthOscGUIFreq()
859 int SynthOscGUIFreq::handle_event()
861 SynthOscillatorConfig *config = synth->config.oscillator_config.values[gui->number];
862 config->freq_factor = get_value();
863 gui->window->canvas->update();
864 synth->send_configure_change();
874 SynthAddOsc::SynthAddOsc(Synth *synth, SynthWindow *window, int x, int y)
875 : BC_GenericButton(x, y, _("Add"))
878 this->window = window;
881 SynthAddOsc::~SynthAddOsc()
885 int SynthAddOsc::handle_event()
887 synth->add_oscillator();
888 synth->send_configure_change();
889 window->update_gui();
895 SynthDelOsc::SynthDelOsc(Synth *synth, SynthWindow *window, int x, int y)
896 : BC_GenericButton(x, y, _("Delete"))
899 this->window = window;
902 SynthDelOsc::~SynthDelOsc()
906 int SynthDelOsc::handle_event()
908 synth->delete_oscillator();
909 synth->send_configure_change();
910 window->update_gui();
915 SynthScroll::SynthScroll(Synth *synth,
924 synth->config.oscillator_config.total * OSCILLATORHEIGHT,
926 window->subwindow->get_h())
929 this->window = window;
932 SynthScroll::~SynthScroll()
936 int SynthScroll::handle_event()
938 window->update_gui();
949 SynthSubWindow::SynthSubWindow(Synth *synth, int x, int y, int w, int h)
950 : BC_SubWindow(x, y, w, h)
954 SynthSubWindow::~SynthSubWindow()
966 SynthClear::SynthClear(Synth *synth, int x, int y)
967 : BC_GenericButton(x, y, _("Clear"))
971 SynthClear::~SynthClear()
974 int SynthClear::handle_event()
976 synth->config.reset();
977 synth->send_configure_change();
987 SynthWaveForm::SynthWaveForm(Synth *synth, int x, int y, char *text)
988 : BC_PopupMenu(x, y, 120, text)
993 SynthWaveForm::~SynthWaveForm()
997 int SynthWaveForm::create_objects()
999 // add_item(new SynthWaveFormItem(synth, _("DC"), DC));
1000 add_item(new SynthWaveFormItem(synth, _("Sine"), SINE));
1001 add_item(new SynthWaveFormItem(synth, _("Sawtooth"), SAWTOOTH));
1002 add_item(new SynthWaveFormItem(synth, _("Square"), SQUARE));
1003 add_item(new SynthWaveFormItem(synth, _("Triangle"), TRIANGLE));
1004 add_item(new SynthWaveFormItem(synth, _("Pulse"), PULSE));
1005 add_item(new SynthWaveFormItem(synth, _("Noise"), NOISE));
1009 SynthWaveFormItem::SynthWaveFormItem(Synth *synth, char *text, int value)
1012 this->synth = synth;
1013 this->value = value;
1016 SynthWaveFormItem::~SynthWaveFormItem()
1020 int SynthWaveFormItem::handle_event()
1022 synth->config.wavefunction = value;
1023 synth->thread->window->canvas->update();
1024 synth->send_configure_change();
1029 SynthWetness::SynthWetness(Synth *synth, int x, int y)
1032 synth->config.wetness,
1036 this->synth = synth;
1039 int SynthWetness::handle_event()
1041 synth->config.wetness = get_value();
1042 synth->send_configure_change();
1048 SynthFreqPot::SynthFreqPot(Synth *synth, SynthWindow *window, int x, int y)
1049 : BC_QPot(x, y, synth->config.base_freq)
1051 this->synth = synth;
1053 SynthFreqPot::~SynthFreqPot()
1056 int SynthFreqPot::handle_event()
1058 if(get_value() > 0 && get_value() < 30000)
1060 synth->config.base_freq = get_value();
1061 freq_text->update(get_value());
1062 synth->send_configure_change();
1069 SynthBaseFreq::SynthBaseFreq(Synth *synth, int x, int y)
1070 : BC_TextBox(x, y, 70, 1, (int)synth->config.base_freq)
1072 this->synth = synth;
1074 SynthBaseFreq::~SynthBaseFreq()
1077 int SynthBaseFreq::handle_event()
1079 int new_value = atol(get_text());
1081 if(new_value > 0 && new_value < 30000)
1083 synth->config.base_freq = new_value;
1084 freq_pot->update(synth->config.base_freq);
1085 synth->send_configure_change();
1094 SynthCanvas::SynthCanvas(Synth *synth,
1095 SynthWindow *window,
1106 this->synth = synth;
1107 this->window = window;
1110 SynthCanvas::~SynthCanvas()
1114 int SynthCanvas::update()
1118 clear_box(0, 0, get_w(), get_h());
1121 draw_line(0, get_h() / 2 + y, get_w(), get_h() / 2 + y);
1125 double normalize_constant = (double)1 / synth->get_total_power();
1126 y1 = (int)(synth->get_point((float)0, normalize_constant) * get_h() / 2);
1128 for(int i = 1; i < get_w(); i++)
1130 y2 = (int)(synth->get_point((float)i / get_w(), normalize_constant) * get_h() / 2);
1131 draw_line(i - 1, get_h() / 2 - y1, i, get_h() / 2 - y2);
1145 // ======================= level calculations
1146 SynthLevelZero::SynthLevelZero(Synth *synth)
1147 : BC_MenuItem(_("Zero"))
1149 this->synth = synth;
1152 SynthLevelZero::~SynthLevelZero()
1156 int SynthLevelZero::handle_event()
1158 for(int i = 0; i < synth->config.oscillator_config.total; i++)
1160 synth->config.oscillator_config.values[i]->level = INFINITYGAIN;
1163 synth->thread->window->update_gui();
1164 synth->send_configure_change();
1167 SynthLevelMax::SynthLevelMax(Synth *synth)
1168 : BC_MenuItem(_("Maximum"))
1170 this->synth = synth;
1173 SynthLevelMax::~SynthLevelMax()
1177 int SynthLevelMax::handle_event()
1179 for(int i = 0; i < synth->config.oscillator_config.total; i++)
1181 synth->config.oscillator_config.values[i]->level = 0;
1183 synth->thread->window->update_gui();
1184 synth->send_configure_change();
1187 SynthLevelNormalize::SynthLevelNormalize(Synth *synth)
1188 : BC_MenuItem(_("Normalize"))
1190 this->synth = synth;
1193 SynthLevelNormalize::~SynthLevelNormalize()
1197 int SynthLevelNormalize::handle_event()
1202 for(int i = 0; i < synth->config.oscillator_config.total; i++)
1204 total += synth->db.fromdb(synth->config.oscillator_config.values[i]->level);
1207 float scale = 1 / total;
1210 for(int i = 0; i < synth->config.oscillator_config.total; i++)
1212 new_value = synth->db.fromdb(synth->config.oscillator_config.values[i]->level);
1214 new_value = synth->db.todb(new_value);
1216 synth->config.oscillator_config.values[i]->level = new_value;
1219 synth->thread->window->update_gui();
1220 synth->send_configure_change();
1223 SynthLevelSlope::SynthLevelSlope(Synth *synth)
1224 : BC_MenuItem(_("Slope"))
1226 this->synth = synth;
1229 SynthLevelSlope::~SynthLevelSlope()
1233 int SynthLevelSlope::handle_event()
1235 float slope = (float)INFINITYGAIN / synth->config.oscillator_config.total;
1237 for(int i = 0; i < synth->config.oscillator_config.total; i++)
1239 synth->config.oscillator_config.values[i]->level = i * slope;
1242 synth->thread->window->update_gui();
1243 synth->send_configure_change();
1246 SynthLevelRandom::SynthLevelRandom(Synth *synth)
1247 : BC_MenuItem(_("Random"))
1249 this->synth = synth;
1251 SynthLevelRandom::~SynthLevelRandom()
1255 int SynthLevelRandom::handle_event()
1258 for(int i = 0; i < synth->config.oscillator_config.total; i++)
1260 synth->config.oscillator_config.values[i]->level = -(rand() % -INFINITYGAIN);
1263 synth->thread->window->update_gui();
1264 synth->send_configure_change();
1267 SynthLevelInvert::SynthLevelInvert(Synth *synth)
1268 : BC_MenuItem(_("Invert"))
1270 this->synth = synth;
1272 SynthLevelInvert::~SynthLevelInvert()
1276 int SynthLevelInvert::handle_event()
1278 for(int i = 0; i < synth->config.oscillator_config.total; i++)
1280 synth->config.oscillator_config.values[i]->level =
1281 INFINITYGAIN - synth->config.oscillator_config.values[i]->level;
1284 synth->thread->window->update_gui();
1285 synth->send_configure_change();
1288 SynthLevelSine::SynthLevelSine(Synth *synth)
1289 : BC_MenuItem(_("Sine"))
1291 this->synth = synth;
1293 SynthLevelSine::~SynthLevelSine()
1297 int SynthLevelSine::handle_event()
1301 for(int i = 0; i < synth->config.oscillator_config.total; i++)
1303 new_value = (float)i / synth->config.oscillator_config.total * 2 * M_PI;
1304 new_value = sin(new_value) * INFINITYGAIN / 2 + INFINITYGAIN / 2;
1305 synth->config.oscillator_config.values[i]->level = new_value;
1308 synth->thread->window->update_gui();
1309 synth->send_configure_change();
1312 // ============================ phase calculations
1314 SynthPhaseInvert::SynthPhaseInvert(Synth *synth)
1315 : BC_MenuItem(_("Invert"))
1317 this->synth = synth;
1319 SynthPhaseInvert::~SynthPhaseInvert()
1323 int SynthPhaseInvert::handle_event()
1325 for(int i = 0; i < synth->config.oscillator_config.total; i++)
1327 synth->config.oscillator_config.values[i]->phase =
1328 1 - synth->config.oscillator_config.values[i]->phase;
1331 synth->thread->window->update_gui();
1332 synth->send_configure_change();
1335 SynthPhaseZero::SynthPhaseZero(Synth *synth)
1336 : BC_MenuItem(_("Zero"))
1338 this->synth = synth;
1340 SynthPhaseZero::~SynthPhaseZero()
1344 int SynthPhaseZero::handle_event()
1346 for(int i = 0; i < synth->config.oscillator_config.total; i++)
1348 synth->config.oscillator_config.values[i]->phase = 0;
1351 synth->thread->window->update_gui();
1352 synth->send_configure_change();
1355 SynthPhaseSine::SynthPhaseSine(Synth *synth)
1356 : BC_MenuItem(_("Sine"))
1358 this->synth = synth;
1360 SynthPhaseSine::~SynthPhaseSine()
1364 int SynthPhaseSine::handle_event()
1367 for(int i = 0; i < synth->config.oscillator_config.total; i++)
1369 new_value = (float)i / synth->config.oscillator_config.total * 2 * M_PI;
1370 new_value = sin(new_value) / 2 + .5;
1371 synth->config.oscillator_config.values[i]->phase = new_value;
1374 synth->thread->window->update_gui();
1375 synth->send_configure_change();
1378 SynthPhaseRandom::SynthPhaseRandom(Synth *synth)
1379 : BC_MenuItem(_("Random"))
1381 this->synth = synth;
1383 SynthPhaseRandom::~SynthPhaseRandom()
1387 int SynthPhaseRandom::handle_event()
1390 for(int i = 0; i < synth->config.oscillator_config.total; i++)
1392 synth->config.oscillator_config.values[i]->phase =
1393 (float)(rand() % 360) / 360;
1396 synth->thread->window->update_gui();
1397 synth->send_configure_change();
1401 // ============================ freq calculations
1403 SynthFreqRandom::SynthFreqRandom(Synth *synth)
1404 : BC_MenuItem(_("Random"))
1406 this->synth = synth;
1408 SynthFreqRandom::~SynthFreqRandom()
1412 int SynthFreqRandom::handle_event()
1415 for(int i = 0; i < synth->config.oscillator_config.total; i++)
1417 synth->config.oscillator_config.values[i]->freq_factor = rand() % 100;
1420 synth->thread->window->update_gui();
1421 synth->send_configure_change();
1424 SynthFreqEnum::SynthFreqEnum(Synth *synth)
1425 : BC_MenuItem(_("Enumerate"))
1427 this->synth = synth;
1429 SynthFreqEnum::~SynthFreqEnum()
1433 int SynthFreqEnum::handle_event()
1435 for(int i = 0; i < synth->config.oscillator_config.total; i++)
1437 synth->config.oscillator_config.values[i]->freq_factor = (float)i + 1;
1440 synth->thread->window->update_gui();
1441 synth->send_configure_change();
1444 SynthFreqEven::SynthFreqEven(Synth *synth)
1445 : BC_MenuItem(_("Even"))
1447 this->synth = synth;
1449 SynthFreqEven::~SynthFreqEven()
1453 int SynthFreqEven::handle_event()
1455 if(synth->config.oscillator_config.total)
1456 synth->config.oscillator_config.values[0]->freq_factor = (float)1;
1458 for(int i = 1; i < synth->config.oscillator_config.total; i++)
1460 synth->config.oscillator_config.values[i]->freq_factor = (float)i * 2;
1463 synth->thread->window->update_gui();
1464 synth->send_configure_change();
1467 SynthFreqOdd::SynthFreqOdd(Synth *synth)
1468 : BC_MenuItem(_("Odd"))
1469 { this->synth = synth; }
1470 SynthFreqOdd::~SynthFreqOdd()
1474 int SynthFreqOdd::handle_event()
1476 for(int i = 0; i < synth->config.oscillator_config.total; i++)
1478 synth->config.oscillator_config.values[i]->freq_factor = (float)1 + i * 2;
1481 synth->thread->window->update_gui();
1482 synth->send_configure_change();
1485 SynthFreqFibonacci::SynthFreqFibonacci(Synth *synth)
1486 : BC_MenuItem(_("Fibonnacci"))
1488 this->synth = synth;
1490 SynthFreqFibonacci::~SynthFreqFibonacci()
1494 int SynthFreqFibonacci::handle_event()
1496 float last_value1 = 0, last_value2 = 1;
1497 for(int i = 0; i < synth->config.oscillator_config.total; i++)
1499 synth->config.oscillator_config.values[i]->freq_factor = last_value1 + last_value2;
1500 if(synth->config.oscillator_config.values[i]->freq_factor > 100) synth->config.oscillator_config.values[i]->freq_factor = 100;
1501 last_value1 = last_value2;
1502 last_value2 = synth->config.oscillator_config.values[i]->freq_factor;
1505 synth->thread->window->update_gui();
1506 synth->send_configure_change();
1509 SynthFreqPrime::SynthFreqPrime(Synth *synth)
1510 : BC_MenuItem(_("Prime"))
1512 this->synth = synth;
1514 SynthFreqPrime::~SynthFreqPrime()
1518 int SynthFreqPrime::handle_event()
1521 for(int i = 0; i < synth->config.oscillator_config.total; i++)
1523 synth->config.oscillator_config.values[i]->freq_factor = number;
1524 number = get_next_prime(number);
1527 synth->thread->window->update_gui();
1528 synth->send_configure_change();
1531 float SynthFreqPrime::get_next_prime(float number)
1540 for(float i = number - 1; i > 1 && !result; i--)
1542 if((number / i) - (int)(number / i) == 0) result = 1;
1556 SynthOscillatorConfig::SynthOscillatorConfig(int number)
1559 this->number = number;
1562 SynthOscillatorConfig::~SynthOscillatorConfig()
1566 void SynthOscillatorConfig::reset()
1573 void SynthOscillatorConfig::load_defaults(Defaults *defaults)
1575 char string[BCTEXTLEN];
1577 sprintf(string, "LEVEL%d", number);
1578 level = defaults->get(string, (float)0);
1579 sprintf(string, "PHASE%d", number);
1580 phase = defaults->get(string, (float)0);
1581 sprintf(string, "FREQFACTOR%d", number);
1582 freq_factor = defaults->get(string, (float)1);
1585 void SynthOscillatorConfig::save_defaults(Defaults *defaults)
1587 char string[BCTEXTLEN];
1589 sprintf(string, "LEVEL%d", number);
1590 defaults->update(string, (float)level);
1591 sprintf(string, "PHASE%d", number);
1592 defaults->update(string, (float)phase);
1593 sprintf(string, "FREQFACTOR%d", number);
1594 defaults->update(string, (float)freq_factor);
1597 void SynthOscillatorConfig::read_data(FileXML *file)
1599 level = file->tag.get_property("LEVEL", (float)level);
1600 phase = file->tag.get_property("PHASE", (float)phase);
1601 freq_factor = file->tag.get_property("FREQFACTOR", (float)freq_factor);
1604 void SynthOscillatorConfig::save_data(FileXML *file)
1606 file->tag.set_title("OSCILLATOR");
1607 file->tag.set_property("LEVEL", (float)level);
1608 file->tag.set_property("PHASE", (float)phase);
1609 file->tag.set_property("FREQFACTOR", (float)freq_factor);
1611 file->append_newline();
1614 int SynthOscillatorConfig::equivalent(SynthOscillatorConfig &that)
1616 if(EQUIV(level, that.level) &&
1617 EQUIV(phase, that.phase) &&
1618 EQUIV(freq_factor, that.freq_factor))
1624 void SynthOscillatorConfig::copy_from(SynthOscillatorConfig& that)
1628 freq_factor = that.freq_factor;
1642 SynthConfig::SynthConfig()
1647 SynthConfig::~SynthConfig()
1649 oscillator_config.remove_all_objects();
1652 void SynthConfig::reset()
1656 wavefunction = SINE;
1657 for(int i = 0; i < oscillator_config.total; i++)
1659 oscillator_config.values[i]->reset();
1663 int SynthConfig::equivalent(SynthConfig &that)
1665 //printf("SynthConfig::equivalent %d %d\n", base_freq, that.base_freq);
1666 if(base_freq != that.base_freq ||
1667 wavefunction != that.wavefunction ||
1668 oscillator_config.total != that.oscillator_config.total) return 0;
1670 for(int i = 0; i < oscillator_config.total; i++)
1672 if(!oscillator_config.values[i]->equivalent(*that.oscillator_config.values[i]))
1679 void SynthConfig::copy_from(SynthConfig& that)
1681 wetness = that.wetness;
1682 base_freq = that.base_freq;
1683 wavefunction = that.wavefunction;
1687 i < oscillator_config.total && i < that.oscillator_config.total;
1690 oscillator_config.values[i]->copy_from(*that.oscillator_config.values[i]);
1694 i < that.oscillator_config.total;
1697 oscillator_config.append(new SynthOscillatorConfig(i));
1698 oscillator_config.values[i]->copy_from(*that.oscillator_config.values[i]);
1702 i < oscillator_config.total;
1705 oscillator_config.remove_object();
1709 void SynthConfig::interpolate(SynthConfig &prev,
1713 int64_t current_frame)
1715 double next_scale = (double)(current_frame - prev_frame) / (next_frame - prev_frame);
1716 double prev_scale = (double)(next_frame - current_frame) / (next_frame - prev_frame);
1719 wetness = (int)(prev.wetness * prev_scale + next.wetness * next_scale);
1720 base_freq = (int)(prev.base_freq * prev_scale + next.base_freq * next_scale);