◀ Back to Theory of operation

Frequency response

What it is for

The frequency-response module measures a device's transfer function - its gain and phase shift at every frequency across the band - in a single sweep of a few seconds. Point it at a filter, an amplifier, a phono stage, a loudspeaker, and it returns the magnitude and phase curves. The result can be compared against a reference curve (RIAA, IEC) or saved as a calibration file that the FFT analyser later divides out of its own measurements.

How it works: play a sweep, divide out the input

The transfer function H(f) of a linear system is, by definition, the output spectrum divided by the input spectrum. So the measurement is conceptually simple: play a known signal X through the device, record the output Y, and divide.

H(f) = Y(f) / X(f)(1)

The known signal is a logarithmic (Farina) sine sweep[1] - the same exponential chirp described in the generator chapter, equation (9). It is chosen because it puts equal energy in every octave (good signal-to-noise across the whole band) and because its harmonic distortion separates cleanly from the linear response in the time domain, so the device's own non-linearity doesn't corrupt the curve. The conceptual background is summarised in The exponential sine sweep in practice.

sweep X(t) pre-rendered DAC DUT device under test ADC record Y(t) both channels deconvolution H = Y / X remove transport delay · time-gate resample to log grid · smooth same X(t) as reference H(f) curve magnitude · phase

The reference must be exactly what was played

Equation (1) is only honest if X is precisely the signal that drove the DAC. This is why the sweep is pre-rendered into a buffer rather than synthesized on the fly: the very same buffer is handed to the deconvolution as the reference X, so reference and stimulus are identical sample for sample. The same applies to the raised-cosine fade applied at the sweep's start and end (to suppress start/stop leakage ripple): the identical fade is applied to the reference, or the boundary shapes would mismatch and the ripple would survive the division.

Cleaning up the raw division

A few corrections turn the raw Y/X into a usable curve:

The output is reported on a logarithmic frequency grid - geometrically spaced points from start to stop - so the readout density is even across decades. The number of points is selectable in powers of two from 8192 up to several million; a named FS/2 preset sets the count to half the sample rate (24 000 points for a 48 kHz input, 96 000 at 192 kHz), giving the grid as many points as there are hertz up to Nyquist - dense enough that no resolvable feature can fall between two readout points. Both ADC channels are deconvolved in parallel, so a stereo device is characterised in one pass.

Calibration: measuring the measurer

A frequency-response sweep measures the whole chain: the DAC, the cabling, and the ADC, as well as the device under test. To isolate the device, you first sweep a known-flat path (a direct DAC->ADC loopback, or a reference cable) and save that as a calibration. Dividing a later measurement by the calibration cancels the chain's own response, leaving the device alone - exactly the cross-spectrum / reference-channel idea from the FFT essentials page, applied across a whole sweep.

Calibration is applied at plot time. The stored measurement is the raw deconvolution; the loaded calibration is divided out only when the curve is drawn (and at save time). So you can swap the calibration, or compare against RIAA/IEC reference curves, and re-trace the existing measurement instantly - no re-sweep needed. The same calibration files feed the FFT analyser's de-embedding.

The notch-tuning sweep: a live variant

Measuring the distortion of a very clean source calls for a passive twin-T notch filter[4] ahead of the ADC: it pulls the fundamental down by tens of dB so the ADC's own non-linearity is never exercised at full scale, while the harmonics pass through untouched. But a twin-T only reaches its theoretical null when its two arms are matched to a fraction of a percent, so in practice it is built with trimmers and tuned - and tuning by repeated one-shot sweeps is hopeless, because each trimmer touch needs immediate feedback. The frequency-response engine therefore offers a live variant: a very short sweep (about a quarter of a second) plays in a continuous loop while the deconvolved curve is redrawn roughly ten times per second. Turning a trimmer moves the null on screen in real time; a readout tracks the deepest point (frequency and depth in dB), and a marker at the chosen target frequency grades from green to red according to the attenuation at the target - because what matters for the distortion measurement is suppression at the fundamental you will actually use, not the depth of a null sitting somewhere nearby. The grading is relative to the null this same sweep reached: green within 1 dB of that floor, red 20 dB above it. An absolute pair of thresholds cannot work here, because the depth a twin-T can reach depends on its impedances and on the noise floor it is measured through - a network whose best null is −70 dB would never satisfy an absolute −90 dB rule however perfectly it was trimmed, while the question the operator is actually asking is "is the null on my target frequency yet".

The loop can be analysed at any arbitrary instant because its period is an exact power of two samples: any window of that length contains one complete sweep, merely rotated in time, and the rotation looks to the deconvolution like extra transport delay - which the impulse-peak delay removal described above cancels anyway. The seam of the loop is hidden by a short raised-cosine fade (25 ms per side), and the played band is widened 2.5× beyond the displayed span so that the fades and the band-edge roll-off fall outside what is shown.

Every probe lands exactly on an FFT bin. Because the analysed window is exactly one loop period, the sweep is periodic in the window: its spectrum consists of lines sitting precisely on bin centres, and there is no leakage - each bin holds the exact magnitude at that frequency. The live curve is therefore reported directly on the bin grid (a few hertz per point) rather than resampled onto the usual logarithmic grid. Interpolating between bins would be harmless for a broad response, but a good notch null spans only a handful of bins: interpolation blurs it and makes the reported depth jitter from frame to frame.

Smoothing must be off. The Savitzky-Golay smoothing that benefits an ordinary sweep is fatal here. Its sliding polynomial fit spans seven grid points - on the bin-aligned grid, a window some 15-20 Hz wide. A well-tuned null is far narrower than that, so the fit averages the steep notch walls into the minimum and fills the notch in, under-reporting its depth by roughly 9 dB. The notch sweep therefore uses the raw bin magnitudes.

The null is read off the drawn curve. The reported frequency and depth are the minimum of the trace as painted, found by evaluating the curve at every pixel column of the plot and keeping the lowest:

(fnull, Dnull) : fnull = arg mink ∈ [0, W) D(f(k))(2)

where W is the plot width in pixels, f(k) the frequency the painter maps to column k, and D the very estimator the painter draws with - the per-pixel Lanczos reconstruction while that is active for the current axis and width, plain interpolation between bins otherwise. Earlier versions refined the null by fitting a parabola through the lowest bin and its two neighbours; that fit is gone. A well-trimmed null is a V, not a parabola, and a curve laid across its two steep walls puts its vertex above the true bottom - it reported the notch shallower than it was. Reading the painted minimum instead also removes the last disagreement between the readout, the target marker and the curve on screen, which used to differ by 2-3 dB at a sharp null.

Where it sits

Unlike the scope and FFT, which share one input device, the frequency-response sweep needs the DAC and ADC simultaneously and exclusively. It therefore asks every other module to stop and waits until the devices are genuinely free before opening both directions itself - see the audio backend. It drives the generator for the sweep and produces the calibration files the FFT analyser consumes.

References

  1. 1. A. Farina, "Simultaneous measurement of impulse response and distortion with a swept-sine technique", 108th AES Convention, 2000; hands-on walkthrough: local summary.
  2. 2. Impulse response and deconvolution - Wikipedia: Impulse response, Wikipedia: Deconvolution.
  3. 3. Savitzky-Golay smoothing filter - Wikipedia: Savitzky-Golay filter.
  4. 4. Twin-T notch network - Wikipedia: Band-stop filter.

◀ De-rotation accuracy · Theory of operation