hilbert.h
The analytic signal, and the frequency shifter built on it.
#include <sonore/hilbert.h>- 2types
- Guides: Getting started, MIDI and MPE
On this page
Design notes
A frequency shifter moves every partial by the same number of hertz -- not a pitch shift, which multiplies them -- and the result is the Bode shifter's inharmonic shimmer, the feedback-safe "detune" that never builds up, single-sideband ring modulation. All of it needs the signal's quadrature twin: a copy with every frequency shifted by exactly ninety degrees, at every frequency at once. No FIR of sensible length does that, and no first-order allpass does; what does is a PAIR of allpass cascades whose phase responses differ by ninety degrees across the band.
The pair is derived, not pasted. An elliptic half-band lowpass can be written as two parallel allpass branches, H(z) = ½[A0(z²) + z⁻¹A1(z²)] (Valenzuela & Constantinides 1983; Ansari 1985 for the elliptic design of exactly this class), and its coefficients come from the elliptic nome for the transition width asked for -- the same construction resample.h uses with Butterworth poles, here elliptic because elliptic is what makes a twelve-section pair accurate to a degree from 300 Hz to 20 kHz. Rotating the half-band's frequency axis by a quarter turn (z -> jz, which negates each section's coefficient) turns the two branches into the Hilbert pair: the passband between the transition edges becomes the band over which the branches are ninety degrees apart. The test measures that angle at six frequencies and the image rejection of the shifter, which is what the angle buys.
Included by dsp.h.
Types 2
template <int Sections = 12> class HilbertTransformer
Two allpass cascades, ninety degrees apart from transition × fs up to (½ − transition) × fs. Sections is the total; they alternate between the branches. 12 sections and a transition of 0.005 (240 Hz at 48 kHz) is the default: a degree of error across the band that matters.
The Bode frequency shifter: the analytic signal multiplied by a complex exponential, real part out. Positive shifts move everything up; the sideband that would fold to the other side is what the Hilbert pair suppresses, and its residue is the image rejection the test measures. There is no dry/wet mix, and that is deliberate: both outputs of the Hilbert pair are phase-shifted copies of the input, so the input itself summed with the shifted signal combs. Feedback is the caller's, and this is the effect that makes a feedback loop safe to build.