I am currently stuck trying to implement filter poles to stabilize a ΔΣ modulator. What I think I know is:
- a noise shaping filter with only complex zeros along the unit circle destabilizes a 1 bit ΔΣ modulator when the order is beyond 2.
- filter poles can be used to reduce the out-of-band noise, making the modulator more stable
For testing this approach, I am trying to realize a simple 2nd order modulator with 2 zeros and 2 poles.
Initially, I tried it without the poles and only with the two zeros which works and I implement it in the following way for testing (using python/numpy):
import numpy as np roots = np.exp(1j*np.array([0.05, -0.05])) # two exemplary complex roots b = np.poly(roots) # and corresponding filter coeffs errors = np.zeros_like(b) signal = np.random.rand(100) - 0.5 # any signal smaller than [-1,1] samps = np.zeros_like(signal) for iSAM in range(len(samps)): desired = signal[iSAM] + np.dot(b[1:],errors2[:-1]) # add the filtered errors to the input samps[iSAM] = np.sign(desired) # discretize to 1-bit errors = np.roll(errors, 1) errors = samps[iSAM] - desired # calculate new error
As expected when FFT'ing the results, I see a frequency response like that of the desired filter. Also as expected when adding another root at exp(i*0)=1 (creating a 3rd order modulator), the whole thing becomes unstable, even for small inputs.
I have no issue making filters with poles, and defining their frequency response. I am also able to take a time domain signal and filter it, with the designed biquad filter (2 zeros, 2 poles) and I obtain correct results.
The question is: how do I use the poles in the noise shaping algorithm. How would I even use a simple biquad filter for noise shaping ? I have watched many videos and papers today, but still don't understand it. Everyone draws these diagrams like this here from a video series i watched: https://youtu.be/IE8tU_10Hpg?t=63
A more detailed flow chart is in Stanley Lipshitz paper from 1991.
However, even if i follow this flow chart literally, I get no results. The state variables just explode. The guy in the video series also implemented a 3rd order filter with 3 zeros and 3 poles to define a stable 3rd order modulator. While I can reproduce the filter coefficients, and the Noise transfer function (NTF), I don't understand how to actually use the filter. In one video he makes a quick remark about testing the filter performance in a simulation. He says that performing the test is "trivial" or something like this. So obviously I am missing something very fundamental here :)
UPDATE: After more days of trying, I am really at a loss. Can anyone please post an example of noise shaping with even a very simple IIR filter, even with only 2 zeros and 2 poles. The shaped noise spectrum should reproduce the magnitude response of the designed filter. I am putting some bounty on it as much as I can. Because all the guides on the internet haven't helped me. I don't care about which programming language you use for it but the shaped spectrum should demonstrably produce the correct magnitude.