The fun thing is: FIR filters don't have a state, so you can evaluate them individually for each sample in any order you like. Since you're down-sampling after filtering anyway it would not make sense to run the filter at 176.4kHz and then discard half of the results. Instead run the first filter at 88.2kHz on each second input sample and directly generate the 88.2kHz output.
The same applies to the second cascade which directly outputs a 44.1kHz signal.
If you put these two numbers together you'll effectively get down-sampling and anti-alias filtering of your 176.4kHz signal at the price of a single filter running at 132.3kHz (88.2 + 44.1).
Thanks again for all these great tips torusle! I have an implementation that is working but after looking at the results another question has popped up.
Obviously using an FIR will introduce some latency or lag in the system, i.e. if I compare the filtered output to the unfiltered output the filtered output lags behind the unfiltered output by a certain number of samples (that is related to the filter order if I understand correctly).
Is there any way to get rid of this? I found some articles which proposed that the first few sample should be thrown away to synchronize the filtered signal with the unfiltered one. However, I wonder whether such an approach is only feasible for offline cases where all the data is known before hand.
To be more clear let's consider an example. Let's say I have a plugin and the process method is called with a buffer size of 128 samples. Also let's assume that the filter introduces a delay of 8 samples before the "real" filtered signal appears. A "note on" event occurs and my oscillator starts to produce some output. If my filter produces 128 samples from which we need to throw away the first 8 samples it will effectively have created 120 samples that I can put in the buffer. However, for a complete result I will need to compute the next 8 samples which I can only get once I will produce the next 128 samples, i.e. during the next process call which might provide me with other input data.
Am I overthinking this? Do I have to care about these delays? What do other synth implementations do? In my examples even having only a few samples of delay already resulted in quite large phase offsets compared to the unfiltered signal, e.g. offsets of 72 degrees. Also if I have several other oversampling processes in my chain, e.g. for some distortion effect, these numbers will add up to even more delay and make things even worse.
Passed 303 posts. Next stop: 808.