add controller logic for visualizations and add to gear menu

This commit is contained in:
Drew Weymouth
2024-07-22 18:16:18 -07:00
parent 0b3687a2ff
commit 9d0b381572
6 changed files with 87 additions and 44 deletions
+4 -1
View File
@@ -460,12 +460,15 @@ func (p *Player) GetPeaks() (float64, float64, float64, float64) {
return nInf, nInf, nInf, nInf
}
m := prop.(*mpv.Node).Data.(map[string]*mpv.Node)
lPeak, _ := strconv.ParseFloat(m["lavfi.astats.1.Peak_level"].Data.(string), 64)
if lPeakNode, ok := m["lavfi.astats.1.Peak_level"]; ok {
lPeak, _ := strconv.ParseFloat(lPeakNode.Data.(string), 64)
rPeak, _ := strconv.ParseFloat(m["lavfi.astats.2.Peak_level"].Data.(string), 64)
lRMS, _ := strconv.ParseFloat(m["lavfi.astats.1.RMS_level"].Data.(string), 64)
rRMS, _ := strconv.ParseFloat(m["lavfi.astats.2.RMS_level"].Data.(string), 64)
return lPeak, rPeak, lRMS, rRMS
}
return nInf, nInf, nInf, nInf
}
// sets the state and invokes callbacks, if triggered
func (p *Player) setState(s player.State) {
-9
View File
@@ -74,15 +74,6 @@ func main() {
}
}()
myApp.LocalPlayer.SetPeaksEnabled(true)
peaks := fyneApp.NewWindow("Peak meter")
meter := ui.NewPeakMeter(myApp.LocalPlayer.GetPeaks)
peaks.SetContent(meter)
meter.Start()
peaks.Show()
mainWindow.ShowAndRun()
log.Println("Running shutdown tasks...")
+1
View File
@@ -36,6 +36,7 @@ type NavigationHandler func(Route)
type CurPageFunc func() Route
type Controller struct {
visualizationData
AppVersion string
App *backend.App
MainWindow fyne.Window
+68
View File
@@ -0,0 +1,68 @@
package controller
import (
"math"
"time"
"fyne.io/fyne/v2"
"fyne.io/fyne/v2/lang"
"github.com/dweymouth/supersonic/ui/visualizations"
)
// embedded in parent controller struct
type visualizationData struct {
peakMeter *visualizations.PeakMeter
visualizationAnim *fyne.Animation
}
func (c *Controller) InitVisualizations() {
c.App.LocalPlayer.OnStopped(c.stopVisualizationAnim)
c.App.LocalPlayer.OnPaused(c.stopVisualizationAnim)
c.App.LocalPlayer.OnPlaying(func() {
if c.peakMeter != nil {
c.startVisualizationAnim()
}
})
}
func (c *Controller) ShowPeakMeter() {
if c.peakMeter != nil {
return
}
win := fyne.CurrentApp().NewWindow(lang.L("Peak Meter"))
win.SetCloseIntercept(func() {
c.stopVisualizationAnim()
c.peakMeter = nil
win.Close()
})
c.peakMeter = visualizations.NewPeakMeter()
win.SetContent(c.peakMeter)
c.startVisualizationAnim()
win.Show()
}
func (c *Controller) stopVisualizationAnim() {
if c.visualizationAnim != nil {
c.visualizationAnim.Stop()
c.visualizationAnim = nil
c.App.LocalPlayer.SetPeaksEnabled(false)
}
}
func (c *Controller) startVisualizationAnim() {
if c.visualizationAnim == nil {
c.App.LocalPlayer.SetPeaksEnabled(true)
c.visualizationAnim = fyne.NewAnimation(
time.Duration(math.MaxInt64), /*until stopped*/
c.tickVisualizations)
c.visualizationAnim.Start()
}
}
func (c *Controller) tickVisualizations(_ float32) {
lP, rP, lRMS, rRMS := c.App.LocalPlayer.GetPeaks()
if c.visualizationData.peakMeter != nil {
c.visualizationData.peakMeter.UpdatePeaks(lP, rP, lRMS, rRMS)
}
}
+3
View File
@@ -21,6 +21,7 @@ import (
"fyne.io/fyne/v2/container"
"fyne.io/fyne/v2/dialog"
"fyne.io/fyne/v2/driver/desktop"
"fyne.io/fyne/v2/lang"
"fyne.io/fyne/v2/widget"
)
@@ -80,6 +81,7 @@ func NewMainWindow(fyneApp fyne.App, appName, displayAppName, appVersion string,
MainWindow: m.Window,
App: app,
}
m.Controller.InitVisualizations()
m.BrowsingPane = browsing.NewBrowsingPane(app, m.Controller, func() { m.Router.NavigateTo(m.StartupPage()) })
m.Router = browsing.NewRouter(app, m.Controller, m.BrowsingPane)
// inject controller dependencies
@@ -136,6 +138,7 @@ func NewMainWindow(fyneApp fyne.App, appName, displayAppName, appVersion string,
m.BrowsingPane.AddSettingsMenuItem("Switch Servers", func() { app.ServerManager.Logout(false) })
m.BrowsingPane.AddSettingsMenuItem("Rescan Library", func() { app.ServerManager.Server.RescanLibrary() })
m.BrowsingPane.AddSettingsMenuSeparator()
m.BrowsingPane.AddSettingsMenuItem(lang.L("Show Peak Meter"), m.Controller.ShowPeakMeter)
m.BrowsingPane.AddSettingsMenuItem("Check for Updates", func() {
go func() {
if t := app.UpdateChecker.CheckLatestVersionTag(); t != "" && t != app.VersionTag() {
@@ -1,10 +1,9 @@
package ui
package visualizations
import (
"fmt"
"image/color"
"math"
"time"
"fyne.io/fyne/v2"
"fyne.io/fyne/v2/canvas"
@@ -20,11 +19,8 @@ const (
peakHoldFrames = 60
)
type PeakFN func() (float64, float64, float64, float64)
type PeakMeter struct {
widget.BaseWidget
peakFnDB PeakFN
lPeak float64
rPeak float64
lRMS float64
@@ -34,36 +30,18 @@ type PeakMeter struct {
lPeakHoldFrame uint64
rPeakHoldFrame uint64
frameCounter uint64
anim *fyne.Animation
}
func NewPeakMeter(peakFnDB PeakFN) *PeakMeter {
p := &PeakMeter{peakFnDB: peakFnDB}
func NewPeakMeter() *PeakMeter {
p := &PeakMeter{}
p.ExtendBaseWidget(p)
return p
}
func (p *PeakMeter) Start() {
if p.anim != nil {
return
}
p.anim = fyne.NewAnimation(time.Duration(math.MaxInt64) /*until stopped*/, p.tick)
p.anim.Start()
}
func (p *PeakMeter) Stop() {
if p.anim != nil {
p.anim.Stop()
p.anim = nil
p.frameCounter = 0
p.lPeakHoldFrame = 0
p.rPeakHoldFrame = 0
}
}
func (p *PeakMeter) tick(_ float32) {
lPeak, rPeak, lRMS, rRMS := p.peakFnDB()
// UpdatePeaks updates the peaks that are displayed in the meter.
// This function is expected to be called from a fyne.Animation callback,
// running at 60 Hz
func (p *PeakMeter) UpdatePeaks(lPeak, rPeak, lRMS, rRMS float64) {
p.lPeak = lPeak
p.rPeak = rPeak
lRMS = math.Max(-96, lRMS)
@@ -231,5 +209,4 @@ func (l *peakMeterRenderer) Objects() []fyne.CanvasObject {
}
func (l *peakMeterRenderer) Destroy() {
l.p.Stop()
}