| 74 | } |
| 75 | |
| 76 | float LFO::Value(int samplesIn /*= 0*/, float forcePhase /*= -1*/) const |
| 77 | { |
| 78 | //PROFILER(LFO_Value); |
| 79 | |
| 80 | if (mPeriod == kInterval_None) //no oscillator |
| 81 | return mMode == kLFOMode_Envelope ? 1 : 0; |
| 82 | |
| 83 | float phase = CalculatePhase(samplesIn); |
| 84 | |
| 85 | if (forcePhase != -1 && !std::isnan(forcePhase)) |
| 86 | phase = forcePhase; |
| 87 | |
| 88 | phase *= FTWO_PI; |
| 89 | |
| 90 | float sample; |
| 91 | bool nonstandardOsc = false; |
| 92 | |
| 93 | //use sample-and-hold value |
| 94 | if (mOsc.GetType() == kOsc_Random) |
| 95 | { |
| 96 | nonstandardOsc = true; |
| 97 | sample = pow(mRandom.Value(gTime + samplesIn * gInvSampleRateMs), powf((1 - mOsc.GetPulseWidth()) * 2, 2)); |
| 98 | } |
| 99 | else if (mOsc.GetType() == kOsc_Drunk) |
| 100 | { |
| 101 | nonstandardOsc = true; |
| 102 | sample = mDrunk; |
| 103 | } |
| 104 | else if (mOsc.GetType() == kOsc_Perlin) |
| 105 | { |
| 106 | nonstandardOsc = true; |
| 107 | |
| 108 | double perlinPos = gTime + gInvSampleRateMs * samplesIn; |
| 109 | if (forcePhase != -1 && !std::isnan(forcePhase)) |
| 110 | perlinPos += forcePhase * 1000; |
| 111 | double perlinPhase = perlinPos * mFreeRate / 1000.0f; |
| 112 | sample = sPerlinNoise.noise(perlinPhase, mPerlinSeed, -perlinPhase); |
| 113 | } |
| 114 | else |
| 115 | { |
| 116 | sample = mOsc.Value(phase); |
| 117 | if (mMode == kLFOMode_Envelope) //rescale to 0 1 |
| 118 | sample = sample * .5f + .5f; |
| 119 | } |
| 120 | |
| 121 | if (nonstandardOsc) |
| 122 | { |
| 123 | if (mOsc.GetPulseWidth() != .5f) |
| 124 | sample = Bias(sample, mOsc.GetPulseWidth()); |
| 125 | |
| 126 | if (mMode == kLFOMode_Oscillator) //rescale to -1 1 |
| 127 | sample = (sample - .5f * 2); |
| 128 | } |
| 129 | |
| 130 | return sample; |
| 131 | } |
| 132 | |
| 133 | void LFO::SetPeriod(NoteInterval interval) |
no test coverage detected