[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