|
- package dsp
-
- import "math"
-
- // Oscillator produces a sine wave at a configured frequency and sample rate.
- type Oscillator struct {
- Frequency float64
- SampleRate float64
- phase float64
- }
-
- // Tick advances the oscillator by one sample and returns the current sine value.
- func (o *Oscillator) Tick() float64 {
- if o.SampleRate <= 0 || o.Frequency == 0 {
- return 0
- }
- value := math.Sin(2 * math.Pi * o.phase)
- step := o.Frequency / o.SampleRate
- o.phase += step
- if o.phase >= 1 || o.phase < 0 {
- o.phase -= math.Floor(o.phase)
- }
- return value
- }
-
- // Reset brings the phase back to zero.
- func (o *Oscillator) Reset() {
- o.phase = 0
- }
-
- // Phase returns the current phase of the oscillator in [0, 1).
- func (o *Oscillator) Phase() float64 {
- return o.phase
- }
-
- // PilotGenerator emits the 19 kHz pilot tone required by FM stereo.
- // Output is unity-normalized (peak ±1.0). The caller controls the
- // actual injection level via the combiner gain.
- type PilotGenerator struct {
- Oscillator
- }
-
- // NewPilotGenerator constructs a pilot tone generator for the given sample rate.
- func NewPilotGenerator(sampleRate float64) PilotGenerator {
- return PilotGenerator{
- Oscillator: Oscillator{Frequency: 19000, SampleRate: sampleRate},
- }
- }
-
- // Sample returns the next pilot sample (unity amplitude).
- func (p *PilotGenerator) Sample() float64 {
- return p.Oscillator.Tick()
- }
|