package factory import ( "fmt" "io" "net/http" "os" "strings" "github.com/jan/fm-rds-tx/internal/config" "github.com/jan/fm-rds-tx/internal/ingest" "github.com/jan/fm-rds-tx/internal/ingest/adapters/httpraw" "github.com/jan/fm-rds-tx/internal/ingest/adapters/icecast" "github.com/jan/fm-rds-tx/internal/ingest/adapters/stdinpcm" ) type Deps struct { Stdin io.Reader HTTP *http.Client } type AudioIngress interface { WritePCM16(data []byte) (int, error) } func BuildSource(cfg config.Config, deps Deps) (ingest.Source, AudioIngress, error) { switch normalizeIngestKind(cfg.Ingest.Kind) { case "", "none": return nil, nil, nil case "stdin", "stdin-pcm": reader := deps.Stdin if reader == nil { reader = os.Stdin } src := stdinpcm.New("stdin-main", reader, cfg.Ingest.Stdin.SampleRateHz, cfg.Ingest.Stdin.Channels, 1024) return src, nil, nil case "http-raw": src := httpraw.New("http-raw-main", cfg.Ingest.HTTPRaw.SampleRateHz, cfg.Ingest.HTTPRaw.Channels) return src, src, nil case "icecast": src := icecast.New( "icecast-main", cfg.Ingest.Icecast.URL, deps.HTTP, icecast.ReconnectConfig{ Enabled: cfg.Ingest.Reconnect.Enabled, InitialBackoffMs: cfg.Ingest.Reconnect.InitialBackoffMs, MaxBackoffMs: cfg.Ingest.Reconnect.MaxBackoffMs, }, icecast.WithDecoderPreference(cfg.Ingest.Icecast.Decoder), ) return src, nil, nil default: return nil, nil, fmt.Errorf("unsupported ingest kind: %s", cfg.Ingest.Kind) } } func SampleRateForKind(cfg config.Config) int { switch normalizeIngestKind(cfg.Ingest.Kind) { case "stdin", "stdin-pcm": if cfg.Ingest.Stdin.SampleRateHz > 0 { return cfg.Ingest.Stdin.SampleRateHz } case "http-raw": if cfg.Ingest.HTTPRaw.SampleRateHz > 0 { return cfg.Ingest.HTTPRaw.SampleRateHz } case "icecast": return 44100 } return 44100 } func normalizeIngestKind(kind string) string { return strings.ToLower(strings.TrimSpace(kind)) }