package main import ( "context" "encoding/binary" "fmt" "os" "time" "github.com/jan/fm-rds-tx/internal/output" "github.com/jan/fm-rds-tx/internal/platform" ) func main() { ctx := context.Background() fb, err := output.NewFileBackend("examples/simulated_mpx.iq", binary.LittleEndian, output.BackendInfo{ Name: "example-file", Description: "Captures simulated Soapy output for later playback.", }) if err != nil { fmt.Fprintf(os.Stderr, "failed to open file backend: %v\n", err) os.Exit(1) } defer fb.Close(ctx) cfg := platform.SoapyConfig{ Driver: "simulated", Device: "dummy", CenterFreqHz: 100e6, Simulated: true, BackendConfig: output.BackendConfig{ SampleRateHz: 238_000, Channels: 2, IQLevel: 1.0, Metadata: map[string]string{"example": "soapy-sim"}, }, } driver := platform.NewSimulatedDriver(fb) backend := platform.NewSoapyBackend(cfg, driver) if err := backend.Configure(ctx, cfg.BackendConfig); err != nil { fmt.Fprintf(os.Stderr, "backend configure: %v\n", err) os.Exit(1) } frame := &output.CompositeFrame{ SampleRateHz: cfg.BackendConfig.SampleRateHz, Timestamp: time.Now(), Samples: make([]output.IQSample, 512), } for idx := range frame.Samples { val := float32((idx%64))/32 - 1 frame.Samples[idx].I = val frame.Samples[idx].Q = -val } written, err := backend.Write(ctx, frame) if err != nil { fmt.Fprintf(os.Stderr, "write frame: %v\n", err) os.Exit(1) } fmt.Printf("wrote %d samples to simulated Soapy backend\n", written) if err := backend.Flush(ctx); err != nil { fmt.Fprintf(os.Stderr, "flush: %v\n", err) } }