Re: [Jack-Devel] more ringbuffer challenges

PrevNext  Index
DateMon, 02 May 2011 07:16:00 -0400
From Paul Davis <[hidden] at linuxaudiosystems dot com>
ToTimothy Godfrey <[hidden] at gmail dot com>
Cc[hidden] at lists dot jackaudio dot org
In-Reply-ToTimothy Godfrey [Jack-Devel] more ringbuffer challenges
On Mon, May 2, 2011 at 1:44 AM, Timothy Godfrey
<[hidden]> wrote:

> A bit of background is probably in order to describe my problem. I am
> working on transmitting audio streams reliably and with minimum
> latency over a wireless network. I have heard of and read a bit about
> netjack1 and netjack2 (and I have used them a little bit). I haven't
> investigated thoroughly the possibility of modifying them or
> contributing to them so that they work well over wireless networks. So
> this is my signal flow from one end to another;

not sure why you would not investigate them for this purpose, but ok .....


> for (int i = 0; i < 2; i++) {
>        input[i] = (jack_default_audio_sample_t*)jack_port_get_buffer(input_port[i],
> nframes);
>        jack_ringbuffer_write(rb[i], (char*)input[i], nframes * BPS);
> }

if jack_ringbuffer_write_space() is less than nframes*BPS you've just
screwed up your audio stream by throwing away some data. this means
that if your reader thread ever falls behind the writer (the process
thread in this case), you will lose sync with the stream.

i made the mistake recently in a side project of forgetting to check
the status of two ringbuffers that i was copying between and ended up
totally screwing up the stream. you cannot assume that the ringbuffer
has space to read or write, and you must have some kind of plan in the
event that it does not.

in addition, for reasons that i believe i've gone over before but will
be happy to do so again, the amount of space you can write into a
jack_ringbuffer_t is always 1 byte less than the size of the buffer.
thus if you call jack_ringbuffer_write() indiscriminately to simply
fill up however much space is there, its not too hard to end up
writing only part of a sample and not all of it.

you need to make sure that you always use the modulus of the available
space with sizeof(jack_default_audio_sample_t), which in some cases
will lead you to *not* write as much data as you would otherwise (e.g.
write_space == 19 will result in you writing just 4 samples, with 3
bytes left unwritten. if you had passed in 5 samples and just called
jack_ringbuffer_write(), you would have written 35 bytes and left the
last byte of the last sample unwritten (and if the code looks like the
code above, you would not have checked for this error.)).

> As an aside, would this situation be helped by creating a
> parameterized ringbuffer, something like
> jack_ringbuffer_t<jack_default_audio_sample_t>?

ardour's own ringbuffers use this, but that is because (as peter
noted) JACK is a C API, not a C++ API.
PrevNext  Index

1304334977.19192_0.ltw:2,a <BANLkTin2DcaCECSd81Nz3aAEddFivTZNmA at mail dot gmail dot com>