Mercurial > games > semicongine
changeset 1441:b17d2b1ffc20
fix: improve alsa error handling on linux
author | sam <sam@basx.dev> |
---|---|
date | Sun, 16 Feb 2025 21:15:13 +0700 |
parents | fbabeba33807 |
children | 8d26eb12f6e8 |
files | semicongine/platform/linux/audio.nim |
diffstat | 1 files changed, 13 insertions(+), 4 deletions(-) [+] |
line wrap: on
line diff
--- a/semicongine/platform/linux/audio.nim Sun Feb 16 20:56:14 2025 +0700 +++ b/semicongine/platform/linux/audio.nim Sun Feb 16 21:15:13 2025 +0700 @@ -40,12 +40,16 @@ proc snd_pcm_recover*(pcm: snd_pcm_p, err: cint, silent: cint): cint {.alsafunc.} proc snd_pcm_avail(pcm: snd_pcm_p): snd_pcm_sframes_t {.alsafunc.} +proc snd_strerror(errnum: cint): cstring {.alsafunc.} template checkAlsaResult(call: untyped) = let value = call if value < 0: - raise - newException(Exception, "Alsa error: " & astToStr(call) & " returned " & $value) + raise newException( + Exception, + "Alsa error: " & astToStr(call) & " returned " & $value & " " & + $(snd_strerror(cint(value))), + ) # required for engine: @@ -79,15 +83,20 @@ var i = 0 let buflen = soundDevice.buffers[buffer][].len while i < buflen: - var availFrames = snd_pcm_avail(soundDevice.handle) + let availFrames = snd_pcm_avail(soundDevice.handle) + if availFrames < 0: + checkAlsaResult snd_pcm_recover(soundDevice.handle, cint(availFrames), 0) + continue + checkAlsaResult availFrames let nFrames = min(availFrames, buflen - i) - var ret = snd_pcm_writei( + let ret = snd_pcm_writei( soundDevice.handle, addr soundDevice.buffers[buffer][][i], snd_pcm_uframes_t(nFrames), ) if ret < 0: checkAlsaResult snd_pcm_recover(soundDevice.handle, cint(ret), 0) + continue i += nFrames proc CloseSoundDevice*(soundDevice: NativeSoundDevice) =