LFO::LFO(LFOParams *lfopars, float basefreq, SynthEngine *_synth): synth(_synth) { if (lfopars->Pstretch == 0) lfopars->Pstretch = 1; float lfostretch = powf(basefreq / 440.0f, (float)((int)lfopars->Pstretch - 64) / 63.0f); // max 2x/octave float lfofreq = (powf(2.0f, lfopars->Pfreq * 10.0f) - 1.0f) / 12.0f * lfostretch; incx = fabsf(lfofreq) * synth->buffersize_f / synth->samplerate_f; if (lfopars->Pcontinous == 0) { if (lfopars->Pstartphase == 0) x = synth->numRandom(); else x = fmodf(((float)((int)lfopars->Pstartphase - 64) / 127.0f + 1.0f), 1.0f); } else { float tmp = fmodf(synth->getLFOtime() * incx, 1.0f); x = fmodf((((int)lfopars->Pstartphase - 64) / 127.0f + 1.0f + tmp), 1.0f); } // Limit the Frequency (or else...) if (incx > 0.49999999f) incx = 0.499999999f; lfornd = lfopars->Prandomness / 127.0f; if (lfornd < 0.0f) lfornd = 0.0f; else if (lfornd > 1.0f) lfornd = 1.0f; // (orig comment) lfofreqrnd=pow(lfopars->Pfreqrand/127.0,2.0)*2.0*4.0; lfofreqrnd = powf(lfopars->Pfreqrand / 127.0f, 2.0f) * 4.0f; switch (lfopars->fel) { case 1: lfointensity = lfopars->Pintensity / 127.0f; break; case 2: lfointensity = lfopars->Pintensity / 127.0f * 4.0f; break; // in octave default: lfointensity = powf(2.0f, lfopars->Pintensity / 127.0f * 11.0f) - 1.0f; // in centi x -= 0.25f; // chance the starting phase break; } amp1 = (1 - lfornd) + lfornd * synth->numRandom(); amp2 = (1 - lfornd) + lfornd * synth->numRandom(); lfotype = lfopars->PLFOtype; lfodelay = lfopars->Pdelay / 127.0f * 4.0f; // 0..4 sec incrnd = nextincrnd = 1.0f; freqrndenabled = (lfopars->Pfreqrand != 0); computenextincrnd(); computenextincrnd(); // twice because I want incrnd & nextincrnd to be random }
LFO::LFO(LFOParams *lfopars, REALTYPE basefreq) { if(lfopars->Pstretch == 0) lfopars->Pstretch = 1; REALTYPE lfostretch = pow(basefreq / 440.0, (lfopars->Pstretch - 64.0) / 63.0); //max 2x/octave REALTYPE lfofreq = (pow(2, lfopars->Pfreq * 10.0) - 1.0) / 12.0 * lfostretch; incx = fabs(lfofreq) * (REALTYPE)SOUND_BUFFER_SIZE / (REALTYPE)SAMPLE_RATE; if(lfopars->Pcontinous == 0) { if(lfopars->Pstartphase == 0) x = RND; else x = fmod((lfopars->Pstartphase - 64.0) / 127.0 + 1.0, 1.0); } else { REALTYPE tmp = fmod(lfopars->time * incx, 1.0); x = fmod((lfopars->Pstartphase - 64.0) / 127.0 + 1.0 + tmp, 1.0); } //Limit the Frequency(or else...) if(incx > 0.49999999) incx = 0.499999999; lfornd = lfopars->Prandomness / 127.0; if(lfornd < 0.0) lfornd = 0.0; else if(lfornd > 1.0) lfornd = 1.0; // lfofreqrnd=pow(lfopars->Pfreqrand/127.0,2.0)*2.0*4.0; lfofreqrnd = pow(lfopars->Pfreqrand / 127.0, 2.0) * 4.0; switch(lfopars->fel) { case 1: lfointensity = lfopars->Pintensity / 127.0; break; case 2: lfointensity = lfopars->Pintensity / 127.0 * 4.0; break; //in octave default: lfointensity = pow(2, lfopars->Pintensity / 127.0 * 11.0) - 1.0; //in centi x -= 0.25; //chance the starting phase break; } amp1 = (1 - lfornd) + lfornd * RND; amp2 = (1 - lfornd) + lfornd * RND; lfotype = lfopars->PLFOtype; lfodelay = lfopars->Pdelay / 127.0 * 4.0; //0..4 sec incrnd = nextincrnd = 1.0; freqrndenabled = (lfopars->Pfreqrand != 0); computenextincrnd(); computenextincrnd(); //twice because I want incrnd & nextincrnd to be random }
// LFO out float LFO::lfoout(void) { float out; switch (lfotype) { case 1: // LFO_TRIANGLE if (x >= 0.0f && x < 0.25f) out = 4.0f * x; else if (x > 0.25f && x < 0.75f) out = 2.0f - 4.0f * x; else out = 4.0f * x - 4.0f; break; case 2: // LFO_SQUARE if (x < 0.5f) out = -1.0f; else out = 1.0f; break; case 3: // LFO_RAMPUP out = (x - 0.5f) * 2.0f; break; case 4: // LFO_RAMPDOWN out = (0.5f - x) * 2.0f; break; case 5: // LFO_EXP_DOWN 1 out = powf(0.05f, x) * 2.0f - 1.0f; break; case 6: // LFO_EXP_DOWN 2 out = powf(0.001f, x) * 2.0f - 1.0f; break; default: out = cosf( x * TWOPI); // LFO_SINE } if (lfotype == 0 || lfotype == 1) out *= lfointensity * (amp1 + x * (amp2 - amp1)); else out *= lfointensity * amp2; if (lfodelay < 0.00001f) { if (!freqrndenabled) x += incx; else { float tmp = (incrnd * (1.0f - x) + nextincrnd * x); tmp = (tmp > 1.0f) ? 1.0f : tmp; x += incx * tmp; } if (x >= 1) { x = fmodf(x, 1.0f); amp1 = amp2; amp2 = (1 - lfornd) + lfornd * synth->numRandom(); computenextincrnd(); } } else lfodelay -= synth->buffersize_f / synth->samplerate_f; return out; }
inline void LFO::Recompute(void) { // mostly copied from LFO::LFO() RecomputeFreq(); lfornd = lfopars->Prandomness / 127.0f; if (lfornd < 0.0f) lfornd = 0.0f; else if (lfornd > 1.0f) lfornd = 1.0f; // (orig comment) lfofreqrnd=pow(lfopars->Pfreqrand/127.0,2.0)*2.0*4.0; lfofreqrnd = powf(lfopars->Pfreqrand / 127.0f, 2.0f) * 4.0f; switch (lfopars->fel) { case 1: lfointensity = lfopars->Pintensity / 127.0f; break; case 2: lfointensity = lfopars->Pintensity / 127.0f * 4.0f; break; // in octave default: lfointensity = powf(2.0f, lfopars->Pintensity / 127.0f * 11.0f) - 1.0f; // in centi break; } lfotype = lfopars->PLFOtype; freqrndenabled = (lfopars->Pfreqrand != 0); computenextincrnd(); }
LFO::LFO(LFOParams *_lfopars, float _basefreq, SynthEngine *_synth): lfopars(_lfopars), basefreq(_basefreq), synth(_synth) { if (lfopars->Pstretch == 0) lfopars->Pstretch = 1; RecomputeFreq(); // need incx early if (lfopars->Pcontinous == 0) { // pre-init phase if (lfopars->Pstartphase == 0) x = synth->numRandom(); else x = fmodf(((float)((int)lfopars->Pstartphase - 64) / 127.0f + 1.0f), 1.0f); } else { // pre-init phase, synced to other notes float tmp = fmodf(synth->getLFOtime() * incx, 1.0f); x = fmodf((((int)lfopars->Pstartphase - 64) / 127.0f + 1.0f + tmp), 1.0f); } lfodelay = lfopars->Pdelay / 127.0f * 4.0f; // 0..4 sec incrnd = nextincrnd = 1.0f; Recompute(); if (lfopars->fel == 0) // this is a Frequency LFO x -= 0.25f; // change the starting phase amp1 = (1 - lfornd) + lfornd * synth->numRandom(); amp2 = (1 - lfornd) + lfornd * synth->numRandom(); computenextincrnd(); // twice because I want incrnd & nextincrnd to be random }
/* * LFO out */ REALTYPE LFO::lfoout(){ REALTYPE out; switch (lfotype){ case 1: //LFO_TRIANGLE if ((x>=0.0)&&(x<0.25)) out=4.0*x; else if ((x>0.25)&&(x<0.75)) out=2-4*x; else out=4.0*x-4.0; break; case 2: //LFO_SQUARE if (x<0.5) out=-1; else out=1; break; case 3: //LFO_RAMPUP out=(x-0.5)*2.0; break; case 4: //LFO_RAMPDOWN out=(0.5-x)*2.0; break; case 5: //LFO_EXP_DOWN 1 out=pow(0.05,x)*2.0-1.0; break; case 6: //LFO_EXP_DOWN 2 out=pow(0.001,x)*2.0-1.0; break; default:out=cos(x*2.0*double_Pi);//LFO_SINE }; if ((lfotype==0)||(lfotype==1)) out*=lfointensity*(amp1+x*(amp2-amp1)); else out*=lfointensity*amp2; if (lfodelay<0.00001) { if (freqrndenabled==0) x+=incx; else x+=incx*(incrnd*(1.0-x)+nextincrnd*x); if (x>=1) { x=fmod(x,1.0); amp1=amp2; amp2=(1-lfornd)+lfornd*RND; computenextincrnd(); }; } else lfodelay-=(REALTYPE)SOUND_BUFFER_SIZE/(REALTYPE)SAMPLE_RATE; return(out); };
void LFO::init( float sample_rate, float base_frequency, // note const struct zyn_lfo_parameters * parameters_ptr, unsigned int type) { float lfostretch; float lfofreq; m_sample_rate = sample_rate; // max 2x/octave lfostretch = pow(base_frequency / 440.0, parameters_ptr->stretch); lfofreq = pow(2, parameters_ptr->frequency * 10.0); lfofreq -= 1.0; lfofreq /= 12.0; lfofreq *= lfostretch; m_incx = fabs(lfofreq) * (float)SOUND_BUFFER_SIZE / sample_rate; m_x = parameters_ptr->random_start_phase ? zyn_random() : parameters_ptr->start_phase; // Limit the Frequency(or else...) if (m_incx > 0.49999999) { m_incx = 0.499999999; } m_depth_randomness_enabled = parameters_ptr->depth_randomness_enabled; if (m_depth_randomness_enabled) { if (parameters_ptr->depth_randomness < 0.0) { assert(0); // this should be checked by caller m_depth_randomness = 0.0; } else if (parameters_ptr->depth_randomness > 1.0) { assert(0); // this should be checked by caller m_depth_randomness = 1.0; } else { m_depth_randomness = parameters_ptr->depth_randomness; } m_amp1 = (1 - m_depth_randomness) + m_depth_randomness * zyn_random(); m_amp2 = (1 - m_depth_randomness) + m_depth_randomness * zyn_random(); } else { m_amp1 = 1; m_amp2 = 1; } m_frequency_randomness_enabled = parameters_ptr->frequency_randomness_enabled; if (m_frequency_randomness_enabled) { // m_frequency_randomness = pow(parameters_ptr->frequency_randomness, 2.0) * 2.0 * 4.0; m_frequency_randomness = pow(parameters_ptr->frequency_randomness, 2.0) * 4.0; } switch (type) { case ZYN_LFO_TYPE_AMPLITUDE: m_lfointensity = parameters_ptr->depth; break; case ZYN_LFO_TYPE_FILTER: // in octave m_lfointensity = parameters_ptr->depth * 4.0; break; case ZYN_LFO_TYPE_FREQUENCY: // in centi m_lfointensity = pow(2, parameters_ptr->depth * 11.0) - 1.0; m_x -= 0.25; // chance the starting phase break; default: assert(0); } m_shape = parameters_ptr->shape; m_delay = parameters_ptr->delay; m_incrnd = m_nextincrnd = 1.0; // twice because I want incrnd & nextincrnd to be random computenextincrnd(); computenextincrnd(); }
/* * LFO out */ float LFO::lfoout() { float out; float tmp; switch (m_shape) { case ZYN_LFO_SHAPE_TYPE_SINE: out = cos(m_x * 2.0 * PI); case ZYN_LFO_SHAPE_TYPE_TRIANGLE: if ((m_x >= 0.0) && (m_x < 0.25)) { out = 4.0 * m_x; } else if ((m_x > 0.25) && (m_x < 0.75)) { out = 2 - 4 * m_x; } else { out = 4.0 * m_x - 4.0; } break; case ZYN_LFO_SHAPE_TYPE_SQUARE: if (m_x < 0.5) { out =- 1; } else { out = 1; } break; case ZYN_LFO_SHAPE_TYPE_RAMP_UP: out = (m_x - 0.5) * 2.0; break; case ZYN_LFO_SHAPE_TYPE_RAMP_DOWN: out = (0.5 - m_x) * 2.0; break; case ZYN_LFO_SHAPE_TYPE_EXP_DOWN_1: out = pow(0.05, m_x) * 2.0 - 1.0; break; case ZYN_LFO_SHAPE_TYPE_EXP_DOWN_2: out = pow(0.001, m_x) * 2.0 - 1.0; break; default: assert(0); }; if ((m_shape == ZYN_LFO_SHAPE_TYPE_SINE) || (m_shape == ZYN_LFO_SHAPE_TYPE_TRIANGLE)) { out *= m_lfointensity * (m_amp1 + m_x * (m_amp2 - m_amp1)); } else { out *= m_lfointensity * m_amp2; } if (m_delay < 0.00001) { if (m_frequency_randomness_enabled == 0) { m_x += m_incx; } else { tmp = (m_incrnd * (1.0 - m_x) + m_nextincrnd * m_x); if (tmp > 1.0) { tmp = 1.0; } else if (tmp < 0.0) { tmp = 0.0; } m_x += m_incx * tmp; } if (m_x >= 1) { m_x = fmod(m_x, 1.0); m_amp1 = m_amp2; if (m_depth_randomness_enabled) { m_amp2 = (1 - m_depth_randomness) + m_depth_randomness * zyn_random(); } else { m_amp2 = 1; } computenextincrnd(); } } else { m_delay -= (float)SOUND_BUFFER_SIZE / m_sample_rate; } return out; }