golang调用sdl2,播放pcm音频,报错signal arrived during external code execu

2022年6月21日 335点热度 0人点赞 0条评论

golang调用sdl2,播放pcm音频,报错signal arrived during external code execution。


win10 x64下测试成功,其他操作系统下不保证成功。


采用的是syscall方式,不是cgo方式。


[见地址](https://github.com/moonfdd/sdl2-go/blob/main/examples/a06-sdl-pcm/main1.go)

在go1.16.15编译后然后执行,会报如下错。换成go1.18就不报错了。


Exception 0xc0000005 0x0 0xc000442000 0x7ff96da8db50

PC=0x7ff96da8db50

signal arrived during external code execution


syscall.Syscall6(0x7ff96daa7440, 0x4, 0x20d6354a0a0, 0xc000442000, 0x1000, 0x10, 0x0, 0x0, 0x0, 0x0, ...)

D:/Program Files/Go/go1.16.15/src/runtime/syscall_windows.go:347 +0xf2

syscall.(*Proc).Call(0xc000599b40, 0xc0001207c0, 0x4, 0x4, 0x20, 0xa6ffa0, 0x20d6354a001, 0xc0001207c0)

D:/Program Files/Go/go1.16.15/src/syscall/dll_windows.go:188 +0x385

syscall.(*LazyProc).Call(0xc00007fc50, 0xc0001207c0, 0x4, 0x4, 0x3, 0x3, 0x20d6354a0a0, 0x0)

D:/Program Files/Go/go1.16.15/src/syscall/dll_windows.go:339 +0x78

github.com/moonfdd/sdl2-go/sdl.SDL_MixAudio(0x20d6354a0a0, 0xc000442000, 0x1000001000)

D:/mysetup/gopath/src/sdl2-go/sdl/SDL_audio.go:1185 +0xf1

main.fill_audio_pcm(0xc00010ff48, 0x20d6354a0a0, 0x1000, 0x0)

D:/mysetup/gopath/src/sdl2-go/examples/a06-sdl-pcm/main1.go:33 +0x125


goroutine 1 [chan receive]:

main.main()

D:/mysetup/gopath/src/sdl2-go/examples/a06-sdl-pcm/main1.go:66 +0x288

rax     0x20d6354a0a0

rbx     0xc0000086e0

rcx     0x20d6354a0a0

rdi     0xecaa4c3000

rsi     0xc0000439c0

rbp     0xc000043960

rsp     0xecabbffb50

r8      0x8010

r9      0x20d6354b0a0

r10     0x10

r11     0x4

r12     0xa7b800

r13     0x0

r14     0x0

r15     0x2030001

rip     0x7ff96da8db50

rflags  0x10206

cs      0x33

fs      0x53

gs      0x2b

golang代码如下:

package main
import ( "fmt" "github.com/moonfdd/sdl2-go/sdl" "github.com/moonfdd/sdl2-go/sdlcommon" "io/ioutil" "sync" "syscall" "unsafe")
var o sync.Once
//音频设备回调函数func fill_audio_pcm(udata sdlcommon.FVoidP, stream *sdlcommon.FUint8T, len1 sdlcommon.FInt) uintptr { info := (*Info)(unsafe.Pointer(udata)) if info.isStop { return 0 } if info.Start >= info.Len { info.isStop = true o.Do(func() { ch <- struct{}{} }) return 0 } sdl.SDL_memset(uintptr(unsafe.Pointer(stream)), 0, uint64(len1)) if len1 > int32(info.Len-info.Start) { fmt.Println("不足len", len1, info.Len-info.Start) len1 = int32(info.Len - info.Start) } sdl.SDL_MixAudio(stream, &info.Data[info.Start], uint32(len1), sdl.SDL_MIX_MAXVOLUME/8) info.Start += int(len1) return 0}
var ch = make(chan struct{}, 1)
func main() { sdlcommon.SetSDL2Path("SDL2.dll") var spec sdl.SDL_AudioSpec sdl.SDL_Init(sdl.SDL_INIT_AUDIO) spec.Freq = 44100 spec.Format = sdl.AUDIO_S16SYS // 采样点格式 spec.Channels = 2 // 2通道 spec.Silence = 0 spec.Userdata = uintptr(0) spec.Samples = 1024 // 23.2ms -> 46.4ms 每次读取的采样数量,多久产生一次回调和 samples spec.Callback = syscall.NewCallback(fill_audio_pcm) // 回调函数
fileData, err := ioutil.ReadFile("44100_16bit_2ch.pcm") if err != nil { fmt.Println("读取文件失败", err) return } info := new(Info) info.Data = fileData info.Len = len(fileData) spec.Userdata = uintptr(unsafe.Pointer(info)) if sdl.SDL_OpenAudio(&spec, nil) != 0 { fmt.Println("打开音频设备失败") return } sdl.SDL_PauseAudio(0) <-ch fmt.Println("关闭") sdl.SDL_CloseAudio() sdl.SDL_Quit()}
type Info struct { Data []byte Len int Start int isStop bool}

执行结果如下:

图片

8220golang调用sdl2,播放pcm音频,报错signal arrived during external code execu

root

这个人很懒,什么都没留下

文章评论