mirror of
https://github.com/libretro/ludo.git
synced 2026-11-07 04:05:58 -10:00
audio: fix handling of Sample(l,r) which passed invalid sized data into write buffer (#393)
This commit is contained in:
1 parent
5ddf78c7a8
commit
445f7ba036
2 files changed
+13
-16
No files matched your search
+10
-14
@@ -6,6 +6,7 @@ import (
|
||||
"log"
|
||||
"path/filepath"
|
||||
"time"
|
||||
"unsafe"
|
||||
|
||||
"github.com/libretro/ludo/settings"
|
||||
"github.com/libretro/ludo/state"
|
||||
@@ -22,7 +23,6 @@ var audio struct {
|
||||
numBuffers int32
|
||||
tmpBuf [bufSize]byte
|
||||
tmpBufPtr int32
|
||||
bufPtr int32
|
||||
resPtr int32
|
||||
}
|
||||
|
||||
@@ -94,7 +94,6 @@ func alGetBuffer() al.Buffer {
|
||||
if alUnqueueBuffers() {
|
||||
break
|
||||
}
|
||||
|
||||
time.Sleep(time.Millisecond)
|
||||
}
|
||||
}
|
||||
@@ -103,12 +102,9 @@ func alGetBuffer() al.Buffer {
|
||||
return audio.buffers[audio.resPtr]
|
||||
}
|
||||
|
||||
func fillInternalBuf(buf []byte, size int32) int32 {
|
||||
readSize := min(bufSize-audio.tmpBufPtr, size)
|
||||
if readSize > int32(len(buf)) {
|
||||
return size
|
||||
}
|
||||
copy(audio.tmpBuf[audio.tmpBufPtr:], buf[audio.bufPtr:audio.bufPtr+readSize])
|
||||
func fillInternalBuf(buf []byte) int32 {
|
||||
readSize := min(bufSize-audio.tmpBufPtr, int32(len(buf)))
|
||||
copy(audio.tmpBuf[audio.tmpBufPtr:], buf[:readSize])
|
||||
audio.tmpBufPtr += readSize
|
||||
return readSize
|
||||
}
|
||||
@@ -122,10 +118,9 @@ func write(buf []byte, size int32) int32 {
|
||||
|
||||
for size > 0 {
|
||||
|
||||
rc := fillInternalBuf(buf, size)
|
||||
rc := fillInternalBuf(buf[written:])
|
||||
|
||||
written += rc
|
||||
audio.bufPtr += rc
|
||||
size -= rc
|
||||
|
||||
if audio.tmpBufPtr != bufSize {
|
||||
@@ -143,16 +138,17 @@ func write(buf []byte, size int32) int32 {
|
||||
}
|
||||
}
|
||||
|
||||
audio.bufPtr = 0
|
||||
|
||||
return written
|
||||
}
|
||||
|
||||
// Sample renders a single audio frame.
|
||||
// It is passed as a callback to the libretro implementation.
|
||||
func Sample(left int16, right int16) {
|
||||
buf := []byte{byte(left), byte(right)}
|
||||
write(buf, 4)
|
||||
// simulate the kind of raw byte array that would be provided from C via SampleBatch.
|
||||
// (effectively typecasting int16 array to byte array)
|
||||
buf := []int16{left, right}
|
||||
pi := (*[4]byte)(unsafe.Pointer(&buf[0]))
|
||||
write((*pi)[:], 4)
|
||||
}
|
||||
|
||||
// SampleBatch renders multiple audio frames in one go
|
||||
|
||||
+3
-2
@@ -15,7 +15,8 @@ func Test_alUnqueueBuffers(t *testing.T) {
|
||||
|
||||
func Test_Sample(t *testing.T) {
|
||||
t.Run("Doesn't crash when called", func(t *testing.T) {
|
||||
Sample(30000, 30000)
|
||||
Sample(-30000, -30000)
|
||||
Sample( 30000, 30000)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -49,7 +50,7 @@ func Test_fillInternalBuf(t *testing.T) {
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if got := fillInternalBuf(tt.args.buf, tt.args.size); got != tt.want {
|
||||
if got := fillInternalBuf(tt.args.buf[:tt.args.size]); got != tt.want {
|
||||
t.Errorf("fillInternalBuf() = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
|
||||
Reference in new issue
Block a user