Go-based FM stereo transmitter with RDS, Windows-first and cross-platform
Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

54 linhas
1.2KB

  1. package dsp
  2. import "math"
  3. // Oscillator produces a sine wave at a configured frequency and sample rate.
  4. type Oscillator struct {
  5. Frequency float64
  6. SampleRate float64
  7. phase float64
  8. }
  9. // Tick advances the oscillator by one sample and returns the current sine value.
  10. func (o *Oscillator) Tick() float64 {
  11. if o.SampleRate <= 0 || o.Frequency == 0 {
  12. return 0
  13. }
  14. value := math.Sin(2 * math.Pi * o.phase)
  15. step := o.Frequency / o.SampleRate
  16. o.phase += step
  17. if o.phase >= 1 {
  18. o.phase -= math.Floor(o.phase)
  19. }
  20. return value
  21. }
  22. // Reset brings the phase back to zero.
  23. func (o *Oscillator) Reset() {
  24. o.phase = 0
  25. }
  26. // Phase returns the current phase of the oscillator in [0, 1).
  27. func (o *Oscillator) Phase() float64 {
  28. return o.phase
  29. }
  30. // PilotGenerator emits the 19 kHz pilot tone required by FM stereo.
  31. type PilotGenerator struct {
  32. Oscillator
  33. Level float64
  34. }
  35. // NewPilotGenerator constructs a pilot tone generator for the given sample rate and level.
  36. func NewPilotGenerator(sampleRate, level float64) PilotGenerator {
  37. return PilotGenerator{
  38. Oscillator: Oscillator{Frequency: 19000, SampleRate: sampleRate},
  39. Level: level,
  40. }
  41. }
  42. // Sample returns the next pilot sample.
  43. func (p *PilotGenerator) Sample() float64 {
  44. return p.Level * p.Oscillator.Tick()
  45. }