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(); }
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; }
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; }
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; } }
void SUBnoteUI::cb_detunevalueoutput_i(Fl_Value_Output* o, void*) { o->value(getdetune(pars->PDetuneType,0,pars->PDetune)); }
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; } }
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; };
// 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. };
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; } }
// 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. }