From ab22f871d214357750a8ab108c9c29c7837df7f5 Mon Sep 17 00:00:00 2001 From: Drew Weymouth Date: Thu, 22 Jun 2023 18:36:06 -0700 Subject: [PATCH] add ISO 15 equalizer implementation --- player/equalizer.go | 52 +++++++++++++++++++++++++++++++++++++++++++++ player/player.go | 9 ++++++++ 2 files changed, 61 insertions(+) diff --git a/player/equalizer.go b/player/equalizer.go index 8203142..9b8117d 100644 --- a/player/equalizer.go +++ b/player/equalizer.go @@ -1,10 +1,62 @@ package player +// Equalizer implementations based on the ffmpeg 'equalizer' filter + import ( "fmt" + "math" "strings" ) +type Equalizer interface { + IsEnabled() bool + Curve() EqualizerCurve + Type() string + // Returns the band frequencies as strings friendly for display + BandFrequencies() []string +} + +type ISO15BandEqualizer struct { + Disabled bool + BandGains [15]float64 +} + +var ( + iso15Bands = []string{"25", "40", "63", "100", "160", "250", "400", "630", "1k", "1.6k", "2.5k", "4k", "6.3k", "10k", "16k"} + iso15FMult = math.Pow(2, 2./3) +) + +var _ Equalizer = (*ISO15BandEqualizer)(nil) + +func (i *ISO15BandEqualizer) IsEnabled() bool { + return !i.Disabled +} + +func (i *ISO15BandEqualizer) Curve() EqualizerCurve { + fC := float64(25) + curve := make([]EqualizerBand, 0, len(i.BandGains)) + for _, bandGain := range i.BandGains { + curve = append(curve, EqualizerBand{ + Frequency: int(math.Round(fC)), + Width: 2. / 3, + WidthType: WidthTypeOctave, + Gain: bandGain, + }) + fC *= iso15FMult + } + return curve +} + +func (*ISO15BandEqualizer) BandFrequencies() []string { + ret := make([]string, len(iso15Bands)) + copy(ret, iso15Bands) + return ret +} + +func (*ISO15BandEqualizer) Type() string { + return "ISO15Band" +} + type WidthType int const ( diff --git a/player/player.go b/player/player.go index 62f7091..2447cbb 100644 --- a/player/player.go +++ b/player/player.go @@ -113,6 +113,7 @@ type Player struct { curPlaylistPos int64 prePausedState State clientName string + equalizer Equalizer bgCancel context.CancelFunc @@ -501,6 +502,14 @@ func (p *Player) SetAudioDevice(deviceName string) error { return p.mpv.SetPropertyString("audio-device", deviceName) } +func (p *Player) SetEqualizer(eq Equalizer) error { + p.equalizer = eq + if eq == nil || !eq.IsEnabled() { + return p.mpv.SetPropertyString("af", "") + } + return p.mpv.SetPropertyString("af", eq.Curve().String()) +} + func (p *Player) GetMediaInfo() (MediaInfo, error) { var info MediaInfo n, err := p.mpv.GetProperty("audio-params", mpv.FORMAT_NODE)