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 _("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->get_data(), strlen(keyframe->get_data()));
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->get_data(), MESSAGESIZE);
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.terminate_string();
132 // data is now in *text
135 int Piano::show_gui()
137 load_configuration();
139 thread = new PianoThread(this);
144 int Piano::set_string()
146 if(thread) thread->window->set_title(gui_string);
150 void Piano::raise_window()
154 thread->window->raise_window();
155 thread->window->flush();
159 void Piano::update_gui()
163 load_configuration();
164 thread->window->lock_window();
165 thread->window->update_gui();
166 thread->window->unlock_window();
171 void Piano::add_oscillator()
173 if(config.oscillator_config.total > 20) return;
175 config.oscillator_config.append(new PianoOscillatorConfig(config.oscillator_config.total - 1));
178 void Piano::delete_oscillator()
180 if(config.oscillator_config.total)
182 config.oscillator_config.remove_object();
187 double Piano::get_total_power()
191 if(config.wavefunction == DC) return 1.0;
193 for(int i = 0; i < config.oscillator_config.total; i++)
195 result += db.fromdb(config.oscillator_config.values[i]->level);
198 if(result == 0) result = 1; // prevent division by 0
203 double Piano::solve_eqn(double *output,
206 double normalize_constant,
209 PianoOscillatorConfig *config = this->config.oscillator_config.values[oscillator];
210 if(config->level <= INFINITYGAIN) return 0;
214 double power = this->db.fromdb(config->level) * normalize_constant;
215 double phase_offset = config->phase * this->period;
216 double x3 = x1 + phase_offset;
217 double x4 = x2 + phase_offset;
218 double period = this->period / config->freq_factor;
221 switch(this->config.wavefunction)
224 for(sample = (int)x1, x = x3; x < x4; x++, sample++)
226 output[sample] += power;
230 for(sample = (int)x1, x = x3; x < x4; x++, sample++)
232 output[sample] += sin(x / period * 2 * M_PI) * power;
236 for(sample = (int)x1, x = x3; x < x4; x++, sample++)
238 output[sample] += function_sawtooth(x / period) * power;
242 for(sample = (int)x1, x = x3; x < x4; x++, sample++)
244 output[sample] += function_square(x / period) * power;
248 for(sample = (int)x1, x = x3; x < x4; x++, sample++)
250 output[sample] += function_triangle(x / period) * power;
254 for(sample = (int)x1, x = x3; x < x4; x++, sample++)
256 output[sample] += function_pulse(x / period) * power;
260 for(sample = (int)x1, x = x3; x < x4; x++, sample++)
262 output[sample] += function_noise() * power;
268 double Piano::get_point(float x, double normalize_constant)
271 for(int i = 0; i < config.oscillator_config.total; i++)
272 result += get_oscillator_point(x, normalize_constant, i);
277 double Piano::get_oscillator_point(float x,
278 double normalize_constant,
281 PianoOscillatorConfig *config = this->config.oscillator_config.values[oscillator];
282 double power = db.fromdb(config->level) * normalize_constant;
283 switch(this->config.wavefunction)
289 return sin((x + config->phase) * config->freq_factor * 2 * M_PI) * power;
292 return function_sawtooth((x + config->phase) * config->freq_factor) * power;
295 return function_square((x + config->phase) * config->freq_factor) * power;
298 return function_triangle((x + config->phase) * config->freq_factor) * power;
301 return function_pulse((x + config->phase) * config->freq_factor) * power;
304 return function_noise() * power;
309 double Piano::function_square(double x)
311 x -= (int)x; // only fraction counts
312 return (x < .5) ? -1 : 1;
315 double Piano::function_pulse(double x)
317 x -= (int)x; // only fraction counts
318 return (x < .5) ? 0 : 1;
321 double Piano::function_noise()
323 return (double)(rand() % 65536 - 32768) / 32768;
326 double Piano::function_sawtooth(double x)
332 double Piano::function_triangle(double x)
335 return (x < .5) ? 1 - x * 4 : -3 + x * 4;
338 int Piano::process_realtime(int64_t size, double *input_ptr, double *output_ptr)
342 need_reconfigure |= load_configuration();
343 if(need_reconfigure) reconfigure();
345 double wetness = DB::fromdb(config.wetness);
346 if(EQUIV(config.wetness, INFINITYGAIN)) wetness = 0;
348 for(int j = 0; j < size; j++)
349 output_ptr[j] = input_ptr[j] * wetness;
351 int64_t fragment_len;
352 for(int64_t i = 0; i < size; i += fragment_len)
355 if(i + fragment_len > size) fragment_len = size - i;
357 //printf("Piano::process_realtime 1 %d %d %d\n", i, fragment_len, size);
358 fragment_len = overlay_synth(i, fragment_len, input_ptr, output_ptr);
359 //printf("Piano::process_realtime 2\n");
366 int Piano::overlay_synth(int64_t start, int64_t length, double *input, double *output)
368 if(waveform_sample + length > waveform_length)
369 length = waveform_length - waveform_sample;
371 //printf("Piano::overlay_synth 1 %d %d\n", length, waveform_length);
373 // calculate some more data
374 // only calculate what's needed to speed it up
375 if(waveform_sample + length > samples_rendered)
377 int64_t start = waveform_sample, end = waveform_sample + length;
378 for(int i = start; i < end; i++) dsp_buffer[i] = 0;
380 double normalize_constant = 1 / get_total_power();
381 for(int i = 0; i < config.oscillator_config.total; i++)
382 solve_eqn(dsp_buffer,
389 samples_rendered = end;
391 //printf("Piano::overlay_synth 2\n");
394 double *buffer_in = &input[start];
395 double *buffer_out = &output[start];
397 for(int i = 0; i < length; i++)
399 buffer_out[i] += dsp_buffer[waveform_sample++];
401 //printf("Piano::overlay_synth 3\n");
403 if(waveform_sample >= waveform_length) waveform_sample = 0;
408 void Piano::reconfigure()
410 need_reconfigure = 0;
414 delete [] dsp_buffer;
417 //printf("Piano::reconfigure 1 %d\n", PluginAClient::project_sample_rate);
418 waveform_length = PluginAClient::project_sample_rate;
419 period = (float)PluginAClient::project_sample_rate / config.base_freq;
420 dsp_buffer = new double[waveform_length + 1];
422 samples_rendered = 0; // do some calculations on the next process_realtime
446 PianoThread::PianoThread(Piano *synth)
454 PianoThread::~PianoThread()
459 void PianoThread::run()
462 window = new PianoWindow(synth,
463 info.get_abs_cursor_x() - 125,
464 info.get_abs_cursor_y() - 115);
465 window->create_objects();
466 int result = window->run_window();
468 // Last command executed in thread
469 if(result) synth->client_side_close();
482 PianoWindow::PianoWindow(Piano *synth, int x, int y)
483 : BC_Window(synth->gui_string,
497 PianoWindow::~PianoWindow()
501 int PianoWindow::create_objects()
504 add_subwindow(menu = new BC_MenuBar(0, 0, get_w()));
506 BC_Menu *levelmenu, *phasemenu, *harmonicmenu;
507 menu->add_menu(levelmenu = new BC_Menu(_("Level")));
508 menu->add_menu(phasemenu = new BC_Menu(_("Phase")));
509 menu->add_menu(harmonicmenu = new BC_Menu(_("Harmonic")));
511 levelmenu->add_item(new PianoLevelInvert(synth));
512 levelmenu->add_item(new PianoLevelMax(synth));
513 levelmenu->add_item(new PianoLevelRandom(synth));
514 levelmenu->add_item(new PianoLevelSine(synth));
515 levelmenu->add_item(new PianoLevelSlope(synth));
516 levelmenu->add_item(new PianoLevelZero(synth));
518 phasemenu->add_item(new PianoPhaseInvert(synth));
519 phasemenu->add_item(new PianoPhaseRandom(synth));
520 phasemenu->add_item(new PianoPhaseSine(synth));
521 phasemenu->add_item(new PianoPhaseZero(synth));
523 harmonicmenu->add_item(new PianoFreqEnum(synth));
524 harmonicmenu->add_item(new PianoFreqEven(synth));
525 harmonicmenu->add_item(new PianoFreqFibonacci(synth));
526 harmonicmenu->add_item(new PianoFreqOdd(synth));
527 harmonicmenu->add_item(new PianoFreqPrime(synth));
529 int x = 10, y = 30, i;
530 add_subwindow(new BC_Title(x, y, _("Waveform")));
532 add_subwindow(new BC_Title(x, y, _("Wave Function")));
535 add_subwindow(canvas = new PianoCanvas(synth, this, x, y, 230, 160));
539 char string[BCTEXTLEN];
540 waveform_to_text(string, synth->config.wavefunction);
542 add_subwindow(waveform = new PianoWaveForm(synth, x, y, string));
543 waveform->create_objects();
547 add_subwindow(new BC_Title(x, y, _("Base Frequency:")));
549 add_subwindow(base_freq = new PianoBaseFreq(synth, x, y));
551 add_subwindow(freqpot = new PianoFreqPot(synth, this, x, y - 10));
552 base_freq->freq_pot = freqpot;
553 freqpot->freq_text = base_freq;
556 add_subwindow(new BC_Title(x, y, _("Wetness:")));
557 add_subwindow(wetness = new PianoWetness(synth, x + 70, y - 10));
560 add_subwindow(new PianoClear(synth, x, y));
565 add_subwindow(new BC_Title(x, y, _("Level")));
567 add_subwindow(new BC_Title(x, y, _("Phase")));
569 add_subwindow(new BC_Title(x, y, _("Harmonic")));
574 add_subwindow(subwindow = new PianoSubWindow(synth, x, y, 265, get_h() - y));
576 add_subwindow(scroll = new PianoScroll(synth, this, x, y, get_h() - y));
580 add_subwindow(new PianoAddOsc(synth, this, x, y));
582 add_subwindow(new PianoDelOsc(synth, this, x, y));
585 update_oscillators();
592 int PianoWindow::close_event()
594 // Set result to 1 to indicate a client side close
599 int PianoWindow::resize_event(int w, int h)
601 clear_box(0, 0, w, h);
602 subwindow->reposition_window(subwindow->get_x(),
605 h - subwindow->get_y());
606 subwindow->clear_box(0, 0, subwindow->get_w(), subwindow->get_h());
607 scroll->reposition_window(scroll->get_x(),
609 h - scroll->get_y());
611 update_oscillators();
617 void PianoWindow::update_gui()
619 char string[BCTEXTLEN];
620 freqpot->update(synth->config.base_freq);
621 base_freq->update((int64_t)synth->config.base_freq);
622 wetness->update(synth->config.wetness);
623 waveform_to_text(string, synth->config.wavefunction);
624 waveform->set_text(string);
627 update_oscillators();
631 void PianoWindow::update_scrollbar()
633 scroll->update_length(synth->config.oscillator_config.total * OSCILLATORHEIGHT,
634 scroll->get_position(),
638 void PianoWindow::update_oscillators()
640 int i, y = -scroll->get_position();
644 // Add new oscillators
646 i < synth->config.oscillator_config.total;
650 PianoOscillatorConfig *config = synth->config.oscillator_config.values[i];
652 if(oscillators.total <= i)
654 oscillators.append(gui = new PianoOscGUI(this, i));
655 gui->create_objects(y);
659 gui = oscillators.values[i];
661 gui->title->reposition_window(gui->title->get_x(), y + 15);
663 gui->level->reposition_window(gui->level->get_x(), y);
664 gui->level->update(config->level);
666 gui->phase->reposition_window(gui->phase->get_x(), y);
667 gui->phase->update((int64_t)(config->phase * 360));
669 gui->freq->reposition_window(gui->freq->get_x(), y);
670 gui->freq->update((int64_t)(config->freq_factor));
672 y += OSCILLATORHEIGHT;
675 // Delete old oscillators
677 i < oscillators.total;
679 oscillators.remove_object();
683 int PianoWindow::waveform_to_text(char *text, int waveform)
687 case DC: sprintf(text, _("DC")); break;
688 case SINE: sprintf(text, _("Sine")); break;
689 case SAWTOOTH: sprintf(text, _("Sawtooth")); break;
690 case SQUARE: sprintf(text, _("Square")); break;
691 case TRIANGLE: sprintf(text, _("Triangle")); break;
692 case PULSE: sprintf(text, _("Pulse")); break;
693 case NOISE: sprintf(text, _("Noise")); break;
704 PianoOscGUI::PianoOscGUI(PianoWindow *window, int number)
706 this->window = window;
707 this->number = number;
710 PianoOscGUI::~PianoOscGUI()
718 int PianoOscGUI::create_objects(int y)
720 char text[BCTEXTLEN];
721 sprintf(text, "%d:", number + 1);
722 window->subwindow->add_subwindow(title = new BC_Title(10, y + 15, text));
724 window->subwindow->add_subwindow(level = new PianoOscGUILevel(window->synth, this, y));
725 window->subwindow->add_subwindow(phase = new PianoOscGUIPhase(window->synth, this, y));
726 window->subwindow->add_subwindow(freq = new PianoOscGUIFreq(window->synth, this, y));
733 PianoOscGUILevel::PianoOscGUILevel(Piano *synth, PianoOscGUI *gui, int y)
736 synth->config.oscillator_config.values[gui->number]->level,
744 PianoOscGUILevel::~PianoOscGUILevel()
748 int PianoOscGUILevel::handle_event()
750 PianoOscillatorConfig *config = synth->config.oscillator_config.values[gui->number];
751 config->level = get_value();
752 gui->window->canvas->update();
753 synth->send_configure_change();
759 PianoOscGUIPhase::PianoOscGUIPhase(Piano *synth, PianoOscGUI *gui, int y)
762 (int64_t)(synth->config.oscillator_config.values[gui->number]->phase * 360),
770 PianoOscGUIPhase::~PianoOscGUIPhase()
774 int PianoOscGUIPhase::handle_event()
776 PianoOscillatorConfig *config = synth->config.oscillator_config.values[gui->number];
777 config->phase = (float)get_value() / 360;
778 gui->window->canvas->update();
779 synth->send_configure_change();
785 PianoOscGUIFreq::PianoOscGUIFreq(Piano *synth, PianoOscGUI *gui, int y)
788 (int64_t)(synth->config.oscillator_config.values[gui->number]->freq_factor),
796 PianoOscGUIFreq::~PianoOscGUIFreq()
800 int PianoOscGUIFreq::handle_event()
802 PianoOscillatorConfig *config = synth->config.oscillator_config.values[gui->number];
803 config->freq_factor = get_value();
804 gui->window->canvas->update();
805 synth->send_configure_change();
815 PianoAddOsc::PianoAddOsc(Piano *synth, PianoWindow *window, int x, int y)
816 : BC_GenericButton(x, y, _("Add"))
819 this->window = window;
822 PianoAddOsc::~PianoAddOsc()
826 int PianoAddOsc::handle_event()
828 synth->add_oscillator();
829 synth->send_configure_change();
830 window->update_gui();
836 PianoDelOsc::PianoDelOsc(Piano *synth, PianoWindow *window, int x, int y)
837 : BC_GenericButton(x, y, _("Delete"))
840 this->window = window;
843 PianoDelOsc::~PianoDelOsc()
847 int PianoDelOsc::handle_event()
849 synth->delete_oscillator();
850 synth->send_configure_change();
851 window->update_gui();
856 PianoScroll::PianoScroll(Piano *synth,
865 synth->config.oscillator_config.total * OSCILLATORHEIGHT,
867 window->subwindow->get_h())
870 this->window = window;
873 PianoScroll::~PianoScroll()
877 int PianoScroll::handle_event()
879 window->update_gui();
890 PianoSubWindow::PianoSubWindow(Piano *synth, int x, int y, int w, int h)
891 : BC_SubWindow(x, y, w, h)
895 PianoSubWindow::~PianoSubWindow()
907 PianoClear::PianoClear(Piano *synth, int x, int y)
908 : BC_GenericButton(x, y, _("Clear"))
912 PianoClear::~PianoClear()
915 int PianoClear::handle_event()
917 synth->config.reset();
918 synth->send_configure_change();
928 PianoWaveForm::PianoWaveForm(Piano *synth, int x, int y, char *text)
929 : BC_PopupMenu(x, y, 120, text)
934 PianoWaveForm::~PianoWaveForm()
938 int PianoWaveForm::create_objects()
940 // add_item(new PianoWaveFormItem(synth, _("DC"), DC));
941 add_item(new PianoWaveFormItem(synth, _("Sine"), SINE));
942 add_item(new PianoWaveFormItem(synth, _("Sawtooth"), SAWTOOTH));
943 add_item(new PianoWaveFormItem(synth, _("Square"), SQUARE));
944 add_item(new PianoWaveFormItem(synth, _("Triangle"), TRIANGLE));
945 add_item(new PianoWaveFormItem(synth, _("Pulse"), PULSE));
946 add_item(new PianoWaveFormItem(synth, _("Noise"), NOISE));
950 PianoWaveFormItem::PianoWaveFormItem(Piano *synth, char *text, int value)
957 PianoWaveFormItem::~PianoWaveFormItem()
961 int PianoWaveFormItem::handle_event()
963 synth->config.wavefunction = value;
964 synth->thread->window->canvas->update();
965 synth->send_configure_change();
970 PianoWetness::PianoWetness(Piano *synth, int x, int y)
973 synth->config.wetness,
980 int PianoWetness::handle_event()
982 synth->config.wetness = get_value();
983 synth->send_configure_change();
989 PianoFreqPot::PianoFreqPot(Piano *synth, PianoWindow *window, int x, int y)
990 : BC_QPot(x, y, synth->config.base_freq)
994 PianoFreqPot::~PianoFreqPot()
997 int PianoFreqPot::handle_event()
999 if(get_value() > 0 && get_value() < 30000)
1001 synth->config.base_freq = get_value();
1002 freq_text->update(get_value());
1003 synth->send_configure_change();
1010 PianoBaseFreq::PianoBaseFreq(Piano *synth, int x, int y)
1011 : BC_TextBox(x, y, 70, 1, (int)synth->config.base_freq)
1013 this->synth = synth;
1015 PianoBaseFreq::~PianoBaseFreq()
1018 int PianoBaseFreq::handle_event()
1020 int new_value = atol(get_text());
1022 if(new_value > 0 && new_value < 30000)
1024 synth->config.base_freq = new_value;
1025 freq_pot->update(synth->config.base_freq);
1026 synth->send_configure_change();
1035 PianoCanvas::PianoCanvas(Piano *synth,
1036 PianoWindow *window,
1047 this->synth = synth;
1048 this->window = window;
1051 PianoCanvas::~PianoCanvas()
1055 int PianoCanvas::update()
1059 clear_box(0, 0, get_w(), get_h());
1062 draw_line(0, get_h() / 2 + y, get_w(), get_h() / 2 + y);
1066 double normalize_constant = (double)1 / synth->get_total_power();
1067 y1 = (int)(synth->get_point((float)0, normalize_constant) * get_h() / 2);
1069 for(int i = 1; i < get_w(); i++)
1071 y2 = (int)(synth->get_point((float)i / get_w(), normalize_constant) * get_h() / 2);
1072 draw_line(i - 1, get_h() / 2 - y1, i, get_h() / 2 - y2);
1086 // ======================= level calculations
1087 PianoLevelZero::PianoLevelZero(Piano *synth)
1088 : BC_MenuItem(_("Zero"))
1090 this->synth = synth;
1093 PianoLevelZero::~PianoLevelZero()
1097 int PianoLevelZero::handle_event()
1099 for(int i = 0; i < synth->config.oscillator_config.total; i++)
1101 synth->config.oscillator_config.values[i]->level = INFINITYGAIN;
1104 synth->thread->window->update_gui();
1105 synth->send_configure_change();
1108 PianoLevelMax::PianoLevelMax(Piano *synth)
1109 : BC_MenuItem(_("Maximum"))
1111 this->synth = synth;
1114 PianoLevelMax::~PianoLevelMax()
1118 int PianoLevelMax::handle_event()
1120 for(int i = 0; i < synth->config.oscillator_config.total; i++)
1122 synth->config.oscillator_config.values[i]->level = 0;
1124 synth->thread->window->update_gui();
1125 synth->send_configure_change();
1128 PianoLevelNormalize::PianoLevelNormalize(Piano *synth)
1129 : BC_MenuItem(_("Normalize"))
1131 this->synth = synth;
1134 PianoLevelNormalize::~PianoLevelNormalize()
1138 int PianoLevelNormalize::handle_event()
1143 for(int i = 0; i < synth->config.oscillator_config.total; i++)
1145 total += synth->db.fromdb(synth->config.oscillator_config.values[i]->level);
1148 float scale = 1 / total;
1151 for(int i = 0; i < synth->config.oscillator_config.total; i++)
1153 new_value = synth->db.fromdb(synth->config.oscillator_config.values[i]->level);
1155 new_value = synth->db.todb(new_value);
1157 synth->config.oscillator_config.values[i]->level = new_value;
1160 synth->thread->window->update_gui();
1161 synth->send_configure_change();
1164 PianoLevelSlope::PianoLevelSlope(Piano *synth)
1165 : BC_MenuItem(_("Slope"))
1167 this->synth = synth;
1170 PianoLevelSlope::~PianoLevelSlope()
1174 int PianoLevelSlope::handle_event()
1176 float slope = (float)INFINITYGAIN / synth->config.oscillator_config.total;
1178 for(int i = 0; i < synth->config.oscillator_config.total; i++)
1180 synth->config.oscillator_config.values[i]->level = i * slope;
1183 synth->thread->window->update_gui();
1184 synth->send_configure_change();
1187 PianoLevelRandom::PianoLevelRandom(Piano *synth)
1188 : BC_MenuItem(_("Random"))
1190 this->synth = synth;
1192 PianoLevelRandom::~PianoLevelRandom()
1196 int PianoLevelRandom::handle_event()
1199 for(int i = 0; i < synth->config.oscillator_config.total; i++)
1201 synth->config.oscillator_config.values[i]->level = -(rand() % -INFINITYGAIN);
1204 synth->thread->window->update_gui();
1205 synth->send_configure_change();
1208 PianoLevelInvert::PianoLevelInvert(Piano *synth)
1209 : BC_MenuItem(_("Invert"))
1211 this->synth = synth;
1213 PianoLevelInvert::~PianoLevelInvert()
1217 int PianoLevelInvert::handle_event()
1219 for(int i = 0; i < synth->config.oscillator_config.total; i++)
1221 synth->config.oscillator_config.values[i]->level =
1222 INFINITYGAIN - synth->config.oscillator_config.values[i]->level;
1225 synth->thread->window->update_gui();
1226 synth->send_configure_change();
1229 PianoLevelSine::PianoLevelSine(Piano *synth)
1230 : BC_MenuItem(_("Sine"))
1232 this->synth = synth;
1234 PianoLevelSine::~PianoLevelSine()
1238 int PianoLevelSine::handle_event()
1242 for(int i = 0; i < synth->config.oscillator_config.total; i++)
1244 new_value = (float)i / synth->config.oscillator_config.total * 2 * M_PI;
1245 new_value = sin(new_value) * INFINITYGAIN / 2 + INFINITYGAIN / 2;
1246 synth->config.oscillator_config.values[i]->level = new_value;
1249 synth->thread->window->update_gui();
1250 synth->send_configure_change();
1253 // ============================ phase calculations
1255 PianoPhaseInvert::PianoPhaseInvert(Piano *synth)
1256 : BC_MenuItem(_("Invert"))
1258 this->synth = synth;
1260 PianoPhaseInvert::~PianoPhaseInvert()
1264 int PianoPhaseInvert::handle_event()
1266 for(int i = 0; i < synth->config.oscillator_config.total; i++)
1268 synth->config.oscillator_config.values[i]->phase =
1269 1 - synth->config.oscillator_config.values[i]->phase;
1272 synth->thread->window->update_gui();
1273 synth->send_configure_change();
1276 PianoPhaseZero::PianoPhaseZero(Piano *synth)
1277 : BC_MenuItem(_("Zero"))
1279 this->synth = synth;
1281 PianoPhaseZero::~PianoPhaseZero()
1285 int PianoPhaseZero::handle_event()
1287 for(int i = 0; i < synth->config.oscillator_config.total; i++)
1289 synth->config.oscillator_config.values[i]->phase = 0;
1292 synth->thread->window->update_gui();
1293 synth->send_configure_change();
1296 PianoPhaseSine::PianoPhaseSine(Piano *synth)
1297 : BC_MenuItem(_("Sine"))
1299 this->synth = synth;
1301 PianoPhaseSine::~PianoPhaseSine()
1305 int PianoPhaseSine::handle_event()
1308 for(int i = 0; i < synth->config.oscillator_config.total; i++)
1310 new_value = (float)i / synth->config.oscillator_config.total * 2 * M_PI;
1311 new_value = sin(new_value) / 2 + .5;
1312 synth->config.oscillator_config.values[i]->phase = new_value;
1315 synth->thread->window->update_gui();
1316 synth->send_configure_change();
1319 PianoPhaseRandom::PianoPhaseRandom(Piano *synth)
1320 : BC_MenuItem(_("Random"))
1322 this->synth = synth;
1324 PianoPhaseRandom::~PianoPhaseRandom()
1328 int PianoPhaseRandom::handle_event()
1331 for(int i = 0; i < synth->config.oscillator_config.total; i++)
1333 synth->config.oscillator_config.values[i]->phase =
1334 (float)(rand() % 360) / 360;
1337 synth->thread->window->update_gui();
1338 synth->send_configure_change();
1342 // ============================ freq calculations
1344 PianoFreqRandom::PianoFreqRandom(Piano *synth)
1345 : BC_MenuItem(_("Random"))
1347 this->synth = synth;
1349 PianoFreqRandom::~PianoFreqRandom()
1353 int PianoFreqRandom::handle_event()
1356 for(int i = 0; i < synth->config.oscillator_config.total; i++)
1358 synth->config.oscillator_config.values[i]->freq_factor = rand() % 100;
1361 synth->thread->window->update_gui();
1362 synth->send_configure_change();
1365 PianoFreqEnum::PianoFreqEnum(Piano *synth)
1366 : BC_MenuItem(_("Enumerate"))
1368 this->synth = synth;
1370 PianoFreqEnum::~PianoFreqEnum()
1374 int PianoFreqEnum::handle_event()
1376 for(int i = 0; i < synth->config.oscillator_config.total; i++)
1378 synth->config.oscillator_config.values[i]->freq_factor = (float)i + 1;
1381 synth->thread->window->update_gui();
1382 synth->send_configure_change();
1385 PianoFreqEven::PianoFreqEven(Piano *synth)
1386 : BC_MenuItem(_("Even"))
1388 this->synth = synth;
1390 PianoFreqEven::~PianoFreqEven()
1394 int PianoFreqEven::handle_event()
1396 if(synth->config.oscillator_config.total)
1397 synth->config.oscillator_config.values[0]->freq_factor = (float)1;
1399 for(int i = 1; i < synth->config.oscillator_config.total; i++)
1401 synth->config.oscillator_config.values[i]->freq_factor = (float)i * 2;
1404 synth->thread->window->update_gui();
1405 synth->send_configure_change();
1408 PianoFreqOdd::PianoFreqOdd(Piano *synth)
1409 : BC_MenuItem(_("Odd"))
1410 { this->synth = synth; }
1411 PianoFreqOdd::~PianoFreqOdd()
1415 int PianoFreqOdd::handle_event()
1417 for(int i = 0; i < synth->config.oscillator_config.total; i++)
1419 synth->config.oscillator_config.values[i]->freq_factor = (float)1 + i * 2;
1422 synth->thread->window->update_gui();
1423 synth->send_configure_change();
1426 PianoFreqFibonacci::PianoFreqFibonacci(Piano *synth)
1427 : BC_MenuItem(_("Fibonnacci"))
1429 this->synth = synth;
1431 PianoFreqFibonacci::~PianoFreqFibonacci()
1435 int PianoFreqFibonacci::handle_event()
1437 float last_value1 = 0, last_value2 = 1;
1438 for(int i = 0; i < synth->config.oscillator_config.total; i++)
1440 synth->config.oscillator_config.values[i]->freq_factor = last_value1 + last_value2;
1441 if(synth->config.oscillator_config.values[i]->freq_factor > 100) synth->config.oscillator_config.values[i]->freq_factor = 100;
1442 last_value1 = last_value2;
1443 last_value2 = synth->config.oscillator_config.values[i]->freq_factor;
1446 synth->thread->window->update_gui();
1447 synth->send_configure_change();
1450 PianoFreqPrime::PianoFreqPrime(Piano *synth)
1451 : BC_MenuItem(_("Prime"))
1453 this->synth = synth;
1455 PianoFreqPrime::~PianoFreqPrime()
1459 int PianoFreqPrime::handle_event()
1462 for(int i = 0; i < synth->config.oscillator_config.total; i++)
1464 synth->config.oscillator_config.values[i]->freq_factor = number;
1465 number = get_next_prime(number);
1468 synth->thread->window->update_gui();
1469 synth->send_configure_change();
1472 float PianoFreqPrime::get_next_prime(float number)
1481 for(float i = number - 1; i > 1 && !result; i--)
1483 if((number / i) - (int)(number / i) == 0) result = 1;
1497 PianoOscillatorConfig::PianoOscillatorConfig(int number)
1500 this->number = number;
1503 PianoOscillatorConfig::~PianoOscillatorConfig()
1507 void PianoOscillatorConfig::reset()
1514 void PianoOscillatorConfig::read_data(FileXML *file)
1516 level = file->tag.get_property("LEVEL", (float)level);
1517 phase = file->tag.get_property("PHASE", (float)phase);
1518 freq_factor = file->tag.get_property("FREQFACTOR", (float)freq_factor);
1521 void PianoOscillatorConfig::save_data(FileXML *file)
1523 file->tag.set_title("OSCILLATOR");
1524 file->tag.set_property("LEVEL", (float)level);
1525 file->tag.set_property("PHASE", (float)phase);
1526 file->tag.set_property("FREQFACTOR", (float)freq_factor);
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);