Add .Playing() function to Track interface
This commit is contained in:
parent
65068820cb
commit
fa6eb3d3a0
|
@ -36,6 +36,7 @@ type Engine interface {
|
||||||
// Playable is a music or sound effect object that can be played and managed.
|
// Playable is a music or sound effect object that can be played and managed.
|
||||||
type Playable interface {
|
type Playable interface {
|
||||||
Play(loops int) error
|
Play(loops int) error
|
||||||
|
Playing() bool
|
||||||
Pause() error
|
Pause() error
|
||||||
Stop() error
|
Stop() error
|
||||||
|
|
||||||
|
|
30
sdl/currently_playing.go
Normal file
30
sdl/currently_playing.go
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
package sdl
|
||||||
|
|
||||||
|
import "errors"
|
||||||
|
|
||||||
|
// setPlaying associates a channel no. to the Track playing.
|
||||||
|
func (e *Engine) setPlaying(channel int, t *Track) {
|
||||||
|
e.channelMu.Lock()
|
||||||
|
defer e.channelMu.Unlock()
|
||||||
|
e.channelsPlaying[channel] = t
|
||||||
|
}
|
||||||
|
|
||||||
|
// unsetPlaying associates a channel no. to the Track playing.
|
||||||
|
func (e *Engine) unsetPlaying(channel int) error {
|
||||||
|
e.channelMu.Lock()
|
||||||
|
defer e.channelMu.Unlock()
|
||||||
|
if track, ok := e.channelsPlaying[channel]; ok {
|
||||||
|
track.channel = -1
|
||||||
|
delete(e.channelsPlaying, channel)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return errors.New("didn't even know channel %d was playing a sound")
|
||||||
|
}
|
||||||
|
|
||||||
|
// isPlaying checks if a sound effect is playing on a channel.
|
||||||
|
func (e *Engine) isPlaying(channel int) bool {
|
||||||
|
e.channelMu.RLock()
|
||||||
|
defer e.channelMu.RUnlock()
|
||||||
|
_, ok := e.channelsPlaying[channel]
|
||||||
|
return ok
|
||||||
|
}
|
13
sdl/music.go
13
sdl/music.go
|
@ -9,6 +9,8 @@ import (
|
||||||
type Track struct {
|
type Track struct {
|
||||||
isMusic bool // false = is sound effect
|
isMusic bool // false = is sound effect
|
||||||
|
|
||||||
|
engine *Engine
|
||||||
|
|
||||||
// If isMusic
|
// If isMusic
|
||||||
mus *mix.Music
|
mus *mix.Music
|
||||||
|
|
||||||
|
@ -46,6 +48,7 @@ func (e *Engine) LoadSound(filename string) (Track, error) {
|
||||||
wav, err := mix.LoadWAV(filename)
|
wav, err := mix.LoadWAV(filename)
|
||||||
return Track{
|
return Track{
|
||||||
isMusic: false,
|
isMusic: false,
|
||||||
|
engine: e,
|
||||||
wav: wav,
|
wav: wav,
|
||||||
channel: -1,
|
channel: -1,
|
||||||
}, err
|
}, err
|
||||||
|
@ -62,6 +65,7 @@ func (e *Engine) LoadSoundBin(data []byte) (Track, error) {
|
||||||
wav, err := mix.LoadWAVRW(rw, false)
|
wav, err := mix.LoadWAVRW(rw, false)
|
||||||
return Track{
|
return Track{
|
||||||
isMusic: false,
|
isMusic: false,
|
||||||
|
engine: e,
|
||||||
wav: wav,
|
wav: wav,
|
||||||
channel: -1,
|
channel: -1,
|
||||||
}, err
|
}, err
|
||||||
|
@ -93,9 +97,18 @@ func (t *Track) Play(loops int) error {
|
||||||
}
|
}
|
||||||
channel, err := t.wav.Play(-1, loops)
|
channel, err := t.wav.Play(-1, loops)
|
||||||
t.channel = channel
|
t.channel = channel
|
||||||
|
t.engine.setPlaying(channel, t)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Playing tells if this sound is already playing.
|
||||||
|
func (t *Track) Playing() bool {
|
||||||
|
if t.isMusic {
|
||||||
|
return mix.PlayingMusic()
|
||||||
|
}
|
||||||
|
return t.channel >= 0 && t.engine.isPlaying(t.channel)
|
||||||
|
}
|
||||||
|
|
||||||
// Pause the track.
|
// Pause the track.
|
||||||
func (t Track) Pause() error {
|
func (t Track) Pause() error {
|
||||||
if t.isMusic {
|
if t.isMusic {
|
||||||
|
|
18
sdl/sdl.go
18
sdl/sdl.go
|
@ -1,17 +1,27 @@
|
||||||
// Package sdl implements an audio engine using libSDL2.
|
// Package sdl implements an audio engine using libSDL2.
|
||||||
package sdl
|
package sdl
|
||||||
|
|
||||||
import "github.com/veandco/go-sdl2/mix"
|
import (
|
||||||
|
"sync"
|
||||||
|
|
||||||
|
"github.com/veandco/go-sdl2/mix"
|
||||||
|
)
|
||||||
|
|
||||||
// Engine is the SDL2 audio engine.
|
// Engine is the SDL2 audio engine.
|
||||||
type Engine struct {
|
type Engine struct {
|
||||||
initFlags int
|
initFlags int
|
||||||
|
|
||||||
|
// Keep track of which SDL channel numbers are ACTUALLY playing sound
|
||||||
|
// effects right now, and watch for when the channels are finished.
|
||||||
|
channelMu sync.RWMutex
|
||||||
|
channelsPlaying map[int]*Track
|
||||||
}
|
}
|
||||||
|
|
||||||
// New initializes an SDL2 Mixer for the audio engine.
|
// New initializes an SDL2 Mixer for the audio engine.
|
||||||
//
|
//
|
||||||
// Pass the SDL2 Mixer flags for its initialization. The flags are an OR'd
|
// Pass the SDL2 Mixer flags for its initialization. The flags are an OR'd
|
||||||
// value made up of:
|
// value made up of:
|
||||||
|
//
|
||||||
// mix.INIT_MP3
|
// mix.INIT_MP3
|
||||||
// mix.INIT_OGG
|
// mix.INIT_OGG
|
||||||
// mix.INIT_FLAC
|
// mix.INIT_FLAC
|
||||||
|
@ -19,6 +29,7 @@ type Engine struct {
|
||||||
func New(flags int) (*Engine, error) {
|
func New(flags int) (*Engine, error) {
|
||||||
return &Engine{
|
return &Engine{
|
||||||
initFlags: flags,
|
initFlags: flags,
|
||||||
|
channelsPlaying: map[int]*Track{},
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,6 +40,11 @@ func (e *Engine) Setup() error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Subscribe to sound effect channels finishing.
|
||||||
|
mix.ChannelFinished(func(channel int) {
|
||||||
|
_ = e.unsetPlaying(channel)
|
||||||
|
})
|
||||||
|
|
||||||
// Open the audio mixer.
|
// Open the audio mixer.
|
||||||
// the '2' is stereo (two channels), '1' would be mono.
|
// the '2' is stereo (two channels), '1' would be mono.
|
||||||
// 4096 is the chunk size.
|
// 4096 is the chunk size.
|
||||||
|
|
Loading…
Reference in New Issue
Block a user