Added volume controls

This commit is contained in:
strNophix 2022-03-22 00:22:23 +01:00
parent 8eb850d9fe
commit 8fc218ac2d
5 changed files with 93 additions and 17 deletions

View File

@ -21,3 +21,13 @@ func newTrackPauseCmd(isPaused bool) tea.Cmd {
return trackPauseMsg{isPaused} return trackPauseMsg{isPaused}
} }
} }
type trackVolumeMsg struct {
volume float64
}
func newTrackVolumeCmd(volume float64) tea.Cmd {
return func() tea.Msg {
return trackVolumeMsg{volume}
}
}

View File

@ -21,6 +21,7 @@ type Model struct {
currentlyPlaying int currentlyPlaying int
TrackPlayer TrackPlayer
TrackPlayerEffects
trackIndex trackIndex
trackPlayerView trackPlayerView
@ -36,6 +37,7 @@ func NewModel(args ModelArgs) Model {
trackIndex: ti, trackIndex: ti,
TrackPlayer: TrackPlayer{}, TrackPlayer: TrackPlayer{},
TrackPlayerEffects: newTrackPlayerEffects(),
trackPlayerView: tpv, trackPlayerView: tpv,
} }
@ -59,16 +61,42 @@ func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
return m, tea.Quit return m, tea.Quit
case "enter": case "enter":
t := m.trackPlayerView.trackList.SelectedItem().(track) t := m.trackPlayerView.trackList.SelectedItem().(track)
cmds = append(cmds, newTrackChangeCmd(t))
stream, format, err := t.GetStream() stream, format, err := t.GetStream()
check(err) check(err)
speaker.Init(format.SampleRate, format.SampleRate.N(time.Second/10)) speaker.Init(format.SampleRate, format.SampleRate.N(time.Second/10))
m.TrackPlayer.Play(&stream)
m.TrackPlayer.Play(&stream, &m.TrackPlayerEffects)
cmds = append(cmds, newTrackChangeCmd(t))
case " ": case " ":
pauseState := m.TrackPlayer.TogglePause() if m.TrackPlayer.playerCtrl != nil {
cmds = append(cmds, newTrackPauseCmd(pauseState)) s := m.TrackPlayer.TogglePause()
cmds = append(cmds, newTrackPauseCmd(s))
}
case "-", "=":
v := &m.TrackPlayerEffects.volume
if msg.String() == "-" {
*v -= 0.1
if *v < minVolume {
*v = minVolume
}
} else {
*v += 0.1
if *v > maxVolume {
*v = maxVolume
} }
} }
if m.TrackPlayer.playerVol != nil {
m.TrackPlayer.SetVolume(*v)
}
cmds = append(cmds, newTrackVolumeCmd(*v))
}
}
var cmd tea.Cmd var cmd tea.Cmd
m.trackPlayerView, cmd = m.trackPlayerView.Update(msg) m.trackPlayerView, cmd = m.trackPlayerView.Update(msg)
cmds = append(cmds, cmd) cmds = append(cmds, cmd)

View File

@ -1,6 +1,8 @@
package gomus package gomus
import ( import (
"fmt"
tea "github.com/charmbracelet/bubbletea" tea "github.com/charmbracelet/bubbletea"
"github.com/charmbracelet/lipgloss" "github.com/charmbracelet/lipgloss"
) )
@ -14,8 +16,7 @@ var (
Inherit(statusBarStyle). Inherit(statusBarStyle).
Foreground(lipgloss.Color("#FFFDF5")). Foreground(lipgloss.Color("#FFFDF5")).
Background(lipgloss.Color("#FF5F87")). Background(lipgloss.Color("#FF5F87")).
Padding(0, 1). Padding(0, 1)
MarginRight(1)
statusText = lipgloss.NewStyle().Inherit(statusBarStyle) statusText = lipgloss.NewStyle().Inherit(statusBarStyle)
) )
@ -23,9 +24,10 @@ var (
type statusBar struct { type statusBar struct {
isPaused bool isPaused bool
currentTrack track currentTrack track
currentVolume float64
} }
func (s statusBar) Init() tea.Cmd { func (s *statusBar) Init() tea.Cmd {
return nil return nil
} }
@ -39,16 +41,22 @@ func (s statusBar) View() string {
statusKey = statusStyle.Render("") statusKey = statusStyle.Render("")
} }
v := MapFloatBetween(s.currentVolume, minVolume, maxVolume, 0, 100)
vs := fmt.Sprintf("vol %d", int(v))
statusVal := statusText.Copy(). statusVal := statusText.Copy().
Width(termWidth - w(statusKey)). Width(termWidth - w(statusKey) - w(vs) - 2).
Render(s.currentTrack.fullName()) Render(s.currentTrack.fullName())
statusVol := statusStyle.Copy().Align(lipgloss.Right).Width(w(vs) + 2).Render(vs)
bar := lipgloss.JoinHorizontal(lipgloss.Top, bar := lipgloss.JoinHorizontal(lipgloss.Top,
statusKey, statusKey,
statusVal, statusVal,
statusVol,
) )
return statusBarStyle.Width(termWidth).Render(bar) return statusBarStyle.Render(bar)
} }
func (s statusBar) Update(msg tea.Msg) (statusBar, tea.Cmd) { func (s statusBar) Update(msg tea.Msg) (statusBar, tea.Cmd) {
@ -57,6 +65,8 @@ func (s statusBar) Update(msg tea.Msg) (statusBar, tea.Cmd) {
s.currentTrack = msg.nextTrack s.currentTrack = msg.nextTrack
case trackPauseMsg: case trackPauseMsg:
s.isPaused = msg.isPaused s.isPaused = msg.isPaused
case trackVolumeMsg:
s.currentVolume = msg.volume
} }
return s, nil return s, nil

View File

@ -2,24 +2,43 @@ package gomus
import ( import (
"github.com/faiface/beep" "github.com/faiface/beep"
"github.com/faiface/beep/effects"
"github.com/faiface/beep/speaker" "github.com/faiface/beep/speaker"
) )
const (
base = 2
minVolume = -5
maxVolume = 1
startVolume = -2
)
type TrackPlayerEffects struct {
volume float64
}
func newTrackPlayerEffects() TrackPlayerEffects {
return TrackPlayerEffects{volume: startVolume}
}
type TrackPlayer struct { type TrackPlayer struct {
streamer *beep.StreamSeekCloser streamer *beep.StreamSeekCloser
playerCtrl *beep.Ctrl playerCtrl *beep.Ctrl
playerVol *effects.Volume
} }
func (t *TrackPlayer) Play(streamer *beep.StreamSeekCloser) { func (t *TrackPlayer) Play(streamer *beep.StreamSeekCloser, trackEffects *TrackPlayerEffects) {
if t.streamer != nil { if t.streamer != nil {
t.Close() t.Close()
} }
ctrl := &beep.Ctrl{Streamer: beep.Loop(-1, *streamer), Paused: false} ctrl := &beep.Ctrl{Streamer: beep.Loop(-1, *streamer), Paused: false}
speaker.Play(ctrl) volume := &effects.Volume{Streamer: ctrl, Base: base, Volume: trackEffects.volume, Silent: false}
speaker.Play(volume)
t.playerCtrl = ctrl
t.streamer = streamer t.streamer = streamer
t.playerCtrl = ctrl
t.playerVol = volume
} }
func (t *TrackPlayer) TogglePause() bool { func (t *TrackPlayer) TogglePause() bool {
@ -30,6 +49,12 @@ func (t *TrackPlayer) TogglePause() bool {
return newState return newState
} }
func (t *TrackPlayer) SetVolume(volume float64) {
speaker.Lock()
(*t.playerVol).Volume = volume
speaker.Unlock()
}
func (t *TrackPlayer) Close() { func (t *TrackPlayer) Close() {
(*t.streamer).Close() (*t.streamer).Close()
} }

View File

@ -15,13 +15,16 @@ func newTrackPlayerView(tracks []track) trackPlayerView {
c := mapList(tracks, func(t track) list.Item { c := mapList(tracks, func(t track) list.Item {
return t return t
}) })
l := list.New(c, newTrackListDelegate(), 0, 0) l := list.New(c, newTrackListDelegate(), 0, 0)
l.SetShowTitle(false) l.SetShowTitle(false)
l.SetShowStatusBar(false) l.SetShowStatusBar(false)
l.SetShowHelp(false) l.SetShowHelp(false)
l.SetFilteringEnabled(false) l.SetFilteringEnabled(false)
return trackPlayerView{trackList: l} s := statusBar{currentVolume: startVolume}
return trackPlayerView{trackList: l, statusBar: s}
} }
func (v trackPlayerView) Init() tea.Cmd { func (v trackPlayerView) Init() tea.Cmd {