# Filtering of streaming audio

Given something like 103 data points ($N=103$), a DFT will give back 103 frequency values. Then to do something like filtering the high frequencies involves setting the high frequency values from the DFT to zero, and doing the inverse DFT to get back 103 data points that represent the original signal without the high frequencies.

This makes sense to me given all 103 data points all at once. But what about streaming an audio WAV file that is rather large (say for example $N=10^5$). If one wanted to filter the high frequencies then the approach i just described on the entire data of $10^5$ points logically makes sense. But that is not reasonable when streaming a WAV file for playback. What is done to high frequency filter a streaming playback of an audio file?

FFT -> zeroing coefficients -> IFFT is not the correct way of doing filtering - the actual filter realized by doing so has poor characteristics.

The correct way of filtering signals is to compute the coefficients of a digital filter, a process known as filter design and for which a large body of software tools/documentation is available, and apply it to your input sequence. In short, this consists in evaluating for each sample a linear combination of the past input samples, and the past output samples. Depending on the requirements of your filter in terms of stop-band rejection / ripple, only a few coefficients could be necessary, making it way more efficient than FFT. Since the only information required to compute an output sample is the few past input/output samples, there is no problem to apply it to streaming audio.

You will need to use FFT only if you decide to go with FIR filters, and if your filter requirements cause them to have an insanely large number of coefficients. In this particular case, it will be efficient to apply the filter to successive blocks of your input data through FFT and overlap-add.

The best way to apply frequency domain filtering for signal streams is overlap add (or related flavors overlap save, or block convolvers, etc.).

You basically take in one frame at a time (say 1024 samples). Zero pad to twice the length (2048), do an FFT, multiply with (also zero padded) transfer function of the filter, do an inverse FFT. Save the last 1024 samples as overlap for the next frame, add the overlap from the previous frame the the first 1024 samples and this is your output. For every 1024 input samples you get 1024 output samples and you simply repeat this for the next frames until the stream is done.

The whole business with zero padding and overlap is required since multiplication in the frequency domain implements circular convolution and you really want linear convolution in most applications.

There are variants to these methods using different window functions and overlaps but it's all the same principle: cut it up into small chunks and process one chunk at a time.