dsp

package
v0.1.5 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 16, 2026 License: Apache-2.0 Imports: 3 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type AGC

type AGC struct {
	Reference float32 // target output magnitude (default 1.0)
	Rate      float32 // adaptation step (typical 1e-3 to 1e-2)
	MaxGain   float32 // ceiling to avoid runaway on dead-air
	// contains filtered or unexported fields
}

AGC is a feedback automatic-gain-control loop that drives the average magnitude of a complex IQ stream toward Reference.

func NewAGC

func NewAGC(reference, rate, maxGain float32) *AGC

func (*AGC) Gain

func (a *AGC) Gain() float32

func (*AGC) Process

func (a *AGC) Process(dst, src []complex64) []complex64

type AudioAGC

type AudioAGC struct {
	// contains filtered or unexported fields
}

AudioAGC is the real-valued counterpart of AGC, sized for the post-demod chain in internal/voice/composer. The IQ-domain AGC drives the *complex* baseband magnitude toward a target with a single adaptation rate, which works because FM has a constant envelope on air. After demod the signal is voice — bursty, with short loud transients separated by quieter passages — so a single rate either pumps badly (too fast) or never catches up (too slow).

AudioAGC is a classic envelope-follower + gain stage:

abs   = |x|
if abs > level: level += (1 - α_attack) × (abs - level)   // ramp up fast
else:           level += (1 - α_release) × (abs - level)  // ramp down slow
gain  = clamp(reference / max(level, floor), 0, MaxGain)
y[n]  = x[n] × gain

Attack / release are time constants (in samples after construction); short attack catches transients before they clip, long release keeps the gain steady through speech gaps so the output doesn't pump. Reference is the target |y| ≈ Reference; pick something that leaves headroom for downstream stages (typical 0.3 keeps int16 conversion comfortably under MaxInt16 at the existing 10 000-scale in voice/composer).

AudioAGC is not safe for concurrent Process calls — pin it to a single demod goroutine and Reset between calls.

func NewAudioAGC

func NewAudioAGC(cfg AudioAGCConfig) *AudioAGC

NewAudioAGC builds an envelope-follower-based AGC. Bad parameters trip a panic at startup so misconfiguration shows up loudly rather than silently producing wrong audio.

func (*AudioAGC) Gain

func (a *AudioAGC) Gain() float32

Gain returns the current adaptive gain. Useful for diagnostics; not needed for normal operation.

func (*AudioAGC) Process

func (a *AudioAGC) Process(dst, src []float32) []float32

Process applies the AGC to src and writes to dst (or appends to it). dst is reused if it has enough capacity; in-place src == dst is supported.

func (*AudioAGC) Reset

func (a *AudioAGC) Reset()

Reset clears the running envelope estimate so the next Process call starts from silence (gain begins at MaxGain).

type AudioAGCConfig

type AudioAGCConfig struct {
	Reference  float32       // target |output| (default 0.3)
	Attack     time.Duration // ramp-up time constant (default 5 ms)
	Release    time.Duration // ramp-down time constant (default 200 ms)
	MaxGain    float32       // ceiling on adaptive gain (default 64.0)
	SampleRate float64       // sample rate of the audio stream (Hz, required)
}

AudioAGCConfig configures NewAudioAGC. All time constants are in real time; the constructor folds in the sample rate.

type RealResampler

type RealResampler struct {
	L, M int
	// contains filtered or unexported fields
}

RealResampler is the real-valued counterpart of Resampler. Same polyphase decomposition, same L/M rate, but operates on float32 audio instead of complex64 IQ. Sized for the post-demod chain in internal/voice/composer where the FM demod hands real audio to a resampler that retunes 48 kHz → 8 kHz (or arbitrary rational ratios) with proper anti-aliasing built into the polyphase prototype filter.

The complex Resampler stays where it is — IQ paths still want it. Splitting them keeps each loop hot on the right data type without the complex64 ↔ float32 conversion overhead that an interface would impose.

RealResampler is not safe for concurrent Process calls — pin it to a single demod goroutine and Reset between calls.

func NewRealResampler

func NewRealResampler(L, M, tapsPerBranch int, beta float64) *RealResampler

NewRealResampler builds a real-valued resampler with rate L/M using a Kaiser-window LPF of total length tapsPerBranch*L. Cutoff is min(0.5/L, 0.5/M) so the prototype rejects images and aliases for both the interpolation and decimation steps. Bad parameters trip a panic at construction so misconfiguration shows up loudly.

func (*RealResampler) Process

func (r *RealResampler) Process(dst, src []float32) []float32

Process consumes len(src) input samples and returns approximately len(src)*L/M output samples. dst is reused if it has capacity.

func (*RealResampler) Reset

func (r *RealResampler) Reset()

Reset clears the running history and commutator state so the next Process call starts from silence.

type Resampler

type Resampler struct {
	L, M int
	// contains filtered or unexported fields
}

Resampler is a polyphase rational resampler with rate L/M. It interpolates by L (using polyphase branches of an LPF) and decimates by M.

func NewResampler

func NewResampler(L, M, tapsPerBranch int, beta float64) *Resampler

NewResampler builds a resampler with rate L/M using a Kaiser-window LPF of total length tapsPerBranch*L. Cutoff is min(0.5/L, 0.5/M) so that the filter rejects images and aliases for both interpolation and decimation.

func (*Resampler) Process

func (r *Resampler) Process(dst, src []complex64) []complex64

Process consumes len(src) input samples and returns approximately len(src)*L/M output samples. dst is reused if it has capacity.

Directories

Path Synopsis
Package channelizer implements an M-channel critically-sampled polyphase channelizer.
Package channelizer implements an M-channel critically-sampled polyphase channelizer.
Package demod contains baseband demodulators that convert IQ streams into real-valued symbol streams (or audio, for FM).
Package demod contains baseband demodulators that convert IQ streams into real-valued symbol streams (or audio, for FM).
Package diversity combines IQ streams from N receivers tuned to the same frequency into a single per-sample IQ stream that's stronger and less faded than any one source.
Package diversity combines IQ streams from N receivers tuned to the same frequency into a single per-sample IQ stream that's stronger and less faded than any one source.
Package equalizer implements adaptive channel equalizers used to fight simulcast distortion — the inter-symbol interference produced when multiple transmitters cover the same frequency at slightly different arrival delays at the receiver.
Package equalizer implements adaptive channel equalizers used to fight simulcast distortion — the inter-symbol interference produced when multiple transmitters cover the same frequency at slightly different arrival delays at the receiver.
Package fft provides a swappable FFT abstraction.
Package fft provides a swappable FFT abstraction.
Package filter implements the FIR/CIC/halfband primitives used by the DSP pipeline.
Package filter implements the FIR/CIC/halfband primitives used by the DSP pipeline.
Package sync provides symbol-time recovery and frame sync correlators.
Package sync provides symbol-time recovery and frame sync correlators.
Package window provides standard window functions for FIR design and FFT pre-processing.
Package window provides standard window functions for FIR design and FFT pre-processing.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL