|
|
|
@@ -20,6 +20,12 @@ type frameSource interface { |
|
|
|
NextFrame() audio.Frame |
|
|
|
} |
|
|
|
|
|
|
|
type SourceInfo struct { |
|
|
|
Kind string |
|
|
|
SampleRate float64 |
|
|
|
Detail string |
|
|
|
} |
|
|
|
|
|
|
|
type Generator struct { |
|
|
|
cfg cfgpkg.Config |
|
|
|
} |
|
|
|
@@ -28,13 +34,14 @@ func NewGenerator(cfg cfgpkg.Config) *Generator { |
|
|
|
return &Generator{cfg: cfg} |
|
|
|
} |
|
|
|
|
|
|
|
func (g *Generator) sourceFor(sampleRate float64) frameSource { |
|
|
|
func (g *Generator) sourceFor(sampleRate float64) (frameSource, SourceInfo) { |
|
|
|
if g.cfg.Audio.InputPath != "" { |
|
|
|
if src, err := audio.LoadWAVSource(g.cfg.Audio.InputPath); err == nil { |
|
|
|
return audio.NewResampledSource(src, sampleRate) |
|
|
|
return audio.NewResampledSource(src, sampleRate), SourceInfo{Kind: "wav", SampleRate: float64(src.SampleRate), Detail: g.cfg.Audio.InputPath} |
|
|
|
} |
|
|
|
return audio.NewConfiguredToneSource(sampleRate, g.cfg.Audio.ToneLeftHz, g.cfg.Audio.ToneRightHz, g.cfg.Audio.ToneAmplitude), SourceInfo{Kind: "tone-fallback", SampleRate: sampleRate, Detail: g.cfg.Audio.InputPath} |
|
|
|
} |
|
|
|
return audio.NewConfiguredToneSource(sampleRate, g.cfg.Audio.ToneLeftHz, g.cfg.Audio.ToneRightHz, g.cfg.Audio.ToneAmplitude) |
|
|
|
return audio.NewConfiguredToneSource(sampleRate, g.cfg.Audio.ToneLeftHz, g.cfg.Audio.ToneRightHz, g.cfg.Audio.ToneAmplitude), SourceInfo{Kind: "tones", SampleRate: sampleRate, Detail: "generated"} |
|
|
|
} |
|
|
|
|
|
|
|
func (g *Generator) GenerateFrame(duration time.Duration) *output.CompositeFrame { |
|
|
|
@@ -68,7 +75,7 @@ func (g *Generator) GenerateFrame(duration time.Duration) *output.CompositeFrame |
|
|
|
}) |
|
|
|
rdsSamples := rdsEnc.Generate(samples) |
|
|
|
|
|
|
|
source := g.sourceFor(sampleRate) |
|
|
|
source, _ := g.sourceFor(sampleRate) |
|
|
|
|
|
|
|
for i := 0; i < samples; i++ { |
|
|
|
t := float64(i) / sampleRate |
|
|
|
@@ -121,9 +128,10 @@ func (g *Generator) WriteFile(path string, duration time.Duration) error { |
|
|
|
} |
|
|
|
|
|
|
|
func (g *Generator) Summary(duration time.Duration) string { |
|
|
|
source := "tones" |
|
|
|
if g.cfg.Audio.InputPath != "" { |
|
|
|
source = g.cfg.Audio.InputPath |
|
|
|
sampleRate := float64(g.cfg.FM.CompositeRateHz) |
|
|
|
if sampleRate <= 0 { |
|
|
|
sampleRate = 228000 |
|
|
|
} |
|
|
|
return fmt.Sprintf("offline frame: freq=%.1fMHz sampleRate=%d duration=%s outputDrive=%.2f stereo=%t rds=%t source=%s", g.cfg.FM.FrequencyMHz, g.cfg.FM.CompositeRateHz, duration.String(), g.cfg.FM.OutputDrive, g.cfg.FM.StereoEnabled, g.cfg.RDS.Enabled, source) |
|
|
|
_, info := g.sourceFor(sampleRate) |
|
|
|
return fmt.Sprintf("offline frame: freq=%.1fMHz sampleRate=%d duration=%s outputDrive=%.2f stereo=%t rds=%t source=%s detail=%s", g.cfg.FM.FrequencyMHz, g.cfg.FM.CompositeRateHz, duration.String(), g.cfg.FM.OutputDrive, g.cfg.FM.StereoEnabled, g.cfg.RDS.Enabled, info.Kind, info.Detail) |
|
|
|
} |