# Smooth random LFO Generator¶

• Author or source: Rob Belcham
• Created: 2009-06-30 08:31:24
notes
```I've been after a random LFO that's suitable for modulating a delay line for ages ( e.g
for chorus / reverb modulation) , so after i rolled my own, i thought i'd better make it
my first contribution to the music-dsp community.

My aim was to achive a sinusoidal based random but smooth waveform with a frequency
control that has no discontinuities and stays within a -1:1 range. If you listen to it, it
sounds quite like brown noise, or wind through a microphone (at rate = 100Hz for example)

It's written as a matlab m function, so shouldn't be too hard to port to C.

The oscillator generates a random level stepped waveform with random time spent at each
step (within bounds). These levels are linearly interpolated between and used to drive the
frequency of a sinewave. To achive amplitude variation, at each zero crossing a new random
amplitude scale factor is generated. The amplitude coefficient is ramped to this value
with a simple exponential.

An example call would be,
t = 4; Fs = 44100;
y = random_lfo(100, t*Fs, Fs);
axis([0, t*Fs, -1, 1]);
plot(y)

Enjoy !
```
code
 ``` 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50``` ```% Random LFO Generator % creates a random sinusoidal waveform with no discontinuities % rate = average rate in Hz % N = run length in samples % Fs = sample frequency in Hz function y = random_lfo(rate, N, Fs) step_freq_scale = Fs / (1*rate); min_Cn = 0.1 * step_freq_scale; An = 0; lastA = 0; Astep = 0; y = zeros(1,N); % output x = 0; % sine phase lastSign = 0; amp_scale = 0.6; new_amp_scale = 0.6; amp_scale_ramp = exp(1000/Fs)-1; for (n=1:N) if (An == 0) || (An>=Cn) % generate a new random freq scale factor Cn = floor(step_freq_scale * rand()); % limit to prevent rapid transitions Cn = max(Cn, min_Cn); % generate new value & step coefficient newA = 0.1 + 0.9*rand(); Astep = (newA - lastA) / Cn; A = lastA; lastA = newA; % reset counter An = 0; end An = An + 1; % generate output y(n) = sin(x) * amp_scale; % ramp amplitude amp_scale = amp_scale + ( new_amp_scale - amp_scale ) * amp_scale_ramp; sin_inc = 2*pi*rate*A/Fs; A = A + Astep; % increment phase x = x + sin_inc; if (x >= 2*pi) x = x - 2*pi; end % scale at each zero crossing if (sign(y(n)) ~= 0) && (sign(y(n)) ~= lastSign) lastSign = sign(y(n)); new_amp_scale = 0.25 + 0.75*rand(); end; end; ```