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() { return N_("Synthesizer"); }
59 int Synth::is_realtime() { return 1; }
60 int Synth::is_synthesis() { return 1; }
73 LOAD_CONFIGURATION_MACRO(Synth, SynthConfig)
78 int Synth::load_defaults()
80 char directory[BCTEXTLEN], string[BCTEXTLEN];
82 sprintf(directory, "%ssynthesizer.rc", BCASTDIR);
83 defaults = new Defaults(directory);
85 w = defaults->get("WIDTH", 380);
86 h = defaults->get("HEIGHT", 400);
88 config.wetness = defaults->get("WETNESS", 0);
89 config.base_freq = defaults->get("BASEFREQ", 440);
90 config.wavefunction = defaults->get("WAVEFUNCTION", 0);
92 int total_oscillators = defaults->get("OSCILLATORS", TOTALOSCILLATORS);
93 config.oscillator_config.remove_all_objects();
94 for(int i = 0; i < total_oscillators; i++)
96 config.oscillator_config.append(new SynthOscillatorConfig(i));
97 config.oscillator_config.values[i]->load_defaults(defaults);
104 void Synth::read_data(KeyFrame *keyframe)
107 // cause htal file to read directly from text
108 input.set_shared_string(keyframe->data, strlen(keyframe->data));
110 //printf("Synth::read_data %s\n", keyframe->data);
111 int result = 0, current_osc = 0, total_oscillators = 0;
114 result = input.read_tag();
118 if(input.tag.title_is("SYNTH"))
120 config.wetness = input.tag.get_property("WETNESS", config.wetness);
121 config.base_freq = input.tag.get_property("BASEFREQ", config.base_freq);
122 config.wavefunction = input.tag.get_property("WAVEFUNCTION", config.wavefunction);
123 total_oscillators = input.tag.get_property("OSCILLATORS", 0);
126 if(input.tag.title_is("OSCILLATOR"))
128 if(current_osc >= config.oscillator_config.total)
129 config.oscillator_config.append(new SynthOscillatorConfig(current_osc));
131 config.oscillator_config.values[current_osc]->read_data(&input);
137 while(config.oscillator_config.total > current_osc)
138 config.oscillator_config.remove_object();
141 void Synth::save_data(KeyFrame *keyframe)
144 // cause htal file to store data directly in text
145 output.set_shared_string(keyframe->data, MESSAGESIZE);
147 output.tag.set_title("SYNTH");
148 output.tag.set_property("WETNESS", config.wetness);
149 output.tag.set_property("BASEFREQ", config.base_freq);
150 output.tag.set_property("WAVEFUNCTION", config.wavefunction);
151 output.tag.set_property("OSCILLATORS", config.oscillator_config.total);
153 output.append_newline();
155 for(int i = 0; i < config.oscillator_config.total; i++)
157 config.oscillator_config.values[i]->save_data(&output);
160 output.terminate_string();
161 // data is now in *text
164 int Synth::save_defaults()
166 char string[BCTEXTLEN];
168 defaults->update("WIDTH", w);
169 defaults->update("HEIGHT", h);
170 defaults->update("WETNESS", config.wetness);
171 defaults->update("BASEFREQ", config.base_freq);
172 defaults->update("WAVEFUNCTION", config.wavefunction);
173 defaults->update("OSCILLATORS", config.oscillator_config.total);
175 for(int i = 0; i < config.oscillator_config.total; i++)
177 config.oscillator_config.values[i]->save_defaults(defaults);
184 int Synth::show_gui()
186 load_configuration();
188 thread = new SynthThread(this);
193 int Synth::set_string()
195 if(thread) thread->window->set_title(gui_string);
199 void Synth::raise_window()
203 thread->window->raise_window();
204 thread->window->flush();
208 void Synth::update_gui()
212 load_configuration();
213 thread->window->lock_window();
214 thread->window->update_gui();
215 thread->window->unlock_window();
220 void Synth::add_oscillator()
222 if(config.oscillator_config.total > 20) return;
224 config.oscillator_config.append(new SynthOscillatorConfig(config.oscillator_config.total - 1));
227 void Synth::delete_oscillator()
229 if(config.oscillator_config.total)
231 config.oscillator_config.remove_object();
236 double Synth::get_total_power()
240 if(config.wavefunction == DC) return 1.0;
242 for(int i = 0; i < config.oscillator_config.total; i++)
244 result += db.fromdb(config.oscillator_config.values[i]->level);
247 if(result == 0) result = 1; // prevent division by 0
252 double Synth::solve_eqn(double *output,
255 double normalize_constant,
258 SynthOscillatorConfig *config = this->config.oscillator_config.values[oscillator];
259 if(config->level <= INFINITYGAIN) return 0;
263 double power = this->db.fromdb(config->level) * normalize_constant;
264 double phase_offset = config->phase * this->period;
265 double x3 = x1 + phase_offset;
266 double x4 = x2 + phase_offset;
267 double period = this->period / config->freq_factor;
270 switch(this->config.wavefunction)
273 for(sample = (int)x1, x = x3; x < x4; x++, sample++)
275 output[sample] += power;
279 for(sample = (int)x1, x = x3; x < x4; x++, sample++)
281 output[sample] += sin(x / period * 2 * M_PI) * power;
285 for(sample = (int)x1, x = x3; x < x4; x++, sample++)
287 output[sample] += function_sawtooth(x / period) * power;
291 for(sample = (int)x1, x = x3; x < x4; x++, sample++)
293 output[sample] += function_square(x / period) * power;
297 for(sample = (int)x1, x = x3; x < x4; x++, sample++)
299 output[sample] += function_triangle(x / period) * power;
303 for(sample = (int)x1, x = x3; x < x4; x++, sample++)
305 output[sample] += function_pulse(x / period) * power;
309 for(sample = (int)x1, x = x3; x < x4; x++, sample++)
311 output[sample] += function_noise() * power;
317 double Synth::get_point(float x, double normalize_constant)
320 for(int i = 0; i < config.oscillator_config.total; i++)
321 result += get_oscillator_point(x, normalize_constant, i);
326 double Synth::get_oscillator_point(float x,
327 double normalize_constant,
330 SynthOscillatorConfig *config = this->config.oscillator_config.values[oscillator];
331 double power = db.fromdb(config->level) * normalize_constant;
332 switch(this->config.wavefunction)
338 return sin((x + config->phase) * config->freq_factor * 2 * M_PI) * power;
341 return function_sawtooth((x + config->phase) * config->freq_factor) * power;
344 return function_square((x + config->phase) * config->freq_factor) * power;
347 return function_triangle((x + config->phase) * config->freq_factor) * power;
350 return function_pulse((x + config->phase) * config->freq_factor) * power;
353 return function_noise() * power;
358 double Synth::function_square(double x)
360 x -= (int)x; // only fraction counts
361 return (x < .5) ? -1 : 1;
364 double Synth::function_pulse(double x)
366 x -= (int)x; // only fraction counts
367 return (x < .5) ? 0 : 1;
370 double Synth::function_noise()
372 return (double)(rand() % 65536 - 32768) / 32768;
375 double Synth::function_sawtooth(double x)
381 double Synth::function_triangle(double x)
384 return (x < .5) ? 1 - x * 4 : -3 + x * 4;
387 int Synth::process_realtime(int64_t size, double *input_ptr, double *output_ptr)
391 need_reconfigure |= load_configuration();
392 if(need_reconfigure) reconfigure();
394 double wetness = DB::fromdb(config.wetness);
395 if(EQUIV(config.wetness, INFINITYGAIN)) wetness = 0;
397 for(int j = 0; j < size; j++)
398 output_ptr[j] = input_ptr[j] * wetness;
400 int64_t fragment_len;
401 for(int64_t i = 0; i < size; i += fragment_len)
404 if(i + fragment_len > size) fragment_len = size - i;
406 //printf("Synth::process_realtime 1 %d %d %d\n", i, fragment_len, size);
407 fragment_len = overlay_synth(i, fragment_len, input_ptr, output_ptr);
408 //printf("Synth::process_realtime 2\n");
415 int Synth::overlay_synth(int64_t start, int64_t length, double *input, double *output)
417 if(waveform_sample + length > waveform_length)
418 length = waveform_length - waveform_sample;
420 //printf("Synth::overlay_synth 1 %d %d\n", length, waveform_length);
422 // calculate some more data
423 // only calculate what's needed to speed it up
424 if(waveform_sample + length > samples_rendered)
426 int64_t start = waveform_sample, end = waveform_sample + length;
427 for(int i = start; i < end; i++) dsp_buffer[i] = 0;
429 double normalize_constant = 1 / get_total_power();
430 for(int i = 0; i < config.oscillator_config.total; i++)
431 solve_eqn(dsp_buffer,
438 samples_rendered = end;
440 //printf("Synth::overlay_synth 2\n");
443 double *buffer_in = &input[start];
444 double *buffer_out = &output[start];
446 for(int i = 0; i < length; i++)
448 buffer_out[i] += dsp_buffer[waveform_sample++];
450 //printf("Synth::overlay_synth 3\n");
452 if(waveform_sample >= waveform_length) waveform_sample = 0;
457 void Synth::reconfigure()
459 need_reconfigure = 0;
463 delete [] dsp_buffer;
466 //printf("Synth::reconfigure 1 %d\n", PluginAClient::project_sample_rate);
467 waveform_length = PluginAClient::project_sample_rate;
468 period = (float)PluginAClient::project_sample_rate / config.base_freq;
469 dsp_buffer = new double[waveform_length + 1];
471 samples_rendered = 0; // do some calculations on the next process_realtime
495 SynthThread::SynthThread(Synth *synth)
503 SynthThread::~SynthThread()
508 void SynthThread::run()
511 window = new SynthWindow(synth,
512 info.get_abs_cursor_x() - 125,
513 info.get_abs_cursor_y() - 115);
514 window->create_objects();
515 int result = window->run_window();
517 // Last command executed in thread
518 if(result) synth->client_side_close();
531 SynthWindow::SynthWindow(Synth *synth, int x, int y)
532 : BC_Window(synth->gui_string,
546 SynthWindow::~SynthWindow()
550 int SynthWindow::create_objects()
553 add_subwindow(menu = new BC_MenuBar(0, 0, get_w()));
555 BC_Menu *levelmenu, *phasemenu, *harmonicmenu;
556 menu->add_menu(levelmenu = new BC_Menu(_("Level")));
557 menu->add_menu(phasemenu = new BC_Menu(_("Phase")));
558 menu->add_menu(harmonicmenu = new BC_Menu(_("Harmonic")));
560 levelmenu->add_item(new SynthLevelInvert(synth));
561 levelmenu->add_item(new SynthLevelMax(synth));
562 levelmenu->add_item(new SynthLevelRandom(synth));
563 levelmenu->add_item(new SynthLevelSine(synth));
564 levelmenu->add_item(new SynthLevelSlope(synth));
565 levelmenu->add_item(new SynthLevelZero(synth));
567 phasemenu->add_item(new SynthPhaseInvert(synth));
568 phasemenu->add_item(new SynthPhaseRandom(synth));
569 phasemenu->add_item(new SynthPhaseSine(synth));
570 phasemenu->add_item(new SynthPhaseZero(synth));
572 harmonicmenu->add_item(new SynthFreqEnum(synth));
573 harmonicmenu->add_item(new SynthFreqEven(synth));
574 harmonicmenu->add_item(new SynthFreqFibonacci(synth));
575 harmonicmenu->add_item(new SynthFreqOdd(synth));
576 harmonicmenu->add_item(new SynthFreqPrime(synth));
578 int x = 10, y = 30, i;
579 add_subwindow(new BC_Title(x, y, _("Waveform")));
581 add_subwindow(new BC_Title(x, y, _("Wave Function")));
584 add_subwindow(canvas = new SynthCanvas(synth, this, x, y, 230, 160));
588 char string[BCTEXTLEN];
589 waveform_to_text(string, synth->config.wavefunction);
591 add_subwindow(waveform = new SynthWaveForm(synth, x, y, string));
592 waveform->create_objects();
596 add_subwindow(new BC_Title(x, y, _("Base Frequency:")));
598 add_subwindow(base_freq = new SynthBaseFreq(synth, x, y));
600 add_subwindow(freqpot = new SynthFreqPot(synth, this, x, y - 10));
601 base_freq->freq_pot = freqpot;
602 freqpot->freq_text = base_freq;
605 add_subwindow(new BC_Title(x, y, _("Wetness:")));
606 add_subwindow(wetness = new SynthWetness(synth, x + 70, y - 10));
609 add_subwindow(new SynthClear(synth, x, y));
614 add_subwindow(new BC_Title(x, y, _("Level")));
616 add_subwindow(new BC_Title(x, y, _("Phase")));
618 add_subwindow(new BC_Title(x, y, _("Harmonic")));
623 add_subwindow(subwindow = new SynthSubWindow(synth, x, y, 265, get_h() - y));
625 add_subwindow(scroll = new SynthScroll(synth, this, x, y, get_h() - y));
629 add_subwindow(new SynthAddOsc(synth, this, x, y));
631 add_subwindow(new SynthDelOsc(synth, this, x, y));
634 update_oscillators();
641 int SynthWindow::close_event()
643 // Set result to 1 to indicate a client side close
648 int SynthWindow::resize_event(int w, int h)
650 clear_box(0, 0, w, h);
651 subwindow->reposition_window(subwindow->get_x(),
654 h - subwindow->get_y());
655 subwindow->clear_box(0, 0, subwindow->get_w(), subwindow->get_h());
656 scroll->reposition_window(scroll->get_x(),
658 h - scroll->get_y());
660 update_oscillators();
666 void SynthWindow::update_gui()
668 char string[BCTEXTLEN];
669 freqpot->update(synth->config.base_freq);
670 base_freq->update((int64_t)synth->config.base_freq);
671 wetness->update(synth->config.wetness);
672 waveform_to_text(string, synth->config.wavefunction);
673 waveform->set_text(string);
676 update_oscillators();
680 void SynthWindow::update_scrollbar()
682 scroll->update_length(synth->config.oscillator_config.total * OSCILLATORHEIGHT,
683 scroll->get_position(),
687 void SynthWindow::update_oscillators()
689 int i, y = -scroll->get_position();
693 // Add new oscillators
695 i < synth->config.oscillator_config.total;
699 SynthOscillatorConfig *config = synth->config.oscillator_config.values[i];
701 if(oscillators.total <= i)
703 oscillators.append(gui = new SynthOscGUI(this, i));
704 gui->create_objects(y);
708 gui = oscillators.values[i];
710 gui->title->reposition_window(gui->title->get_x(), y + 15);
712 gui->level->reposition_window(gui->level->get_x(), y);
713 gui->level->update(config->level);
715 gui->phase->reposition_window(gui->phase->get_x(), y);
716 gui->phase->update((int64_t)(config->phase * 360));
718 gui->freq->reposition_window(gui->freq->get_x(), y);
719 gui->freq->update((int64_t)(config->freq_factor));
721 y += OSCILLATORHEIGHT;
724 // Delete old oscillators
726 i < oscillators.total;
728 oscillators.remove_object();
732 int SynthWindow::waveform_to_text(char *text, int waveform)
736 case DC: sprintf(text, _("DC")); break;
737 case SINE: sprintf(text, _("Sine")); break;
738 case SAWTOOTH: sprintf(text, _("Sawtooth")); break;
739 case SQUARE: sprintf(text, _("Square")); break;
740 case TRIANGLE: sprintf(text, _("Triangle")); break;
741 case PULSE: sprintf(text, _("Pulse")); break;
742 case NOISE: sprintf(text, _("Noise")); break;
753 SynthOscGUI::SynthOscGUI(SynthWindow *window, int number)
755 this->window = window;
756 this->number = number;
759 SynthOscGUI::~SynthOscGUI()
767 int SynthOscGUI::create_objects(int y)
769 char text[BCTEXTLEN];
770 sprintf(text, "%d:", number + 1);
771 window->subwindow->add_subwindow(title = new BC_Title(10, y + 15, text));
773 window->subwindow->add_subwindow(level = new SynthOscGUILevel(window->synth, this, y));
774 window->subwindow->add_subwindow(phase = new SynthOscGUIPhase(window->synth, this, y));
775 window->subwindow->add_subwindow(freq = new SynthOscGUIFreq(window->synth, this, y));
782 SynthOscGUILevel::SynthOscGUILevel(Synth *synth, SynthOscGUI *gui, int y)
785 synth->config.oscillator_config.values[gui->number]->level,
793 SynthOscGUILevel::~SynthOscGUILevel()
797 int SynthOscGUILevel::handle_event()
799 SynthOscillatorConfig *config = synth->config.oscillator_config.values[gui->number];
800 config->level = get_value();
801 gui->window->canvas->update();
802 synth->send_configure_change();
808 SynthOscGUIPhase::SynthOscGUIPhase(Synth *synth, SynthOscGUI *gui, int y)
811 (int64_t)(synth->config.oscillator_config.values[gui->number]->phase * 360),
819 SynthOscGUIPhase::~SynthOscGUIPhase()
823 int SynthOscGUIPhase::handle_event()
825 SynthOscillatorConfig *config = synth->config.oscillator_config.values[gui->number];
826 config->phase = (float)get_value() / 360;
827 gui->window->canvas->update();
828 synth->send_configure_change();
834 SynthOscGUIFreq::SynthOscGUIFreq(Synth *synth, SynthOscGUI *gui, int y)
837 (int64_t)(synth->config.oscillator_config.values[gui->number]->freq_factor),
845 SynthOscGUIFreq::~SynthOscGUIFreq()
849 int SynthOscGUIFreq::handle_event()
851 SynthOscillatorConfig *config = synth->config.oscillator_config.values[gui->number];
852 config->freq_factor = get_value();
853 gui->window->canvas->update();
854 synth->send_configure_change();
864 SynthAddOsc::SynthAddOsc(Synth *synth, SynthWindow *window, int x, int y)
865 : BC_GenericButton(x, y, _("Add"))
868 this->window = window;
871 SynthAddOsc::~SynthAddOsc()
875 int SynthAddOsc::handle_event()
877 synth->add_oscillator();
878 synth->send_configure_change();
879 window->update_gui();
885 SynthDelOsc::SynthDelOsc(Synth *synth, SynthWindow *window, int x, int y)
886 : BC_GenericButton(x, y, _("Delete"))
889 this->window = window;
892 SynthDelOsc::~SynthDelOsc()
896 int SynthDelOsc::handle_event()
898 synth->delete_oscillator();
899 synth->send_configure_change();
900 window->update_gui();
905 SynthScroll::SynthScroll(Synth *synth,
914 synth->config.oscillator_config.total * OSCILLATORHEIGHT,
916 window->subwindow->get_h())
919 this->window = window;
922 SynthScroll::~SynthScroll()
926 int SynthScroll::handle_event()
928 window->update_gui();
939 SynthSubWindow::SynthSubWindow(Synth *synth, int x, int y, int w, int h)
940 : BC_SubWindow(x, y, w, h)
944 SynthSubWindow::~SynthSubWindow()
956 SynthClear::SynthClear(Synth *synth, int x, int y)
957 : BC_GenericButton(x, y, _("Clear"))
961 SynthClear::~SynthClear()
964 int SynthClear::handle_event()
966 synth->config.reset();
967 synth->send_configure_change();
977 SynthWaveForm::SynthWaveForm(Synth *synth, int x, int y, char *text)
978 : BC_PopupMenu(x, y, 120, text)
983 SynthWaveForm::~SynthWaveForm()
987 int SynthWaveForm::create_objects()
989 // add_item(new SynthWaveFormItem(synth, _("DC"), DC));
990 add_item(new SynthWaveFormItem(synth, _("Sine"), SINE));
991 add_item(new SynthWaveFormItem(synth, _("Sawtooth"), SAWTOOTH));
992 add_item(new SynthWaveFormItem(synth, _("Square"), SQUARE));
993 add_item(new SynthWaveFormItem(synth, _("Triangle"), TRIANGLE));
994 add_item(new SynthWaveFormItem(synth, _("Pulse"), PULSE));
995 add_item(new SynthWaveFormItem(synth, _("Noise"), NOISE));
999 SynthWaveFormItem::SynthWaveFormItem(Synth *synth, char *text, int value)
1002 this->synth = synth;
1003 this->value = value;
1006 SynthWaveFormItem::~SynthWaveFormItem()
1010 int SynthWaveFormItem::handle_event()
1012 synth->config.wavefunction = value;
1013 synth->thread->window->canvas->update();
1014 synth->send_configure_change();
1019 SynthWetness::SynthWetness(Synth *synth, int x, int y)
1022 synth->config.wetness,
1026 this->synth = synth;
1029 int SynthWetness::handle_event()
1031 synth->config.wetness = get_value();
1032 synth->send_configure_change();
1038 SynthFreqPot::SynthFreqPot(Synth *synth, SynthWindow *window, int x, int y)
1039 : BC_QPot(x, y, synth->config.base_freq)
1041 this->synth = synth;
1043 SynthFreqPot::~SynthFreqPot()
1046 int SynthFreqPot::handle_event()
1048 if(get_value() > 0 && get_value() < 30000)
1050 synth->config.base_freq = get_value();
1051 freq_text->update(get_value());
1052 synth->send_configure_change();
1059 SynthBaseFreq::SynthBaseFreq(Synth *synth, int x, int y)
1060 : BC_TextBox(x, y, 70, 1, (int)synth->config.base_freq)
1062 this->synth = synth;
1064 SynthBaseFreq::~SynthBaseFreq()
1067 int SynthBaseFreq::handle_event()
1069 int new_value = atol(get_text());
1071 if(new_value > 0 && new_value < 30000)
1073 synth->config.base_freq = new_value;
1074 freq_pot->update(synth->config.base_freq);
1075 synth->send_configure_change();
1084 SynthCanvas::SynthCanvas(Synth *synth,
1085 SynthWindow *window,
1096 this->synth = synth;
1097 this->window = window;
1100 SynthCanvas::~SynthCanvas()
1104 int SynthCanvas::update()
1108 clear_box(0, 0, get_w(), get_h());
1111 draw_line(0, get_h() / 2 + y, get_w(), get_h() / 2 + y);
1115 double normalize_constant = (double)1 / synth->get_total_power();
1116 y1 = (int)(synth->get_point((float)0, normalize_constant) * get_h() / 2);
1118 for(int i = 1; i < get_w(); i++)
1120 y2 = (int)(synth->get_point((float)i / get_w(), normalize_constant) * get_h() / 2);
1121 draw_line(i - 1, get_h() / 2 - y1, i, get_h() / 2 - y2);
1135 // ======================= level calculations
1136 SynthLevelZero::SynthLevelZero(Synth *synth)
1137 : BC_MenuItem(_("Zero"))
1139 this->synth = synth;
1142 SynthLevelZero::~SynthLevelZero()
1146 int SynthLevelZero::handle_event()
1148 for(int i = 0; i < synth->config.oscillator_config.total; i++)
1150 synth->config.oscillator_config.values[i]->level = INFINITYGAIN;
1153 synth->thread->window->update_gui();
1154 synth->send_configure_change();
1157 SynthLevelMax::SynthLevelMax(Synth *synth)
1158 : BC_MenuItem(_("Maximum"))
1160 this->synth = synth;
1163 SynthLevelMax::~SynthLevelMax()
1167 int SynthLevelMax::handle_event()
1169 for(int i = 0; i < synth->config.oscillator_config.total; i++)
1171 synth->config.oscillator_config.values[i]->level = 0;
1173 synth->thread->window->update_gui();
1174 synth->send_configure_change();
1177 SynthLevelNormalize::SynthLevelNormalize(Synth *synth)
1178 : BC_MenuItem(_("Normalize"))
1180 this->synth = synth;
1183 SynthLevelNormalize::~SynthLevelNormalize()
1187 int SynthLevelNormalize::handle_event()
1192 for(int i = 0; i < synth->config.oscillator_config.total; i++)
1194 total += synth->db.fromdb(synth->config.oscillator_config.values[i]->level);
1197 float scale = 1 / total;
1200 for(int i = 0; i < synth->config.oscillator_config.total; i++)
1202 new_value = synth->db.fromdb(synth->config.oscillator_config.values[i]->level);
1204 new_value = synth->db.todb(new_value);
1206 synth->config.oscillator_config.values[i]->level = new_value;
1209 synth->thread->window->update_gui();
1210 synth->send_configure_change();
1213 SynthLevelSlope::SynthLevelSlope(Synth *synth)
1214 : BC_MenuItem(_("Slope"))
1216 this->synth = synth;
1219 SynthLevelSlope::~SynthLevelSlope()
1223 int SynthLevelSlope::handle_event()
1225 float slope = (float)INFINITYGAIN / synth->config.oscillator_config.total;
1227 for(int i = 0; i < synth->config.oscillator_config.total; i++)
1229 synth->config.oscillator_config.values[i]->level = i * slope;
1232 synth->thread->window->update_gui();
1233 synth->send_configure_change();
1236 SynthLevelRandom::SynthLevelRandom(Synth *synth)
1237 : BC_MenuItem(_("Random"))
1239 this->synth = synth;
1241 SynthLevelRandom::~SynthLevelRandom()
1245 int SynthLevelRandom::handle_event()
1248 for(int i = 0; i < synth->config.oscillator_config.total; i++)
1250 synth->config.oscillator_config.values[i]->level = -(rand() % -INFINITYGAIN);
1253 synth->thread->window->update_gui();
1254 synth->send_configure_change();
1257 SynthLevelInvert::SynthLevelInvert(Synth *synth)
1258 : BC_MenuItem(_("Invert"))
1260 this->synth = synth;
1262 SynthLevelInvert::~SynthLevelInvert()
1266 int SynthLevelInvert::handle_event()
1268 for(int i = 0; i < synth->config.oscillator_config.total; i++)
1270 synth->config.oscillator_config.values[i]->level =
1271 INFINITYGAIN - synth->config.oscillator_config.values[i]->level;
1274 synth->thread->window->update_gui();
1275 synth->send_configure_change();
1278 SynthLevelSine::SynthLevelSine(Synth *synth)
1279 : BC_MenuItem(_("Sine"))
1281 this->synth = synth;
1283 SynthLevelSine::~SynthLevelSine()
1287 int SynthLevelSine::handle_event()
1291 for(int i = 0; i < synth->config.oscillator_config.total; i++)
1293 new_value = (float)i / synth->config.oscillator_config.total * 2 * M_PI;
1294 new_value = sin(new_value) * INFINITYGAIN / 2 + INFINITYGAIN / 2;
1295 synth->config.oscillator_config.values[i]->level = new_value;
1298 synth->thread->window->update_gui();
1299 synth->send_configure_change();
1302 // ============================ phase calculations
1304 SynthPhaseInvert::SynthPhaseInvert(Synth *synth)
1305 : BC_MenuItem(_("Invert"))
1307 this->synth = synth;
1309 SynthPhaseInvert::~SynthPhaseInvert()
1313 int SynthPhaseInvert::handle_event()
1315 for(int i = 0; i < synth->config.oscillator_config.total; i++)
1317 synth->config.oscillator_config.values[i]->phase =
1318 1 - synth->config.oscillator_config.values[i]->phase;
1321 synth->thread->window->update_gui();
1322 synth->send_configure_change();
1325 SynthPhaseZero::SynthPhaseZero(Synth *synth)
1326 : BC_MenuItem(_("Zero"))
1328 this->synth = synth;
1330 SynthPhaseZero::~SynthPhaseZero()
1334 int SynthPhaseZero::handle_event()
1336 for(int i = 0; i < synth->config.oscillator_config.total; i++)
1338 synth->config.oscillator_config.values[i]->phase = 0;
1341 synth->thread->window->update_gui();
1342 synth->send_configure_change();
1345 SynthPhaseSine::SynthPhaseSine(Synth *synth)
1346 : BC_MenuItem(_("Sine"))
1348 this->synth = synth;
1350 SynthPhaseSine::~SynthPhaseSine()
1354 int SynthPhaseSine::handle_event()
1357 for(int i = 0; i < synth->config.oscillator_config.total; i++)
1359 new_value = (float)i / synth->config.oscillator_config.total * 2 * M_PI;
1360 new_value = sin(new_value) / 2 + .5;
1361 synth->config.oscillator_config.values[i]->phase = new_value;
1364 synth->thread->window->update_gui();
1365 synth->send_configure_change();
1368 SynthPhaseRandom::SynthPhaseRandom(Synth *synth)
1369 : BC_MenuItem(_("Random"))
1371 this->synth = synth;
1373 SynthPhaseRandom::~SynthPhaseRandom()
1377 int SynthPhaseRandom::handle_event()
1380 for(int i = 0; i < synth->config.oscillator_config.total; i++)
1382 synth->config.oscillator_config.values[i]->phase =
1383 (float)(rand() % 360) / 360;
1386 synth->thread->window->update_gui();
1387 synth->send_configure_change();
1391 // ============================ freq calculations
1393 SynthFreqRandom::SynthFreqRandom(Synth *synth)
1394 : BC_MenuItem(_("Random"))
1396 this->synth = synth;
1398 SynthFreqRandom::~SynthFreqRandom()
1402 int SynthFreqRandom::handle_event()
1405 for(int i = 0; i < synth->config.oscillator_config.total; i++)
1407 synth->config.oscillator_config.values[i]->freq_factor = rand() % 100;
1410 synth->thread->window->update_gui();
1411 synth->send_configure_change();
1414 SynthFreqEnum::SynthFreqEnum(Synth *synth)
1415 : BC_MenuItem(_("Enumerate"))
1417 this->synth = synth;
1419 SynthFreqEnum::~SynthFreqEnum()
1423 int SynthFreqEnum::handle_event()
1425 for(int i = 0; i < synth->config.oscillator_config.total; i++)
1427 synth->config.oscillator_config.values[i]->freq_factor = (float)i + 1;
1430 synth->thread->window->update_gui();
1431 synth->send_configure_change();
1434 SynthFreqEven::SynthFreqEven(Synth *synth)
1435 : BC_MenuItem(_("Even"))
1437 this->synth = synth;
1439 SynthFreqEven::~SynthFreqEven()
1443 int SynthFreqEven::handle_event()
1445 if(synth->config.oscillator_config.total)
1446 synth->config.oscillator_config.values[0]->freq_factor = (float)1;
1448 for(int i = 1; i < synth->config.oscillator_config.total; i++)
1450 synth->config.oscillator_config.values[i]->freq_factor = (float)i * 2;
1453 synth->thread->window->update_gui();
1454 synth->send_configure_change();
1457 SynthFreqOdd::SynthFreqOdd(Synth *synth)
1458 : BC_MenuItem(_("Odd"))
1459 { this->synth = synth; }
1460 SynthFreqOdd::~SynthFreqOdd()
1464 int SynthFreqOdd::handle_event()
1466 for(int i = 0; i < synth->config.oscillator_config.total; i++)
1468 synth->config.oscillator_config.values[i]->freq_factor = (float)1 + i * 2;
1471 synth->thread->window->update_gui();
1472 synth->send_configure_change();
1475 SynthFreqFibonacci::SynthFreqFibonacci(Synth *synth)
1476 : BC_MenuItem(_("Fibonnacci"))
1478 this->synth = synth;
1480 SynthFreqFibonacci::~SynthFreqFibonacci()
1484 int SynthFreqFibonacci::handle_event()
1486 float last_value1 = 0, last_value2 = 1;
1487 for(int i = 0; i < synth->config.oscillator_config.total; i++)
1489 synth->config.oscillator_config.values[i]->freq_factor = last_value1 + last_value2;
1490 if(synth->config.oscillator_config.values[i]->freq_factor > 100) synth->config.oscillator_config.values[i]->freq_factor = 100;
1491 last_value1 = last_value2;
1492 last_value2 = synth->config.oscillator_config.values[i]->freq_factor;
1495 synth->thread->window->update_gui();
1496 synth->send_configure_change();
1499 SynthFreqPrime::SynthFreqPrime(Synth *synth)
1500 : BC_MenuItem(_("Prime"))
1502 this->synth = synth;
1504 SynthFreqPrime::~SynthFreqPrime()
1508 int SynthFreqPrime::handle_event()
1511 for(int i = 0; i < synth->config.oscillator_config.total; i++)
1513 synth->config.oscillator_config.values[i]->freq_factor = number;
1514 number = get_next_prime(number);
1517 synth->thread->window->update_gui();
1518 synth->send_configure_change();
1521 float SynthFreqPrime::get_next_prime(float number)
1530 for(float i = number - 1; i > 1 && !result; i--)
1532 if((number / i) - (int)(number / i) == 0) result = 1;
1546 SynthOscillatorConfig::SynthOscillatorConfig(int number)
1549 this->number = number;
1552 SynthOscillatorConfig::~SynthOscillatorConfig()
1556 void SynthOscillatorConfig::reset()
1563 void SynthOscillatorConfig::load_defaults(Defaults *defaults)
1565 char string[BCTEXTLEN];
1567 sprintf(string, "LEVEL%d", number);
1568 level = defaults->get(string, (float)0);
1569 sprintf(string, "PHASE%d", number);
1570 phase = defaults->get(string, (float)0);
1571 sprintf(string, "FREQFACTOR%d", number);
1572 freq_factor = defaults->get(string, (float)1);
1575 void SynthOscillatorConfig::save_defaults(Defaults *defaults)
1577 char string[BCTEXTLEN];
1579 sprintf(string, "LEVEL%d", number);
1580 defaults->update(string, (float)level);
1581 sprintf(string, "PHASE%d", number);
1582 defaults->update(string, (float)phase);
1583 sprintf(string, "FREQFACTOR%d", number);
1584 defaults->update(string, (float)freq_factor);
1587 void SynthOscillatorConfig::read_data(FileXML *file)
1589 level = file->tag.get_property("LEVEL", (float)level);
1590 phase = file->tag.get_property("PHASE", (float)phase);
1591 freq_factor = file->tag.get_property("FREQFACTOR", (float)freq_factor);
1594 void SynthOscillatorConfig::save_data(FileXML *file)
1596 file->tag.set_title("OSCILLATOR");
1597 file->tag.set_property("LEVEL", (float)level);
1598 file->tag.set_property("PHASE", (float)phase);
1599 file->tag.set_property("FREQFACTOR", (float)freq_factor);
1601 file->append_newline();
1604 int SynthOscillatorConfig::equivalent(SynthOscillatorConfig &that)
1606 if(EQUIV(level, that.level) &&
1607 EQUIV(phase, that.phase) &&
1608 EQUIV(freq_factor, that.freq_factor))
1614 void SynthOscillatorConfig::copy_from(SynthOscillatorConfig& that)
1618 freq_factor = that.freq_factor;
1632 SynthConfig::SynthConfig()
1637 SynthConfig::~SynthConfig()
1639 oscillator_config.remove_all_objects();
1642 void SynthConfig::reset()
1646 wavefunction = SINE;
1647 for(int i = 0; i < oscillator_config.total; i++)
1649 oscillator_config.values[i]->reset();
1653 int SynthConfig::equivalent(SynthConfig &that)
1655 //printf("SynthConfig::equivalent %d %d\n", base_freq, that.base_freq);
1656 if(base_freq != that.base_freq ||
1657 wavefunction != that.wavefunction ||
1658 oscillator_config.total != that.oscillator_config.total) return 0;
1660 for(int i = 0; i < oscillator_config.total; i++)
1662 if(!oscillator_config.values[i]->equivalent(*that.oscillator_config.values[i]))
1669 void SynthConfig::copy_from(SynthConfig& that)
1671 wetness = that.wetness;
1672 base_freq = that.base_freq;
1673 wavefunction = that.wavefunction;
1677 i < oscillator_config.total && i < that.oscillator_config.total;
1680 oscillator_config.values[i]->copy_from(*that.oscillator_config.values[i]);
1684 i < that.oscillator_config.total;
1687 oscillator_config.append(new SynthOscillatorConfig(i));
1688 oscillator_config.values[i]->copy_from(*that.oscillator_config.values[i]);
1692 i < oscillator_config.total;
1695 oscillator_config.remove_object();
1699 void SynthConfig::interpolate(SynthConfig &prev,
1703 int64_t current_frame)
1705 double next_scale = (double)(current_frame - prev_frame) / (next_frame - prev_frame);
1706 double prev_scale = (double)(next_frame - current_frame) / (next_frame - prev_frame);
1709 wetness = (int)(prev.wetness * prev_scale + next.wetness * next_scale);
1710 base_freq = (int)(prev.base_freq * prev_scale + next.base_freq * next_scale);