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.

72 lines
2.1KB

  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. Source string `json:"source"`
  20. PreviewSamples []float64 `json:"previewSamples"`
  21. }
  22. func Generate(cfg cfgpkg.Config) FrameSummary {
  23. preview := make([]float64, 16)
  24. base := cfg.Audio.Gain * cfg.FM.OutputDrive
  25. for i := range preview {
  26. sign := 1.0
  27. if i%2 == 1 {
  28. sign = -1.0
  29. }
  30. preview[i] = sign * base * float64(i+1) / 16.0
  31. }
  32. source := "tones"
  33. if cfg.Audio.InputPath != "" {
  34. source = cfg.Audio.InputPath
  35. }
  36. return FrameSummary{
  37. Mode: "dry-run",
  38. FrequencyMHz: cfg.FM.FrequencyMHz,
  39. StereoEnabled: cfg.FM.StereoEnabled,
  40. RDSEnabled: cfg.RDS.Enabled,
  41. SampleRateHz: cfg.Audio.SampleRate,
  42. CompositeRate: cfg.FM.CompositeRateHz,
  43. PilotLevel: cfg.FM.PilotLevel,
  44. RDSInjection: cfg.FM.RDSInjection,
  45. OutputDrive: cfg.FM.OutputDrive,
  46. Source: source,
  47. PreviewSamples: preview,
  48. }
  49. }
  50. func WriteJSON(path string, frame FrameSummary) error {
  51. data, err := json.MarshalIndent(frame, "", " ")
  52. if err != nil {
  53. return fmt.Errorf("marshal dry-run frame: %w", err)
  54. }
  55. if path == "" || path == "-" {
  56. _, err = os.Stdout.Write(append(data, '\n'))
  57. return err
  58. }
  59. if err := os.MkdirAll(filepath.Dir(path), 0o755); err != nil {
  60. return fmt.Errorf("create output dir: %w", err)
  61. }
  62. if err := os.WriteFile(path, append(data, '\n'), 0o644); err != nil {
  63. return fmt.Errorf("write dry-run frame: %w", err)
  64. }
  65. return nil
  66. }