[sdiy] digital noise band generator?
Olivier Gillet
ol.gillet at gmail.com
Thu Aug 25 16:16:54 CEST 2011
> Thanks for the responses so far.
> I have had a vision - a white noise source through an adjustable LP filter
> at frequency F1 fed to a ring modulator, with a sine oscillator frequency F2
> to the other input.
> If I am correct, and assuming the LP filter goes to zero frequency, then the
> modulator output will be a noise band of (F1-0) width on both sides of F2.
>
> How bad the notching in the middle will be (due to not being able to get to
> zero freq) will be, I cannot say. But I think it might do for experimenting.
I tried it:
http://img198.imageshack.us/img198/434/screenshot20110825at358.png
I don't think the notch at the modulator frequency will be noticeable.
The big difference between the LP + ringmod approach and a true
bandpass "sculpting" the white noise is that in the first case the
spectrum will have one axis of symmetry which won't be present with a
true band-limited white noise. I generated audio samples and it sounds
like there's a difference in tone (.wav available on demand).
If you have the computational resources to do a sharp LP, you might as
well directly do a BP!
Here is the quick code:
==== 8< =====
import numpy
import pylab
sr = 44100
bandwidth = 1000
center_frequency = 4000
num_samples = 32768
def plot_spectrum(x, label):
xf = numpy.fft.rfft(x)
f = numpy.arange(0.0, len(xf)) / len(x) * sr
pylab.plot(f[1:], 20 * numpy.log10(numpy.abs(xf[1:]) + 1e-8))
pylab.title(label)
def plot_xcorr(x, label):
xc = numpy.fft.irfft(numpy.abs(numpy.fft.rfft(x) ** 2))
pylab.plot(xc[:400])
pylab.title(label)
x = numpy.random.randn(num_samples)
t = numpy.arange(0.0, num_samples) / sr
mod = numpy.sin(2 * numpy.pi * t * center_frequency)
# Compute impulse response of LP
filter_len = 8192
h = numpy.zeros((filter_len, ))
h[:int(bandwidth * filter_len / sr)] = 1
h = numpy.fft.fftshift(numpy.fft.irfft(h))
# Filter by LP and ringmod
y = numpy.convolve(x, h, 'same')
z = y * mod
# Compute impulse response of BP
h = numpy.zeros((filter_len, ))
ffrom = 2 * (center_frequency - bandwidth / 2)
fto = 2 * (center_frequency + bandwidth / 2)
h[int(ffrom * filter_len / sr):int(fto * filter_len / sr)] = 1
h = numpy.fft.fftshift(numpy.fft.irfft(h))
zz = numpy.convolve(x, h, 'same')
pylab.subplot(421)
plot_spectrum(x, 'white')
pylab.subplot(423)
plot_spectrum(y, 'lp')
pylab.subplot(425)
plot_spectrum(z, 'lp ringmod')
pylab.subplot(427)
plot_spectrum(zz, 'bp')
pylab.subplot(422)
plot_xcorr(x, 'white')
pylab.subplot(424)
plot_xcorr(y, 'lp')
pylab.subplot(426)
plot_xcorr(z, 'lp ringmod')
pylab.subplot(428)
plot_xcorr(zz, 'bp')
file('ringmod.raw', 'w').write(z.astype(numpy.float32).tostring())
file('bandpass.raw', 'w').write(zz.astype(numpy.float32).tostring())
More information about the Synth-diy
mailing list