4 * Copyright (C) 2008 Adam Williams <broadcast at earthling dot net>
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.
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.
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
22 #include "bcdisplayinfo.h"
34 REGISTER_PLUGIN(Piano)
40 Piano::Piano(PluginServer *server)
41 : PluginAClient(server)
50 if(dsp_buffer) delete [] dsp_buffer;
54 char* Piano::plugin_title() { return N_("Pianoesizer"); }
55 int Piano::is_realtime() { return 1; }
56 int Piano::is_synthesis() { return 1; }
69 LOAD_CONFIGURATION_MACRO(Piano, PianoConfig)
75 void Piano::read_data(KeyFrame *keyframe)
78 // cause htal file to read directly from text
79 input.set_shared_input(keyframe->xbuf);
81 //printf("Piano::read_data %s\n", keyframe->get_data());
82 int result = 0, current_osc = 0, total_oscillators = 0;
85 result = input.read_tag();
89 if(input.tag.title_is("SYNTH"))
91 config.wetness = input.tag.get_property("WETNESS", config.wetness);
92 config.base_freq = input.tag.get_property("BASEFREQ", config.base_freq);
93 config.wavefunction = input.tag.get_property("WAVEFUNCTION", config.wavefunction);
94 total_oscillators = input.tag.get_property("OSCILLATORS", 0);
97 if(input.tag.title_is("OSCILLATOR"))
99 if(current_osc >= config.oscillator_config.total)
100 config.oscillator_config.append(new PianoOscillatorConfig(current_osc));
102 config.oscillator_config.values[current_osc]->read_data(&input);
108 while(config.oscillator_config.total > current_osc)
109 config.oscillator_config.remove_object();
112 void Piano::save_data(KeyFrame *keyframe)
115 // cause htal file to store data directly in text
116 output.set_shared_output(keyframe->xbuf);
118 output.tag.set_title("SYNTH");
119 output.tag.set_property("WETNESS", config.wetness);
120 output.tag.set_property("BASEFREQ", config.base_freq);
121 output.tag.set_property("WAVEFUNCTION", config.wavefunction);
122 output.tag.set_property("OSCILLATORS", config.oscillator_config.total);
124 output.append_newline();
126 for(int i = 0; i < config.oscillator_config.total; i++)
128 config.oscillator_config.values[i]->save_data(&output);
131 output.tag.set_title("/SYNTH");
133 output.append_newline();
134 output.terminate_string();
135 // data is now in *text
138 int Piano::show_gui()
140 load_configuration();
142 thread = new PianoThread(this);
147 int Piano::set_string()
150 thread->window->set_title(gui_string);
154 void Piano::raise_window()
158 thread->window->raise_window();
159 thread->window->flush();
163 void Piano::update_gui()
165 if( !thread ) return;
166 PianoWindow *window = (PianoWindow *)thread->window:
167 // load_configuration,read_data deletes oscillator_config
168 window->lock_window("Piano::update_gui");
169 load_configuration();
170 window->update_gui();
171 window->unlock_window();
175 void Piano::add_oscillator()
177 if(config.oscillator_config.total > 20) return;
179 config.oscillator_config.append(new PianoOscillatorConfig(config.oscillator_config.total - 1));
182 void Piano::delete_oscillator()
184 if(config.oscillator_config.total)
186 config.oscillator_config.remove_object();
191 double Piano::get_total_power()
195 if(config.wavefunction == DC) return 1.0;
197 for(int i = 0; i < config.oscillator_config.total; i++)
199 result += db.fromdb(config.oscillator_config.values[i]->level);
202 if(result == 0) result = 1; // prevent division by 0
207 double Piano::solve_eqn(double *output,
210 double normalize_constant,
213 PianoOscillatorConfig *config = this->config.oscillator_config.values[oscillator];
214 if(config->level <= INFINITYGAIN) return 0;
218 double power = this->db.fromdb(config->level) * normalize_constant;
219 double phase_offset = config->phase * this->period;
220 double x3 = x1 + phase_offset;
221 double x4 = x2 + phase_offset;
222 double period = this->period / config->freq_factor;
225 switch(this->config.wavefunction)
228 for(sample = (int)x1, x = x3; x < x4; x++, sample++)
230 output[sample] += power;
234 for(sample = (int)x1, x = x3; x < x4; x++, sample++)
236 output[sample] += sin(x / period * 2 * M_PI) * power;
240 for(sample = (int)x1, x = x3; x < x4; x++, sample++)
242 output[sample] += function_sawtooth(x / period) * power;
246 for(sample = (int)x1, x = x3; x < x4; x++, sample++)
248 output[sample] += function_square(x / period) * power;
252 for(sample = (int)x1, x = x3; x < x4; x++, sample++)
254 output[sample] += function_triangle(x / period) * power;
258 for(sample = (int)x1, x = x3; x < x4; x++, sample++)
260 output[sample] += function_pulse(x / period) * power;
264 for(sample = (int)x1, x = x3; x < x4; x++, sample++)
266 output[sample] += function_noise() * power;
272 double Piano::get_point(float x, double normalize_constant)
275 for(int i = 0; i < config.oscillator_config.total; i++)
276 result += get_oscillator_point(x, normalize_constant, i);
281 double Piano::get_oscillator_point(float x,
282 double normalize_constant,
285 PianoOscillatorConfig *config = this->config.oscillator_config.values[oscillator];
286 double power = db.fromdb(config->level) * normalize_constant;
287 switch(this->config.wavefunction)
293 return sin((x + config->phase) * config->freq_factor * 2 * M_PI) * power;
296 return function_sawtooth((x + config->phase) * config->freq_factor) * power;
299 return function_square((x + config->phase) * config->freq_factor) * power;
302 return function_triangle((x + config->phase) * config->freq_factor) * power;
305 return function_pulse((x + config->phase) * config->freq_factor) * power;
308 return function_noise() * power;
313 double Piano::function_square(double x)
315 x -= (int)x; // only fraction counts
316 return (x < .5) ? -1 : 1;
319 double Piano::function_pulse(double x)
321 x -= (int)x; // only fraction counts
322 return (x < .5) ? 0 : 1;
325 double Piano::function_noise()
327 return (double)(rand() % 65536 - 32768) / 32768;
330 double Piano::function_sawtooth(double x)
336 double Piano::function_triangle(double x)
339 return (x < .5) ? 1 - x * 4 : -3 + x * 4;
342 int Piano::process_realtime(int64_t size, double *input_ptr, double *output_ptr)
346 need_reconfigure |= load_configuration();
347 if(need_reconfigure) reconfigure();
349 double wetness = DB::fromdb(config.wetness);
350 if(EQUIV(config.wetness, INFINITYGAIN)) wetness = 0;
352 for(int j = 0; j < size; j++)
353 output_ptr[j] = input_ptr[j] * wetness;
355 int64_t fragment_len;
356 for(int64_t i = 0; i < size; i += fragment_len)
359 if(i + fragment_len > size) fragment_len = size - i;
361 //printf("Piano::process_realtime 1 %d %d %d\n", i, fragment_len, size);
362 fragment_len = overlay_synth(i, fragment_len, input_ptr, output_ptr);
363 //printf("Piano::process_realtime 2\n");
370 int Piano::overlay_synth(int64_t start, int64_t length, double *input, double *output)
372 if(waveform_sample + length > waveform_length)
373 length = waveform_length - waveform_sample;
375 //printf("Piano::overlay_synth 1 %d %d\n", length, waveform_length);
377 // calculate some more data
378 // only calculate what's needed to speed it up
379 if(waveform_sample + length > samples_rendered)
381 int64_t start = waveform_sample, end = waveform_sample + length;
382 for(int i = start; i < end; i++) dsp_buffer[i] = 0;
384 double normalize_constant = 1 / get_total_power();
385 for(int i = 0; i < config.oscillator_config.total; i++)
386 solve_eqn(dsp_buffer,
393 samples_rendered = end;
395 //printf("Piano::overlay_synth 2\n");
398 double *buffer_in = &input[start];
399 double *buffer_out = &output[start];
401 for(int i = 0; i < length; i++)
403 buffer_out[i] += dsp_buffer[waveform_sample++];
405 //printf("Piano::overlay_synth 3\n");
407 if(waveform_sample >= waveform_length) waveform_sample = 0;
412 void Piano::reconfigure()
414 need_reconfigure = 0;
418 delete [] dsp_buffer;
421 //printf("Piano::reconfigure 1 %d\n", PluginAClient::project_sample_rate);
422 waveform_length = PluginAClient::project_sample_rate;
423 period = (float)PluginAClient::project_sample_rate / config.base_freq;
424 dsp_buffer = new double[waveform_length + 1];
426 samples_rendered = 0; // do some calculations on the next process_realtime
450 PianoThread::PianoThread(Piano *synth)
458 PianoThread::~PianoThread()
463 void PianoThread::run()
466 window = new PianoWindow(synth,
467 info.get_abs_cursor_x() - xS(125),
468 info.get_abs_cursor_y() - yS(115));
469 window->create_objects();
470 int result = window->run_window();
472 // Last command executed in thread
473 if(result) synth->client_side_close();
486 PianoWindow::PianoWindow(Piano *synth, int x, int y)
487 : BC_Window(synth->gui_string, x, y, xS(380), synth->h,
488 xS(380), yS(10), 1, 0, 1)
493 PianoWindow::~PianoWindow()
497 int PianoWindow::create_objects()
500 add_subwindow(menu = new BC_MenuBar(0, 0, get_w()));
502 BC_Menu *levelmenu, *phasemenu, *harmonicmenu;
503 menu->add_menu(levelmenu = new BC_Menu(_("Level")));
504 menu->add_menu(phasemenu = new BC_Menu(_("Phase")));
505 menu->add_menu(harmonicmenu = new BC_Menu(_("Harmonic")));
507 levelmenu->add_item(new PianoLevelInvert(synth));
508 levelmenu->add_item(new PianoLevelMax(synth));
509 levelmenu->add_item(new PianoLevelRandom(synth));
510 levelmenu->add_item(new PianoLevelSine(synth));
511 levelmenu->add_item(new PianoLevelSlope(synth));
512 levelmenu->add_item(new PianoLevelZero(synth));
514 phasemenu->add_item(new PianoPhaseInvert(synth));
515 phasemenu->add_item(new PianoPhaseRandom(synth));
516 phasemenu->add_item(new PianoPhaseSine(synth));
517 phasemenu->add_item(new PianoPhaseZero(synth));
519 harmonicmenu->add_item(new PianoFreqEnum(synth));
520 harmonicmenu->add_item(new PianoFreqEven(synth));
521 harmonicmenu->add_item(new PianoFreqFibonacci(synth));
522 harmonicmenu->add_item(new PianoFreqOdd(synth));
523 harmonicmenu->add_item(new PianoFreqPrime(synth));
525 int xs10 = xS(10), xs240 = xS(240);
526 int ys10 = yS(10), ys20 = yS(20), ys30 = yS(30), ys35 = yS(35);
527 int x = xs10, y = ys30, i;
528 add_subwindow(new BC_Title(x, y, _("Waveform")));
530 add_subwindow(new BC_Title(x, y, _("Wave Function")));
533 add_subwindow(canvas = new PianoCanvas(synth, this, x, y, xS(230), yS(160)));
537 char string[BCTEXTLEN];
538 waveform_to_text(string, synth->config.wavefunction);
540 add_subwindow(waveform = new PianoWaveForm(synth, x, y, string));
541 waveform->create_objects();
545 add_subwindow(new BC_Title(x, y, _("Base Frequency:")));
547 add_subwindow(base_freq = new PianoBaseFreq(synth, x, y));
549 add_subwindow(freqpot = new PianoFreqPot(synth, this, x, y - ys10));
550 base_freq->freq_pot = freqpot;
551 freqpot->freq_text = base_freq;
554 add_subwindow(new BC_Title(x, y, _("Wetness:")));
555 add_subwindow(wetness = new PianoWetness(synth, x + xs70, y - ys10));
558 add_subwindow(new PianoClear(synth, x, y));
563 add_subwindow(new BC_Title(x, y, _("Level")));
565 add_subwindow(new BC_Title(x, y, _("Phase")));
567 add_subwindow(new BC_Title(x, y, _("Harmonic")));
572 add_subwindow(subwindow = new PianoSubWindow(synth, x, y, xS(265), get_h() - y));
574 add_subwindow(scroll = new PianoScroll(synth, this, x, y, get_h() - y));
578 add_subwindow(new PianoAddOsc(synth, this, x, y));
580 add_subwindow(new PianoDelOsc(synth, this, x, y));
583 update_oscillators();
590 int PianoWindow::close_event()
592 // Set result to 1 to indicate a client side close
597 int PianoWindow::resize_event(int w, int h)
599 clear_box(0, 0, w, h);
600 subwindow->reposition_window(subwindow->get_x(),
603 h - subwindow->get_y());
604 subwindow->clear_box(0, 0, subwindow->get_w(), subwindow->get_h());
605 scroll->reposition_window(scroll->get_x(),
607 h - scroll->get_y());
609 update_oscillators();
615 void PianoWindow::update_gui()
617 char string[BCTEXTLEN];
618 freqpot->update(synth->config.base_freq);
619 base_freq->update((int64_t)synth->config.base_freq);
620 wetness->update(synth->config.wetness);
621 waveform_to_text(string, synth->config.wavefunction);
622 waveform->set_text(string);
625 update_oscillators();
629 void PianoWindow::update_scrollbar()
631 scroll->update_length(synth->config.oscillator_config.total * OSCILLATORHEIGHT,
632 scroll->get_position(),
636 void PianoWindow::update_oscillators()
638 int i, y = -scroll->get_position();
642 // Add new oscillators
644 i < synth->config.oscillator_config.total;
648 PianoOscillatorConfig *config = synth->config.oscillator_config.values[i];
650 if(oscillators.total <= i)
652 oscillators.append(gui = new PianoOscGUI(this, i));
653 gui->create_objects(y);
657 gui = oscillators.values[i];
659 gui->title->reposition_window(gui->title->get_x(), y + yS(15));
661 gui->level->reposition_window(gui->level->get_x(), y);
662 gui->level->update(config->level);
664 gui->phase->reposition_window(gui->phase->get_x(), y);
665 gui->phase->update((int64_t)(config->phase * 360));
667 gui->freq->reposition_window(gui->freq->get_x(), y);
668 gui->freq->update((int64_t)(config->freq_factor));
670 y += OSCILLATORHEIGHT;
673 // Delete old oscillators
675 i < oscillators.total;
677 oscillators.remove_object();
681 int PianoWindow::waveform_to_text(char *text, int waveform)
685 case DC: sprintf(text, _("DC")); break;
686 case SINE: sprintf(text, _("Sine")); break;
687 case SAWTOOTH: sprintf(text, _("Sawtooth")); break;
688 case SQUARE: sprintf(text, _("Square")); break;
689 case TRIANGLE: sprintf(text, _("Triangle")); break;
690 case PULSE: sprintf(text, _("Pulse")); break;
691 case NOISE: sprintf(text, _("Noise")); break;
702 PianoOscGUI::PianoOscGUI(PianoWindow *window, int number)
704 this->window = window;
705 this->number = number;
708 PianoOscGUI::~PianoOscGUI()
716 int PianoOscGUI::create_objects(int y)
718 char text[BCTEXTLEN];
719 sprintf(text, "%d:", number + 1);
720 window->subwindow->add_subwindow(title = new BC_Title(xs10, y + ys15, text));
722 window->subwindow->add_subwindow(level = new PianoOscGUILevel(window->synth, this, y));
723 window->subwindow->add_subwindow(phase = new PianoOscGUIPhase(window->synth, this, y));
724 window->subwindow->add_subwindow(freq = new PianoOscGUIFreq(window->synth, this, y));
731 PianoOscGUILevel::PianoOscGUILevel(Piano *synth, PianoOscGUI *gui, int y)
734 synth->config.oscillator_config.values[gui->number]->level,
742 PianoOscGUILevel::~PianoOscGUILevel()
746 int PianoOscGUILevel::handle_event()
748 PianoOscillatorConfig *config = synth->config.oscillator_config.values[gui->number];
749 config->level = get_value();
750 gui->window->canvas->update();
751 synth->send_configure_change();
757 PianoOscGUIPhase::PianoOscGUIPhase(Piano *synth, PianoOscGUI *gui, int y)
760 (int64_t)(synth->config.oscillator_config.values[gui->number]->phase * 360),
768 PianoOscGUIPhase::~PianoOscGUIPhase()
772 int PianoOscGUIPhase::handle_event()
774 PianoOscillatorConfig *config = synth->config.oscillator_config.values[gui->number];
775 config->phase = (float)get_value() / 360;
776 gui->window->canvas->update();
777 synth->send_configure_change();
783 PianoOscGUIFreq::PianoOscGUIFreq(Piano *synth, PianoOscGUI *gui, int y)
786 (int64_t)(synth->config.oscillator_config.values[gui->number]->freq_factor),
794 PianoOscGUIFreq::~PianoOscGUIFreq()
798 int PianoOscGUIFreq::handle_event()
800 PianoOscillatorConfig *config = synth->config.oscillator_config.values[gui->number];
801 config->freq_factor = get_value();
802 gui->window->canvas->update();
803 synth->send_configure_change();
813 PianoAddOsc::PianoAddOsc(Piano *synth, PianoWindow *window, int x, int y)
814 : BC_GenericButton(x, y, _("Add"))
817 this->window = window;
820 PianoAddOsc::~PianoAddOsc()
824 int PianoAddOsc::handle_event()
826 synth->add_oscillator();
827 synth->send_configure_change();
828 window->update_gui();
834 PianoDelOsc::PianoDelOsc(Piano *synth, PianoWindow *window, int x, int y)
835 : BC_GenericButton(x, y, _("Delete"))
838 this->window = window;
841 PianoDelOsc::~PianoDelOsc()
845 int PianoDelOsc::handle_event()
847 synth->delete_oscillator();
848 synth->send_configure_change();
849 window->update_gui();
854 PianoScroll::PianoScroll(Piano *synth,
863 synth->config.oscillator_config.total * OSCILLATORHEIGHT,
865 window->subwindow->get_h())
868 this->window = window;
871 PianoScroll::~PianoScroll()
875 int PianoScroll::handle_event()
877 window->update_gui();
888 PianoSubWindow::PianoSubWindow(Piano *synth, int x, int y, int w, int h)
889 : BC_SubWindow(x, y, w, h)
893 PianoSubWindow::~PianoSubWindow()
905 PianoClear::PianoClear(Piano *synth, int x, int y)
906 : BC_GenericButton(x, y, _("Clear"))
910 PianoClear::~PianoClear()
913 int PianoClear::handle_event()
915 synth->config.reset();
916 synth->send_configure_change();
926 PianoWaveForm::PianoWaveForm(Piano *synth, int x, int y, char *text)
927 : BC_PopupMenu(x, y, xS(120), text)
932 PianoWaveForm::~PianoWaveForm()
936 int PianoWaveForm::create_objects()
938 // add_item(new PianoWaveFormItem(synth, _("DC"), DC));
939 add_item(new PianoWaveFormItem(synth, _("Sine"), SINE));
940 add_item(new PianoWaveFormItem(synth, _("Sawtooth"), SAWTOOTH));
941 add_item(new PianoWaveFormItem(synth, _("Square"), SQUARE));
942 add_item(new PianoWaveFormItem(synth, _("Triangle"), TRIANGLE));
943 add_item(new PianoWaveFormItem(synth, _("Pulse"), PULSE));
944 add_item(new PianoWaveFormItem(synth, _("Noise"), NOISE));
948 PianoWaveFormItem::PianoWaveFormItem(Piano *synth, char *text, int value)
955 PianoWaveFormItem::~PianoWaveFormItem()
959 int PianoWaveFormItem::handle_event()
961 synth->config.wavefunction = value;
962 synth->thread->window->canvas->update();
963 synth->send_configure_change();
968 PianoWetness::PianoWetness(Piano *synth, int x, int y)
971 synth->config.wetness,
978 int PianoWetness::handle_event()
980 synth->config.wetness = get_value();
981 synth->send_configure_change();
987 PianoFreqPot::PianoFreqPot(Piano *synth, PianoWindow *window, int x, int y)
988 : BC_QPot(x, y, synth->config.base_freq)
992 PianoFreqPot::~PianoFreqPot()
995 int PianoFreqPot::handle_event()
997 if(get_value() > 0 && get_value() < 30000)
999 synth->config.base_freq = get_value();
1000 freq_text->update(get_value());
1001 synth->send_configure_change();
1008 PianoBaseFreq::PianoBaseFreq(Piano *synth, int x, int y)
1009 : BC_TextBox(x, y, xS(70), 1, (int)synth->config.base_freq)
1011 this->synth = synth;
1013 PianoBaseFreq::~PianoBaseFreq()
1016 int PianoBaseFreq::handle_event()
1018 int new_value = atol(get_text());
1020 if(new_value > 0 && new_value < 30000)
1022 synth->config.base_freq = new_value;
1023 freq_pot->update(synth->config.base_freq);
1024 synth->send_configure_change();
1033 PianoCanvas::PianoCanvas(Piano *synth,
1034 PianoWindow *window,
1045 this->synth = synth;
1046 this->window = window;
1049 PianoCanvas::~PianoCanvas()
1053 int PianoCanvas::update()
1057 clear_box(0, 0, get_w(), get_h());
1060 draw_line(0, get_h() / 2 + y, get_w(), get_h() / 2 + y);
1064 double normalize_constant = (double)1 / synth->get_total_power();
1065 y1 = (int)(synth->get_point((float)0, normalize_constant) * get_h() / 2);
1067 for(int i = 1; i < get_w(); i++)
1069 y2 = (int)(synth->get_point((float)i / get_w(), normalize_constant) * get_h() / 2);
1070 draw_line(i - 1, get_h() / 2 - y1, i, get_h() / 2 - y2);
1084 // ======================= level calculations
1085 PianoLevelZero::PianoLevelZero(Piano *synth)
1086 : BC_MenuItem(_("Zero"))
1088 this->synth = synth;
1091 PianoLevelZero::~PianoLevelZero()
1095 int PianoLevelZero::handle_event()
1097 for(int i = 0; i < synth->config.oscillator_config.total; i++)
1099 synth->config.oscillator_config.values[i]->level = INFINITYGAIN;
1102 synth->thread->window->update_gui();
1103 synth->send_configure_change();
1106 PianoLevelMax::PianoLevelMax(Piano *synth)
1107 : BC_MenuItem(_("Maximum"))
1109 this->synth = synth;
1112 PianoLevelMax::~PianoLevelMax()
1116 int PianoLevelMax::handle_event()
1118 for(int i = 0; i < synth->config.oscillator_config.total; i++)
1120 synth->config.oscillator_config.values[i]->level = 0;
1122 synth->thread->window->update_gui();
1123 synth->send_configure_change();
1126 PianoLevelNormalize::PianoLevelNormalize(Piano *synth)
1127 : BC_MenuItem(_("Normalize"))
1129 this->synth = synth;
1132 PianoLevelNormalize::~PianoLevelNormalize()
1136 int PianoLevelNormalize::handle_event()
1141 for(int i = 0; i < synth->config.oscillator_config.total; i++)
1143 total += synth->db.fromdb(synth->config.oscillator_config.values[i]->level);
1146 float scale = 1 / total;
1149 for(int i = 0; i < synth->config.oscillator_config.total; i++)
1151 new_value = synth->db.fromdb(synth->config.oscillator_config.values[i]->level);
1153 new_value = synth->db.todb(new_value);
1155 synth->config.oscillator_config.values[i]->level = new_value;
1158 synth->thread->window->update_gui();
1159 synth->send_configure_change();
1162 PianoLevelSlope::PianoLevelSlope(Piano *synth)
1163 : BC_MenuItem(_("Slope"))
1165 this->synth = synth;
1168 PianoLevelSlope::~PianoLevelSlope()
1172 int PianoLevelSlope::handle_event()
1174 float slope = (float)INFINITYGAIN / synth->config.oscillator_config.total;
1176 for(int i = 0; i < synth->config.oscillator_config.total; i++)
1178 synth->config.oscillator_config.values[i]->level = i * slope;
1181 synth->thread->window->update_gui();
1182 synth->send_configure_change();
1185 PianoLevelRandom::PianoLevelRandom(Piano *synth)
1186 : BC_MenuItem(_("Random"))
1188 this->synth = synth;
1190 PianoLevelRandom::~PianoLevelRandom()
1194 int PianoLevelRandom::handle_event()
1197 for(int i = 0; i < synth->config.oscillator_config.total; i++)
1199 synth->config.oscillator_config.values[i]->level = -(rand() % -INFINITYGAIN);
1202 synth->thread->window->update_gui();
1203 synth->send_configure_change();
1206 PianoLevelInvert::PianoLevelInvert(Piano *synth)
1207 : BC_MenuItem(_("Invert"))
1209 this->synth = synth;
1211 PianoLevelInvert::~PianoLevelInvert()
1215 int PianoLevelInvert::handle_event()
1217 for(int i = 0; i < synth->config.oscillator_config.total; i++)
1219 synth->config.oscillator_config.values[i]->level =
1220 INFINITYGAIN - synth->config.oscillator_config.values[i]->level;
1223 synth->thread->window->update_gui();
1224 synth->send_configure_change();
1227 PianoLevelSine::PianoLevelSine(Piano *synth)
1228 : BC_MenuItem(_("Sine"))
1230 this->synth = synth;
1232 PianoLevelSine::~PianoLevelSine()
1236 int PianoLevelSine::handle_event()
1240 for(int i = 0; i < synth->config.oscillator_config.total; i++)
1242 new_value = (float)i / synth->config.oscillator_config.total * 2 * M_PI;
1243 new_value = sin(new_value) * INFINITYGAIN / 2 + INFINITYGAIN / 2;
1244 synth->config.oscillator_config.values[i]->level = new_value;
1247 synth->thread->window->update_gui();
1248 synth->send_configure_change();
1251 // ============================ phase calculations
1253 PianoPhaseInvert::PianoPhaseInvert(Piano *synth)
1254 : BC_MenuItem(_("Invert"))
1256 this->synth = synth;
1258 PianoPhaseInvert::~PianoPhaseInvert()
1262 int PianoPhaseInvert::handle_event()
1264 for(int i = 0; i < synth->config.oscillator_config.total; i++)
1266 synth->config.oscillator_config.values[i]->phase =
1267 1 - synth->config.oscillator_config.values[i]->phase;
1270 synth->thread->window->update_gui();
1271 synth->send_configure_change();
1274 PianoPhaseZero::PianoPhaseZero(Piano *synth)
1275 : BC_MenuItem(_("Zero"))
1277 this->synth = synth;
1279 PianoPhaseZero::~PianoPhaseZero()
1283 int PianoPhaseZero::handle_event()
1285 for(int i = 0; i < synth->config.oscillator_config.total; i++)
1287 synth->config.oscillator_config.values[i]->phase = 0;
1290 synth->thread->window->update_gui();
1291 synth->send_configure_change();
1294 PianoPhaseSine::PianoPhaseSine(Piano *synth)
1295 : BC_MenuItem(_("Sine"))
1297 this->synth = synth;
1299 PianoPhaseSine::~PianoPhaseSine()
1303 int PianoPhaseSine::handle_event()
1306 for(int i = 0; i < synth->config.oscillator_config.total; i++)
1308 new_value = (float)i / synth->config.oscillator_config.total * 2 * M_PI;
1309 new_value = sin(new_value) / 2 + .5;
1310 synth->config.oscillator_config.values[i]->phase = new_value;
1313 synth->thread->window->update_gui();
1314 synth->send_configure_change();
1317 PianoPhaseRandom::PianoPhaseRandom(Piano *synth)
1318 : BC_MenuItem(_("Random"))
1320 this->synth = synth;
1322 PianoPhaseRandom::~PianoPhaseRandom()
1326 int PianoPhaseRandom::handle_event()
1329 for(int i = 0; i < synth->config.oscillator_config.total; i++)
1331 synth->config.oscillator_config.values[i]->phase =
1332 (float)(rand() % 360) / 360;
1335 synth->thread->window->update_gui();
1336 synth->send_configure_change();
1340 // ============================ freq calculations
1342 PianoFreqRandom::PianoFreqRandom(Piano *synth)
1343 : BC_MenuItem(_("Random"))
1345 this->synth = synth;
1347 PianoFreqRandom::~PianoFreqRandom()
1351 int PianoFreqRandom::handle_event()
1354 for(int i = 0; i < synth->config.oscillator_config.total; i++)
1356 synth->config.oscillator_config.values[i]->freq_factor = rand() % 100;
1359 synth->thread->window->update_gui();
1360 synth->send_configure_change();
1363 PianoFreqEnum::PianoFreqEnum(Piano *synth)
1364 : BC_MenuItem(_("Enumerate"))
1366 this->synth = synth;
1368 PianoFreqEnum::~PianoFreqEnum()
1372 int PianoFreqEnum::handle_event()
1374 for(int i = 0; i < synth->config.oscillator_config.total; i++)
1376 synth->config.oscillator_config.values[i]->freq_factor = (float)i + 1;
1379 synth->thread->window->update_gui();
1380 synth->send_configure_change();
1383 PianoFreqEven::PianoFreqEven(Piano *synth)
1384 : BC_MenuItem(_("Even"))
1386 this->synth = synth;
1388 PianoFreqEven::~PianoFreqEven()
1392 int PianoFreqEven::handle_event()
1394 if(synth->config.oscillator_config.total)
1395 synth->config.oscillator_config.values[0]->freq_factor = (float)1;
1397 for(int i = 1; i < synth->config.oscillator_config.total; i++)
1399 synth->config.oscillator_config.values[i]->freq_factor = (float)i * 2;
1402 synth->thread->window->update_gui();
1403 synth->send_configure_change();
1406 PianoFreqOdd::PianoFreqOdd(Piano *synth)
1407 : BC_MenuItem(_("Odd"))
1408 { this->synth = synth; }
1409 PianoFreqOdd::~PianoFreqOdd()
1413 int PianoFreqOdd::handle_event()
1415 for(int i = 0; i < synth->config.oscillator_config.total; i++)
1417 synth->config.oscillator_config.values[i]->freq_factor = (float)1 + i * 2;
1420 synth->thread->window->update_gui();
1421 synth->send_configure_change();
1424 PianoFreqFibonacci::PianoFreqFibonacci(Piano *synth)
1425 : BC_MenuItem(_("Fibonnacci"))
1427 this->synth = synth;
1429 PianoFreqFibonacci::~PianoFreqFibonacci()
1433 int PianoFreqFibonacci::handle_event()
1435 float last_value1 = 0, last_value2 = 1;
1436 for(int i = 0; i < synth->config.oscillator_config.total; i++)
1438 synth->config.oscillator_config.values[i]->freq_factor = last_value1 + last_value2;
1439 if(synth->config.oscillator_config.values[i]->freq_factor > 100) synth->config.oscillator_config.values[i]->freq_factor = 100;
1440 last_value1 = last_value2;
1441 last_value2 = synth->config.oscillator_config.values[i]->freq_factor;
1444 synth->thread->window->update_gui();
1445 synth->send_configure_change();
1448 PianoFreqPrime::PianoFreqPrime(Piano *synth)
1449 : BC_MenuItem(_("Prime"))
1451 this->synth = synth;
1453 PianoFreqPrime::~PianoFreqPrime()
1457 int PianoFreqPrime::handle_event()
1460 for(int i = 0; i < synth->config.oscillator_config.total; i++)
1462 synth->config.oscillator_config.values[i]->freq_factor = number;
1463 number = get_next_prime(number);
1466 synth->thread->window->update_gui();
1467 synth->send_configure_change();
1470 float PianoFreqPrime::get_next_prime(float number)
1479 for(float i = number - 1; i > 1 && !result; i--)
1481 if((number / i) - (int)(number / i) == 0) result = 1;
1495 PianoOscillatorConfig::PianoOscillatorConfig(int number)
1498 this->number = number;
1501 PianoOscillatorConfig::~PianoOscillatorConfig()
1505 void PianoOscillatorConfig::reset()
1512 void PianoOscillatorConfig::read_data(FileXML *file)
1514 level = file->tag.get_property("LEVEL", (float)level);
1515 phase = file->tag.get_property("PHASE", (float)phase);
1516 freq_factor = file->tag.get_property("FREQFACTOR", (float)freq_factor);
1519 void PianoOscillatorConfig::save_data(FileXML *file)
1521 file->tag.set_title("OSCILLATOR");
1522 file->tag.set_property("LEVEL", (float)level);
1523 file->tag.set_property("PHASE", (float)phase);
1524 file->tag.set_property("FREQFACTOR", (float)freq_factor);
1526 file->tag.set_title("/OSCILLATOR");
1528 file->append_newline();
1531 int PianoOscillatorConfig::equivalent(PianoOscillatorConfig &that)
1533 if(EQUIV(level, that.level) &&
1534 EQUIV(phase, that.phase) &&
1535 EQUIV(freq_factor, that.freq_factor))
1541 void PianoOscillatorConfig::copy_from(PianoOscillatorConfig& that)
1545 freq_factor = that.freq_factor;
1559 PianoConfig::PianoConfig()
1564 PianoConfig::~PianoConfig()
1566 oscillator_config.remove_all_objects();
1569 void PianoConfig::reset()
1573 wavefunction = SINE;
1574 for(int i = 0; i < oscillator_config.total; i++)
1576 oscillator_config.values[i]->reset();
1580 int PianoConfig::equivalent(PianoConfig &that)
1582 //printf("PianoConfig::equivalent %d %d\n", base_freq, that.base_freq);
1583 if(base_freq != that.base_freq ||
1584 wavefunction != that.wavefunction ||
1585 oscillator_config.total != that.oscillator_config.total) return 0;
1587 for(int i = 0; i < oscillator_config.total; i++)
1589 if(!oscillator_config.values[i]->equivalent(*that.oscillator_config.values[i]))
1596 void PianoConfig::copy_from(PianoConfig& that)
1598 wetness = that.wetness;
1599 base_freq = that.base_freq;
1600 wavefunction = that.wavefunction;
1604 i < oscillator_config.total && i < that.oscillator_config.total;
1607 oscillator_config.values[i]->copy_from(*that.oscillator_config.values[i]);
1611 i < that.oscillator_config.total;
1614 oscillator_config.append(new PianoOscillatorConfig(i));
1615 oscillator_config.values[i]->copy_from(*that.oscillator_config.values[i]);
1619 i < oscillator_config.total;
1622 oscillator_config.remove_object();
1626 void PianoConfig::interpolate(PianoConfig &prev,
1630 int64_t current_frame)
1632 double next_scale = (double)(current_frame - prev_frame) / (next_frame - prev_frame);
1633 double prev_scale = (double)(next_frame - current_frame) / (next_frame - prev_frame);
1636 wetness = (int)(prev.wetness * prev_scale + next.wetness * next_scale);
1637 base_freq = (int)(prev.base_freq * prev_scale + next.base_freq * next_scale);