|
- package app
-
- import (
- "context"
- "encoding/binary"
- "fmt"
- "path/filepath"
- "time"
-
- cfgpkg "github.com/jan/fm-rds-tx/internal/config"
- offpkg "github.com/jan/fm-rds-tx/internal/offline"
- "github.com/jan/fm-rds-tx/internal/output"
- "github.com/jan/fm-rds-tx/internal/platform"
- )
-
- func RunSimulatedTransmit(cfg cfgpkg.Config, outPath string, duration time.Duration) (string, error) {
- if outPath == "" {
- outPath = filepath.Join("build", "sim", "simulated-soapy.iqf32")
- }
- fileBackend, err := output.NewFileBackend(outPath, binary.LittleEndian, output.BackendInfo{
- Name: "simulated-soapy-file", Description: "simulated soapy sink to file",
- })
- if err != nil { return "", err }
- defer fileBackend.Close(context.Background())
-
- soapyCfg := platform.SoapyConfig{
- BackendConfig: output.BackendConfig{
- SampleRateHz: float64(cfg.FM.CompositeRateHz), Channels: 2,
- IQLevel: float32(cfg.FM.OutputDrive),
- },
- Driver: "simulated", Device: cfg.Backend.Device,
- CenterFreqHz: cfg.FM.FrequencyMHz * 1_000_000,
- Simulated: true, SimulationPath: outPath,
- }
- driver := platform.NewSimulatedDriver(fileBackend)
- backend := platform.NewSoapyBackend(soapyCfg, driver)
- if err := backend.Configure(context.Background(), soapyCfg.BackendConfig); err != nil { return "", err }
- if err := driver.Start(context.Background()); err != nil { return "", err }
-
- gen := offpkg.NewGenerator(cfg)
- frame := gen.GenerateFrame(duration)
- if _, err := backend.Write(context.Background(), frame); err != nil { return "", err }
- if err := backend.Flush(context.Background()); err != nil { return "", err }
- _ = driver.Stop(context.Background())
-
- return fmt.Sprintf("simulated transmit: backend=%s output=%s duration=%s input=%s freq=%.1fMHz rate=%d",
- backend.Info().Name, outPath, duration, inputLabel(cfg), cfg.FM.FrequencyMHz, cfg.FM.CompositeRateHz), nil
- }
-
- func inputLabel(cfg cfgpkg.Config) string {
- if cfg.Audio.InputPath != "" { return cfg.Audio.InputPath }
- return "tones"
- }
|