Creating wind instrument breath noise samples via FFT

Chet Singer
Chet Singer Member Posts: 73 Advisor
edited October 26 in Building With Reaktor

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?

Comments

  • Tr97
    Tr97 Member Posts: 19 Member

    🤔Hmm, this looks more like a stairstep curve, f=1..60 →1, 61..99 → 0.5 and 101..149 → 0.2, 150.. →1 again

    But I have no Python experience, so maybe I am missing something

    For a piecewise linear response I would use something of the form a=a0+(f-f0)/(f1-f0)*(a1-a0) for each piece (with f0,f1 outer frequencies, a0,a1 target amplitudes)

  • Chet Singer
    Chet Singer Member Posts: 73 Advisor

    Thanks for your help. But I don't understand your last paragraph. I think I need to read up and understand more about what FFTs actually are.

  • Tr97
    Tr97 Member Posts: 19 Member

    Oh sry, the last paragraph is not really well formulated, it is only supposed to be a formula for a linear function through two points, for a single piece so to speak - it is not FFT related

Back To Top