mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-12-24 02:38:53 +01:00
audio, audio/mp3, audio/vorbis, audio/wav: Remove Close functions
Fixes #859
This commit is contained in:
parent
946cf1d250
commit
f1f7b350de
@ -162,7 +162,7 @@ func (c *Context) addPlayer(p *playerImpl) {
|
||||
c.players[p] = struct{}{}
|
||||
|
||||
// Check the source duplication
|
||||
srcs := map[io.ReadCloser]struct{}{}
|
||||
srcs := map[io.Reader]struct{}{}
|
||||
for p := range c.players {
|
||||
if _, ok := srcs[p.src]; ok {
|
||||
c.err = errors.New("audio: a same source is used by multiple Player")
|
||||
@ -211,34 +211,6 @@ func (c *Context) SampleRate() int {
|
||||
return c.sampleRate
|
||||
}
|
||||
|
||||
// ReadSeekCloser is an io.ReadSeeker and io.Closer.
|
||||
type ReadSeekCloser interface {
|
||||
io.ReadSeeker
|
||||
io.Closer
|
||||
}
|
||||
|
||||
type bytesReadSeekCloser struct {
|
||||
reader *bytes.Reader
|
||||
}
|
||||
|
||||
func (b *bytesReadSeekCloser) Read(buf []byte) (int, error) {
|
||||
return b.reader.Read(buf)
|
||||
}
|
||||
|
||||
func (b *bytesReadSeekCloser) Seek(offset int64, whence int) (int64, error) {
|
||||
return b.reader.Seek(offset, whence)
|
||||
}
|
||||
|
||||
func (b *bytesReadSeekCloser) Close() error {
|
||||
b.reader = nil
|
||||
return nil
|
||||
}
|
||||
|
||||
// BytesReadSeekCloser creates ReadSeekCloser from bytes.
|
||||
func BytesReadSeekCloser(b []byte) ReadSeekCloser {
|
||||
return &bytesReadSeekCloser{reader: bytes.NewReader(b)}
|
||||
}
|
||||
|
||||
// Player is an audio player which has one stream.
|
||||
//
|
||||
// Even when all references to a Player object is gone,
|
||||
@ -251,7 +223,7 @@ type Player struct {
|
||||
|
||||
type playerImpl struct {
|
||||
context *Context
|
||||
src io.ReadCloser
|
||||
src io.Reader
|
||||
sampleRate int
|
||||
playing bool
|
||||
closedExplicitly bool
|
||||
@ -278,8 +250,9 @@ type playerImpl struct {
|
||||
// NewPlayer tries to call Seek of src to get the current position.
|
||||
// NewPlayer returns error when the Seek returns error.
|
||||
//
|
||||
// NewPlayer takes the ownership of src. Player's Close calls src's Close.
|
||||
func NewPlayer(context *Context, src io.ReadCloser) (*Player, error) {
|
||||
// A Player doesn't close src even if src implements io.Closer.
|
||||
// Closing the source is src owner's responsibility.
|
||||
func NewPlayer(context *Context, src io.Reader) (*Player, error) {
|
||||
p := &Player{
|
||||
&playerImpl{
|
||||
context: context,
|
||||
@ -308,7 +281,7 @@ func NewPlayer(context *Context, src io.ReadCloser) (*Player, error) {
|
||||
//
|
||||
// The format of src should be same as noted at NewPlayer.
|
||||
func NewPlayerFromBytes(context *Context, src []byte) *Player {
|
||||
b := BytesReadSeekCloser(src)
|
||||
b := bytes.NewReader(src)
|
||||
p, err := NewPlayer(context, b)
|
||||
if err != nil {
|
||||
// Errors should never happen.
|
||||
@ -329,7 +302,7 @@ func (p *Player) finalize() {
|
||||
// When closing, the stream owned by the player will also be closed by calling its Close.
|
||||
// This means that the source stream passed via NewPlayer will also be closed.
|
||||
//
|
||||
// Close returns error when closing the source returns error.
|
||||
// Close returns error when the player is already closed.
|
||||
func (p *Player) Close() error {
|
||||
runtime.SetFinalizer(p, nil)
|
||||
return p.p.Close()
|
||||
@ -344,11 +317,6 @@ func (p *playerImpl) Close() error {
|
||||
return fmt.Errorf("audio: the player is already closed")
|
||||
}
|
||||
p.closedExplicitly = true
|
||||
// src.Close is called only when Player's Close is called.
|
||||
// TODO: Is it ok not to call src.Close when GCed?
|
||||
if err := p.src.Close(); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -15,6 +15,7 @@
|
||||
package audio_test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"runtime"
|
||||
"testing"
|
||||
"time"
|
||||
@ -38,7 +39,7 @@ func TestGC(t *testing.T) {
|
||||
setup()
|
||||
defer teardown()
|
||||
|
||||
p, _ := NewPlayer(context, BytesReadSeekCloser(make([]byte, 4)))
|
||||
p, _ := NewPlayer(context, bytes.NewReader(make([]byte, 4)))
|
||||
got := PlayersNumForTesting()
|
||||
if want := 0; got != want {
|
||||
t.Errorf("PlayersNum(): got: %d, want: %d", got, want)
|
||||
@ -74,7 +75,7 @@ func TestSameSourcePlayers(t *testing.T) {
|
||||
setup()
|
||||
defer teardown()
|
||||
|
||||
src := BytesReadSeekCloser(make([]byte, 4))
|
||||
src := bytes.NewReader(make([]byte, 4))
|
||||
p0, err := NewPlayer(context, src)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
@ -101,7 +102,7 @@ func TestPauseBeforeInit(t *testing.T) {
|
||||
setup()
|
||||
defer teardown()
|
||||
|
||||
src := BytesReadSeekCloser(make([]byte, 4))
|
||||
src := bytes.NewReader(make([]byte, 4))
|
||||
p, err := NewPlayer(context, src)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
|
@ -15,11 +15,11 @@
|
||||
package convert_test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io/ioutil"
|
||||
"math"
|
||||
"testing"
|
||||
|
||||
"github.com/hajimehoshi/ebiten/v2/audio"
|
||||
. "github.com/hajimehoshi/ebiten/v2/audio/internal/convert"
|
||||
)
|
||||
|
||||
@ -69,7 +69,7 @@ func TestResampling(t *testing.T) {
|
||||
}
|
||||
for _, c := range cases {
|
||||
inB := newSoundBytes(c.In)
|
||||
outS := NewResampling(audio.BytesReadSeekCloser(inB), int64(len(inB)), c.In, c.Out)
|
||||
outS := NewResampling(bytes.NewReader(inB), int64(len(inB)), c.In, c.Out)
|
||||
gotB, err := ioutil.ReadAll(outS)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
|
@ -16,17 +16,15 @@ package convert
|
||||
|
||||
import (
|
||||
"io"
|
||||
|
||||
"github.com/hajimehoshi/ebiten/v2/audio"
|
||||
)
|
||||
|
||||
type Stereo16 struct {
|
||||
source audio.ReadSeekCloser
|
||||
source io.ReadSeeker
|
||||
mono bool
|
||||
eight bool
|
||||
}
|
||||
|
||||
func NewStereo16(source audio.ReadSeekCloser, mono, eight bool) *Stereo16 {
|
||||
func NewStereo16(source io.ReadSeeker, mono, eight bool) *Stereo16 {
|
||||
return &Stereo16{
|
||||
source: source,
|
||||
mono: mono,
|
||||
@ -91,7 +89,3 @@ func (s *Stereo16) Seek(offset int64, whence int) (int64, error) {
|
||||
}
|
||||
return s.source.Seek(offset, whence)
|
||||
}
|
||||
|
||||
func (s *Stereo16) Close() error {
|
||||
return s.source.Close()
|
||||
}
|
||||
|
@ -21,20 +21,20 @@ import (
|
||||
|
||||
// InfiniteLoop represents a looped stream which never ends.
|
||||
type InfiniteLoop struct {
|
||||
src ReadSeekCloser
|
||||
src io.ReadSeeker
|
||||
lstart int64
|
||||
llength int64
|
||||
pos int64
|
||||
}
|
||||
|
||||
// NewInfiniteLoop creates a new infinite loop stream with a source stream and length in bytes.
|
||||
func NewInfiniteLoop(src ReadSeekCloser, length int64) *InfiniteLoop {
|
||||
func NewInfiniteLoop(src io.ReadSeeker, length int64) *InfiniteLoop {
|
||||
return NewInfiniteLoopWithIntro(src, 0, length)
|
||||
}
|
||||
|
||||
// NewInfiniteLoopWithIntro creates a new infinite loop stream with an intro part.
|
||||
// NewInfiniteLoopWithIntro accepts a source stream src, introLength in bytes and loopLength in bytes.
|
||||
func NewInfiniteLoopWithIntro(src ReadSeekCloser, introLength int64, loopLength int64) *InfiniteLoop {
|
||||
func NewInfiniteLoopWithIntro(src io.ReadSeeker, introLength int64, loopLength int64) *InfiniteLoop {
|
||||
return &InfiniteLoop{
|
||||
src: src,
|
||||
lstart: introLength,
|
||||
@ -121,8 +121,3 @@ func (i *InfiniteLoop) Seek(offset int64, whence int) (int64, error) {
|
||||
i.pos = next
|
||||
return i.pos, nil
|
||||
}
|
||||
|
||||
// Close is implementation of ReadSeekCloser's Close.
|
||||
func (l *InfiniteLoop) Close() error {
|
||||
return l.src.Close()
|
||||
}
|
||||
|
@ -15,6 +15,7 @@
|
||||
package audio_test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io"
|
||||
"math"
|
||||
"testing"
|
||||
@ -31,7 +32,7 @@ func TestInfiniteLoop(t *testing.T) {
|
||||
for i := range src {
|
||||
src[i] = indexToByte(i)
|
||||
}
|
||||
l := NewInfiniteLoop(BytesReadSeekCloser(src), int64(len(src)))
|
||||
l := NewInfiniteLoop(bytes.NewReader(src), int64(len(src)))
|
||||
|
||||
buf := make([]byte, len(src)*4)
|
||||
if _, err := io.ReadFull(l, buf); err != nil {
|
||||
@ -93,7 +94,7 @@ func TestInfiniteLoopWithIntro(t *testing.T) {
|
||||
for i := range src {
|
||||
src[i] = indexToByte(i)
|
||||
}
|
||||
srcInf := NewInfiniteLoop(BytesReadSeekCloser(src), srcLength)
|
||||
srcInf := NewInfiniteLoop(bytes.NewReader(src), srcLength)
|
||||
l := NewInfiniteLoopWithIntro(srcInf, introLength, loopLength)
|
||||
|
||||
buf := make([]byte, srcLength*4)
|
||||
|
@ -20,7 +20,6 @@ package mp3
|
||||
|
||||
import (
|
||||
"io"
|
||||
"runtime"
|
||||
|
||||
"github.com/hajimehoshi/go-mp3"
|
||||
|
||||
@ -32,7 +31,6 @@ import (
|
||||
type Stream struct {
|
||||
orig *mp3.Decoder
|
||||
resampling *convert.Resampling
|
||||
toClose io.Closer
|
||||
}
|
||||
|
||||
// Read is implementation of io.Reader's Read.
|
||||
@ -51,12 +49,6 @@ func (s *Stream) Seek(offset int64, whence int) (int64, error) {
|
||||
return s.orig.Seek(offset, whence)
|
||||
}
|
||||
|
||||
// Close is implementation of io.Closer's Close.
|
||||
func (s *Stream) Close() error {
|
||||
runtime.SetFinalizer(s, nil)
|
||||
return s.toClose.Close()
|
||||
}
|
||||
|
||||
// Length returns the size of decoded stream in bytes.
|
||||
func (s *Stream) Length() int64 {
|
||||
if s.resampling != nil {
|
||||
@ -71,8 +63,9 @@ func (s *Stream) Length() int64 {
|
||||
//
|
||||
// Decode automatically resamples the stream to fit with the audio context if necessary.
|
||||
//
|
||||
// Decode takes the ownership of src, and Stream's Close function closes src.
|
||||
func Decode(context *audio.Context, src audio.ReadSeekCloser) (*Stream, error) {
|
||||
// A Stream doesn't close src even if src implements io.Closer.
|
||||
// Closing the source is src owner's responsibility.
|
||||
func Decode(context *audio.Context, src io.ReadSeeker) (*Stream, error) {
|
||||
d, err := mp3.NewDecoder(src)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -85,8 +78,6 @@ func Decode(context *audio.Context, src audio.ReadSeekCloser) (*Stream, error) {
|
||||
s := &Stream{
|
||||
orig: d,
|
||||
resampling: r,
|
||||
toClose: src,
|
||||
}
|
||||
runtime.SetFinalizer(s, (*Stream).Close)
|
||||
return s, nil
|
||||
}
|
||||
|
@ -18,7 +18,6 @@ package vorbis
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"runtime"
|
||||
|
||||
"github.com/jfreymuth/oggvorbis"
|
||||
|
||||
@ -28,7 +27,7 @@ import (
|
||||
|
||||
// Stream is a decoded audio stream.
|
||||
type Stream struct {
|
||||
decoded audio.ReadSeekCloser
|
||||
decoded io.ReadSeeker
|
||||
size int64
|
||||
}
|
||||
|
||||
@ -44,15 +43,6 @@ func (s *Stream) Seek(offset int64, whence int) (int64, error) {
|
||||
return s.decoded.Seek(offset, whence)
|
||||
}
|
||||
|
||||
// Close is implementation of io.Closer's Close.
|
||||
func (s *Stream) Close() error {
|
||||
runtime.SetFinalizer(s, nil)
|
||||
if err := s.decoded.Close(); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Length returns the size of decoded stream in bytes.
|
||||
func (s *Stream) Length() int64 {
|
||||
return s.size
|
||||
@ -69,7 +59,6 @@ type decoder interface {
|
||||
type decoded struct {
|
||||
totalBytes int
|
||||
posInBytes int
|
||||
source io.Closer
|
||||
decoder decoder
|
||||
decoderr io.Reader
|
||||
}
|
||||
@ -122,22 +111,12 @@ func (d *decoded) Seek(offset int64, whence int) (int64, error) {
|
||||
return next, nil
|
||||
}
|
||||
|
||||
func (d *decoded) Close() error {
|
||||
runtime.SetFinalizer(d, nil)
|
||||
if err := d.source.Close(); err != nil {
|
||||
return err
|
||||
}
|
||||
d.decoder = nil
|
||||
d.decoderr = nil
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *decoded) Length() int64 {
|
||||
return int64(d.totalBytes)
|
||||
}
|
||||
|
||||
// decode accepts an ogg stream and returns a decorded stream.
|
||||
func decode(in audio.ReadSeekCloser) (*decoded, int, int, error) {
|
||||
func decode(in io.ReadSeeker) (*decoded, int, int, error) {
|
||||
r, err := oggvorbis.NewReader(in)
|
||||
if err != nil {
|
||||
return nil, 0, 0, err
|
||||
@ -147,10 +126,8 @@ func decode(in audio.ReadSeekCloser) (*decoded, int, int, error) {
|
||||
// Should we check that?
|
||||
totalBytes: int(r.Length()) * r.Channels() * 2, // 2 means 16bit per sample.
|
||||
posInBytes: 0,
|
||||
source: in,
|
||||
decoder: r,
|
||||
}
|
||||
runtime.SetFinalizer(d, (*decoded).Close)
|
||||
if _, err := d.Read(make([]byte, 65536)); err != nil && err != io.EOF {
|
||||
return nil, 0, 0, err
|
||||
}
|
||||
@ -166,8 +143,9 @@ func decode(in audio.ReadSeekCloser) (*decoded, int, int, error) {
|
||||
//
|
||||
// Decode automatically resamples the stream to fit with the audio context if necessary.
|
||||
//
|
||||
// Decode takes the ownership of src, and Stream's Close function closes src.
|
||||
func Decode(context *audio.Context, src audio.ReadSeekCloser) (*Stream, error) {
|
||||
// A Stream doesn't close src even if src implements io.Closer.
|
||||
// Closing the source is src owner's responsibility.
|
||||
func Decode(context *audio.Context, src io.ReadSeeker) (*Stream, error) {
|
||||
decoded, channelNum, sampleRate, err := decode(src)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -175,7 +153,7 @@ func Decode(context *audio.Context, src audio.ReadSeekCloser) (*Stream, error) {
|
||||
if channelNum != 1 && channelNum != 2 {
|
||||
return nil, fmt.Errorf("vorbis: number of channels must be 1 or 2 but was %d", channelNum)
|
||||
}
|
||||
var s audio.ReadSeekCloser = decoded
|
||||
var s io.ReadSeeker = decoded
|
||||
size := decoded.Length()
|
||||
if channelNum == 1 {
|
||||
s = convert.NewStereo16(s, true, false)
|
||||
@ -187,6 +165,5 @@ func Decode(context *audio.Context, src audio.ReadSeekCloser) (*Stream, error) {
|
||||
size = r.Length()
|
||||
}
|
||||
stream := &Stream{decoded: s, size: size}
|
||||
runtime.SetFinalizer(stream, (*Stream).Close)
|
||||
return stream, nil
|
||||
}
|
||||
|
@ -15,6 +15,7 @@
|
||||
package vorbis_test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"testing"
|
||||
|
||||
"github.com/jfreymuth/oggvorbis"
|
||||
@ -28,12 +29,12 @@ var audioContext = audio.NewContext(44100)
|
||||
func TestMono(t *testing.T) {
|
||||
bs := test_mono_ogg
|
||||
|
||||
s, err := Decode(audioContext, audio.BytesReadSeekCloser(bs))
|
||||
s, err := Decode(audioContext, bytes.NewReader(bs))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
r, err := oggvorbis.NewReader(audio.BytesReadSeekCloser(bs))
|
||||
r, err := oggvorbis.NewReader(bytes.NewReader(bs))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@ -54,7 +55,7 @@ func TestMono(t *testing.T) {
|
||||
func TestTooShort(t *testing.T) {
|
||||
bs := test_tooshort_ogg
|
||||
|
||||
s, err := Decode(audioContext, audio.BytesReadSeekCloser(bs))
|
||||
s, err := Decode(audioContext, bytes.NewReader(bs))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
@ -19,7 +19,6 @@ import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"runtime"
|
||||
|
||||
"github.com/hajimehoshi/ebiten/v2/audio"
|
||||
"github.com/hajimehoshi/ebiten/v2/audio/internal/convert"
|
||||
@ -27,7 +26,7 @@ import (
|
||||
|
||||
// Stream is a decoded audio stream.
|
||||
type Stream struct {
|
||||
inner audio.ReadSeekCloser
|
||||
inner io.ReadSeeker
|
||||
size int64
|
||||
}
|
||||
|
||||
@ -43,19 +42,13 @@ func (s *Stream) Seek(offset int64, whence int) (int64, error) {
|
||||
return s.inner.Seek(offset, whence)
|
||||
}
|
||||
|
||||
// Read is implementation of io.Closer's Close.
|
||||
func (s *Stream) Close() error {
|
||||
runtime.SetFinalizer(s, nil)
|
||||
return s.inner.Close()
|
||||
}
|
||||
|
||||
// Length returns the size of decoded stream in bytes.
|
||||
func (s *Stream) Length() int64 {
|
||||
return s.size
|
||||
}
|
||||
|
||||
type stream struct {
|
||||
src audio.ReadSeekCloser
|
||||
src io.ReadSeeker
|
||||
headerSize int64
|
||||
dataSize int64
|
||||
remaining int64
|
||||
@ -100,12 +93,6 @@ func (s *stream) Seek(offset int64, whence int) (int64, error) {
|
||||
return n - s.headerSize, nil
|
||||
}
|
||||
|
||||
// Close is implementation of io.Closer's Close.
|
||||
func (s *stream) Close() error {
|
||||
runtime.SetFinalizer(s, nil)
|
||||
return s.src.Close()
|
||||
}
|
||||
|
||||
// Decode decodes WAV (RIFF) data to playable stream.
|
||||
//
|
||||
// The format must be 1 or 2 channels, 8bit or 16bit little endian PCM.
|
||||
@ -115,8 +102,9 @@ func (s *stream) Close() error {
|
||||
//
|
||||
// Decode automatically resamples the stream to fit with the audio context if necessary.
|
||||
//
|
||||
// Decode takes the ownership of src, and Stream's Close function closes src.
|
||||
func Decode(context *audio.Context, src audio.ReadSeekCloser) (*Stream, error) {
|
||||
// A Stream doesn't close src even if src implements io.Closer.
|
||||
// Closing the source is src owner's responsibility.
|
||||
func Decode(context *audio.Context, src io.ReadSeeker) (*Stream, error) {
|
||||
buf := make([]byte, 12)
|
||||
n, err := io.ReadFull(src, buf)
|
||||
if n != len(buf) {
|
||||
@ -203,13 +191,12 @@ chunks:
|
||||
headerSize += size
|
||||
}
|
||||
}
|
||||
var s audio.ReadSeekCloser = &stream{
|
||||
var s io.ReadSeeker = &stream{
|
||||
src: src,
|
||||
headerSize: headerSize,
|
||||
dataSize: dataSize,
|
||||
remaining: dataSize,
|
||||
}
|
||||
runtime.SetFinalizer(s, (*stream).Close)
|
||||
|
||||
if mono || bitsPerSample != 16 {
|
||||
s = convert.NewStereo16(s, mono, bitsPerSample != 16)
|
||||
@ -226,6 +213,5 @@ chunks:
|
||||
dataSize = r.Length()
|
||||
}
|
||||
ss := &Stream{inner: s, size: dataSize}
|
||||
runtime.SetFinalizer(ss, (*Stream).Close)
|
||||
return ss, nil
|
||||
}
|
||||
|
@ -20,8 +20,10 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"image/color"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"time"
|
||||
@ -87,7 +89,7 @@ func playerBarRect() (x, y, w, h int) {
|
||||
|
||||
func NewPlayer(audioContext *audio.Context, musicType musicType) (*Player, error) {
|
||||
type audioStream interface {
|
||||
audio.ReadSeekCloser
|
||||
io.ReadSeeker
|
||||
Length() int64
|
||||
}
|
||||
|
||||
@ -98,13 +100,13 @@ func NewPlayer(audioContext *audio.Context, musicType musicType) (*Player, error
|
||||
switch musicType {
|
||||
case typeOgg:
|
||||
var err error
|
||||
s, err = vorbis.Decode(audioContext, audio.BytesReadSeekCloser(raudio.Ragtime_ogg))
|
||||
s, err = vorbis.Decode(audioContext, bytes.NewReader(raudio.Ragtime_ogg))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
case typeMP3:
|
||||
var err error
|
||||
s, err = mp3.Decode(audioContext, audio.BytesReadSeekCloser(raudio.Classic_mp3))
|
||||
s, err = mp3.Decode(audioContext, bytes.NewReader(raudio.Classic_mp3))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -128,7 +130,7 @@ func NewPlayer(audioContext *audio.Context, musicType musicType) (*Player, error
|
||||
}
|
||||
player.audioPlayer.Play()
|
||||
go func() {
|
||||
s, err := wav.Decode(audioContext, audio.BytesReadSeekCloser(raudio.Jab_wav))
|
||||
s, err := wav.Decode(audioContext, bytes.NewReader(raudio.Jab_wav))
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
return
|
||||
|
@ -17,6 +17,7 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"log"
|
||||
"time"
|
||||
@ -50,7 +51,7 @@ func (g *Game) Update() error {
|
||||
|
||||
// Decode an Ogg file.
|
||||
// oggS is a decoded io.ReadCloser and io.Seeker.
|
||||
oggS, err := vorbis.Decode(audioContext, audio.BytesReadSeekCloser(raudio.Ragtime_ogg))
|
||||
oggS, err := vorbis.Decode(audioContext, bytes.NewReader(raudio.Ragtime_ogg))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -21,6 +21,7 @@ import (
|
||||
"fmt"
|
||||
"image"
|
||||
_ "image/png"
|
||||
"io"
|
||||
"log"
|
||||
"math"
|
||||
"time"
|
||||
@ -64,7 +65,7 @@ func (g *Game) initAudio() {
|
||||
|
||||
// Decode an Ogg file.
|
||||
// oggS is a decoded io.ReadCloser and io.Seeker.
|
||||
oggS, err := vorbis.Decode(audioContext, audio.BytesReadSeekCloser(raudio.Ragtime_ogg))
|
||||
oggS, err := vorbis.Decode(audioContext, bytes.NewReader(raudio.Ragtime_ogg))
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
@ -145,12 +146,12 @@ func main() {
|
||||
// StereoPanStream is an audio buffer that changes the stereo channel's signal
|
||||
// based on the Panning.
|
||||
type StereoPanStream struct {
|
||||
audio.ReadSeekCloser
|
||||
io.ReadSeeker
|
||||
pan float64 // -1: left; 0: center; 1: right
|
||||
}
|
||||
|
||||
func (s *StereoPanStream) Read(p []byte) (n int, err error) {
|
||||
n, err = s.ReadSeekCloser.Read(p)
|
||||
n, err = s.ReadSeeker.Read(p)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
@ -187,8 +188,8 @@ func (s *StereoPanStream) Pan() float64 {
|
||||
// The src's format must be linear PCM (16bits little endian, 2 channel stereo)
|
||||
// without a header (e.g. RIFF header). The sample rate must be same as that
|
||||
// of the audio context.
|
||||
func NewStereoPanStreamFromReader(src audio.ReadSeekCloser) *StereoPanStream {
|
||||
func NewStereoPanStreamFromReader(src io.ReadSeeker) *StereoPanStream {
|
||||
return &StereoPanStream{
|
||||
ReadSeekCloser: src,
|
||||
ReadSeeker: src,
|
||||
}
|
||||
}
|
||||
|
@ -122,7 +122,7 @@ var (
|
||||
)
|
||||
|
||||
func init() {
|
||||
jumpD, err := vorbis.Decode(audioContext, audio.BytesReadSeekCloser(raudio.Jump_ogg))
|
||||
jumpD, err := vorbis.Decode(audioContext, bytes.NewReader(raudio.Jump_ogg))
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
@ -131,7 +131,7 @@ func init() {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
jabD, err := wav.Decode(audioContext, audio.BytesReadSeekCloser(raudio.Jab_wav))
|
||||
jabD, err := wav.Decode(audioContext, bytes.NewReader(raudio.Jab_wav))
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
@ -17,6 +17,7 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"log"
|
||||
|
||||
"github.com/hajimehoshi/ebiten/v2"
|
||||
@ -59,7 +60,7 @@ func init() {
|
||||
// ...
|
||||
|
||||
// Decode wav-formatted data and retrieve decoded PCM stream.
|
||||
d, err := wav.Decode(g.audioContext, audio.BytesReadSeekCloser(raudio.Jab_wav))
|
||||
d, err := wav.Decode(g.audioContext, bytes.NewReader(raudio.Jab_wav))
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user