Go-based FM stereo transmitter with RDS, Windows-first and cross-platform
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

66 line
2.0KB

  1. package dryrun
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "os"
  6. "path/filepath"
  7. cfgpkg "github.com/jan/fm-rds-tx/internal/config"
  8. )
  9. type FrameSummary struct {
  10. Mode string `json:"mode"`
  11. FrequencyMHz float64 `json:"frequencyMHz"`
  12. StereoEnabled bool `json:"stereoEnabled"`
  13. RDSEnabled bool `json:"rdsEnabled"`
  14. SampleRateHz int `json:"sampleRateHz"`
  15. CompositeRate int `json:"compositeRateHz"`
  16. PilotLevel float64 `json:"pilotLevel"`
  17. RDSInjection float64 `json:"rdsInjection"`
  18. OutputDrive float64 `json:"outputDrive"`
  19. PreviewSamples []float64 `json:"previewSamples"`
  20. }
  21. func Generate(cfg cfgpkg.Config) FrameSummary {
  22. preview := make([]float64, 16)
  23. base := cfg.Audio.Gain * cfg.FM.OutputDrive
  24. for i := range preview {
  25. sign := 1.0
  26. if i%2 == 1 {
  27. sign = -1.0
  28. }
  29. preview[i] = sign * base * float64(i+1) / 16.0
  30. }
  31. return FrameSummary{
  32. Mode: "dry-run",
  33. FrequencyMHz: cfg.FM.FrequencyMHz,
  34. StereoEnabled: cfg.FM.StereoEnabled,
  35. RDSEnabled: cfg.RDS.Enabled,
  36. SampleRateHz: cfg.Audio.SampleRate,
  37. CompositeRate: cfg.FM.CompositeRateHz,
  38. PilotLevel: cfg.FM.PilotLevel,
  39. RDSInjection: cfg.FM.RDSInjection,
  40. OutputDrive: cfg.FM.OutputDrive,
  41. PreviewSamples: preview,
  42. }
  43. }
  44. func WriteJSON(path string, frame FrameSummary) error {
  45. data, err := json.MarshalIndent(frame, "", " ")
  46. if err != nil {
  47. return fmt.Errorf("marshal dry-run frame: %w", err)
  48. }
  49. if path == "" || path == "-" {
  50. _, err = os.Stdout.Write(append(data, '\n'))
  51. return err
  52. }
  53. if err := os.MkdirAll(filepath.Dir(path), 0o755); err != nil {
  54. return fmt.Errorf("create output dir: %w", err)
  55. }
  56. if err := os.WriteFile(path, append(data, '\n'), 0o644); err != nil {
  57. return fmt.Errorf("write dry-run frame: %w", err)
  58. }
  59. return nil
  60. }