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() - 125,
468 info.get_abs_cursor_y() - 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,
501 PianoWindow::~PianoWindow()
505 int PianoWindow::create_objects()
508 add_subwindow(menu = new BC_MenuBar(0, 0, get_w()));
510 BC_Menu *levelmenu, *phasemenu, *harmonicmenu;
511 menu->add_menu(levelmenu = new BC_Menu(_("Level")));
512 menu->add_menu(phasemenu = new BC_Menu(_("Phase")));
513 menu->add_menu(harmonicmenu = new BC_Menu(_("Harmonic")));
515 levelmenu->add_item(new PianoLevelInvert(synth));
516 levelmenu->add_item(new PianoLevelMax(synth));
517 levelmenu->add_item(new PianoLevelRandom(synth));
518 levelmenu->add_item(new PianoLevelSine(synth));
519 levelmenu->add_item(new PianoLevelSlope(synth));
520 levelmenu->add_item(new PianoLevelZero(synth));
522 phasemenu->add_item(new PianoPhaseInvert(synth));
523 phasemenu->add_item(new PianoPhaseRandom(synth));
524 phasemenu->add_item(new PianoPhaseSine(synth));
525 phasemenu->add_item(new PianoPhaseZero(synth));
527 harmonicmenu->add_item(new PianoFreqEnum(synth));
528 harmonicmenu->add_item(new PianoFreqEven(synth));
529 harmonicmenu->add_item(new PianoFreqFibonacci(synth));
530 harmonicmenu->add_item(new PianoFreqOdd(synth));
531 harmonicmenu->add_item(new PianoFreqPrime(synth));
533 int x = 10, y = 30, i;
534 add_subwindow(new BC_Title(x, y, _("Waveform")));
536 add_subwindow(new BC_Title(x, y, _("Wave Function")));
539 add_subwindow(canvas = new PianoCanvas(synth, this, x, y, 230, 160));
543 char string[BCTEXTLEN];
544 waveform_to_text(string, synth->config.wavefunction);
546 add_subwindow(waveform = new PianoWaveForm(synth, x, y, string));
547 waveform->create_objects();
551 add_subwindow(new BC_Title(x, y, _("Base Frequency:")));
553 add_subwindow(base_freq = new PianoBaseFreq(synth, x, y));
555 add_subwindow(freqpot = new PianoFreqPot(synth, this, x, y - 10));
556 base_freq->freq_pot = freqpot;
557 freqpot->freq_text = base_freq;
560 add_subwindow(new BC_Title(x, y, _("Wetness:")));
561 add_subwindow(wetness = new PianoWetness(synth, x + 70, y - 10));
564 add_subwindow(new PianoClear(synth, x, y));
569 add_subwindow(new BC_Title(x, y, _("Level")));
571 add_subwindow(new BC_Title(x, y, _("Phase")));
573 add_subwindow(new BC_Title(x, y, _("Harmonic")));
578 add_subwindow(subwindow = new PianoSubWindow(synth, x, y, 265, get_h() - y));
580 add_subwindow(scroll = new PianoScroll(synth, this, x, y, get_h() - y));
584 add_subwindow(new PianoAddOsc(synth, this, x, y));
586 add_subwindow(new PianoDelOsc(synth, this, x, y));
589 update_oscillators();
596 int PianoWindow::close_event()
598 // Set result to 1 to indicate a client side close
603 int PianoWindow::resize_event(int w, int h)
605 clear_box(0, 0, w, h);
606 subwindow->reposition_window(subwindow->get_x(),
609 h - subwindow->get_y());
610 subwindow->clear_box(0, 0, subwindow->get_w(), subwindow->get_h());
611 scroll->reposition_window(scroll->get_x(),
613 h - scroll->get_y());
615 update_oscillators();
621 void PianoWindow::update_gui()
623 char string[BCTEXTLEN];
624 freqpot->update(synth->config.base_freq);
625 base_freq->update((int64_t)synth->config.base_freq);
626 wetness->update(synth->config.wetness);
627 waveform_to_text(string, synth->config.wavefunction);
628 waveform->set_text(string);
631 update_oscillators();
635 void PianoWindow::update_scrollbar()
637 scroll->update_length(synth->config.oscillator_config.total * OSCILLATORHEIGHT,
638 scroll->get_position(),
642 void PianoWindow::update_oscillators()
644 int i, y = -scroll->get_position();
648 // Add new oscillators
650 i < synth->config.oscillator_config.total;
654 PianoOscillatorConfig *config = synth->config.oscillator_config.values[i];
656 if(oscillators.total <= i)
658 oscillators.append(gui = new PianoOscGUI(this, i));
659 gui->create_objects(y);
663 gui = oscillators.values[i];
665 gui->title->reposition_window(gui->title->get_x(), y + 15);
667 gui->level->reposition_window(gui->level->get_x(), y);
668 gui->level->update(config->level);
670 gui->phase->reposition_window(gui->phase->get_x(), y);
671 gui->phase->update((int64_t)(config->phase * 360));
673 gui->freq->reposition_window(gui->freq->get_x(), y);
674 gui->freq->update((int64_t)(config->freq_factor));
676 y += OSCILLATORHEIGHT;
679 // Delete old oscillators
681 i < oscillators.total;
683 oscillators.remove_object();
687 int PianoWindow::waveform_to_text(char *text, int waveform)
691 case DC: sprintf(text, _("DC")); break;
692 case SINE: sprintf(text, _("Sine")); break;
693 case SAWTOOTH: sprintf(text, _("Sawtooth")); break;
694 case SQUARE: sprintf(text, _("Square")); break;
695 case TRIANGLE: sprintf(text, _("Triangle")); break;
696 case PULSE: sprintf(text, _("Pulse")); break;
697 case NOISE: sprintf(text, _("Noise")); break;
708 PianoOscGUI::PianoOscGUI(PianoWindow *window, int number)
710 this->window = window;
711 this->number = number;
714 PianoOscGUI::~PianoOscGUI()
722 int PianoOscGUI::create_objects(int y)
724 char text[BCTEXTLEN];
725 sprintf(text, "%d:", number + 1);
726 window->subwindow->add_subwindow(title = new BC_Title(10, y + 15, text));
728 window->subwindow->add_subwindow(level = new PianoOscGUILevel(window->synth, this, y));
729 window->subwindow->add_subwindow(phase = new PianoOscGUIPhase(window->synth, this, y));
730 window->subwindow->add_subwindow(freq = new PianoOscGUIFreq(window->synth, this, y));
737 PianoOscGUILevel::PianoOscGUILevel(Piano *synth, PianoOscGUI *gui, int y)
740 synth->config.oscillator_config.values[gui->number]->level,
748 PianoOscGUILevel::~PianoOscGUILevel()
752 int PianoOscGUILevel::handle_event()
754 PianoOscillatorConfig *config = synth->config.oscillator_config.values[gui->number];
755 config->level = get_value();
756 gui->window->canvas->update();
757 synth->send_configure_change();
763 PianoOscGUIPhase::PianoOscGUIPhase(Piano *synth, PianoOscGUI *gui, int y)
766 (int64_t)(synth->config.oscillator_config.values[gui->number]->phase * 360),
774 PianoOscGUIPhase::~PianoOscGUIPhase()
778 int PianoOscGUIPhase::handle_event()
780 PianoOscillatorConfig *config = synth->config.oscillator_config.values[gui->number];
781 config->phase = (float)get_value() / 360;
782 gui->window->canvas->update();
783 synth->send_configure_change();
789 PianoOscGUIFreq::PianoOscGUIFreq(Piano *synth, PianoOscGUI *gui, int y)
792 (int64_t)(synth->config.oscillator_config.values[gui->number]->freq_factor),
800 PianoOscGUIFreq::~PianoOscGUIFreq()
804 int PianoOscGUIFreq::handle_event()
806 PianoOscillatorConfig *config = synth->config.oscillator_config.values[gui->number];
807 config->freq_factor = get_value();
808 gui->window->canvas->update();
809 synth->send_configure_change();
819 PianoAddOsc::PianoAddOsc(Piano *synth, PianoWindow *window, int x, int y)
820 : BC_GenericButton(x, y, _("Add"))
823 this->window = window;
826 PianoAddOsc::~PianoAddOsc()
830 int PianoAddOsc::handle_event()
832 synth->add_oscillator();
833 synth->send_configure_change();
834 window->update_gui();
840 PianoDelOsc::PianoDelOsc(Piano *synth, PianoWindow *window, int x, int y)
841 : BC_GenericButton(x, y, _("Delete"))
844 this->window = window;
847 PianoDelOsc::~PianoDelOsc()
851 int PianoDelOsc::handle_event()
853 synth->delete_oscillator();
854 synth->send_configure_change();
855 window->update_gui();
860 PianoScroll::PianoScroll(Piano *synth,
869 synth->config.oscillator_config.total * OSCILLATORHEIGHT,
871 window->subwindow->get_h())
874 this->window = window;
877 PianoScroll::~PianoScroll()
881 int PianoScroll::handle_event()
883 window->update_gui();
894 PianoSubWindow::PianoSubWindow(Piano *synth, int x, int y, int w, int h)
895 : BC_SubWindow(x, y, w, h)
899 PianoSubWindow::~PianoSubWindow()
911 PianoClear::PianoClear(Piano *synth, int x, int y)
912 : BC_GenericButton(x, y, _("Clear"))
916 PianoClear::~PianoClear()
919 int PianoClear::handle_event()
921 synth->config.reset();
922 synth->send_configure_change();
932 PianoWaveForm::PianoWaveForm(Piano *synth, int x, int y, char *text)
933 : BC_PopupMenu(x, y, 120, text)
938 PianoWaveForm::~PianoWaveForm()
942 int PianoWaveForm::create_objects()
944 // add_item(new PianoWaveFormItem(synth, _("DC"), DC));
945 add_item(new PianoWaveFormItem(synth, _("Sine"), SINE));
946 add_item(new PianoWaveFormItem(synth, _("Sawtooth"), SAWTOOTH));
947 add_item(new PianoWaveFormItem(synth, _("Square"), SQUARE));
948 add_item(new PianoWaveFormItem(synth, _("Triangle"), TRIANGLE));
949 add_item(new PianoWaveFormItem(synth, _("Pulse"), PULSE));
950 add_item(new PianoWaveFormItem(synth, _("Noise"), NOISE));
954 PianoWaveFormItem::PianoWaveFormItem(Piano *synth, char *text, int value)
961 PianoWaveFormItem::~PianoWaveFormItem()
965 int PianoWaveFormItem::handle_event()
967 synth->config.wavefunction = value;
968 synth->thread->window->canvas->update();
969 synth->send_configure_change();
974 PianoWetness::PianoWetness(Piano *synth, int x, int y)
977 synth->config.wetness,
984 int PianoWetness::handle_event()
986 synth->config.wetness = get_value();
987 synth->send_configure_change();
993 PianoFreqPot::PianoFreqPot(Piano *synth, PianoWindow *window, int x, int y)
994 : BC_QPot(x, y, synth->config.base_freq)
998 PianoFreqPot::~PianoFreqPot()
1001 int PianoFreqPot::handle_event()
1003 if(get_value() > 0 && get_value() < 30000)
1005 synth->config.base_freq = get_value();
1006 freq_text->update(get_value());
1007 synth->send_configure_change();
1014 PianoBaseFreq::PianoBaseFreq(Piano *synth, int x, int y)
1015 : BC_TextBox(x, y, 70, 1, (int)synth->config.base_freq)
1017 this->synth = synth;
1019 PianoBaseFreq::~PianoBaseFreq()
1022 int PianoBaseFreq::handle_event()
1024 int new_value = atol(get_text());
1026 if(new_value > 0 && new_value < 30000)
1028 synth->config.base_freq = new_value;
1029 freq_pot->update(synth->config.base_freq);
1030 synth->send_configure_change();
1039 PianoCanvas::PianoCanvas(Piano *synth,
1040 PianoWindow *window,
1051 this->synth = synth;
1052 this->window = window;
1055 PianoCanvas::~PianoCanvas()
1059 int PianoCanvas::update()
1063 clear_box(0, 0, get_w(), get_h());
1066 draw_line(0, get_h() / 2 + y, get_w(), get_h() / 2 + y);
1070 double normalize_constant = (double)1 / synth->get_total_power();
1071 y1 = (int)(synth->get_point((float)0, normalize_constant) * get_h() / 2);
1073 for(int i = 1; i < get_w(); i++)
1075 y2 = (int)(synth->get_point((float)i / get_w(), normalize_constant) * get_h() / 2);
1076 draw_line(i - 1, get_h() / 2 - y1, i, get_h() / 2 - y2);
1090 // ======================= level calculations
1091 PianoLevelZero::PianoLevelZero(Piano *synth)
1092 : BC_MenuItem(_("Zero"))
1094 this->synth = synth;
1097 PianoLevelZero::~PianoLevelZero()
1101 int PianoLevelZero::handle_event()
1103 for(int i = 0; i < synth->config.oscillator_config.total; i++)
1105 synth->config.oscillator_config.values[i]->level = INFINITYGAIN;
1108 synth->thread->window->update_gui();
1109 synth->send_configure_change();
1112 PianoLevelMax::PianoLevelMax(Piano *synth)
1113 : BC_MenuItem(_("Maximum"))
1115 this->synth = synth;
1118 PianoLevelMax::~PianoLevelMax()
1122 int PianoLevelMax::handle_event()
1124 for(int i = 0; i < synth->config.oscillator_config.total; i++)
1126 synth->config.oscillator_config.values[i]->level = 0;
1128 synth->thread->window->update_gui();
1129 synth->send_configure_change();
1132 PianoLevelNormalize::PianoLevelNormalize(Piano *synth)
1133 : BC_MenuItem(_("Normalize"))
1135 this->synth = synth;
1138 PianoLevelNormalize::~PianoLevelNormalize()
1142 int PianoLevelNormalize::handle_event()
1147 for(int i = 0; i < synth->config.oscillator_config.total; i++)
1149 total += synth->db.fromdb(synth->config.oscillator_config.values[i]->level);
1152 float scale = 1 / total;
1155 for(int i = 0; i < synth->config.oscillator_config.total; i++)
1157 new_value = synth->db.fromdb(synth->config.oscillator_config.values[i]->level);
1159 new_value = synth->db.todb(new_value);
1161 synth->config.oscillator_config.values[i]->level = new_value;
1164 synth->thread->window->update_gui();
1165 synth->send_configure_change();
1168 PianoLevelSlope::PianoLevelSlope(Piano *synth)
1169 : BC_MenuItem(_("Slope"))
1171 this->synth = synth;
1174 PianoLevelSlope::~PianoLevelSlope()
1178 int PianoLevelSlope::handle_event()
1180 float slope = (float)INFINITYGAIN / synth->config.oscillator_config.total;
1182 for(int i = 0; i < synth->config.oscillator_config.total; i++)
1184 synth->config.oscillator_config.values[i]->level = i * slope;
1187 synth->thread->window->update_gui();
1188 synth->send_configure_change();
1191 PianoLevelRandom::PianoLevelRandom(Piano *synth)
1192 : BC_MenuItem(_("Random"))
1194 this->synth = synth;
1196 PianoLevelRandom::~PianoLevelRandom()
1200 int PianoLevelRandom::handle_event()
1203 for(int i = 0; i < synth->config.oscillator_config.total; i++)
1205 synth->config.oscillator_config.values[i]->level = -(rand() % -INFINITYGAIN);
1208 synth->thread->window->update_gui();
1209 synth->send_configure_change();
1212 PianoLevelInvert::PianoLevelInvert(Piano *synth)
1213 : BC_MenuItem(_("Invert"))
1215 this->synth = synth;
1217 PianoLevelInvert::~PianoLevelInvert()
1221 int PianoLevelInvert::handle_event()
1223 for(int i = 0; i < synth->config.oscillator_config.total; i++)
1225 synth->config.oscillator_config.values[i]->level =
1226 INFINITYGAIN - synth->config.oscillator_config.values[i]->level;
1229 synth->thread->window->update_gui();
1230 synth->send_configure_change();
1233 PianoLevelSine::PianoLevelSine(Piano *synth)
1234 : BC_MenuItem(_("Sine"))
1236 this->synth = synth;
1238 PianoLevelSine::~PianoLevelSine()
1242 int PianoLevelSine::handle_event()
1246 for(int i = 0; i < synth->config.oscillator_config.total; i++)
1248 new_value = (float)i / synth->config.oscillator_config.total * 2 * M_PI;
1249 new_value = sin(new_value) * INFINITYGAIN / 2 + INFINITYGAIN / 2;
1250 synth->config.oscillator_config.values[i]->level = new_value;
1253 synth->thread->window->update_gui();
1254 synth->send_configure_change();
1257 // ============================ phase calculations
1259 PianoPhaseInvert::PianoPhaseInvert(Piano *synth)
1260 : BC_MenuItem(_("Invert"))
1262 this->synth = synth;
1264 PianoPhaseInvert::~PianoPhaseInvert()
1268 int PianoPhaseInvert::handle_event()
1270 for(int i = 0; i < synth->config.oscillator_config.total; i++)
1272 synth->config.oscillator_config.values[i]->phase =
1273 1 - synth->config.oscillator_config.values[i]->phase;
1276 synth->thread->window->update_gui();
1277 synth->send_configure_change();
1280 PianoPhaseZero::PianoPhaseZero(Piano *synth)
1281 : BC_MenuItem(_("Zero"))
1283 this->synth = synth;
1285 PianoPhaseZero::~PianoPhaseZero()
1289 int PianoPhaseZero::handle_event()
1291 for(int i = 0; i < synth->config.oscillator_config.total; i++)
1293 synth->config.oscillator_config.values[i]->phase = 0;
1296 synth->thread->window->update_gui();
1297 synth->send_configure_change();
1300 PianoPhaseSine::PianoPhaseSine(Piano *synth)
1301 : BC_MenuItem(_("Sine"))
1303 this->synth = synth;
1305 PianoPhaseSine::~PianoPhaseSine()
1309 int PianoPhaseSine::handle_event()
1312 for(int i = 0; i < synth->config.oscillator_config.total; i++)
1314 new_value = (float)i / synth->config.oscillator_config.total * 2 * M_PI;
1315 new_value = sin(new_value) / 2 + .5;
1316 synth->config.oscillator_config.values[i]->phase = new_value;
1319 synth->thread->window->update_gui();
1320 synth->send_configure_change();
1323 PianoPhaseRandom::PianoPhaseRandom(Piano *synth)
1324 : BC_MenuItem(_("Random"))
1326 this->synth = synth;
1328 PianoPhaseRandom::~PianoPhaseRandom()
1332 int PianoPhaseRandom::handle_event()
1335 for(int i = 0; i < synth->config.oscillator_config.total; i++)
1337 synth->config.oscillator_config.values[i]->phase =
1338 (float)(rand() % 360) / 360;
1341 synth->thread->window->update_gui();
1342 synth->send_configure_change();
1346 // ============================ freq calculations
1348 PianoFreqRandom::PianoFreqRandom(Piano *synth)
1349 : BC_MenuItem(_("Random"))
1351 this->synth = synth;
1353 PianoFreqRandom::~PianoFreqRandom()
1357 int PianoFreqRandom::handle_event()
1360 for(int i = 0; i < synth->config.oscillator_config.total; i++)
1362 synth->config.oscillator_config.values[i]->freq_factor = rand() % 100;
1365 synth->thread->window->update_gui();
1366 synth->send_configure_change();
1369 PianoFreqEnum::PianoFreqEnum(Piano *synth)
1370 : BC_MenuItem(_("Enumerate"))
1372 this->synth = synth;
1374 PianoFreqEnum::~PianoFreqEnum()
1378 int PianoFreqEnum::handle_event()
1380 for(int i = 0; i < synth->config.oscillator_config.total; i++)
1382 synth->config.oscillator_config.values[i]->freq_factor = (float)i + 1;
1385 synth->thread->window->update_gui();
1386 synth->send_configure_change();
1389 PianoFreqEven::PianoFreqEven(Piano *synth)
1390 : BC_MenuItem(_("Even"))
1392 this->synth = synth;
1394 PianoFreqEven::~PianoFreqEven()
1398 int PianoFreqEven::handle_event()
1400 if(synth->config.oscillator_config.total)
1401 synth->config.oscillator_config.values[0]->freq_factor = (float)1;
1403 for(int i = 1; i < synth->config.oscillator_config.total; i++)
1405 synth->config.oscillator_config.values[i]->freq_factor = (float)i * 2;
1408 synth->thread->window->update_gui();
1409 synth->send_configure_change();
1412 PianoFreqOdd::PianoFreqOdd(Piano *synth)
1413 : BC_MenuItem(_("Odd"))
1414 { this->synth = synth; }
1415 PianoFreqOdd::~PianoFreqOdd()
1419 int PianoFreqOdd::handle_event()
1421 for(int i = 0; i < synth->config.oscillator_config.total; i++)
1423 synth->config.oscillator_config.values[i]->freq_factor = (float)1 + i * 2;
1426 synth->thread->window->update_gui();
1427 synth->send_configure_change();
1430 PianoFreqFibonacci::PianoFreqFibonacci(Piano *synth)
1431 : BC_MenuItem(_("Fibonnacci"))
1433 this->synth = synth;
1435 PianoFreqFibonacci::~PianoFreqFibonacci()
1439 int PianoFreqFibonacci::handle_event()
1441 float last_value1 = 0, last_value2 = 1;
1442 for(int i = 0; i < synth->config.oscillator_config.total; i++)
1444 synth->config.oscillator_config.values[i]->freq_factor = last_value1 + last_value2;
1445 if(synth->config.oscillator_config.values[i]->freq_factor > 100) synth->config.oscillator_config.values[i]->freq_factor = 100;
1446 last_value1 = last_value2;
1447 last_value2 = synth->config.oscillator_config.values[i]->freq_factor;
1450 synth->thread->window->update_gui();
1451 synth->send_configure_change();
1454 PianoFreqPrime::PianoFreqPrime(Piano *synth)
1455 : BC_MenuItem(_("Prime"))
1457 this->synth = synth;
1459 PianoFreqPrime::~PianoFreqPrime()
1463 int PianoFreqPrime::handle_event()
1466 for(int i = 0; i < synth->config.oscillator_config.total; i++)
1468 synth->config.oscillator_config.values[i]->freq_factor = number;
1469 number = get_next_prime(number);
1472 synth->thread->window->update_gui();
1473 synth->send_configure_change();
1476 float PianoFreqPrime::get_next_prime(float number)
1485 for(float i = number - 1; i > 1 && !result; i--)
1487 if((number / i) - (int)(number / i) == 0) result = 1;
1501 PianoOscillatorConfig::PianoOscillatorConfig(int number)
1504 this->number = number;
1507 PianoOscillatorConfig::~PianoOscillatorConfig()
1511 void PianoOscillatorConfig::reset()
1518 void PianoOscillatorConfig::read_data(FileXML *file)
1520 level = file->tag.get_property("LEVEL", (float)level);
1521 phase = file->tag.get_property("PHASE", (float)phase);
1522 freq_factor = file->tag.get_property("FREQFACTOR", (float)freq_factor);
1525 void PianoOscillatorConfig::save_data(FileXML *file)
1527 file->tag.set_title("OSCILLATOR");
1528 file->tag.set_property("LEVEL", (float)level);
1529 file->tag.set_property("PHASE", (float)phase);
1530 file->tag.set_property("FREQFACTOR", (float)freq_factor);
1532 file->tag.set_title("/OSCILLATOR");
1534 file->append_newline();
1537 int PianoOscillatorConfig::equivalent(PianoOscillatorConfig &that)
1539 if(EQUIV(level, that.level) &&
1540 EQUIV(phase, that.phase) &&
1541 EQUIV(freq_factor, that.freq_factor))
1547 void PianoOscillatorConfig::copy_from(PianoOscillatorConfig& that)
1551 freq_factor = that.freq_factor;
1565 PianoConfig::PianoConfig()
1570 PianoConfig::~PianoConfig()
1572 oscillator_config.remove_all_objects();
1575 void PianoConfig::reset()
1579 wavefunction = SINE;
1580 for(int i = 0; i < oscillator_config.total; i++)
1582 oscillator_config.values[i]->reset();
1586 int PianoConfig::equivalent(PianoConfig &that)
1588 //printf("PianoConfig::equivalent %d %d\n", base_freq, that.base_freq);
1589 if(base_freq != that.base_freq ||
1590 wavefunction != that.wavefunction ||
1591 oscillator_config.total != that.oscillator_config.total) return 0;
1593 for(int i = 0; i < oscillator_config.total; i++)
1595 if(!oscillator_config.values[i]->equivalent(*that.oscillator_config.values[i]))
1602 void PianoConfig::copy_from(PianoConfig& that)
1604 wetness = that.wetness;
1605 base_freq = that.base_freq;
1606 wavefunction = that.wavefunction;
1610 i < oscillator_config.total && i < that.oscillator_config.total;
1613 oscillator_config.values[i]->copy_from(*that.oscillator_config.values[i]);
1617 i < that.oscillator_config.total;
1620 oscillator_config.append(new PianoOscillatorConfig(i));
1621 oscillator_config.values[i]->copy_from(*that.oscillator_config.values[i]);
1625 i < oscillator_config.total;
1628 oscillator_config.remove_object();
1632 void PianoConfig::interpolate(PianoConfig &prev,
1636 int64_t current_frame)
1638 double next_scale = (double)(current_frame - prev_frame) / (next_frame - prev_frame);
1639 double prev_scale = (double)(next_frame - current_frame) / (next_frame - prev_frame);
1642 wetness = (int)(prev.wetness * prev_scale + next.wetness * next_scale);
1643 base_freq = (int)(prev.base_freq * prev_scale + next.base_freq * next_scale);