From 5fd8fe839bab5620a3f484bc6dc728d1c7e3d247 Mon Sep 17 00:00:00 2001 From: Hajime Hoshi Date: Sat, 15 Jul 2017 03:03:40 +0900 Subject: [PATCH] audio: Simplify player's Read/Seek --- audio/audio.go | 65 +++++++----------------------------------- audio/buffersize_js.go | 2 ++ audio/timeout_js.go | 27 ------------------ audio/timeout_notjs.go | 25 ---------------- 4 files changed, 12 insertions(+), 107 deletions(-) delete mode 100644 audio/timeout_js.go delete mode 100644 audio/timeout_notjs.go diff --git a/audio/audio.go b/audio/audio.go index 1de7f69e1..8f36733a0 100644 --- a/audio/audio.go +++ b/audio/audio.go @@ -337,8 +337,6 @@ type Player struct { players *players src ReadSeekCloser sampleRate int - readingCh chan readingResult - seekCh chan int64 buf []uint8 pos int64 @@ -366,7 +364,6 @@ func NewPlayer(context *Context, src ReadSeekCloser) (*Player, error) { players: context.players, src: src, sampleRate: context.sampleRate, - seekCh: make(chan int64, 1), buf: []uint8{}, volume: 1, } @@ -415,52 +412,21 @@ func (p *Player) Close() error { } func (p *Player) readToBuffer(length int) (int, error) { - if p.readingCh == nil { - p.readingCh = make(chan readingResult) - go func() { - b := make([]uint8, length) - p.srcM.Lock() - n, err := p.src.Read(b) - p.srcM.Unlock() - if err != nil { - p.readingCh <- readingResult{ - err: err, - } - return - } - p.readingCh <- readingResult{ - data: b[:n], - } - }() - } - select { - case pos := <-p.seekCh: - p.buf = []uint8{} - p.pos = pos - case r := <-p.readingCh: - close(p.readingCh) - p.readingCh = nil - if r.err != nil { - return 0, r.err - } - if len(r.data) > 0 { - p.buf = append(p.buf, r.data...) - } - case <-timeoutIfPossible(10 * time.Millisecond): - if l := length - len(p.buf); l > 0 { - empty := make([]uint8, l) - p.buf = append(p.buf, empty...) - } + b := make([]uint8, length) + p.srcM.Lock() + n, err := p.src.Read(b) + p.srcM.Unlock() + if err != nil { + return 0, err } + p.buf = append(p.buf, b[:n]...) + b = b[:n] return len(p.buf), nil } func (p *Player) bufferToInt16(lengthInBytes int) []int16 { r := make([]int16, lengthInBytes/2) // This function must be called on the same goruotine of readToBuffer. - if p.readingCh != nil { - return r - } p.m.RLock() for i := 0; i < lengthInBytes/2; i++ { r[i] = int16(p.buf[2*i]) | (int16(p.buf[2*i+1]) << 8) @@ -472,9 +438,6 @@ func (p *Player) bufferToInt16(lengthInBytes int) []int16 { func (p *Player) proceed(length int) { // This function must be called on the same goruotine of readToBuffer. - if p.readingCh != nil { - return - } p.buf = p.buf[length:] p.pos += int64(length) } @@ -519,16 +482,8 @@ func (p *Player) Seek(offset time.Duration) error { if err != nil { return err } - // When the player p is not playing, as readToBuffer is never called, - // seekCh will never solved. - // Solve the current seeking here if necessary. - select { - case pos := <-p.seekCh: - p.buf = []uint8{} - p.pos = pos - default: - } - p.seekCh <- pos + p.buf = []uint8{} + p.pos = pos return nil } diff --git a/audio/buffersize_js.go b/audio/buffersize_js.go index e69dd53b0..610771e90 100644 --- a/audio/buffersize_js.go +++ b/audio/buffersize_js.go @@ -21,6 +21,8 @@ import ( ) func (c *Context) bufferSize() int { + // TODO: examples/audio doesn't work well with 1/30[s], + // the other examples work though. Fix this. n := 20 if web.IsMobileBrowser() { n = 10 diff --git a/audio/timeout_js.go b/audio/timeout_js.go deleted file mode 100644 index 3cc0b0146..000000000 --- a/audio/timeout_js.go +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright 2017 The Ebiten Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// +build js - -package audio - -import ( - "time" -) - -func timeoutIfPossible(t time.Duration) <-chan time.Time { - // time.After uses setTimeout and causes performance problems. - // This function returns nil and blocks forever. - return nil -} diff --git a/audio/timeout_notjs.go b/audio/timeout_notjs.go deleted file mode 100644 index 57cd783bd..000000000 --- a/audio/timeout_notjs.go +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright 2017 The Ebiten Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// +build !js - -package audio - -import ( - "time" -) - -func timeoutIfPossible(t time.Duration) <-chan time.Time { - return time.After(t) -}