Go-based FM stereo transmitter with RDS, Windows-first and cross-platform
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

47 lignes
1.3KB

  1. package stereo
  2. import (
  3. "github.com/jan/fm-rds-tx/internal/audio"
  4. "github.com/jan/fm-rds-tx/internal/dsp"
  5. )
  6. // Components holds the individual MPX components produced by the stereo encoder.
  7. // All outputs are unity-normalized. The combiner controls actual injection levels.
  8. type Components struct {
  9. Mono float64 // (L+R)/2 baseband
  10. Stereo float64 // (L-R)/2 * sin(2π·38kHz·t), unity subcarrier
  11. Pilot float64 // sin(2π·19kHz·t), unity amplitude
  12. }
  13. // StereoEncoder generates stereo MPX primitives from stereo audio frames.
  14. type StereoEncoder struct {
  15. pilot dsp.PilotGenerator
  16. subcarrier dsp.Oscillator
  17. }
  18. // NewStereoEncoder creates a StereoEncoder configured for the provided sample rate.
  19. func NewStereoEncoder(sampleRate float64) StereoEncoder {
  20. return StereoEncoder{
  21. pilot: dsp.NewPilotGenerator(sampleRate),
  22. subcarrier: dsp.Oscillator{Frequency: 38000, SampleRate: sampleRate},
  23. }
  24. }
  25. // Encode converts a stereo frame into MPX components.
  26. func (s *StereoEncoder) Encode(frame audio.Frame) Components {
  27. pilot := s.pilot.Sample()
  28. sub38 := s.subcarrier.Tick()
  29. return Components{
  30. Mono: float64(frame.Mono()),
  31. Stereo: float64(frame.Difference()) * sub38,
  32. Pilot: pilot,
  33. }
  34. }
  35. // Reset restarts the pilot and subcarrier generators.
  36. func (s *StereoEncoder) Reset() {
  37. s.pilot.Reset()
  38. s.subcarrier.Reset()
  39. }