X-Git-Url: https://git.cinelerra-gg.org/git/?a=blobdiff_plain;f=cinelerra-5.1%2Fplugins%2Fsynthesizer%2Fsynthesizer.C;h=01a4973896232d98bfb3e33abf220be708ffd379;hb=255d67d0fcabfbcd208f2587a9a75697a15d6349;hp=194da4c70ec13be23009c71db725a4a135aece7e;hpb=7fd85fb66168f6b518c5f2d73e04036e87faa0e1;p=goodguy%2Fcinelerra.git diff --git a/cinelerra-5.1/plugins/synthesizer/synthesizer.C b/cinelerra-5.1/plugins/synthesizer/synthesizer.C index 194da4c7..01a49738 100644 --- a/cinelerra-5.1/plugins/synthesizer/synthesizer.C +++ b/cinelerra-5.1/plugins/synthesizer/synthesizer.C @@ -1,7 +1,7 @@ /* * CINELERRA - * Copyright (C) 1997-2011 Adam Williams + * Copyright (C) 1997-2017 Adam Williams * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -44,8 +44,8 @@ Synth::Synth(PluginServer *server) : PluginAClient(server) { reset(); - window_w = 640; - window_h = 480; + window_w = xS(640); + window_h = yS(480); } @@ -86,7 +86,6 @@ void Synth::read_data(KeyFrame *keyframe) //printf("Synth::read_data %s\n", keyframe->get_data()); int result = 0, current_osc = 0; - //int total_oscillators = 0; while(!result) { result = input.read_tag(); @@ -112,7 +111,7 @@ void Synth::read_data(KeyFrame *keyframe) } config.wavefunction = input.tag.get_property("WAVEFUNCTION", config.wavefunction); - //total_oscillators = input.tag.get_property("OSCILLATORS", 0); + // int total_oscillators = input.tag.get_property("OSCILLATORS", 0); } else if(input.tag.title_is("OSCILLATOR")) @@ -164,9 +163,6 @@ void Synth::save_data(KeyFrame *keyframe) config.oscillator_config.values[i]->save_data(&output); } - output.tag.set_title("/SYNTH"); - output.append_tag(); - output.append_newline(); output.terminate_string(); //printf("Synth::save_data %d %s\n", __LINE__, output.string); // data is now in *text @@ -176,19 +172,21 @@ void Synth::save_data(KeyFrame *keyframe) void Synth::update_gui() { - if( !thread ) return; - SynthWindow *window = (SynthWindow*)thread->window; -// load_configuration,read_data deletes oscillator_config - window->lock_window("Synth::update_gui"); - if( load_configuration() ) - window->update_gui(); - window->unlock_window(); + if(thread) + { + if(load_configuration()) + { + thread->window->lock_window(); + ((SynthWindow*)thread->window)->update_gui(); + thread->window->unlock_window(); + } + } } void Synth::add_oscillator() { - if(config.oscillator_config.total > 20) return; + if(config.oscillator_config.total > MAX_OSCILLATORS) return; config.oscillator_config.append(new SynthOscillatorConfig(config.oscillator_config.total - 1)); } @@ -234,8 +232,8 @@ double Synth::solve_eqn(double *output, freq; // Starting sample in waveform double x = waveform_sample; - double phase_offset = config->phase * orig_period; //printf("Synth::solve_eqn %d %f\n", __LINE__, config->phase); + double phase_offset = config->phase * orig_period; // Period of current oscillator double period = orig_period / config->freq_factor; int sample; @@ -255,9 +253,7 @@ double Synth::solve_eqn(double *output, for(sample = 0; sample < length; sample++) { output[sample] += sin((x + phase_offset) / - period * - 2 * - M_PI) * power; + period * 2 * M_PI) * power; x += step; } break; @@ -425,11 +421,7 @@ int Synth::overlay_synth(double freq, { double normalize_constant = 1.0 / get_total_power(); for(int i = 0; i < config.oscillator_config.total; i++) - solve_eqn(output, - length, - freq, - normalize_constant, - i); + solve_eqn(output, length, freq, normalize_constant, i); return length; } @@ -501,39 +493,9 @@ void Synth::delete_freqs() } - - - - - - - - - - - - - - - - - - - - - - - - - - SynthWindow::SynthWindow(Synth *synth) - : PluginClientWindow(synth, - synth->window_w, - synth->window_h, - 400, - 350, - 1) + : PluginClientWindow(synth, synth->window_w, synth->window_h, + xS(400), yS(350), 1) { this->synth = synth; white_key[0] = 0; @@ -564,6 +526,8 @@ static const char *keyboard_map[] = void SynthWindow::create_objects() { + int margin = client->get_theme()->widget_border; + BC_MenuBar *menu; add_subwindow(menu = new BC_MenuBar(0, 0, get_w())); @@ -584,72 +548,75 @@ void SynthWindow::create_objects() phasemenu->add_item(new SynthPhaseSine(synth)); phasemenu->add_item(new SynthPhaseZero(synth)); + harmonicmenu->add_item(new SynthFreqMin(synth)); harmonicmenu->add_item(new SynthFreqEnum(synth)); harmonicmenu->add_item(new SynthFreqEven(synth)); harmonicmenu->add_item(new SynthFreqFibonacci(synth)); harmonicmenu->add_item(new SynthFreqOdd(synth)); harmonicmenu->add_item(new SynthFreqPrime(synth)); - int x = 10, y = 30; + int xs10 = xS(10), xs20 = xS(20), xs50 = xS(50), xs70 = xS(70), xs75 = xS(75), xs240 = xS(240), xs265 = xS(265); + int ys10 = yS(10), ys20 = yS(20), ys30 = yS(30), ys40 = yS(40), ys220 = yS(220); + int x = xs10, y = ys30; add_subwindow(new BC_Title(x, y, _("Waveform"))); - x += 240; + x += xs240; add_subwindow(new BC_Title(x, y, _("Wave Function"))); - y += 20; - x = 10; - add_subwindow(canvas = new SynthCanvas(synth, this, x, y, 230, 160)); + y += ys20; + x = xs10; + add_subwindow(canvas = new SynthCanvas(synth, this, x, y, xS(230), yS(160))); canvas->update(); - x += 240; + x += xs240; char string[BCTEXTLEN]; waveform_to_text(string, synth->config.wavefunction); add_subwindow(waveform = new SynthWaveForm(synth, x, y, string)); waveform->create_objects(); - y += 30; - int x1 = x + waveform->get_w() + 10; + y += ys30; + int x1 = x + waveform->get_w() + xs50; add_subwindow(new BC_Title(x, y, _("Base Frequency:"))); - y += 30; + y += ys30; add_subwindow(base_freq = new SynthBaseFreq(synth, this, x, y)); base_freq->update((float)synth->config.base_freq[0]); x += base_freq->get_w() + synth->get_theme()->widget_border; - add_subwindow(freqpot = new SynthFreqPot(synth, this, x, y - 10)); + add_subwindow(freqpot = new SynthFreqPot(synth, this, x, y - ys10)); base_freq->freq_pot = freqpot; freqpot->freq_text = base_freq; x -= base_freq->get_w() + synth->get_theme()->widget_border; - y += 40; + y += ys40; add_subwindow(new BC_Title(x, y, _("Wetness:"))); - add_subwindow(wetness = new SynthWetness(synth, x + 70, y - 10)); + add_subwindow(wetness = new SynthWetness(synth, x + xs70, y - ys10)); - y += 40; + y += ys40; add_subwindow(new SynthClear(synth, x, y)); - x = 50; - y = 220; + x = xs50; + y = ys220; add_subwindow(new BC_Title(x, y, _("Level"))); - x += 75; + x += xs75; add_subwindow(new BC_Title(x, y, _("Phase"))); - x += 75; + x += xs75; add_subwindow(new BC_Title(x, y, _("Harmonic"))); - y += 20; x = 10; - add_subwindow(osc_subwindow = new BC_SubWindow(x, y, 265, get_h() - y)); - x += 265; + y += ys20; x = xs10; + add_subwindow(osc_subwindow = new BC_SubWindow(x, y, xs265, get_h() - y)); + x += xs265; add_subwindow(osc_scroll = new OscScroll(synth, this, x, y, get_h() - y)); - x += 20; + x += xs20; add_subwindow(new SynthAddOsc(synth, this, x, y)); - y += 30; + y += ys30; add_subwindow(new SynthDelOsc(synth, this, x, y)); // Create keyboard - y = 30; + y = ys30; #include "white_up_png.h" #include "white_hi_png.h" @@ -673,27 +640,22 @@ void SynthWindow::create_objects() black_key[4] = new VFramePng(black_checkedhi_png); - add_subwindow(note_subwindow = new BC_SubWindow(x1, - y, - get_w() - x1, - white_key[0]->get_h() + MARGIN + - get_text_height(MEDIUMFONT) + MARGIN + - get_text_height(MEDIUMFONT) + MARGIN)); - add_subwindow(note_scroll = new NoteScroll(synth, - this, - x1, + add_subwindow(note_subwindow = new BC_SubWindow(x1+xS(20), + y, get_w() - (x1+xS(20)), + white_key[0]->get_h() + margin + + get_text_height(MEDIUMFONT) + margin + + get_text_height(MEDIUMFONT) + margin)); + add_subwindow(note_scroll = new NoteScroll(synth, this, x1, note_subwindow->get_y() + note_subwindow->get_h(), note_subwindow->get_w())); - add_subwindow(momentary = new SynthMomentary(this, - x1, - note_scroll->get_y() + note_scroll->get_h() + MARGIN, + add_subwindow(momentary = new SynthMomentary(this, x1, + note_scroll->get_y() + note_scroll->get_h() + margin, _("Momentary notes"))); - add_subwindow(note_instructions = new BC_Title( - x1, - momentary->get_y() + momentary->get_h() + MARGIN, + add_subwindow(note_instructions = new BC_Title( x1, + momentary->get_y() + momentary->get_h() + margin, _("Ctrl or Shift to select multiple notes."))); update_scrollbar(); @@ -783,8 +745,7 @@ void SynthWindow::update_whitekey(int number, if(number >= FIRST_TITLE && number < LAST_TITLE) note_subwindow->add_subwindow( note_titles[(*current_title)++] = new BC_Title( - x + text_white_margin, - y2, + x + text_white_margin, y2, keyboard_map[number - FIRST_TITLE])); //printf("SynthWindow::update_whitekey %d\n", __LINE__); } @@ -810,15 +771,13 @@ void SynthWindow::update_blackkey(int number, if(number >= FIRST_TITLE && number < LAST_TITLE) note_subwindow->add_subwindow( note_titles[(*current_title)++] = new BC_Title(x + text_black_margin, - y1, - keyboard_map[number - FIRST_TITLE])); + y1, keyboard_map[number - FIRST_TITLE])); } else { notes[number]->reposition_window(x, y); if(number >= FIRST_TITLE && number < LAST_TITLE) - note_titles[(*current_title)++]->reposition_window(x + text_black_margin, - y1); + note_titles[(*current_title)++]->reposition_window(x + text_black_margin, y1); } } @@ -830,11 +789,10 @@ void SynthWindow::update_notes() int white_w1 = white_w - black_w / 2 - 2; int white_w2 = white_w / 2; int white_w3 = white_w * 2 / 3; - int y = 0; - int x = 0; - y1 = y + white_key[0]->get_h() + 10; - y2 = y1 + get_text_height(MEDIUMFONT) + 10; - y3 = y2 + get_text_height(MEDIUMFONT) + 10; + int x = 0, y = 0, ys5 = yS(5); + y1 = y + white_key[0]->get_h() + ys5; + y2 = y1 + get_text_height(MEDIUMFONT) + ys5; + y3 = y2 + get_text_height(MEDIUMFONT) + ys5; text_black_margin = black_w / 2 - get_text_width(MEDIUMFONT, "O") / 2; text_white_margin = white_w / 2 - get_text_width(MEDIUMFONT, "O") / 2; @@ -985,7 +943,7 @@ void SynthWindow::update_oscillators() { gui = oscillators.values[i]; - gui->title->reposition_window(gui->title->get_x(), y + 15); + gui->title->reposition_window(gui->title->get_x(), y + yS(15)); gui->level->reposition_window(gui->level->get_x(), y); gui->level->update(config->level); @@ -994,7 +952,7 @@ void SynthWindow::update_oscillators() gui->phase->update((int64_t)(config->phase * 360)); gui->freq->reposition_window(gui->freq->get_x(), y); - gui->freq->update((int64_t)(config->freq_factor)); + gui->freq->update(config->freq_factor); } y += OSCILLATORHEIGHT; } @@ -1024,10 +982,7 @@ int SynthWindow::waveform_to_text(char *text, int waveform) SynthMomentary::SynthMomentary(SynthWindow *window, int x, int y, char *text) - : BC_CheckBox(x, - y, - window->synth->config.momentary_notes, - text) + : BC_CheckBox(x, y, window->synth->config.momentary_notes, text) { this->window = window; } @@ -1042,15 +997,8 @@ int SynthMomentary::handle_event() -SynthNote::SynthNote(SynthWindow *window, - VFrame **images, - int number, - int x, - int y) - : BC_Toggle(x, - y, - images, - window->synth->freq_exists(keyboard_freqs[number])) +SynthNote::SynthNote(SynthWindow *window, VFrame **images, int number, int x, int y) + : BC_Toggle(x, y, images, window->synth->freq_exists(keyboard_freqs[number])) { this->window = window; this->number = number; @@ -1258,7 +1206,7 @@ void SynthOscGUI::create_objects(int y) { char text[BCTEXTLEN]; sprintf(text, "%d:", number + 1); - window->osc_subwindow->add_subwindow(title = new BC_Title(10, y + 15, text)); + window->osc_subwindow->add_subwindow(title = new BC_Title(xS(10), y+yS(15), text)); window->osc_subwindow->add_subwindow(level = new SynthOscGUILevel(window->synth, this, y)); window->osc_subwindow->add_subwindow(phase = new SynthOscGUIPhase(window->synth, this, y)); @@ -1269,11 +1217,9 @@ void SynthOscGUI::create_objects(int y) SynthOscGUILevel::SynthOscGUILevel(Synth *synth, SynthOscGUI *gui, int y) - : BC_FPot(50, - y, + : BC_FPot(xS(50), y, synth->config.oscillator_config.values[gui->number]->level, - INFINITYGAIN, - 0) + INFINITYGAIN, 0) { this->synth = synth; this->gui = gui; @@ -1295,11 +1241,9 @@ int SynthOscGUILevel::handle_event() SynthOscGUIPhase::SynthOscGUIPhase(Synth *synth, SynthOscGUI *gui, int y) - : BC_IPot(125, - y, + : BC_IPot(xS(125), y, (int64_t)(synth->config.oscillator_config.values[gui->number]->phase * 360), - 0, - 360) + 0, 360) { this->synth = synth; this->gui = gui; @@ -1321,11 +1265,9 @@ int SynthOscGUIPhase::handle_event() SynthOscGUIFreq::SynthOscGUIFreq(Synth *synth, SynthOscGUI *gui, int y) - : BC_IPot(200, - y, + : BC_FPot(xS(200), y, (int64_t)(synth->config.oscillator_config.values[gui->number]->freq_factor), - 1, - 100) + 1, 100) { this->synth = synth; this->gui = gui; @@ -1345,11 +1287,6 @@ int SynthOscGUIFreq::handle_event() } - - - - - SynthAddOsc::SynthAddOsc(Synth *synth, SynthWindow *window, int x, int y) : BC_GenericButton(x, y, _("Add")) { @@ -1370,7 +1307,6 @@ int SynthAddOsc::handle_event() } - SynthDelOsc::SynthDelOsc(Synth *synth, SynthWindow *window, int x, int y) : BC_GenericButton(x, y, _("Delete")) { @@ -1391,18 +1327,11 @@ int SynthDelOsc::handle_event() } -OscScroll::OscScroll(Synth *synth, - SynthWindow *window, - int x, - int y, - int h) - : BC_ScrollBar(x, - y, - SCROLL_VERT, - h, +OscScroll::OscScroll(Synth *synth, SynthWindow *window, + int x, int y, int h) + : BC_ScrollBar(x, y, SCROLL_VERT, h, synth->config.oscillator_config.total * OSCILLATORHEIGHT, - 0, - window->osc_subwindow->get_h()) + 0, window->osc_subwindow->get_h()) { this->synth = synth; this->window = window; @@ -1420,18 +1349,11 @@ int OscScroll::handle_event() -NoteScroll::NoteScroll(Synth *synth, - SynthWindow *window, - int x, - int y, - int w) - : BC_ScrollBar(x, - y, - SCROLL_HORIZ, - w, +NoteScroll::NoteScroll(Synth *synth, SynthWindow *window, + int x, int y, int w) + : BC_ScrollBar(x, y, SCROLL_HORIZ, w, window->white_key[0]->get_w() * TOTALNOTES * 7 / 12 + window->white_key[0]->get_w(), - 0, - window->note_subwindow->get_w()) + 0, window->note_subwindow->get_w()) { this->synth = synth; this->window = window; @@ -1448,18 +1370,6 @@ int NoteScroll::handle_event() } - - - - - - - - - - - - SynthClear::SynthClear(Synth *synth, int x, int y) : BC_GenericButton(x, y, _("Clear")) { @@ -1482,7 +1392,7 @@ int SynthClear::handle_event() SynthWaveForm::SynthWaveForm(Synth *synth, int x, int y, char *text) - : BC_PopupMenu(x, y, 120, text) + : BC_PopupMenu(x, y, xS(120), text) { this->synth = synth; } @@ -1524,11 +1434,7 @@ int SynthWaveFormItem::handle_event() SynthWetness::SynthWetness(Synth *synth, int x, int y) - : BC_FPot(x, - y, - synth->config.wetness, - INFINITYGAIN, - 0) + : BC_FPot(x, y, synth->config.wetness, INFINITYGAIN, 0) { this->synth = synth; } @@ -1566,7 +1472,7 @@ int SynthFreqPot::handle_event() SynthBaseFreq::SynthBaseFreq(Synth *synth, SynthWindow *window, int x, int y) - : BC_TextBox(x, y, 100, 1, (float)0) + : BC_TextBox(x, y, xS(100), 1, (float)0) { this->synth = synth; this->window = window; @@ -1593,17 +1499,9 @@ int SynthBaseFreq::handle_event() -SynthCanvas::SynthCanvas(Synth *synth, - SynthWindow *window, - int x, - int y, - int w, - int h) - : BC_SubWindow(x, - y, - w, - h, - BLACK) +SynthCanvas::SynthCanvas(Synth *synth, SynthWindow *window, + int x, int y, int w, int h) + : BC_SubWindow(x, y, w, h, BLACK) { this->synth = synth; this->window = window; @@ -1638,12 +1536,6 @@ int SynthCanvas::update() } - - - - - - // ======================= level calculations SynthLevelZero::SynthLevelZero(Synth *synth) : BC_MenuItem(_("Zero")) @@ -1935,6 +1827,74 @@ int SynthFreqRandom::handle_event() return 1; } +SynthFreqPow1::SynthFreqPow1(Synth *synth) + : BC_MenuItem(_("Powers of 1.4")) +{ + this->synth = synth; +} +SynthFreqPow1::~SynthFreqPow1() +{ +} + +int SynthFreqPow1::handle_event() +{ + for(int i = 0; i < synth->config.oscillator_config.total; i++) + { + synth->config.oscillator_config.values[i]->freq_factor = pow(sqrt(2), i); + } + + ((SynthWindow*)synth->thread->window)->update_gui(); + synth->send_configure_change(); + return 1; +} + + +SynthFreqPow2::SynthFreqPow2(Synth *synth) + : BC_MenuItem(_("Powers of 2")) +{ + this->synth = synth; +} +SynthFreqPow2::~SynthFreqPow2() +{ +} + +int SynthFreqPow2::handle_event() +{ + for(int i = 0; i < synth->config.oscillator_config.total; i++) + { + synth->config.oscillator_config.values[i]->freq_factor = pow(2, i); + } + + ((SynthWindow*)synth->thread->window)->update_gui(); + synth->send_configure_change(); + return 1; +} + + + + +SynthFreqMin::SynthFreqMin(Synth *synth) + : BC_MenuItem(_("Minimum")) +{ + this->synth = synth; +} +SynthFreqMin::~SynthFreqMin() +{ +} + +int SynthFreqMin::handle_event() +{ + for(int i = 0; i < synth->config.oscillator_config.total; i++) + { + synth->config.oscillator_config.values[i]->freq_factor = 1; + } + + ((SynthWindow*)synth->thread->window)->update_gui(); + synth->send_configure_change(); + return 1; +} + + SynthFreqEnum::SynthFreqEnum(Synth *synth) : BC_MenuItem(_("Enumerate")) { @@ -2014,7 +1974,8 @@ int SynthFreqFibonacci::handle_event() for(int i = 0; i < synth->config.oscillator_config.total; i++) { synth->config.oscillator_config.values[i]->freq_factor = last_value1 + last_value2; - if(synth->config.oscillator_config.values[i]->freq_factor > 100) synth->config.oscillator_config.values[i]->freq_factor = 100; + if(synth->config.oscillator_config.values[i]->freq_factor > 100) + synth->config.oscillator_config.values[i]->freq_factor = 100; last_value1 = last_value2; last_value2 = synth->config.oscillator_config.values[i]->freq_factor; }