Hi, I have been playing around with "lennart"-branch, or should I say 0.9.7, for a while now. I am implementing a prototype audio system on top of pulseaudio. For most part the new version has worked pretty well for me. However there are couple of problems I have found so far. To ensure minimal latencies I have configure alsa sink and source to use only two 10ms fragments. While running the daemon with real-time priority the sound plays without a glitch (without RT-priority mouse movement etc. activity causes buffer under runs). However every now and then alsa-sink or -source unloads just out of the blue. This seems to happen more often when fragment size is smaller, but not often enough to really bother me at the moment. I just wonder if this is a known problem. I am currently working on an effect module that should links against an algorithm library. The module looks pretty much the same as ladspa-module, but the used algorithm requires the samples in 10 ms chunks. For this I have written peek and drop call backs like this: <code> static int sink_input_peek_cb(pa_sink_input *i, size_t length, pa_memchunk *chunk) { struct userdata *u; pa_sink_input_assert_ref(i); u = i->userdata; pa_assert(chunk && u); if (u->sink_memchunk.memblock == NULL) { pa_memchunk lchunk; while (pa_memblockq_get_length(u->sink_memblockq) < u->window_size) { pa_sink_render(u->sink, u->window_size - pa_memblockq_get_length(u->sink_memblockq), &lchunk); if (pa_memblockq_push(u->sink_memblockq, &lchunk) < 0) { pa_log("Failed to push chunk into memblockq."); pa_memblock_unref(lchunk.memblock); return -1; } pa_memblock_unref(lchunk.memblock); lchunk.memblock = NULL; } if (!memblockq_to_chunk(u->core, u->sink_memblockq, &lchunk, u->window_size)) { pa_log("memblock_to_chunk failed unexpectedly"); return -1; } // The algorithm should be run here... u->sink_memchunk = lchunk; } *chunk = u->sink_memchunk; return 0; } static void sink_input_drop_cb(pa_sink_input *i, size_t length) { struct userdata *u; pa_sink_input_assert_ref(i); pa_assert_se(u = i->userdata); pa_assert(u->sink_memchunk.length >= length); u->sink_memchunk.length -= length; u->sink_memchunk.index += length; if (u->sink_memchunk.length == 0) { pa_memblock_unref(u->sink_memchunk.memblock); u->sink_memchunk.memblock = NULL; } } <\code> The memblockq_to_chunk() just copies and drops specified amount of data to chunk. The function allocates a new memblock and does the actual copying only if necessary. I have tested the function quite thoroughly and there should be no problem there (maybe the function could be added to memblockq API). When the module with the code above is loaded the daemon crashes almost immediately in memblock refcount assertion failure under pa_sink_input_peek. I have been debugging this for a few days now but I can not find an error in my code. Is forcibly rendering 10ms from sink evil? Or have I just overlooked something? Here is the failure: pulseaudio: pulsecore/memblock.c:439: pa_memblock_get_length: Assertion `pa_atomic_load(&(b)->_ref) > 0' failed. and here is a back trace from the crash: #6 0xb7c6c43b in __assert_fail () from /lib/tls/i686/cmov/libc.so.6 #7 0xb7f00112 in pa_memblock_get_length (b=0xb7a0f008) at pulsecore/memblock.c:439 #8 0xb7f123ba in pa_sink_render (s=0x8078c38, length=960, result=0xb7925e10) at pulsecore/sink.c:443 #9 0xb68a8749 in aep_sink_input_peek_cb (i=0x8078600, length=960, chunk=0xb7925e58) at module-AEP.c:357 #10 0xb7f167a3 in pa_sink_input_peek (i=0x8078600, length=1920, chunk=0xb7925ef8, volume=0xb7925f04) at pulsecore/sink-input.c:466 #11 0xb7f11e97 in fill_mix_info (s=0x8060160, length=1920, info=0xb7925ef8, maxinfo=32) at pulsecore/sink.c:339 #12 0xb7f12870 in pa_sink_render_into (s=0x8060160, target=0xb79272c0) at pulsecore/sink.c:504 #13 0xb7f12c76 in pa_sink_render_into_full (s=0x8060160, target=0xb792730c) at pulsecore/sink.c:578 #14 0xb79fe64c in mmap_write (u=0x8056b38) at modules/module-alsa-sink.c:180 #15 0xb79fff49 in thread_func (userdata=0x8056b38) at modules/module-alsa-sink.c:620 One other minor issues, if I have correctly understood what this piece of code is trying to do, alsa-util.c. I have not seen any run-time problems related to this, the code just does not make too much sense. Anyway I think this patch should fix it: <patch> =================================================================== --- src/modules/alsa-util.c (revision 6372) +++ src/modules/alsa-util.c (working copy) @@ -301,11 +301,10 @@ if ((ret = snd_pcm_hw_params_set_access(pcm_handle, hwparams, SND_PCM_ACCESS_MMAP_INTERLEAVED)) < 0) if ((ret = snd_pcm_hw_params_set_access(pcm_handle, hwparams, SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) goto finish; - + else + *use_mmap = 0; } else if ((ret = snd_pcm_hw_params_set_access(pcm_handle, hwparams, SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) goto finish; - else if (*use_mmap) - *use_mmap = 0; if ((ret = set_format(pcm_handle, hwparams, &f)) < 0) goto finish; <\patch> Best regards, Jyri // Jyri Sarha - okuAtikiDotfi