mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-12-25 19:28:57 +01:00
examples/audio: Switchable to MP3 from Ogg
This commit is contained in:
parent
43b37a0ca5
commit
32c04767da
@ -28,6 +28,7 @@ import (
|
|||||||
|
|
||||||
"github.com/hajimehoshi/ebiten"
|
"github.com/hajimehoshi/ebiten"
|
||||||
"github.com/hajimehoshi/ebiten/audio"
|
"github.com/hajimehoshi/ebiten/audio"
|
||||||
|
"github.com/hajimehoshi/ebiten/audio/mp3"
|
||||||
"github.com/hajimehoshi/ebiten/audio/vorbis"
|
"github.com/hajimehoshi/ebiten/audio/vorbis"
|
||||||
"github.com/hajimehoshi/ebiten/audio/wav"
|
"github.com/hajimehoshi/ebiten/audio/wav"
|
||||||
"github.com/hajimehoshi/ebiten/ebitenutil"
|
"github.com/hajimehoshi/ebiten/ebitenutil"
|
||||||
@ -47,6 +48,24 @@ var (
|
|||||||
playerCurrentColor = color.RGBA{0xff, 0xff, 0xff, 0xff}
|
playerCurrentColor = color.RGBA{0xff, 0xff, 0xff, 0xff}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type musicType int
|
||||||
|
|
||||||
|
const (
|
||||||
|
typeOgg musicType = iota
|
||||||
|
typeMP3
|
||||||
|
)
|
||||||
|
|
||||||
|
func (t musicType) String() string {
|
||||||
|
switch t {
|
||||||
|
case typeOgg:
|
||||||
|
return "Ogg"
|
||||||
|
case typeMP3:
|
||||||
|
return "MP3"
|
||||||
|
default:
|
||||||
|
panic("not reached")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Player represents the current audio state.
|
// Player represents the current audio state.
|
||||||
type Player struct {
|
type Player struct {
|
||||||
audioContext *audio.Context
|
audioContext *audio.Context
|
||||||
@ -56,6 +75,7 @@ type Player struct {
|
|||||||
seBytes []byte
|
seBytes []byte
|
||||||
seCh chan []byte
|
seCh chan []byte
|
||||||
volume128 int
|
volume128 int
|
||||||
|
musicType musicType
|
||||||
}
|
}
|
||||||
|
|
||||||
func playerBarRect() (x, y, w, h int) {
|
func playerBarRect() (x, y, w, h int) {
|
||||||
@ -65,12 +85,32 @@ func playerBarRect() (x, y, w, h int) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewPlayer(audioContext *audio.Context) (*Player, error) {
|
func NewPlayer(audioContext *audio.Context, musicType musicType) (*Player, error) {
|
||||||
|
type audioStream interface {
|
||||||
|
audio.ReadSeekCloser
|
||||||
|
Length() int64
|
||||||
|
}
|
||||||
|
|
||||||
const bytesPerSample = 4 // TODO: This should be defined in audio package
|
const bytesPerSample = 4 // TODO: This should be defined in audio package
|
||||||
s, err := vorbis.Decode(audioContext, audio.BytesReadSeekCloser(raudio.Ragtime_ogg))
|
|
||||||
|
var s audioStream
|
||||||
|
|
||||||
|
switch musicType {
|
||||||
|
case typeOgg:
|
||||||
|
var err error
|
||||||
|
s, err = vorbis.Decode(audioContext, audio.BytesReadSeekCloser(raudio.Ragtime_ogg))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
case typeMP3:
|
||||||
|
var err error
|
||||||
|
s, err = mp3.Decode(audioContext, audio.BytesReadSeekCloser(raudio.Classic_mp3))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
panic("not reached")
|
||||||
|
}
|
||||||
p, err := audio.NewPlayer(audioContext, s)
|
p, err := audio.NewPlayer(audioContext, s)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -81,6 +121,7 @@ func NewPlayer(audioContext *audio.Context) (*Player, error) {
|
|||||||
total: time.Second * time.Duration(s.Length()) / bytesPerSample / sampleRate,
|
total: time.Second * time.Duration(s.Length()) / bytesPerSample / sampleRate,
|
||||||
volume128: 128,
|
volume128: 128,
|
||||||
seCh: make(chan []byte),
|
seCh: make(chan []byte),
|
||||||
|
musicType: musicType,
|
||||||
}
|
}
|
||||||
if player.total == 0 {
|
if player.total == 0 {
|
||||||
player.total = 1
|
player.total = 1
|
||||||
@ -102,6 +143,10 @@ func NewPlayer(audioContext *audio.Context) (*Player, error) {
|
|||||||
return player, nil
|
return player, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *Player) Close() error {
|
||||||
|
return p.audioPlayer.Close()
|
||||||
|
}
|
||||||
|
|
||||||
func (p *Player) update() error {
|
func (p *Player) update() error {
|
||||||
select {
|
select {
|
||||||
case p.seBytes = <-p.seCh:
|
case p.seBytes = <-p.seCh:
|
||||||
@ -208,25 +253,65 @@ Press S to toggle Play/Pause
|
|||||||
Press P to play SE
|
Press P to play SE
|
||||||
Press Z or X to change volume of the music
|
Press Z or X to change volume of the music
|
||||||
Press B to switch the run-in-background state
|
Press B to switch the run-in-background state
|
||||||
|
Press A to switch Ogg and MP3
|
||||||
Current Time: %s
|
Current Time: %s
|
||||||
Current Volume: %d/128`, ebiten.CurrentTPS(), currentTimeStr, int(p.audioPlayer.Volume()*128))
|
Current Volume: %d/128
|
||||||
|
Type: %s`, ebiten.CurrentTPS(), currentTimeStr, int(p.audioPlayer.Volume()*128), musicPlayer.musicType)
|
||||||
ebitenutil.DebugPrint(screen, msg)
|
ebitenutil.DebugPrint(screen, msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
musicPlayer *Player
|
musicPlayer *Player
|
||||||
|
musicPlayerCh = make(chan *Player)
|
||||||
|
errCh = make(chan error)
|
||||||
)
|
)
|
||||||
|
|
||||||
func update(screen *ebiten.Image) error {
|
func update(screen *ebiten.Image) error {
|
||||||
|
select {
|
||||||
|
case p := <-musicPlayerCh:
|
||||||
|
musicPlayer = p
|
||||||
|
case err := <-errCh:
|
||||||
|
return err
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
|
||||||
|
if musicPlayer != nil && inpututil.IsKeyJustPressed(ebiten.KeyA) {
|
||||||
|
var t musicType
|
||||||
|
switch musicPlayer.musicType {
|
||||||
|
case typeOgg:
|
||||||
|
t = typeMP3
|
||||||
|
case typeMP3:
|
||||||
|
t = typeOgg
|
||||||
|
default:
|
||||||
|
panic("not reached")
|
||||||
|
}
|
||||||
|
|
||||||
|
musicPlayer.Close()
|
||||||
|
musicPlayer = nil
|
||||||
|
|
||||||
|
go func() {
|
||||||
|
p, err := NewPlayer(audio.CurrentContext(), t)
|
||||||
|
if err != nil {
|
||||||
|
errCh <- err
|
||||||
|
return
|
||||||
|
}
|
||||||
|
musicPlayerCh <- p
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
|
||||||
|
if musicPlayer != nil {
|
||||||
if err := musicPlayer.update(); err != nil {
|
if err := musicPlayer.update(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if ebiten.IsDrawingSkipped() {
|
if ebiten.IsDrawingSkipped() {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if musicPlayer != nil {
|
||||||
musicPlayer.draw(screen)
|
musicPlayer.draw(screen)
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -236,7 +321,7 @@ func main() {
|
|||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
musicPlayer, err = NewPlayer(audioContext)
|
musicPlayer, err = NewPlayer(audioContext, typeOgg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user