Documentation
¶
Overview ¶
Package filter implements the FIR/CIC/halfband primitives used by the DSP pipeline. All filters operate on complex64 IQ samples or real float32 signals; coefficients are stored as float32.
Index ¶
Constants ¶
const ( DeEmphasis75us = 75 * time.Microsecond // FM broadcast in North America DeEmphasis50us = 50 * time.Microsecond // FM broadcast in Europe / most other regions )
Common pre-emphasis time constants. Pass to NewDeEmphasis with the PCM sample rate the filter will see.
Variables ¶
This section is empty.
Functions ¶
func Gaussian ¶
Gaussian returns the impulse response of a Gaussian pulse-shaping / matched filter parameterised by samples-per-symbol, span (in symbols), and the BT product (3 dB bandwidth × symbol period). BT = 0.3 is the standard GFSK premod for EDACS / GE-Marc; BT = 0.5 is typical for Bluetooth. Taps are normalised to unit DC gain so a sustained NRZ level passes through unchanged at the symbol centre.
func HalfbandLowpass ¶
HalfbandLowpass returns coefficients for a length-N halfband lowpass suitable for ×2 decimation. Roughly half the taps are zero (every other tap except the center). Designed via Kaiser window with cutoff at fs/4.
func LowpassKaiser ¶
LowpassKaiser designs a length-N (odd) lowpass FIR with cutoff fc (normalized; 0.5 = Nyquist) using a Kaiser window with shape beta.
func RootRaisedCosine ¶
RootRaisedCosine returns the impulse response of a root-raised-cosine pulse-shaping filter. sps = samples per symbol, nSymbols = total span, alpha = roll-off (0 < alpha ≤ 1). The filter is normalized to unit energy.
Types ¶
type CICDecimator ¶
type CICDecimator struct {
// contains filtered or unexported fields
}
CICDecimator is a multi-stage CIC decimator with rate factor R and N stages. Output is at input/R rate. Suitable for an initial coarse decimation before a sharper FIR; CIC has a sin(x)/x droop that should be compensated by a downstream FIR.
func NewCICDecimator ¶
func NewCICDecimator(rate, stages int) *CICDecimator
func (*CICDecimator) Gain ¶
func (c *CICDecimator) Gain() int64
Gain returns the DC gain of the cascade: R^N. Callers typically divide the output by this value (or shift right by ceil(N*log2(R))).
func (*CICDecimator) ProcessReal ¶
func (c *CICDecimator) ProcessReal(dst []int64, src []int64) []int64
ProcessReal decimates a real signal scaled into int16 (caller scales as needed). Returns the decimated samples appended to dst.
type DeEmphasis ¶
type DeEmphasis struct {
// contains filtered or unexported fields
}
DeEmphasis is the single-pole IIR low-pass that recovers the pre-emphasized treble curve broadcast FM transmitters apply for SNR. The transmitter pre-emphasizes (boosts highs) with a single-pole high-shelf characterized by time constant τ; the receiver inverts with the matching low-pass:
H(s) = 1 / (1 + sτ)
Discretized impulse-invariant at sample rate fs, the difference equation is:
α = exp(-1 / (τ × fs)) y[n] = (1 - α) × x[n] + α × y[n-1]
The DC gain is unity, the −3 dB cutoff is fc = 1 / (2π τ).
Use NewDeEmphasisUS for the 75 µs constant standard in NA, or NewDeEmphasisEU for the 50 µs constant used in most of the world.
DeEmphasis is *not* safe for concurrent Process calls — pin it to a single demod goroutine and Reset between calls.
func NewDeEmphasis ¶
func NewDeEmphasis(tau time.Duration, sampleRate float64) *DeEmphasis
NewDeEmphasis builds a de-emphasis filter tuned to time constant τ at the given sample rate. Both must be positive; the constructor panics otherwise so misconfiguration trips at startup rather than silently producing wrong audio.
func NewDeEmphasisUS ¶
func NewDeEmphasisUS(sampleRate float64) *DeEmphasis
NewDeEmphasisUS is shorthand for NewDeEmphasis(DeEmphasis75us, sampleRate).
func (*DeEmphasis) Process ¶
func (d *DeEmphasis) Process(dst, src []float32) []float32
Process applies the filter to src and writes the result to dst (or appends to it). dst is reused if it has enough capacity. In-place operation (dst == src) is supported.
func (*DeEmphasis) Reset ¶
func (d *DeEmphasis) Reset()
Reset clears the filter's running state. Call between calls so stale audio from one transmission doesn't bleed into the next.
type FIR ¶
type FIR struct {
// contains filtered or unexported fields
}
FIR is a linear-phase finite-impulse-response filter for complex64 IQ. It maintains an internal sample history so consecutive Process calls produce a continuous output stream.
type Halfband2x ¶
type Halfband2x struct {
// contains filtered or unexported fields
}
Halfband2x decimates by 2 using a halfband FIR. Internally it just routes the decimated stream out of a regular FIR; we keep this as a convenience because we know half the taps multiply by zero and could be skipped in a SIMD pass later.
func NewHalfband2x ¶
func NewHalfband2x(taps []float32) *Halfband2x
func (*Halfband2x) Process ¶
func (h *Halfband2x) Process(dst, src []complex64) []complex64
type RealFIR ¶
type RealFIR struct {
// contains filtered or unexported fields
}
RealFIR is the real-valued counterpart of FIR. Same circular-buffer convolution shape, but operates on float32 audio samples instead of complex IQ. Sized for the post-demod chain in internal/voice/composer where the FM demod hands real audio to a band-limiting LPF before the second decimation to PCM.
Like FIR, it isn't safe for concurrent Process calls — pin it to a single demod goroutine and Reset between calls.
func NewRealFIR ¶
NewRealFIR copies taps into a new filter and allocates the matching history ring. The constructor panics on an empty tap slice so a misconfiguration trips at startup.