I am sampling sound at 48 kHz because that's what the DAC for the headset needs. I take every 6th of these. So I have 8 kHz and process 1024 at a time. My goal is to analyse the spectrum in the final end.

My array of data, I have found out, I have presented in three different ways, instead of pointer casts:

typedef struct {
    union {
        // ================================================
        // Reuse of buffer, avoids ram usage and memcpy
        // with union instead of complex casts to pointers
        // ================================================
        mic_sample_t  mic_samples          [NUM_MIC_SAMPLES_REAL];                   // 1 * 1024
        dsp_complex_t complex_array        [NUM_FFT_POINTS_COMPLEX];                 // 2 * 512
        dsp_complex_t complex_half_spectra [NUM_FREQ_SPECTRA][NUM_FREQ_POINTS_REAL]; // 2 * 2 * 256
    } u;
} mic_samples_buff_t;

My data goes through this:

// collect as mic_samples
dsp_fft_bit_reverse (
        buffer.u.complex_array,  // 1024 signed seen as 512 complex
        NUM_FFT_POINTS_COMPLEX); // 512
dsp_fft_forward (
        NUM_FFT_POINTS_COMPLEX, // 512 complex
        FFT_SINE(NUM_FFT_POINTS_COMPLEX)); // dsp_sine_512 is dim (512/4) + 1 = 129
dsp_fft_split_spectrum (
// Handle as two complex_half_spectra

I end up with two spectra, each of 256 values, which I take the magnitude and square root of. I end up with 7.81 Hz/bin - which takes me to about 2 kHz.

I see that as my clean signal passes 2 kHz the mirror of it comes down again and moves downwards in the spectrum.

Should I put a low-pass in front of the bit reverse only? Should it have a cut-off of 2 kHz or somewhat lower? I reckon I'd have a high Q.

But then, I think I perhaps need a windowing function also, in addition. I assume that even if I end up with two spectra, I would need one window across all of the 1024 samples? I think it's the values at both ends that deliver most of the convoluted mirror frequencies, so we'd need to keep them down - in addition to low-pass? If I need both, would Hanning or Hamming be preferred?

(Aside: this is a hobby project, as a retired engineer. I plan to make one of the box, and I have no income or ads from my blog notes. I publish "everything" there. So I have described this at My Beep-BRRR notes)

  • 1
    $\begingroup$ did you filter your analog signal to 4 kHz bandwidth before sampling? Otherwise, taking only every sixth sample of an 48 kHz sampling rate will lead to severe aliasing, which no subsequent processing can remove. $\endgroup$ Apr 22, 2022 at 7:22
  • $\begingroup$ I assume there is no difference between just sampling at 8 kHz and sampling at 48 kHz and taking every 6th? But isn't 8 kHz sampling by Nyquist limited to 4 kHz? Why would I then need an additional filter? Plus, what about windowing? (Aside: I will need to get a better Hz/bin value, so I will take a 256 ms sequence instead of 128 ms. It will take me to 4 kHz after the FFT and splitting. I'm to detect alarm signals, so such a long sequence should be ok. After all, there would be two of 128 ms each that will be handled after the splitting.) $\endgroup$ Apr 22, 2022 at 7:49
  • 1
    $\begingroup$ you're absolutely right, it's the same as directly sampling at 8 kHz. And you'd only need one anti-aliasing filter, one guaranteeing a 4 kHz (or less) bandwidth. Why would you need a high frequency resolution to detect alarm signals? Sounds to me much more like you need to look for specific frequencies (in case your alarm is just a single tone or a set of discrete tones) or specific waveforms (it's a chirp thing or similar)? I don't see how a high-resolution FFT helps here? $\endgroup$ Apr 22, 2022 at 7:52
  • $\begingroup$ The seven MEMS PDM mics (I use one) are sampled at 48 kHz. There are filters in the libraries. Why band limit the 8 kHz to 4 kHz with any anti-aliasing filter? Isn't that used when one know that the signal in fact contains higher frequency components? 8 kHz samples contain max 4 kHz by themselves, don't they? I thought that my aliasing as mirror frequencies after the FFT came as a result of the rotating math in the FFT, that would benefit from windowing instead? So to repeat, do I REALLY need the anti-aliasing low-pass, plus PERHAPS the windowing? (cont.) $\endgroup$ Apr 22, 2022 at 9:10
  • 2
    $\begingroup$ "Why band-limit to 4 kHz": If you effectively sample at 8 kHz and don't band-limit to 4 kHz, you get aliasing – but you already seem to know that. If not: draw on a piece of paper a sine (say, three periods) with a lead pencil, mark its period as "1/6 ms". Now make a tick every 1/8 ms and (with a felt-tip or similar) mark the value of the sine at that point. Erase the lead pencil sine, and draw a sine that has a period > 1/4 ms (i.e. a frequency < 4 kHz). You'll see aliasing! That's a 2 kHz sine that you made out of your 6 kHz sine. $\endgroup$ Apr 22, 2022 at 9:12

1 Answer 1


There are two questions here: when do we need an "anti-alias" filter and when do we need to window the signal?


The need for an anti-alias filter is associated with the sampling process. Once any signal is sampled, the spectrum that exists from $-f_s/2$ to $+f_s/2$ where $f_s$ is the sampling rate, will periodically repeat (exactly) if we were to extend the frequency axis to $\pm \infty$. This is mathematically valid to do so, but because the results are an exact repeat, we only need to show the spectrum from $-f_s/2$ to $+f_s/2$. Further, under the narrower condition that the signal is real, the negative frequency axis will be Hermitian symmetric (same magnitude, opposite phase), so for those cases the information is also redundant and we only need to show the spectrum from $0$ to $f_s/2$.

These points are demonstrated in the graphic below showing the frequency spectrums when sampling an analog 3 Hz cosine wave with a 20 Hz sampling clock. The top row is the spectrum of the analog input, the middle row is the spectrum for the sampling process itself (which is impulses in time that we multiply with our signal to sample; the Fourier Transform of a train of impulses in time is a train of impulses in frequency). We multiplied in time, so the first two rows would convolve in frequency, resulting in the bottom row as the spectrum of our digital signal, when we show the frequency axis extending to $\pm \infty$.

sampling 3 Hz Cosine Wave

With observation of the above, it is clear that any signal at the input that has a frequency between $-f_s/2$ to $+f_s/2$ would be represented accurately in the digital spectrum at the same frequency as the input. This frequency range $-f_s/2$ to $+f_s/2$ at the input is referred to as the "First Nyquist Zone".

What gets really interesting is with further observation we can see how the sampling process is a multi-band down-converter. We see from above how the block from the first Nyquist Zone $-f_s/2$ to $+f_s/2$ in the analog was converted directly to this block in the digital spectrum. What we are about to see is that all higher blocks (such as the "Second Nyquist Zone" from $-f_s$ to $-f_s/2$ and $+f_s/2$ to $f_s$ are also translated to $-f_s/2$ to $+f_s/2$ in the digital spectrum!

Following the same description of the process for sampling the 3 Hz cosine, if we instead sampled a 23 Hz cosine, with the same 20 Hz sampling clock, we would get the spectrums as shown in the graphic below. The convolution process when dealing with impulses is simply adding the frequencies for all the impulses shown: convolving the input with the impulse at 0 in the sampling process creates the tones at +23 Hz and -23 Hz in the digital spectrum. Convolving the input with the impulse at -20 Hz in the sampling process creates the tones at -43 Hz and -3 Hz in the digital spectrum. The main point is that whatever results in any of the bands that extend from $\pm f_s/2$ centered around each multiple of the sampling rate MUST repeat in the digital spectrum. So we get the result as shown and notably, from observation of the digital result alone- we don't know if the input signal was actually as 23 Hz, or 17 Hz, or 3 Hz, or 37 Hz, or 43 Hz, or 63 Hz,...

sampling 23 Hz cosine wave

If we were however to use a filter prior to sampling that selected any one of these Nyquist Zones (and ultimately the A/D converter itself is a low pass filter as it does not have infinite bandwidth, and finite aperture width of the sampling process also limits the bandwidth), then under this condition we can really know what the sampled signal represents in the analog domain.

Everything described applies to resampling as well: when we resample a signal all the same aliasing results can apply with respect to the final output rate. Here we have the opportunity to apply the anti-alias filter for the resampled conditions in either the digital domain (prior to re-sampling!) or in the analog domain. So in the OP's case we have two options:

A more relaxed anti-alias filter with respect to the original 48 KHz sampling rate-- this filter should be concerned with passing the signal of interest, for example DC to 3 KHz, and rejecting the alias frequency bands, which would be at N x 48 KHz +/- 3 KHz. So here we could use a very simple and cheap low pass filter given the huge transition band passing up to 3KHz and rejection starting at 45 KHz. This would then be followed by a digital anti-alias filter prior to resampling to 8 KHz which would need to pass the 0 to 3 KHz signal of interest and reject the alias band from N x 8 KHz +/- 3KHz. Multiband filter techniques can easily be used in the digital domain to do this filter very efficiently.


All anti-aliasing can be done in the analog domain prior to filtering. This would be a much more challenging analog filter as it would need to pass DC to 3KHz and reject 5KHz and above (it could have multiband rejection at all the alias bands at N x 8 KHz +/- 3KHz, but that isn't as simple to implement in the analog domain).

Finally, note that even if we don't expect to have signals in any of the frequency bands that would alias, there is inevitably a noise floor and not providing the proper filtering can lead to noise enhancement.


Windowing a signal prior to taking an FFT of the signal is a completely different process for different considerations. Windowing is the process of multiplying the signal in the time domain with a tapering shape. This serves to reduce severe spectral smearing in the frequency domain. Without further windowing, a "rectangular window" is implied just by having selected a finite duration of our signal in time. The Fourier Transform of a rectangular window is a Sinc function in frequency; multiplying in time is convolving in frequency so by having multiplied our time domain signal with the rectangular function, we convolved it's frequency response with a Sinc function. Sinc functions have side-lobes that go down relatively slowly (the peaks go down by $1/f$) so this results in a significant smearing of what would otherwise be narrow impulses in frequency (for the case of single tones). Windowing with more advanced windows serves to reduce this, as detailed further in these other posts:

Why would one use a Hann or Bartlett window?

Filtering sidelobes

  • $\begingroup$ Thank you so much! I am so impressed. I voted it as "useful" only, simply because I will need to come back here, with a figure and filling-in questions. You talk about "analog domain". But from a PDM mic, would I have any such? I have autoscaled my spectrum values for each spectrum to have top on the scope at max, so the noise is easily seen - it's mostly the fan from the scope! But I'll make an absolute scaling and watch after the 1/f value of the above 2kHz that "comes down". Right now working with getting 4 kHz in the spectrum. Will be back in some days. (Is "OP" me, "original" something?) $\endgroup$ Apr 24, 2022 at 8:52
  • 1
    $\begingroup$ OP is original post. The PDM mic will already have the analog filter appropriate for the 48 KHz sampling rate. If you downsample after that, you need to implement a digital anti-alias filter before downsampling. The links I gave will help explain why but it is just like sampling in the analog: with the analog we “resample” from an infinite sampling rate to 48KHz. Then you resample from 48 KHz to 8 KHz. The aliasing mechanism and process is the same $\endgroup$ Apr 24, 2022 at 12:25
  • 1
    $\begingroup$ @ØyvindTeig Also note that even with no added analog noise (your scope fan etc) you will still always have quantization noise - so downsampling without proper filtering will increase quantization noise itself and thus decrease achievable precision or effective number of bits. $\endgroup$ Apr 24, 2022 at 12:43
  • $\begingroup$ I have now made a figure. It's here. The gray boxes are those related to the question here. I plan to use biquad low-pass filters, and I can cascade them. So I would also wonder about the degree of those filters (2, 4, 6?). I will update at that url as this proceeds, hoping to get to a more correct figure. $\endgroup$ May 9, 2022 at 8:13
  • $\begingroup$ Using a tone gen. and my own speakers, and sitting still in the same position I have tested with the values above, with no filters, one or the other or both. The scope curves are here. But I have made two measurements and they seem to have the same tendency. No filter: the mirror frequency at 4500 Hz (500 above) is larger, of the two the pre-downsampling is best, but using both is best. Garbage in = garbage out? $\endgroup$ May 10, 2022 at 14:30

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.