diff --git a/Kha/Kinc/Backends/System/Linux/Sources/kinc/backend/sound.c.h b/Kha/Kinc/Backends/System/Linux/Sources/kinc/backend/sound.c.h index 6a26044..ab9bc50 100644 --- a/Kha/Kinc/Backends/System/Linux/Sources/kinc/backend/sound.c.h +++ b/Kha/Kinc/Backends/System/Linux/Sources/kinc/backend/sound.c.h @@ -34,22 +34,46 @@ void copySample(void *buffer) { } int playback_callback(snd_pcm_sframes_t nframes) { - int err = 0; - if (kinc_a2_internal_callback(&a2_buffer, nframes)) { - int ni = 0; - while (ni < nframes) { - int i = 0; - for (; ni < nframes && i < 4096 * 2; ++i, ++ni) { - copySample(&buf[i * 2]); - } - int err2; - if ((err2 = snd_pcm_writei(playback_handle, buf, i)) < 0) { - fprintf(stderr, "write failed (%s)\n", snd_strerror(err2)); - } - err += err2; - } - } - return err; + int err = 0; + if (kinc_a2_internal_callback(&a2_buffer, nframes)) { + int ni = 0; + while (ni < nframes) { + int i = 0; + for (; ni < nframes && i < 4096; ++i, ++ni) { + copySample(&buf[i * 2]); + } + int err2 = snd_pcm_writei(playback_handle, buf, i); + if (err2 < 0) { + fprintf(stderr, "ALSA write failed in playback_callback: %s\n", snd_strerror(err2)); + return err2; + } + if (err2 < i) { + fprintf(stderr, "ALSA short write in playback_callback: wrote %d of %d frames\n", err2, i); + } + } + err = nframes; + } + else { + // Write silence data to prevent recovery + if (nframes > 4096) { + fprintf(stderr, "Warning: ALSA requested %ld frames for silence, exceeding local buffer size %d. Clamping.\n", nframes, 4096); + nframes = 4096; + } + memset(buf, 0, nframes * 4); + + int err2 = snd_pcm_writei(playback_handle, buf, nframes); + + if (err2 < 0) { + fprintf(stderr, "ALSA silence write failed in playback_callback: %s\n", snd_strerror(err2)); + err = err2; + } else { + if (err2 < nframes) { + fprintf(stderr, "ALSA short silence write in playback_callback: wrote %d of %d frames\n", err2, (int)nframes); + } + err = err2; + } + } + return err; } bool tryToRecover(snd_pcm_t *handle, int errorCode) {