Beispiel #1
0
void SUBnoteUI::refresh() {
  for (int i=0;i<MAX_SUB_HARMONICS;i++) h[i]->refresh();
vol->value(pars->PVolume);
vsns->value(pars->PAmpVelocityScaleFunction);
pan->value(pars->PPanning);


bandwidth->value(pars->Pbandwidth);
bwidthscale->value(pars->Pbwscale-64);
bwee->value(pars->PBandWidthEnvelopeEnabled);
if (pars->PBandWidthEnvelopeEnabled==0) bandwidthenvelopegroup->deactivate();
    else bandwidthenvelopegroup->activate();
bwee->show();
bandwidthsettingsui->redraw();

detunevalueoutput->value(getdetune(pars->PDetuneType,0,pars->PDetune));
freqee->value(pars->PFreqEnvelopeEnabled);
if (pars->PFreqEnvelopeEnabled==0) freqenvelopegroup->deactivate();
    else freqenvelopegroup->activate();
freqee->show();
freqsettingsui->redraw();

detune->value(pars->PDetune-8192);
hz440->value(pars->Pfixedfreq);

fixedfreqetdial->value(pars->PfixedfreqET);

int k=pars->PCoarseDetune/1024;if (k>=8) k-=16;
octave->value(k);

detunetype->value(pars->PDetuneType-1);

k=pars->PCoarseDetune%1024;if (k>=512) k-=1024;
coarsedet->value(k);

filtere->value(pars->PGlobalFilterEnabled);
if (pars->PGlobalFilterEnabled==0) globalfiltergroup->deactivate();
    else globalfiltergroup->activate();
filtere->show();
globalfiltergroup->redraw();

stereo->value(pars->Pstereo);
filterstages->value(pars->Pnumstages);
magtype->value(pars->Phmagtype);
start->value(pars->Pstart);

ampenv->refresh();
bandwidthenvelopegroup->refresh();
freqenvelopegroup->refresh();
filterui->refresh();
filterenv->refresh();
}
Beispiel #2
0
void SUBnote::setup(float freq,
                    float velocity,
                    int portamento_,
                    int midinote,
                    bool legato)
{
    this->velocity = velocity;
    portamento  = portamento_;
    NoteEnabled = ON;
    volume      = powf(0.1f, 3.0f * (1.0f - pars.PVolume / 96.0f)); //-60 dB .. 0 dB
    volume     *= VelF(velocity, pars.PAmpVelocityScaleFunction);
    if(pars.PPanning != 0)
        panning = pars.PPanning / 127.0f;
    else
        panning = RND;
    if(!legato) {
        numstages = pars.Pnumstages;
        stereo    = pars.Pstereo;
        start     = pars.Pstart;
        firsttick = 1;
    }
    int pos[MAX_SUB_HARMONICS];

    if(pars.Pfixedfreq == 0)
        basefreq = freq;
    else {
        basefreq = 440.0f;
        int fixedfreqET = pars.PfixedfreqET;
        if(fixedfreqET) { //if the frequency varies according the keyboard note
            float tmp = (midinote - 69.0f) / 12.0f
                * (powf(2.0f, (fixedfreqET - 1) / 63.0f) - 1.0f);
            if(fixedfreqET <= 64)
                basefreq *= powf(2.0f, tmp);
            else
                basefreq *= powf(3.0f, tmp);
        }
    }
    int BendAdj = pars.PBendAdjust - 64;
    if (BendAdj % 24 == 0)
        BendAdjust = BendAdj / 24;
    else
        BendAdjust = BendAdj / 24.0f;
    float offset_val = (pars.POffsetHz - 64)/64.0f;
    OffsetHz = 15.0f*(offset_val * sqrtf(fabsf(offset_val)));
    float detune = getdetune(pars.PDetuneType,
                             pars.PCoarseDetune,
                             pars.PDetune);
    basefreq *= powf(2.0f, detune / 1200.0f); //detune
//    basefreq*=ctl.pitchwheel.relfreq;//pitch wheel

    //global filter
    GlobalFilterCenterPitch = pars.GlobalFilter->getfreq() //center freq
                              + (pars.PGlobalFilterVelocityScale / 127.0f
                                 * 6.0f)                                           //velocity sensing
                              * (VelF(velocity,
                                      pars.PGlobalFilterVelocityScaleFunction)
                                 - 1);

    if(!legato) {
        GlobalFilterL = NULL;
        GlobalFilterR = NULL;
        GlobalFilterEnvelope = NULL;
    }

    int harmonics = 0;

    //select only harmonics that desire to compute
    for(int n = 0; n < MAX_SUB_HARMONICS; ++n) {
        if(pars.Phmag[n] == 0)
            continue;
        pos[harmonics++] = n;
    }
    if(!legato)
        firstnumharmonics = numharmonics = harmonics;
    else {
        if(harmonics > firstnumharmonics)
            numharmonics = firstnumharmonics;
        else
            numharmonics = harmonics;
    }


    if(numharmonics == 0) {
        NoteEnabled = OFF;
        return;
    }


    if(!legato) {
        lfilter = memory.valloc<bpfilter>(numstages * numharmonics);
        if(stereo)
            rfilter = memory.valloc<bpfilter>(numstages * numharmonics);
    }

    //how much the amplitude is normalised (because the harmonics)
    float reduceamp = 0.0f;

    for(int n = 0; n < numharmonics; ++n) {
        float freq =  basefreq * pars.POvertoneFreqMult[pos[n]];
        overtone_freq[n] = freq;
        overtone_rolloff[n] = computerolloff(freq);

        //the bandwidth is not absolute(Hz); it is relative to frequency
        float bw =
            powf(10, (pars.Pbandwidth - 127.0f) / 127.0f * 4) * numstages;

        //Bandwidth Scale
        bw *= powf(1000 / freq, (pars.Pbwscale - 64.0f) / 64.0f * 3.0f);

        //Relative BandWidth
        bw *= powf(100, (pars.Phrelbw[pos[n]] - 64.0f) / 64.0f);

        if(bw > 25.0f)
            bw = 25.0f;

        //try to keep same amplitude on all freqs and bw. (empirically)
        float gain = sqrt(1500.0f / (bw * freq));

        float hmagnew = 1.0f - pars.Phmag[pos[n]] / 127.0f;
        float hgain;

        switch(pars.Phmagtype) {
            case 1:
                hgain = expf(hmagnew * logf(0.01f));
                break;
            case 2:
                hgain = expf(hmagnew * logf(0.001f));
                break;
            case 3:
                hgain = expf(hmagnew * logf(0.0001f));
                break;
            case 4:
                hgain = expf(hmagnew * logf(0.00001f));
                break;
            default:
                hgain = 1.0f - hmagnew;
        }
        gain      *= hgain;
        reduceamp += hgain;

        for(int nph = 0; nph < numstages; ++nph) {
            float amp = 1.0f;
            if(nph == 0)
                amp = gain;
            initfilter(lfilter[nph + n * numstages], freq + OffsetHz, bw,
                       amp, hgain);
            if(stereo)
                initfilter(rfilter[nph + n * numstages], freq + OffsetHz, bw,
                           amp, hgain);
        }
    }

    if(reduceamp < 0.001f)
        reduceamp = 1.0f;
    volume /= reduceamp;

    oldpitchwheel = 0;
    oldbandwidth  = 64;
    if(!legato) {
        if(pars.Pfixedfreq == 0)
            initparameters(basefreq);
        else
            initparameters(basefreq / 440.0f * freq);
    }
    else {
        if(pars.Pfixedfreq == 0)
            freq = basefreq;
        else
            freq *= basefreq / 440.0f;

        if(pars.PGlobalFilterEnabled) {
            globalfiltercenterq      = pars.GlobalFilter->getq();
            GlobalFilterFreqTracking = pars.GlobalFilter->getfreqtracking(
                basefreq);
        }
    }

    oldamplitude = newamplitude;
}
Beispiel #3
0
Fl_Double_Window* SUBnoteUI::make_window() {
  { SUBparameters = new Fl_Double_Window(735, 390, "SUBsynth Parameters");
    SUBparameters->user_data((void*)(this));
    { Fl_Scroll* o = new Fl_Scroll(5, 140, 435, 245);
      o->type(1);
      o->box(FL_THIN_UP_BOX);
      { Fl_Pack* o = harmonics = new Fl_Pack(10, 145, 425, 235);
        harmonics->type(1);
        for (int i=0;i<MAX_SUB_HARMONICS;i++){h[i]=new SUBnoteharmonic(0,0,15,o->h(),"");h[i]->init(pars,i);}
        harmonics->end();
      } // Fl_Pack* harmonics
      o->end();
    } // Fl_Scroll* o
    { Fl_Button* o = new Fl_Button(625, 365, 105, 20, "Close");
      o->box(FL_THIN_UP_BOX);
      o->labelfont(1);
      o->labelsize(11);
      o->callback((Fl_Callback*)cb_Close);
    } // Fl_Button* o
    { Fl_Group* o = new Fl_Group(5, 5, 215, 135, "AMPLITUDE");
      o->box(FL_THIN_UP_FRAME);
      o->labeltype(FL_EMBOSSED_LABEL);
      o->labelfont(1);
      o->align(FL_ALIGN_TOP|FL_ALIGN_INSIDE);
      { Fl_Value_Slider* o = vol = new Fl_Value_Slider(10, 25, 140, 15, "Vol");
        vol->tooltip("Volume");
        vol->type(5);
        vol->box(FL_FLAT_BOX);
        vol->labelsize(11);
        vol->maximum(127);
        vol->step(1);
        vol->callback((Fl_Callback*)cb_vol);
        vol->align(FL_ALIGN_RIGHT);
        o->value(pars->PVolume);
      } // Fl_Value_Slider* vol
      { Fl_Value_Slider* o = vsns = new Fl_Value_Slider(10, 45, 140, 15, "V.Sns");
        vsns->tooltip("Velocity Sensing Function (rightmost to disable)");
        vsns->type(5);
        vsns->box(FL_FLAT_BOX);
        vsns->labelsize(11);
        vsns->maximum(127);
        vsns->step(1);
        vsns->callback((Fl_Callback*)cb_vsns);
        vsns->align(FL_ALIGN_RIGHT);
        o->value(pars->PAmpVelocityScaleFunction);
      } // Fl_Value_Slider* vsns
      { WidgetPDial* o = pan = new WidgetPDial(185, 20, 30, 30, "Pan");
        pan->tooltip("Panning (leftmost is Random)");
        pan->box(FL_ROUND_UP_BOX);
        pan->color(FL_BACKGROUND_COLOR);
        pan->selection_color(FL_INACTIVE_COLOR);
        pan->labeltype(FL_NORMAL_LABEL);
        pan->labelfont(0);
        pan->labelsize(10);
        pan->labelcolor(FL_FOREGROUND_COLOR);
        pan->maximum(127);
        pan->step(1);
        pan->callback((Fl_Callback*)cb_pan);
        pan->align(FL_ALIGN_BOTTOM);
        pan->when(FL_WHEN_CHANGED);
        o->value(pars->PPanning);
      } // WidgetPDial* pan
      { EnvelopeUI* o = ampenv = new EnvelopeUI(10, 65, 205, 70, "SUBsynth - Amplitude Envelope");
        ampenv->box(FL_FLAT_BOX);
        ampenv->color((Fl_Color)51);
        ampenv->selection_color(FL_BACKGROUND_COLOR);
        ampenv->labeltype(FL_NORMAL_LABEL);
        ampenv->labelfont(0);
        ampenv->labelsize(14);
        ampenv->labelcolor(FL_FOREGROUND_COLOR);
        ampenv->align(FL_ALIGN_WRAP|FL_ALIGN_INSIDE);
        ampenv->when(FL_WHEN_RELEASE);
        o->init(pars->AmpEnvelope,master);
        ampenv->end();
      } // EnvelopeUI* ampenv
      o->end();
    } // Fl_Group* o
    { Fl_Group* o = new Fl_Group(495, 325, 235, 35);
      o->box(FL_THIN_UP_FRAME);
      { Fl_Counter* o = filterstages = new Fl_Counter(515, 340, 45, 15, "Filter Stages");
        filterstages->tooltip("How many times the noise is filtered");
        filterstages->type(1);
        filterstages->labelfont(1);
        filterstages->labelsize(10);
        filterstages->minimum(1);
        filterstages->maximum(5);
        filterstages->step(1);
        filterstages->textsize(10);
        filterstages->callback((Fl_Callback*)cb_filterstages);
        filterstages->align(FL_ALIGN_TOP);
        o->value(pars->Pnumstages);
      } // Fl_Counter* filterstages
      { Fl_Choice* o = magtype = new Fl_Choice(585, 340, 65, 15, "Mag.Type");
        magtype->down_box(FL_BORDER_BOX);
        magtype->labelfont(1);
        magtype->labelsize(10);
        magtype->textsize(11);
        magtype->callback((Fl_Callback*)cb_magtype);
        magtype->align(FL_ALIGN_TOP);
        magtype->menu(menu_magtype);
        o->value(pars->Phmagtype);
      } // Fl_Choice* magtype
      { Fl_Choice* o = start = new Fl_Choice(670, 340, 50, 15, "Start");
        start->down_box(FL_BORDER_BOX);
        start->labelfont(1);
        start->labelsize(10);
        start->textsize(11);
        start->callback((Fl_Callback*)cb_start);
        start->align(FL_ALIGN_TOP);
        start->menu(menu_start);
        o->value(pars->Pstart);
      } // Fl_Choice* start
      o->end();
    } // Fl_Group* o
    { freqsettingsui = new Fl_Group(440, 5, 290, 135, "FREQUENCY");
      freqsettingsui->box(FL_THIN_UP_FRAME);
      freqsettingsui->labeltype(FL_EMBOSSED_LABEL);
      freqsettingsui->labelfont(1);
      freqsettingsui->align(FL_ALIGN_TOP|FL_ALIGN_INSIDE);
      { EnvelopeUI* o = freqenvelopegroup = new EnvelopeUI(445, 65, 205, 70, "SUBsynth - Frequency Envelope");
        freqenvelopegroup->box(FL_FLAT_BOX);
        freqenvelopegroup->color((Fl_Color)51);
        freqenvelopegroup->selection_color(FL_BACKGROUND_COLOR);
        freqenvelopegroup->labeltype(FL_NORMAL_LABEL);
        freqenvelopegroup->labelfont(0);
        freqenvelopegroup->labelsize(14);
        freqenvelopegroup->labelcolor(FL_FOREGROUND_COLOR);
        freqenvelopegroup->align(FL_ALIGN_WRAP|FL_ALIGN_INSIDE);
        freqenvelopegroup->when(FL_WHEN_RELEASE);
        o->init(pars->FreqEnvelope,master);
        if (pars->PFreqEnvelopeEnabled==0) o->deactivate();
        freqenvelopegroup->end();
      } // EnvelopeUI* freqenvelopegroup
      { Fl_Check_Button* o = freqee = new Fl_Check_Button(445, 68, 55, 15, "Enabled");
        freqee->down_box(FL_DOWN_BOX);
        freqee->labelfont(1);
        freqee->labelsize(10);
        freqee->callback((Fl_Callback*)cb_freqee);
        o->value(pars->PFreqEnvelopeEnabled);
      } // Fl_Check_Button* freqee
      { Fl_Counter* o = octave = new Fl_Counter(670, 50, 45, 15, "Octave");
        octave->tooltip("Octave");
        octave->type(1);
        octave->labelsize(10);
        octave->minimum(-8);
        octave->maximum(7);
        octave->step(1);
        octave->textfont(1);
        octave->textsize(11);
        octave->callback((Fl_Callback*)cb_octave);
        octave->align(FL_ALIGN_TOP);
        int k=pars->PCoarseDetune/1024;if (k>=8) k-=16;
        o->value(k);
      } // Fl_Counter* octave
      { Fl_Counter* o = coarsedet = new Fl_Counter(655, 115, 60, 20, "Coarse Det.");
        coarsedet->tooltip("Coarse Detune");
        coarsedet->labelsize(10);
        coarsedet->minimum(-64);
        coarsedet->maximum(63);
        coarsedet->step(1);
        coarsedet->textfont(1);
        coarsedet->textsize(11);
        coarsedet->callback((Fl_Callback*)cb_coarsedet);
        coarsedet->align(FL_ALIGN_TOP);
        int k=pars->PCoarseDetune%1024;if (k>=512) k-=1024;
        o->value(k);
        o->lstep(10);
      } // Fl_Counter* coarsedet
      { Fl_Slider* o = detune = new Fl_Slider(495, 25, 230, 15);
        detune->tooltip("Fine Detune (cents)");
        detune->type(5);
        detune->box(FL_FLAT_BOX);
        detune->minimum(-8192);
        detune->maximum(8191);
        detune->step(1);
        detune->callback((Fl_Callback*)cb_detune);
        o->value(pars->PDetune-8192);
      } // Fl_Slider* detune
      { Fl_Value_Output* o = detunevalueoutput = new Fl_Value_Output(448, 25, 45, 15, "Detune");
        detunevalueoutput->labelsize(10);
        detunevalueoutput->minimum(-5000);
        detunevalueoutput->maximum(5000);
        detunevalueoutput->step(0.01);
        detunevalueoutput->textfont(1);
        detunevalueoutput->textsize(10);
        detunevalueoutput->callback((Fl_Callback*)cb_detunevalueoutput);
        detunevalueoutput->align(FL_ALIGN_TOP_LEFT);
        o->value(getdetune(pars->PDetuneType,0,pars->PDetune));
      } // Fl_Value_Output* detunevalueoutput
      { Fl_Check_Button* o = hz440 = new Fl_Check_Button(555, 45, 50, 15, "440Hz");
        hz440->tooltip("set the base frequency to 440Hz");
        hz440->down_box(FL_DOWN_BOX);
        hz440->labelfont(1);
        hz440->labelsize(10);
        hz440->callback((Fl_Callback*)cb_hz440);
        o->value(pars->Pfixedfreq);
      } // Fl_Check_Button* hz440
      { WidgetPDial* o = fixedfreqetdial = new WidgetPDial(610, 45, 15, 15, "Eq.T.");
        fixedfreqetdial->tooltip("How the frequency varies acording to the keyboard (leftmost for fixed frequen\
cy)");
        fixedfreqetdial->box(FL_ROUND_UP_BOX);
        fixedfreqetdial->color(FL_BACKGROUND_COLOR);
        fixedfreqetdial->selection_color(FL_INACTIVE_COLOR);
        fixedfreqetdial->labeltype(FL_NORMAL_LABEL);
        fixedfreqetdial->labelfont(0);
        fixedfreqetdial->labelsize(10);
        fixedfreqetdial->labelcolor(FL_FOREGROUND_COLOR);
        fixedfreqetdial->maximum(127);
        fixedfreqetdial->step(1);
        fixedfreqetdial->callback((Fl_Callback*)cb_fixedfreqetdial);
        fixedfreqetdial->align(FL_ALIGN_RIGHT);
        fixedfreqetdial->when(FL_WHEN_CHANGED);
        o->value(pars->PfixedfreqET);
        if (pars->Pfixedfreq==0) o->deactivate();
      } // WidgetPDial* fixedfreqetdial
      { Fl_Choice* o = detunetype = new Fl_Choice(655, 85, 70, 15, "Detune Type");
        detunetype->down_box(FL_BORDER_BOX);
        detunetype->labelsize(10);
        detunetype->textfont(1);
        detunetype->textsize(10);
        detunetype->callback((Fl_Callback*)cb_detunetype);
        detunetype->align(FL_ALIGN_TOP_LEFT);
        o->add("L35cents");o->add("L10cents");o->add("E100cents");o->add("E1200cents");
        o->value(pars->PDetuneType-1);
      } // Fl_Choice* detunetype
      freqsettingsui->end();
    } // Fl_Group* freqsettingsui
    { Fl_Check_Button* o = stereo = new Fl_Check_Button(440, 325, 55, 35, "Stereo");
      stereo->box(FL_THIN_UP_BOX);
      stereo->down_box(FL_DOWN_BOX);
      stereo->labelfont(1);
      stereo->labelsize(10);
      stereo->callback((Fl_Callback*)cb_stereo);
      o->value(pars->Pstereo);
    } // Fl_Check_Button* stereo
    { Fl_Button* o = new Fl_Button(445, 365, 70, 20, "Clear");
      o->tooltip("Clear the harmonics");
      o->box(FL_THIN_UP_BOX);
      o->labelfont(1);
      o->labelsize(11);
      o->callback((Fl_Callback*)cb_Clear);
    } // Fl_Button* o
    { bandwidthsettingsui = new Fl_Group(220, 5, 220, 135, "BANDWIDTH");
      bandwidthsettingsui->box(FL_THIN_UP_FRAME);
      bandwidthsettingsui->labeltype(FL_EMBOSSED_LABEL);
      bandwidthsettingsui->labelfont(1);
      bandwidthsettingsui->align(FL_ALIGN_TOP|FL_ALIGN_INSIDE);
      { EnvelopeUI* o = bandwidthenvelopegroup = new EnvelopeUI(225, 65, 205, 70, "SUBsynth - BandWidth Envelope");
        bandwidthenvelopegroup->box(FL_FLAT_BOX);
        bandwidthenvelopegroup->color((Fl_Color)51);
        bandwidthenvelopegroup->selection_color(FL_BACKGROUND_COLOR);
        bandwidthenvelopegroup->labeltype(FL_NORMAL_LABEL);
        bandwidthenvelopegroup->labelfont(0);
        bandwidthenvelopegroup->labelsize(14);
        bandwidthenvelopegroup->labelcolor(FL_FOREGROUND_COLOR);
        bandwidthenvelopegroup->align(FL_ALIGN_WRAP|FL_ALIGN_INSIDE);
        bandwidthenvelopegroup->when(FL_WHEN_RELEASE);
        o->init(pars->BandWidthEnvelope,master);
        if (pars->PBandWidthEnvelopeEnabled==0) o->deactivate();
        bandwidthenvelopegroup->end();
      } // EnvelopeUI* bandwidthenvelopegroup
      { Fl_Check_Button* o = bwee = new Fl_Check_Button(225, 67, 55, 15, "Enabled");
        bwee->down_box(FL_DOWN_BOX);
        bwee->labelfont(1);
        bwee->labelsize(10);
        bwee->callback((Fl_Callback*)cb_bwee);
        o->value(pars->PBandWidthEnvelopeEnabled);
      } // Fl_Check_Button* bwee
      { Fl_Value_Slider* o = bandwidth = new Fl_Value_Slider(225, 40, 115, 15, "Band Width");
        bandwidth->type(5);
        bandwidth->box(FL_FLAT_BOX);
        bandwidth->labelsize(10);
        bandwidth->maximum(127);
        bandwidth->step(1);
        bandwidth->callback((Fl_Callback*)cb_bandwidth);
        bandwidth->align(FL_ALIGN_TOP);
        o->value(pars->Pbandwidth);
      } // Fl_Value_Slider* bandwidth
      { Fl_Value_Slider* o = bwidthscale = new Fl_Value_Slider(345, 40, 90, 15, "B.Width Scale");
        bwidthscale->tooltip("How much I increase the BandWidth according to lower/higher harmonics");
        bwidthscale->type(5);
        bwidthscale->box(FL_FLAT_BOX);
        bwidthscale->labelsize(10);
        bwidthscale->minimum(-64);
        bwidthscale->maximum(63);
        bwidthscale->step(1);
        bwidthscale->callback((Fl_Callback*)cb_bwidthscale);
        bwidthscale->align(FL_ALIGN_TOP);
        o->value(pars->Pbwscale-64);
      } // Fl_Value_Slider* bwidthscale
      bandwidthsettingsui->end();
    } // Fl_Group* bandwidthsettingsui
    { Fl_Group* o = globalfiltergroup = new Fl_Group(440, 140, 290, 185, "FILTER");
      globalfiltergroup->box(FL_THIN_UP_FRAME);
      globalfiltergroup->labeltype(FL_EMBOSSED_LABEL);
      globalfiltergroup->labelfont(1);
      globalfiltergroup->labelsize(13);
      globalfiltergroup->align(FL_ALIGN_TOP|FL_ALIGN_INSIDE);
      { EnvelopeUI* o = filterenv = new EnvelopeUI(445, 250, 275, 70, "SUBsynth - Filter Envelope");
        filterenv->box(FL_FLAT_BOX);
        filterenv->color((Fl_Color)51);
        filterenv->selection_color(FL_BACKGROUND_COLOR);
        filterenv->labeltype(FL_NORMAL_LABEL);
        filterenv->labelfont(0);
        filterenv->labelsize(14);
        filterenv->labelcolor(FL_FOREGROUND_COLOR);
        filterenv->align(FL_ALIGN_WRAP|FL_ALIGN_INSIDE);
        filterenv->when(FL_WHEN_RELEASE);
        o->init(pars->GlobalFilterEnvelope,master);
        filterenv->end();
      } // EnvelopeUI* filterenv
      { FilterUI* o = filterui = new FilterUI(445, 170, 275, 75, "SUBsynthl - Filter");
        filterui->box(FL_FLAT_BOX);
        filterui->color(FL_LIGHT1);
        filterui->selection_color(FL_BACKGROUND_COLOR);
        filterui->labeltype(FL_NORMAL_LABEL);
        filterui->labelfont(0);
        filterui->labelsize(14);
        filterui->labelcolor(FL_FOREGROUND_COLOR);
        filterui->align(FL_ALIGN_WRAP|FL_ALIGN_INSIDE);
        filterui->when(FL_WHEN_RELEASE);
        o->init(pars->GlobalFilter,&pars->PGlobalFilterVelocityScale,&pars->PGlobalFilterVelocityScaleFunction,master);
        filterui->end();
      } // FilterUI* filterui
      if (pars->PGlobalFilterEnabled==0) o->deactivate();
      globalfiltergroup->end();
    } // Fl_Group* globalfiltergroup
    { Fl_Check_Button* o = filtere = new Fl_Check_Button(445, 145, 85, 20, "Enabled");
      filtere->down_box(FL_DOWN_BOX);
      filtere->labelfont(1);
      filtere->labelsize(11);
      filtere->callback((Fl_Callback*)cb_filtere);
      o->value(pars->PGlobalFilterEnabled);
    } // Fl_Check_Button* filtere
    { Fl_Button* o = new Fl_Button(540, 370, 25, 15, "C");
      o->box(FL_THIN_UP_BOX);
      o->color((Fl_Color)179);
      o->labelfont(1);
      o->labelsize(11);
      o->labelcolor(FL_BACKGROUND2_COLOR);
      o->callback((Fl_Callback*)cb_C);
    } // Fl_Button* o
    { Fl_Button* o = new Fl_Button(570, 370, 25, 15, "P");
      o->box(FL_THIN_UP_BOX);
      o->color((Fl_Color)179);
      o->labelfont(1);
      o->labelsize(11);
      o->labelcolor(FL_BACKGROUND2_COLOR);
      o->callback((Fl_Callback*)cb_P);
    } // Fl_Button* o
    SUBparameters->end();
  } // Fl_Double_Window* SUBparameters
  return SUBparameters;
}
Beispiel #4
0
void PADnote::setup(float freq,
                    float velocity,
                    int portamento_,
                    int midinote,
                    bool legato)
{
    portamento     = portamento_;
    this->velocity = velocity;
    finished_      = false;


    if(pars->Pfixedfreq == 0)
        basefreq = freq;
    else {
        basefreq = 440.0f;
        int fixedfreqET = pars->PfixedfreqET;
        if(fixedfreqET != 0) { //if the frequency varies according the keyboard note
            float tmp =
                (midinote
                 - 69.0f) / 12.0f
                * (powf(2.0f, (fixedfreqET - 1) / 63.0f) - 1.0f);
            if(fixedfreqET <= 64)
                basefreq *= powf(2.0f, tmp);
            else
                basefreq *= powf(3.0f, tmp);
        }
    }

    firsttime = true;
    released  = false;
    realfreq  = basefreq;
    if(!legato)
        NoteGlobalPar.Detune = getdetune(pars->PDetuneType, pars->PCoarseDetune,
                                         pars->PDetune);


    //find out the closest note
    float logfreq = logf(basefreq * powf(2.0f, NoteGlobalPar.Detune / 1200.0f));
    float mindist = fabs(logfreq - logf(pars->sample[0].basefreq + 0.0001f));
    nsample = 0;
    for(int i = 1; i < PAD_MAX_SAMPLES; ++i) {
        if(pars->sample[i].smp == NULL)
            break;
        float dist = fabs(logfreq - logf(pars->sample[i].basefreq + 0.0001f));

        if(dist < mindist) {
            nsample = i;
            mindist = dist;
        }
    }

    int size = pars->sample[nsample].size;
    if(size == 0)
        size = 1;


    if(!legato) { //not sure
        poshi_l = (int)(RND * (size - 1));
        if(pars->PStereo != 0)
            poshi_r = (poshi_l + size / 2) % size;
        else
            poshi_r = poshi_l;
        poslo = 0.0f;
    }


    if(pars->PPanning == 0)
        NoteGlobalPar.Panning = RND;
    else
        NoteGlobalPar.Panning = pars->PPanning / 128.0f;

    NoteGlobalPar.FilterCenterPitch = pars->GlobalFilter->getfreq() //center freq
                                      + pars->PFilterVelocityScale / 127.0f
                                      * 6.0f                                //velocity sensing
                                      * (VelF(velocity,
                                              pars->
                                              PFilterVelocityScaleFunction) - 1);

    if(!legato) {
        if(pars->PPunchStrength != 0) {
            NoteGlobalPar.Punch.Enabled = 1;
            NoteGlobalPar.Punch.t = 1.0f; //start from 1.0f and to 0.0f
            NoteGlobalPar.Punch.initialvalue =
                ((powf(10, 1.5f * pars->PPunchStrength / 127.0f) - 1.0f)
                 * VelF(velocity,
                        pars->PPunchVelocitySensing));
            float time =
                powf(10, 3.0f * pars->PPunchTime / 127.0f) / 10000.0f;             //0.1f .. 100 ms
            float stretch = powf(440.0f / freq, pars->PPunchStretch / 64.0f);
            NoteGlobalPar.Punch.dt = 1.0f
                                     / (time * synth->samplerate_f * stretch);
        }
        else
            NoteGlobalPar.Punch.Enabled = 0;

        NoteGlobalPar.FreqEnvelope = new Envelope(pars->FreqEnvelope, basefreq);
        NoteGlobalPar.FreqLfo      = new LFO(pars->FreqLfo, basefreq);

        NoteGlobalPar.AmpEnvelope = new Envelope(pars->AmpEnvelope, basefreq);
        NoteGlobalPar.AmpLfo      = new LFO(pars->AmpLfo, basefreq);
    }

    NoteGlobalPar.Volume = 4.0f
                           * powf(0.1f, 3.0f * (1.0f - pars->PVolume / 96.0f))      //-60 dB .. 0 dB
                           * VelF(velocity, pars->PAmpVelocityScaleFunction); //velocity sensing

    NoteGlobalPar.AmpEnvelope->envout_dB(); //discard the first envelope output
    globaloldamplitude = globalnewamplitude = NoteGlobalPar.Volume
                                              * NoteGlobalPar.AmpEnvelope->
                                              envout_dB()
                                              * NoteGlobalPar.AmpLfo->amplfoout();

    if(!legato) {
        NoteGlobalPar.GlobalFilterL = Filter::generate(pars->GlobalFilter);
        NoteGlobalPar.GlobalFilterR = Filter::generate(pars->GlobalFilter);

        NoteGlobalPar.FilterEnvelope = new Envelope(pars->FilterEnvelope,
                                                    basefreq);
        NoteGlobalPar.FilterLfo = new LFO(pars->FilterLfo, basefreq);
    }
    NoteGlobalPar.FilterQ = pars->GlobalFilter->getq();
    NoteGlobalPar.FilterFreqTracking = pars->GlobalFilter->getfreqtracking(
        basefreq);

    if(pars->sample[nsample].smp == NULL) {
        finished_ = true;
        return;
    }
}
Beispiel #5
0
void SUBnoteUI::cb_detunevalueoutput_i(Fl_Value_Output* o, void*) {
  o->value(getdetune(pars->PDetuneType,0,pars->PDetune));
}
Beispiel #6
0
void PADnote::setup(float freq,
                    float velocity_,
                    int portamento_,
                    int midinote,
                    bool legato, 
                    WatchManager *wm,
                    const char *prefix)
{
    portamento = portamento_;
    velocity   = velocity_;
    finished_  = false;


    if(!pars.Pfixedfreq)
        basefreq = freq;
    else {
        basefreq = 440.0f;
        int fixedfreqET = pars.PfixedfreqET;
        if(fixedfreqET != 0) { //if the frequency varies according the keyboard note
            float tmp =
                (midinote
                 - 69.0f) / 12.0f
                * (powf(2.0f, (fixedfreqET - 1) / 63.0f) - 1.0f);
            if(fixedfreqET <= 64)
                basefreq *= powf(2.0f, tmp);
            else
                basefreq *= powf(3.0f, tmp);
        }
    }
    int BendAdj = pars.PBendAdjust - 64;
    if (BendAdj % 24 == 0)
        BendAdjust = BendAdj / 24;
    else
        BendAdjust = BendAdj / 24.0f;
    float offset_val = (pars.POffsetHz - 64)/64.0f;
    OffsetHz = 15.0f*(offset_val * sqrtf(fabsf(offset_val)));
    firsttime = true;
    realfreq  = basefreq;
    if(!legato)
        NoteGlobalPar.Detune = getdetune(pars.PDetuneType, pars.PCoarseDetune,
                                         pars.PDetune);


    //find out the closest note
    float logfreq = logf(basefreq * powf(2.0f, NoteGlobalPar.Detune / 1200.0f));
    float mindist = fabs(logfreq - logf(pars.sample[0].basefreq + 0.0001f));
    nsample = 0;
    for(int i = 1; i < PAD_MAX_SAMPLES; ++i) {
        if(pars.sample[i].smp == NULL)
            break;
        float dist = fabs(logfreq - logf(pars.sample[i].basefreq + 0.0001f));

        if(dist < mindist) {
            nsample = i;
            mindist = dist;
        }
    }

    int size = pars.sample[nsample].size;
    if(size == 0)
        size = 1;


    if(!legato) { //not sure
        poshi_l = (int)(RND * (size - 1));
        if(pars.PStereo)
            poshi_r = (poshi_l + size / 2) % size;
        else
            poshi_r = poshi_l;
        poslo = 0.0f;
    }


    if(pars.PPanning == 0)
        NoteGlobalPar.Panning = RND;
    else
        NoteGlobalPar.Panning = pars.PPanning / 128.0f;

    if(!legato) {
        NoteGlobalPar.Fadein_adjustment =
            pars.Fadein_adjustment / (float)FADEIN_ADJUSTMENT_SCALE;
        NoteGlobalPar.Fadein_adjustment *= NoteGlobalPar.Fadein_adjustment;
        if(pars.PPunchStrength != 0) {
            NoteGlobalPar.Punch.Enabled = 1;
            NoteGlobalPar.Punch.t = 1.0f; //start from 1.0f and to 0.0f
            NoteGlobalPar.Punch.initialvalue =
                ((powf(10, 1.5f * pars.PPunchStrength / 127.0f) - 1.0f)
                 * VelF(velocity,
                        pars.PPunchVelocitySensing));
            const float time =
                powf(10, 3.0f * pars.PPunchTime / 127.0f) / 10000.0f;             //0.1f .. 100 ms
            const float stretch = powf(440.0f / freq, pars.PPunchStretch / 64.0f);
            NoteGlobalPar.Punch.dt = 1.0f
                                     / (time * synth.samplerate_f * stretch);
        }
        else
            NoteGlobalPar.Punch.Enabled = 0;

        ScratchString pre = prefix;

        NoteGlobalPar.FreqEnvelope =
            memory.alloc<Envelope>(*pars.FreqEnvelope, basefreq, synth.dt(),
                    wm, (pre+"FreqEnvelope/").c_str);
        NoteGlobalPar.FreqLfo      =
            memory.alloc<LFO>(*pars.FreqLfo, basefreq, time,
                    wm, (pre+"FreqLfo/").c_str);

        NoteGlobalPar.AmpEnvelope =
            memory.alloc<Envelope>(*pars.AmpEnvelope, basefreq, synth.dt(),
                    wm, (pre+"AmpEnvelope/").c_str);
        NoteGlobalPar.AmpLfo      =
            memory.alloc<LFO>(*pars.AmpLfo, basefreq, time,
                    wm, (pre+"AmpLfo/").c_str);
    }

    NoteGlobalPar.Volume = 4.0f
                           * powf(0.1f, 3.0f * (1.0f - pars.PVolume / 96.0f))      //-60 dB .. 0 dB
                           * VelF(velocity, pars.PAmpVelocityScaleFunction); //velocity sensing

    NoteGlobalPar.AmpEnvelope->envout_dB(); //discard the first envelope output
    globaloldamplitude = globalnewamplitude = NoteGlobalPar.Volume
                                              * NoteGlobalPar.AmpEnvelope->
                                              envout_dB()
                                              * NoteGlobalPar.AmpLfo->amplfoout();

    if(!legato) {
        ScratchString pre = prefix;
        auto &flt = NoteGlobalPar.GlobalFilter;
        auto &env = NoteGlobalPar.FilterEnvelope;
        auto &lfo = NoteGlobalPar.FilterLfo;
        assert(flt == nullptr);
        flt = memory.alloc<ModFilter>(*pars.GlobalFilter, synth, time, memory, true, basefreq);

        //setup mod
        env = memory.alloc<Envelope>(*pars.FilterEnvelope, basefreq,
                synth.dt(), wm, (pre+"FilterEnvelope/").c_str);
        lfo = memory.alloc<LFO>(*pars.FilterLfo, basefreq, time,
                wm, (pre+"FilterLfo/").c_str);
        flt->addMod(*env);
        flt->addMod(*lfo);
    }

    {
        auto &flt = *NoteGlobalPar.GlobalFilter;
        flt.updateSense(velocity, pars.PFilterVelocityScale,
                        pars.PFilterVelocityScaleFunction);
        flt.updateNoteFreq(basefreq);
    }

    if(!pars.sample[nsample].smp) {
        finished_ = true;
        return;
    }
}
Beispiel #7
0
SUBnote::SUBnote(SUBnoteParameters *parameters,
                 Controller *ctl_,
                 REALTYPE freq,
                 REALTYPE velocity,
                 int portamento_,
                 int midinote,
                 bool besilent)
{
    ready=0;

    tmpsmp=new REALTYPE[SOUND_BUFFER_SIZE];
    tmprnd=new REALTYPE[SOUND_BUFFER_SIZE];

	this->velocity=velocity;
	this->freq = freq;

    // Initialise some legato-specific vars
    Legato.msg=LM_Norm;
    Legato.fade.length=(int)(SAMPLE_RATE*0.005);// 0.005 seems ok.
    if (Legato.fade.length<1) Legato.fade.length=1;// (if something's fishy)
    Legato.fade.step=(1.0/Legato.fade.length);
    Legato.decounter=-10;
    Legato.param.freq=freq;
    Legato.param.vel=velocity;
    Legato.param.portamento=portamento_;
    Legato.param.midinote=midinote;
    Legato.silent=besilent;

    pars=parameters;
    ctl=ctl_;
    portamento=portamento_;
    NoteEnabled=ON;
    volume=pow(0.1,3.0*(1.0-pars->PVolume/96.0));//-60 dB .. 0 dB
    volume*=VelF(velocity,pars->PAmpVelocityScaleFunction);
    if (pars->PPanning!=0) panning=pars->PPanning/127.0;
    else panning=RND;
    numstages=pars->Pnumstages;
    stereo=pars->Pstereo;
    start=pars->Pstart;
    firsttick=1;
    //int pos[MAX_SUB_HARMONICS];

    if (pars->Pfixedfreq==0) basefreq=freq;
    else {
        basefreq=440.0;
        int fixedfreqET=pars->PfixedfreqET;
        if (fixedfreqET!=0) {//if the frequency varies according the keyboard note
            REALTYPE tmp=(midinote-69.0)/12.0*(pow(2.0,(fixedfreqET-1)/63.0)-1.0);
            if (fixedfreqET<=64) basefreq*=pow(2.0f,tmp);
            else basefreq*=pow(3.0f,tmp);
        };

    };
    REALTYPE detune=getdetune(pars->PDetuneType,pars->PCoarseDetune,pars->PDetune);
    basefreq*=pow(2.0,detune/1200.0);//detune
//    basefreq*=ctl->pitchwheel.relfreq;//pitch wheel

    //global filter
    GlobalFilterCenterPitch=pars->GlobalFilter->getfreq()+//center freq
                            (pars->PGlobalFilterVelocityScale/127.0*6.0)* //velocity sensing
                            (VelF(velocity,pars->PGlobalFilterVelocityScaleFunction)-1);

    GlobalFilterL=NULL;
    GlobalFilterR=NULL;
    GlobalFilterEnvelope=NULL;

    //select only harmonics that desire to compute
    numharmonics=0;
    for (int n=0;n<MAX_SUB_HARMONICS;n++) {
        if (pars->Phmag[n]==0)continue;
        if (n*basefreq>SAMPLE_RATE/2.0) break;//remove the freqs above the Nyquist freq
        pos[numharmonics++]=n;
    };
    firstnumharmonics=numharmonics;//(gf)Useful in legato mode.

    if (numharmonics==0) {
        NoteEnabled=OFF;
        return;
    };


    lfilter=new bpfilter[numstages*numharmonics];
    if (stereo!=0) rfilter=new bpfilter[numstages*numharmonics];

    //how much the amplitude is normalised (because the harmonics)
    reduceamp=0.0;

    for (int n=0;n<numharmonics;n++) {

        REALTYPE freq=basefreq*(pos[n]+1);

        //the bandwidth is not absolute(Hz); it is relative to frequency
        REALTYPE bw=pow(10,(pars->Pbandwidth-127.0)/127.0*4)*numstages;

        //Bandwidth Scale
        bw*=pow(1000/freq,(float)((pars->Pbwscale-64.0)/64.0*3.0));

        //Relative BandWidth
        bw*=pow(100,(float)((pars->Phrelbw[pos[n]]-64.0)/64.0));

        if (bw>25.0) bw=25.0;

        //try to keep same amplitude on all freqs and bw. (empirically)
        gain=sqrt(1500.0/(bw*freq));

        hmagnew=1.0-pars->Phmag[pos[n]]/127.0;
        //hgain;

        switch (pars->Phmagtype) {
        case 1:
            hgain=exp(hmagnew*log(0.01));
            break;
        case 2:
            hgain=exp(hmagnew*log(0.001));
            break;
        case 3:
            hgain=exp(hmagnew*log(0.0001));
            break;
        case 4:
            hgain=exp(hmagnew*log(0.00001));
            break;
        default:
            hgain=1.0-hmagnew;
        };
        gain*=hgain;
        reduceamp+=hgain;

        for (int nph=0;nph<numstages;nph++) {
            REALTYPE amp=1.0;
            if (nph==0) amp=gain;
            initfilter(lfilter[nph+n*numstages],freq,bw,amp,hgain);
            if (stereo!=0) initfilter(rfilter[nph+n*numstages],freq,bw,amp,hgain);
        };
    };

    if (reduceamp<0.001) reduceamp=1.0;
    volume/=reduceamp;

    oldpitchwheel=0;
    oldbandwidth=64;
    if (pars->Pfixedfreq==0) initparameters(basefreq);
    else initparameters(basefreq/440.0*freq);

    oldamplitude=newamplitude;
    ready=1;
};
Beispiel #8
0
// SUBlegatonote: This function is (mostly) a copy of SUBnote(...) and
// initparameters(...) stuck together with some lines removed so that
// it only alter the already playing note (to perform legato). It is
// possible I left stuff that is not required for this.
void SUBnote::SUBlegatonote(REALTYPE freq,
                            REALTYPE velocity,
                            int portamento_,
                            int midinote,
                            bool externcall)
{
    //SUBnoteParameters *parameters=pars;
    //Controller *ctl_=ctl;

    // Manage legato stuff
    if (externcall) Legato.msg=LM_Norm;
    if (Legato.msg!=LM_CatchUp) {
        Legato.lastfreq=Legato.param.freq;
        Legato.param.freq=freq;
        Legato.param.vel=velocity;
        Legato.param.portamento=portamento_;
        Legato.param.midinote=midinote;
        if (Legato.msg==LM_Norm) {
            if (Legato.silent) {
                Legato.fade.m=0.0;
                Legato.msg=LM_FadeIn;
            } else {
                Legato.fade.m=1.0;
                Legato.msg=LM_FadeOut;
                return;
            }
        }
        if (Legato.msg==LM_ToNorm) Legato.msg=LM_Norm;
    }

    portamento=portamento_;
	this->freq = freq;

    volume=pow(0.1,3.0*(1.0-pars->PVolume/96.0));//-60 dB .. 0 dB
    volume*=VelF(velocity,pars->PAmpVelocityScaleFunction);
    if (pars->PPanning!=0) panning=pars->PPanning/127.0;
    else panning=RND;

    ///start=pars->Pstart;

    //int pos[MAX_SUB_HARMONICS];

    if (pars->Pfixedfreq==0) basefreq=freq;
    else {
        basefreq=440.0;
        int fixedfreqET=pars->PfixedfreqET;
        if (fixedfreqET!=0) {//if the frequency varies according the keyboard note
            REALTYPE tmp=(midinote-69.0)/12.0*(pow(2.0,(fixedfreqET-1)/63.0)-1.0);
            if (fixedfreqET<=64) basefreq*=pow(2.0f,tmp);
            else basefreq*=pow(3.0f,tmp);
        };
    };
    REALTYPE detune=getdetune(pars->PDetuneType,pars->PCoarseDetune,pars->PDetune);
    basefreq*=pow(2.0,detune/1200.0);//detune

    //global filter
    GlobalFilterCenterPitch=pars->GlobalFilter->getfreq()+//center freq
                            (pars->PGlobalFilterVelocityScale/127.0*6.0)* //velocity sensing
                            (VelF(velocity,pars->PGlobalFilterVelocityScaleFunction)-1);


    int legatonumharmonics=0;
    for (int n=0;n<MAX_SUB_HARMONICS;n++) {
        if (pars->Phmag[n]==0)continue;
        if (n*basefreq>SAMPLE_RATE/2.0) break;//remove the freqs above the Nyquist freq
        pos[legatonumharmonics++]=n;
    };
    if (legatonumharmonics>firstnumharmonics) numharmonics=firstnumharmonics;
    else numharmonics=legatonumharmonics;

    if (numharmonics==0) {
        NoteEnabled=OFF;
        return;
    };


    //how much the amplitude is normalised (because the harmonics)
    reduceamp=0.0;

    for (int n=0;n<numharmonics;n++) {

        REALTYPE freq=basefreq*(pos[n]+1);

        //the bandwidth is not absolute(Hz); it is relative to frequency
        REALTYPE bw=pow(10,(pars->Pbandwidth-127.0)/127.0*4)*numstages;

        //Bandwidth Scale
        bw*=pow(1000/freq,(float)((pars->Pbwscale-64.0)/64.0*3.0));

        //Relative BandWidth
        bw*=pow(100,(float)((pars->Phrelbw[pos[n]]-64.0)/64.0));

        if (bw>25.0) bw=25.0;

        //try to keep same amplitude on all freqs and bw. (empirically)
        gain=sqrt(1500.0/(bw*freq));

        hmagnew=1.0-pars->Phmag[pos[n]]/127.0;
        

        switch (pars->Phmagtype) {
        case 1:
            hgain=exp(hmagnew*log(0.01));
            break;
        case 2:
            hgain=exp(hmagnew*log(0.001));
            break;
        case 3:
            hgain=exp(hmagnew*log(0.0001));
            break;
        case 4:
            hgain=exp(hmagnew*log(0.00001));
            break;
        default:
            hgain=1.0-hmagnew;
        };
        gain*=hgain;
        reduceamp+=hgain;

        for (int nph=0;nph<numstages;nph++) {
            REALTYPE amp=1.0;
            if (nph==0) amp=gain;
            initfilter(lfilter[nph+n*numstages],freq,bw,amp,hgain);
            if (stereo!=0) initfilter(rfilter[nph+n*numstages],freq,bw,amp,hgain);
        };
    };

    if (reduceamp<0.001) reduceamp=1.0;
    volume/=reduceamp;

    oldpitchwheel=0;
    oldbandwidth=64;

    if (pars->Pfixedfreq==0) freq=basefreq;
    else freq*=basefreq/440.0;


    ///////////////
    // Altered initparameters(...) content:

    if (pars->PGlobalFilterEnabled!=0) {
        globalfiltercenterq=pars->GlobalFilter->getq();
        GlobalFilterFreqTracking=pars->GlobalFilter->getfreqtracking(basefreq);
    };

    // end of the altered initparameters function content.
    ///////////////

    oldamplitude=newamplitude;

    // End of the SUBlegatonote function.
};
Beispiel #9
0
PADnote::PADnote(PADnoteParameters *parameters,
                 Controller *ctl_,
                 REALTYPE freq,
                 REALTYPE velocity,
                 int portamento_,
                 int midinote,
                 bool besilent)
{
    ready = 0;

    // Initialise some legato-specific vars
    Legato.msg = LM_Norm;
    Legato.fade.length      = (int)(SAMPLE_RATE * 0.005); // 0.005 seems ok.
    if(Legato.fade.length < 1)
        Legato.fade.length = 1;                    // (if something's fishy)
    Legato.fade.step        = (1.0 / Legato.fade.length);
    Legato.decounter        = -10;
    Legato.param.freq       = freq;
    Legato.param.vel        = velocity;
    Legato.param.portamento = portamento_;
    Legato.param.midinote   = midinote;
    Legato.silent  = besilent;

    pars           = parameters;
    portamento     = portamento_;
    ctl            = ctl_;
    this->velocity = velocity;
    finished_      = false;


    if(pars->Pfixedfreq == 0)
        basefreq = freq;
    else {
        basefreq = 440.0;
        int fixedfreqET = pars->PfixedfreqET;
        if(fixedfreqET != 0) { //if the frequency varies according the keyboard note
            REALTYPE tmp =
                (midinote
                 - 69.0) / 12.0 * (pow(2.0, (fixedfreqET - 1) / 63.0) - 1.0);
            if(fixedfreqET <= 64)
                basefreq *= pow(2.0, tmp);
            else
                basefreq *= pow(3.0, tmp);
        }
    }

    firsttime = true;
    released  = false;
    realfreq  = basefreq;
    NoteGlobalPar.Detune = getdetune(pars->PDetuneType,
                                     pars->PCoarseDetune, pars->PDetune);


    //find out the closest note
    REALTYPE logfreq = log(basefreq * pow(2.0, NoteGlobalPar.Detune / 1200.0));
    REALTYPE mindist = fabs(logfreq - log(pars->sample[0].basefreq + 0.0001));
    nsample = 0;
    for(int i = 1; i < PAD_MAX_SAMPLES; i++) {
        if(pars->sample[i].smp == NULL)
            break;
        REALTYPE dist = fabs(logfreq - log(pars->sample[i].basefreq + 0.0001));
//	printf("(mindist=%g) %i %g                  %g\n",mindist,i,dist,pars->sample[i].basefreq);

        if(dist < mindist) {
            nsample = i;
            mindist = dist;
        }
    }

    int size = pars->sample[nsample].size;
    if(size == 0)
        size = 1;


    poshi_l = (int)(RND * (size - 1));
    if(pars->PStereo != 0)
        poshi_r = (poshi_l + size / 2) % size;
    else
        poshi_r = poshi_l;
    poslo   = 0.0;

    tmpwave = new REALTYPE [SOUND_BUFFER_SIZE];



    if(pars->PPanning == 0)
        NoteGlobalPar.Panning = RND;
    else
        NoteGlobalPar.Panning = pars->PPanning / 128.0;

    NoteGlobalPar.FilterCenterPitch = pars->GlobalFilter->getfreq() //center freq
                                      + pars->PFilterVelocityScale / 127.0
                                      * 6.0                                //velocity sensing
                                      * (VelF(velocity,
                                              pars->
                                              PFilterVelocityScaleFunction) - 1);

    if(pars->PPunchStrength != 0) {
        NoteGlobalPar.Punch.Enabled      = 1;
        NoteGlobalPar.Punch.t = 1.0; //start from 1.0 and to 0.0
        NoteGlobalPar.Punch.initialvalue =
            ((pow(10, 1.5 * pars->PPunchStrength / 127.0) - 1.0)
             * VelF(velocity,
                    pars->PPunchVelocitySensing));
        REALTYPE time    = pow(10, 3.0 * pars->PPunchTime / 127.0) / 10000.0; //0.1 .. 100 ms
        REALTYPE stretch = pow(440.0 / freq, pars->PPunchStretch / 64.0);
        NoteGlobalPar.Punch.dt = 1.0 / (time * SAMPLE_RATE * stretch);
    }
    else
        NoteGlobalPar.Punch.Enabled = 0;



    NoteGlobalPar.FreqEnvelope = new Envelope(pars->FreqEnvelope, basefreq);
    NoteGlobalPar.FreqLfo      = new LFO(pars->FreqLfo, basefreq);

    NoteGlobalPar.AmpEnvelope  = new Envelope(pars->AmpEnvelope, basefreq);
    NoteGlobalPar.AmpLfo = new LFO(pars->AmpLfo, basefreq);

    NoteGlobalPar.Volume = 4.0 * pow(0.1, 3.0 * (1.0 - pars->PVolume / 96.0)) //-60 dB .. 0 dB
                           * VelF(velocity, pars->PAmpVelocityScaleFunction); //velocity sensing

    NoteGlobalPar.AmpEnvelope->envout_dB(); //discard the first envelope output
    globaloldamplitude = globalnewamplitude = NoteGlobalPar.Volume
                                              * NoteGlobalPar.AmpEnvelope->
                                              envout_dB()
                                              * NoteGlobalPar.AmpLfo->amplfoout();

    NoteGlobalPar.GlobalFilterL      = new Filter(pars->GlobalFilter);
    NoteGlobalPar.GlobalFilterR      = new Filter(pars->GlobalFilter);

    NoteGlobalPar.FilterEnvelope     = new Envelope(pars->FilterEnvelope,
                                                    basefreq);
    NoteGlobalPar.FilterLfo          = new LFO(pars->FilterLfo, basefreq);
    NoteGlobalPar.FilterQ = pars->GlobalFilter->getq();
    NoteGlobalPar.FilterFreqTracking = pars->GlobalFilter->getfreqtracking(
        basefreq);

    ready = 1; ///sa il pun pe asta doar cand e chiar gata

    if(parameters->sample[nsample].smp == NULL) {
        finished_ = true;
        return;
    }
}
Beispiel #10
0
// PADlegatonote: This function is (mostly) a copy of PADnote(...)
// with some lines removed so that it only alter the already playing
// note (to perform legato). It is possible I left stuff that is not
// required for this.
void PADnote::PADlegatonote(REALTYPE freq,
                            REALTYPE velocity,
                            int portamento_,
                            int midinote,
                            bool externcall)
{
    PADnoteParameters *parameters = pars;
    //Controller *ctl_=ctl;

    // Manage legato stuff
    if(externcall)
        Legato.msg = LM_Norm;
    if(Legato.msg != LM_CatchUp) {
        Legato.lastfreq   = Legato.param.freq;
        Legato.param.freq = freq;
        Legato.param.vel  = velocity;
        Legato.param.portamento = portamento_;
        Legato.param.midinote   = midinote;
        if(Legato.msg == LM_Norm) {
            if(Legato.silent) {
                Legato.fade.m = 0.0;
                Legato.msg    = LM_FadeIn;
            }
            else {
                Legato.fade.m = 1.0;
                Legato.msg    = LM_FadeOut;
                return;
            }
        }
        if(Legato.msg == LM_ToNorm)
            Legato.msg = LM_Norm;
    }

    portamento     = portamento_;
    this->velocity = velocity;
    finished_      = false;

    if(pars->Pfixedfreq == 0)
        basefreq = freq;
    else {
        basefreq = 440.0;
        int fixedfreqET = pars->PfixedfreqET;
        if(fixedfreqET != 0) { //if the frequency varies according the keyboard note
            REALTYPE tmp =
                (midinote
                 - 69.0) / 12.0 * (pow(2.0, (fixedfreqET - 1) / 63.0) - 1.0);
            if(fixedfreqET <= 64)
                basefreq *= pow(2.0, tmp);
            else
                basefreq *= pow(3.0, tmp);
        }
    }

    released = false;
    realfreq = basefreq;

    getdetune(pars->PDetuneType, pars->PCoarseDetune, pars->PDetune);


    //find out the closest note
    REALTYPE logfreq = log(basefreq * pow(2.0, NoteGlobalPar.Detune / 1200.0));
    REALTYPE mindist = fabs(logfreq - log(pars->sample[0].basefreq + 0.0001));
    nsample = 0;
    for(int i = 1; i < PAD_MAX_SAMPLES; i++) {
        if(pars->sample[i].smp == NULL)
            break;
        REALTYPE dist = fabs(logfreq - log(pars->sample[i].basefreq + 0.0001));

        if(dist < mindist) {
            nsample = i;
            mindist = dist;
        }
    }

    int size = pars->sample[nsample].size;
    if(size == 0)
        size = 1;

    if(pars->PPanning == 0)
        NoteGlobalPar.Panning = RND;
    else
        NoteGlobalPar.Panning = pars->PPanning / 128.0;

    NoteGlobalPar.FilterCenterPitch = pars->GlobalFilter->getfreq() //center freq
                                      + pars->PFilterVelocityScale / 127.0
                                      * 6.0                                //velocity sensing
                                      * (VelF(velocity,
                                              pars->
                                              PFilterVelocityScaleFunction) - 1);


    NoteGlobalPar.Volume = 4.0 * pow(0.1, 3.0 * (1.0 - pars->PVolume / 96.0)) //-60 dB .. 0 dB
                           * VelF(velocity, pars->PAmpVelocityScaleFunction); //velocity sensing

    NoteGlobalPar.AmpEnvelope->envout_dB(); //discard the first envelope output
    globaloldamplitude = globalnewamplitude = NoteGlobalPar.Volume
                                              * NoteGlobalPar.AmpEnvelope->
                                              envout_dB()
                                              * NoteGlobalPar.AmpLfo->amplfoout();

    NoteGlobalPar.FilterQ = pars->GlobalFilter->getq();
    NoteGlobalPar.FilterFreqTracking = pars->GlobalFilter->getfreqtracking(
        basefreq);


    if(parameters->sample[nsample].smp == NULL) {
        finished_ = true;
        return;
    }

    // End of the PADlegatonote function.
}