I'd like to synthesize short samples (1 to 4 seconds) of specially filtered noise. I'll then use them in a wavetable-based Reaktor ensemble to mimic breath noise.
Such noise is basically a comb filter with peaks at the note frequency and its harmonics. But the peaks of the harmonics and the valleys between them are quite varied. I'd rather play a sample than build a complex set of filters.
I have lists, expressed in amplitudes or decibels, for the peaks and valleys. I'm familiar with Python and believe I can use it, and its FFT libraries, to create the samples. But I'm not familiar with the FFT methodologies themselves. At all.
So, I'm looking for some (hopefully) simple concepts to help me proceed. Here's a short sample of a Python program that creates white noise and then filters it using a Python FFT library.
import numpy as np
from scipy.fft import fft, ifft, fftfreq
# Sample rate in Hz & duration of noise.
sample_rate = 44100
duration = 4
# Generate white noise and normalize it.
signal = np.random.normal(0, 1, sample_rate * duration)
signal = signal / np.max(np.abs(signal))
# Apply FFT
signal_fft = fft(signal)
frequencies = fftfreq(len(signal), 1/sample_rate)
# Design a piecewise linear filter (what is happening here?)
filter_response = np.ones_like(signal_fft)
filter_response[(frequencies > 60) & (frequencies < 100)] = 0.5
filter_response[(frequencies > 100) & (frequencies < 150)] = 0.2
# Apply the filter
filtered_signal_fft = signal_fft * filter_response
# Inverse FFT to get the filtered signal
filtered_signal = ifft(filtered_signal_fft)
I need to understand what's going on at the "Design a piecewise linear filter" section. I see frequencies and amplitudes, but how do I translate the ones I have to the ones being used in the code?