NAudio
frequency analysis
signal processing
audio programming
C# audio开发

NAudio frequency band intensity

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

Introduction

If you want frequency-band intensity from NAudio, you are really building a small spectrum-analysis pipeline. The core steps are capturing PCM audio, buffering a fixed-size frame, applying a window, running an FFT, and then summing the bins that belong to the frequency band you care about.

The hard part is not calling the FFT function. The hard part is getting the signal-processing details right enough that the result is stable and meaningful. Wrong sample-rate assumptions, bad bin mapping, or missing windowing can make the numbers look plausible while still being misleading.

Build the FFT Input Frame Correctly

Your sample rate and FFT size determine the frequency resolution. A common setup is 44100 Hz with a 1024-sample FFT:

csharp
1using NAudio.Wave;
2
3int sampleRate = 44100;
4int fftSize = 1024;
5float[] frame = new float[fftSize];
6int framePos = 0;
7
8var capture = new WasapiLoopbackCapture();
9capture.DataAvailable += (s, e) =>
10{
11    var waveBuffer = new WaveBuffer(e.Buffer);
12    int samples = e.BytesRecorded / 4;
13
14    for (int i = 0; i < samples && framePos < fftSize; i++)
15    {
16        frame[framePos++] = waveBuffer.FloatBuffer[i];
17    }
18};

In production code, you usually want a ring buffer so frames can be processed continuously instead of only filling one array once.

Apply a Window and Run the FFT

Before the FFT, apply a window function to reduce spectral leakage. A Hamming window is a practical default:

csharp
1using NAudio.Dsp;
2
3Complex[] fft = new Complex[fftSize];
4
5for (int i = 0; i < fftSize; i++)
6{
7    float w = (float)FastFourierTransform.HammingWindow(i, fftSize);
8    fft[i].X = frame[i] * w;
9    fft[i].Y = 0f;
10}
11
12int m = (int)Math.Log(fftSize, 2);
13FastFourierTransform.FFT(true, m, fft);

After this, the first half of the FFT output contains the useful spectrum for a real-valued signal. The second half is the mirrored component and usually does not need separate analysis for band-intensity work.

Convert FFT Bins Into Frequency Bands

Each FFT bin corresponds to a frequency range. The center frequency for a bin is approximately:

bin * sampleRate / fftSize

So a band from 200 Hz to 1000 Hz maps to bin indices like this:

csharp
1int lowBin = (int)(200.0 * fftSize / sampleRate);
2int highBin = (int)(1000.0 * fftSize / sampleRate);
3
4double energy = 0;
5for (int b = lowBin; b <= highBin; b++)
6{
7    double mag = Math.Sqrt(fft[b].X * fft[b].X + fft[b].Y * fft[b].Y);
8    energy += mag;
9}

That energy value is a linear-domain intensity-like measure for the chosen band. If you want a meter-style display, converting to decibels is often more intuitive:

csharp
double db = 20.0 * Math.Log10(Math.Max(energy, 1e-12));

The small floor value avoids taking the logarithm of zero.

Smooth the Result for UI Use

Raw spectral intensity changes rapidly from frame to frame. For visualization, exponential smoothing is usually enough:

csharp
1double alpha = 0.2;
2double smoothed = 0;
3
4smoothed = alpha * db + (1.0 - alpha) * smoothed;

A lower alpha gives a steadier meter. A higher alpha responds faster to transients. The right value depends on whether you are building a music visualizer, a loudness monitor, or a trigger detector.

Validate With Known Test Tones

Before trusting live microphone or system-audio analysis, validate the pipeline with synthetic tones. For example, with a 440 Hz sine wave, the strongest energy should appear near the expected bin:

csharp
int expectedBin = (int)(440.0 * fftSize / sampleRate);
Console.WriteLine($"Expected strong bin near {expectedBin}");

This kind of check catches the most common calibration mistakes:

  • wrong sample rate
  • wrong FFT size
  • wrong band boundaries
  • reading the wrong half of the spectrum

If the test tone is not landing where expected, the rest of the pipeline is not trustworthy yet.

Common Pitfalls

The biggest mistake is running an FFT without windowing and then treating leakage as real energy. Windowing is not optional if you care about meaningful band measurements.

Another common issue is incorrect bin-to-frequency mapping. If the sample rate or FFT size used in the formula does not match the actual capture configuration, the reported bands are wrong.

People also sum raw magnitudes and compare them across different FFT sizes without normalization. That can make intensity values look inconsistent between runs.

Finally, UI updates should not happen directly on the audio callback thread. Keep audio processing, smoothing, and UI refresh decoupled so the analyzer stays real-time safe.

Summary

  • Frequency-band intensity in NAudio comes from FFT magnitudes aggregated over explicit bin ranges.
  • Capture settings, windowing, and bin mapping matter as much as the FFT call itself.
  • Convert bins to Hz with bin * sampleRate / fftSize.
  • Smooth the output if the result will drive a visible meter or graph.
  • Validate the pipeline with known tones before trusting live measurements.

Related reading
Course
Intermediate
27 lessons
14 hours
OOD Fundamentals

Master object-oriented design from first principles, SOLID, design patterns, and classic interview problems with hands-on coding.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

All Rights Reserved.