diff --git a/runtime/audren.c b/runtime/audren.c index 407c21f1..f5d9b490 100644 --- a/runtime/audren.c +++ b/runtime/audren.c @@ -307,6 +307,8 @@ static void request_update(AudioRenderer *r, const uint8_t *input, uint64_t in_s } } else memcpy(&v, voices + i * voice_stride, sizeof v); + // An unused slot can have a zero id. Release its own voice and leave voice zero playing. + if (!v.in_use) v.id = (uint32_t)i; update_voice(r, &v); ServerVoice *server = &r->voices[v.id]; server->use_float_biquads = (uint8_t)float_voices; diff --git a/runtime/ipc.c b/runtime/ipc.c index ba6dd934..1cc4f113 100644 --- a/runtime/ipc.c +++ b/runtime/ipc.c @@ -695,7 +695,7 @@ static void update_build(Update *u, int first) { memcpy(w, &h, sizeof h); w += sizeof h + h.behavior + h.memory_pools + h.voice_resources; for (int i = 0; i < p->voice_count; i++) { - AudrenVoiceIn v = {.id = (uint32_t)i}; + AudrenVoiceIn v = {0}; // the client leaves the id of an unused slot zero if (i == 0) { // one PCM16 voice with a 100 ms buffer: consumed after 20 frames v = (AudrenVoiceIn){.id = 0, .is_new = (uint8_t)first, .in_use = 1, .play_state = PLAY_STARTED, .sample_format = FMT_PCM16, .sample_rate = 48000, .channel_count = 1, .pitch = 1,