|
- package stereo
-
- import (
- "github.com/jan/fm-rds-tx/internal/audio"
- "github.com/jan/fm-rds-tx/internal/dsp"
- )
-
- // Components holds the individual MPX components produced by the stereo encoder.
- // All outputs are unity-normalized. The combiner controls actual injection levels.
- type Components struct {
- Mono float64 // (L+R)/2 baseband
- Stereo float64 // (L-R)/2 * sin(2π·38kHz·t), unity subcarrier
- Pilot float64 // sin(2π·19kHz·t), unity amplitude
- }
-
- // StereoEncoder generates stereo MPX primitives from stereo audio frames.
- type StereoEncoder struct {
- pilot dsp.PilotGenerator
- subcarrier dsp.Oscillator
- }
-
- // NewStereoEncoder creates a StereoEncoder configured for the provided sample rate.
- func NewStereoEncoder(sampleRate float64) StereoEncoder {
- return StereoEncoder{
- pilot: dsp.NewPilotGenerator(sampleRate),
- subcarrier: dsp.Oscillator{Frequency: 38000, SampleRate: sampleRate},
- }
- }
-
- // Encode converts a stereo frame into MPX components.
- func (s *StereoEncoder) Encode(frame audio.Frame) Components {
- pilot := s.pilot.Sample()
- sub38 := s.subcarrier.Tick()
-
- return Components{
- Mono: float64(frame.Mono()),
- Stereo: float64(frame.Difference()) * sub38,
- Pilot: pilot,
- }
- }
-
- // Reset restarts the pilot and subcarrier generators.
- func (s *StereoEncoder) Reset() {
- s.pilot.Reset()
- s.subcarrier.Reset()
- }
|