On 15.02.2018 10:07, Raman Shishniou wrote: > On 02/15/2018 10:22 AM, Georg Chini wrote: >> On 14.02.2018 23:09, Raman Shishniou wrote: >>> On 02/15/2018 12:03 AM, Georg Chini wrote: >>>> The null-source currently reports the negative of the correct latency. >>>> Also the memchunk passed to pa_source_post() is not initialized with >>>> silence. >>>> >>>> This patch fixes both issues. >>>> --- >>>> src/modules/module-null-source.c | 5 +++-- >>>> 1 file changed, 3 insertions(+), 2 deletions(-) >>>> >>>> diff --git a/src/modules/module-null-source.c b/src/modules/module-null-source.c >>>> index 41f17bd9..6310bda9 100644 >>>> --- a/src/modules/module-null-source.c >>>> +++ b/src/modules/module-null-source.c >>>> @@ -100,7 +100,7 @@ static int source_process_msg(pa_msgobject *o, int code, void *data, int64_t off >>>> pa_usec_t now; >>>> now = pa_rtclock_now(); >>>> - *((int64_t*) data) = (int64_t)u->timestamp - (int64_t)now; >>>> + *((int64_t*) data) = (int64_t)now - (int64_t)u->timestamp; >>>> return 0; >>>> } >>>> @@ -142,8 +142,9 @@ static void thread_func(void *userdata) { >>>> if ((chunk.length = pa_usec_to_bytes(now - u->timestamp, &u->source->sample_spec)) > 0) { >>>> - chunk.memblock = pa_memblock_new(u->core->mempool, (size_t) -1); /* or chunk.length? */ >>>> + chunk.memblock = pa_memblock_new(u->core->mempool, chunk.length); >>>> chunk.index = 0; >>>> + pa_silence_memchunk(&chunk, &u->source->sample_spec); >>>> pa_source_post(u->source, &chunk); >>>> pa_memblock_unref(chunk.memblock); >>> I think you need to change the next line too: >>> - u->timestamp = now; >>> + u->timestamp += pa_bytes_to_usec(chunk.length, &u->source->sample_spec); >>> } >>> >>> to make silence generator more stable >>> >>> >> How would that make it more stable? It will only lower the precision of the time stamp. > Nope. It will increase the precision. Actually null-source send pa_bytes_to_usec(chunk.length) > microseconds of data each iteration which can be smaller than (now - u->timestamp). > It must increase timestamp by actually data sent. Accumulated difference will be corrected > on the next iteration by sending more data. > > For example each 10ms we need to send a 99.5 bytes of data (s8, mono, 9950Hz), > i.e. pa_usec_to_bytes() does: bytes = usecs * 0.00995 > and pa_bytes_to_usec() does: usecs = bytes / 0.00995 > > First iteration: > u->timestamp == 0 > now = pa_rtclock_now() == 10ms == 10000us > bytes = pa_usec_to_bytes(10000 - 0) = 99 > ... send 99 bytes of data ... > u->timestamp += pa_bytes_to_usec(99) == 9949 > > Second iteration: > u->timestamp == 9949 > now = pa_rtclock_now() == 20ms == 20000us > bytes = pa_usec_to_bytes(20000 - 9949) = 100 > ... send 100 bytes of data ... > u->timestamp += pa_bytes_to_used(100) = 9949 + 10050 = 19999 > > Third iteration: > u->timestamp == 19999 > now = pa_rtclock_now() == 30ms == 30000us > bytes = pa_usec_to_bytes(30000 - 19999) = 99 > ... send 99 bytes of data ... > u->timestamp += pa_bytes_to_used(99) = 19999 + 9949 = 29948 > > and so on > > Current implementation will send only 99 bytes of data each iteration. > > -- > Raman Yes, you are right. I thought the timer was set to the real time consumed by the number of samples generated and not to the specified latency. I'll correct this, though probably by changing the timer value.