On Thu, 10 Dec 2015, Will J Godfrey wrote:

On Thu, 10 Dec 2015 06:51:48 -0800 (PST)
Len Ovens <l...@ovenwerks.net> wrote:

You can check if there are 4 bytes available, if not don't read (yet).
Normally (at least for anything I have done) the reason I use the ring
buffer is to divorce the data processing from any real time requirement.
So I am reading the ring buffer in a loop, I can check how many bytes are
available. jack_ringbuffer_read_space(buffer) can be used I think.

I'm doing this. My main concern was whether the pointers would be updated in
byte steps or block size steps, and what implications that might have.

I'm quite prepared to believe I might be over-thinking the problem. This has
been known before :)

On the input end of the ringbuffer we put a set number of bytes into the buffer. This is done during the time our app has it's time to do whatever it is going to do in that jack period. But this callback might be running on another core than the rest of the app and so it is possible that the write event may be only partly done when our app looks at the buffer. That is why it is not known that if there is data there it has all been written. However, the call back is a RT thread and so it will finish the write "real soon". So there should be an event's worth of bytes by the time you look at it a second time. A time out does not really make sense that I can see. I don't think the ring buffer is un reliable. But, don't read till all the bytes are there.

The answer to your question of how the pointer is updated, does't matter really. What matters is if everything that goes in gets to the output. So if one checks that the right number of bytes are there before reading, it doesn't matter. The safe way to do things might be to update the pointer after each byte written. The least code way/cpu way may be to write n bytes then update. But Paul's answer seems to indicate the first is true... but, the buffer can be written to manually too, where the input manually inserts a byte at a time and updates the pointers after each byte. The API allows that from what I can tell. In fact, if the calling SW wanted to, it could write 10 bytes and only update the pointer 3, write another 3 and then update the pointer 10 (I can't see any sane SW doing so).

But you have control of both the input and the output, so you can make sure the event based input API is used rather than a manual method. The jack ringbuffer does not force you to code in a sane manner, but you can still choose to code in a sane manner if you want to.

In general, jack does things in chunks. It starts doing things at the beginning of a period going through all it's call backs and when finished it does nothing till the beginning of the next period. On a single core system, it is this time when your application will be looking at the non-RT end of the ringbuffer. So in general, so long as the RT end can always access the right number of bytes when it needs to, everything will work.... nothing will be lost.

Someone will correct all my mistakes I am sure.

My own code, after having thought this through in answer to your question, does not do enough checks at all :) I need to go back and fix some things. Oddly enough, it does work :) My particular code is all MIDI events and so those events are various sizes, not all 4 bytes. I started off with more than one ringbuffer for each expected event size. This meant I had to do my sorting in RT, so I have now gone to one buffer and parse it on the output. With one, two or three byte events, I can easily look for the right number... I pull one byte, parse it and know I have it all or expect one or two more. However, I do use sysex events as well so I have to look for an eox.

Len goes back to redo a big chunk of his code. I must be missing at least some events.

--
Len Ovens
www.ovenwerks.net

_______________________________________________
Linux-audio-dev mailing list
Linux-audio-dev@lists.linuxaudio.org
http://lists.linuxaudio.org/listinfo/linux-audio-dev

Reply via email to