# HG changeset patch # User sam # Date 1739714174 -25200 # Node ID fbabeba33807580cdf767c2ff26cbe74333c0a79 # Parent 3502e1efaeb4768c88ee12af562e6b358fb06c47 fix: wrong handling of pcm api on linux diff -r 3502e1efaeb4 -r fbabeba33807 semicongine/audio.nim --- a/semicongine/audio.nim Sat Feb 15 12:11:41 2025 +0700 +++ b/semicongine/audio.nim Sun Feb 16 20:56:14 2025 +0700 @@ -15,8 +15,10 @@ const NBUFFERS = 32 # it seems that some alsa hardware has a problem with smaller buffers than 512 +# TODO: actually, above statment is not true as we did not handle buffer capacity correctly +# initially, needs testing when defined(linux): - const BUFFERSAMPLECOUNT = 512 + const BUFFERSAMPLECOUNT = 256 else: const BUFFERSAMPLECOUNT = 256 diff -r 3502e1efaeb4 -r fbabeba33807 semicongine/platform/linux/audio.nim --- a/semicongine/platform/linux/audio.nim Sat Feb 15 12:11:41 2025 +0700 +++ b/semicongine/platform/linux/audio.nim Sun Feb 16 20:56:14 2025 +0700 @@ -39,6 +39,7 @@ ): snd_pcm_sframes_t {.alsafunc.} 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.} template checkAlsaResult(call: untyped) = let value = call @@ -75,13 +76,19 @@ result.buffers = buffers proc WriteSoundData*(soundDevice: NativeSoundDevice, buffer: int) = - var ret = snd_pcm_writei( - soundDevice.handle, - addr soundDevice.buffers[buffer][][0], - snd_pcm_uframes_t(soundDevice.buffers[buffer][].len), - ) - if ret < 0: - checkAlsaResult snd_pcm_recover(soundDevice.handle, cint(ret), 0) + var i = 0 + let buflen = soundDevice.buffers[buffer][].len + while i < buflen: + var availFrames = snd_pcm_avail(soundDevice.handle) + let nFrames = min(availFrames, buflen - i) + var 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) + i += nFrames proc CloseSoundDevice*(soundDevice: NativeSoundDevice) = discard snd_pcm_close(soundDevice.handle)