mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2025-02-03 14:34:26 +01:00
audio/internal/readerdriver: Remove goroutines for Windows
Also this change changed the buffers to use smaller but more headers to improve latency. Updates #1768
This commit is contained in:
parent
ded679c071
commit
9f1113b733
@ -16,13 +16,15 @@ package readerdriver
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"sync"
|
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
"golang.org/x/sys/windows"
|
"golang.org/x/sys/windows"
|
||||||
)
|
)
|
||||||
|
|
||||||
const headerBufferSize = 8192
|
// Avoid goroutines on Windows (#1768).
|
||||||
|
// Apparently, switching contexts might take longer than other platforms.
|
||||||
|
|
||||||
|
const headerBufferSize = 4096
|
||||||
|
|
||||||
func IsAvailable() bool {
|
func IsAvailable() bool {
|
||||||
return true
|
return true
|
||||||
@ -73,7 +75,7 @@ type context struct {
|
|||||||
waveOut uintptr
|
waveOut uintptr
|
||||||
headers []*header
|
headers []*header
|
||||||
|
|
||||||
cond *sync.Cond
|
buf32 []float32
|
||||||
|
|
||||||
players *players
|
players *players
|
||||||
}
|
}
|
||||||
@ -88,7 +90,6 @@ func NewContext(sampleRate, channelNum, bitDepthInBytes int) (Context, chan stru
|
|||||||
sampleRate: sampleRate,
|
sampleRate: sampleRate,
|
||||||
channelNum: channelNum,
|
channelNum: channelNum,
|
||||||
bitDepthInBytes: bitDepthInBytes,
|
bitDepthInBytes: bitDepthInBytes,
|
||||||
cond: sync.NewCond(&sync.Mutex{}),
|
|
||||||
players: newPlayers(),
|
players: newPlayers(),
|
||||||
}
|
}
|
||||||
theContext = c
|
theContext = c
|
||||||
@ -117,7 +118,7 @@ func NewContext(sampleRate, channelNum, bitDepthInBytes int) (Context, chan stru
|
|||||||
}
|
}
|
||||||
|
|
||||||
c.waveOut = w
|
c.waveOut = w
|
||||||
c.headers = make([]*header, 0, 3)
|
c.headers = make([]*header, 0, 6)
|
||||||
for len(c.headers) < cap(c.headers) {
|
for len(c.headers) < cap(c.headers) {
|
||||||
h, err := newHeader(c.waveOut, headerBufferSize)
|
h, err := newHeader(c.waveOut, headerBufferSize)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -126,7 +127,10 @@ func NewContext(sampleRate, channelNum, bitDepthInBytes int) (Context, chan stru
|
|||||||
c.headers = append(c.headers, h)
|
c.headers = append(c.headers, h)
|
||||||
}
|
}
|
||||||
|
|
||||||
go c.loop()
|
c.buf32 = make([]float32, headerBufferSize/4)
|
||||||
|
for range c.headers {
|
||||||
|
c.appendBuffers()
|
||||||
|
}
|
||||||
|
|
||||||
return c, ready, nil
|
return c, ready, nil
|
||||||
}
|
}
|
||||||
@ -161,36 +165,22 @@ var waveOutOpenCallback = windows.NewCallbackCDecl(func(hwo, uMsg, dwInstance, d
|
|||||||
if uMsg != womDone {
|
if uMsg != womDone {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
theContext.cond.Signal()
|
theContext.appendBuffers()
|
||||||
return 0
|
return 0
|
||||||
})
|
})
|
||||||
|
|
||||||
func (c *context) loop() {
|
func (c *context) appendBuffers() {
|
||||||
buf32 := make([]float32, headerBufferSize/4)
|
for i := range c.buf32 {
|
||||||
for {
|
c.buf32[i] = 0
|
||||||
c.appendBuffer(buf32)
|
|
||||||
}
|
}
|
||||||
}
|
c.players.read(c.buf32)
|
||||||
|
|
||||||
func (c *context) appendBuffer(buf32 []float32) {
|
|
||||||
c.cond.L.Lock()
|
|
||||||
defer c.cond.L.Unlock()
|
|
||||||
|
|
||||||
for !c.isHeaderAvailable() {
|
|
||||||
c.cond.Wait()
|
|
||||||
}
|
|
||||||
|
|
||||||
for i := range buf32 {
|
|
||||||
buf32[i] = 0
|
|
||||||
}
|
|
||||||
c.players.read(buf32)
|
|
||||||
|
|
||||||
for _, h := range c.headers {
|
for _, h := range c.headers {
|
||||||
if h.IsQueued() {
|
if h.IsQueued() {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := h.Write(buf32); err != nil {
|
if err := h.Write(c.buf32); err != nil {
|
||||||
// This error can happen when e.g. a new HDMI connection is detected (hajimehoshi/oto#51).
|
// This error can happen when e.g. a new HDMI connection is detected (hajimehoshi/oto#51).
|
||||||
const errorNotFound = 1168
|
const errorNotFound = 1168
|
||||||
if werr := err.(*winmmError); werr.fname == "waveOutWrite" {
|
if werr := err.(*winmmError); werr.fname == "waveOutWrite" {
|
||||||
@ -204,6 +194,5 @@ func (c *context) appendBuffer(buf32 []float32) {
|
|||||||
// TODO: Treat the error corretly
|
// TODO: Treat the error corretly
|
||||||
panic(fmt.Errorf("readerdriver: Queueing the header failed: %v", err))
|
panic(fmt.Errorf("readerdriver: Queueing the header failed: %v", err))
|
||||||
}
|
}
|
||||||
return
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user