I'm trying to design an efficient, realtime audio ...
# coroutines
t
I'm trying to design an efficient, realtime audio processing pipeline using coroutines. Each pipeline stage would be contained in a coroutine, and bytes transmitted using channels. How to send bytes between coroutines ? Both ByteArray and ByteBuffer are not cheap to create and mutable, so those are not safe to share between coroutines.
s
Ktor has an IO package that you can use as a standalone library. That seems to be where the Kotlin team are directing their efforts in this area. The library has channels designed for sending bytes between coroutines. Under the hood it will still allocate byte arrays and byte buffers though!
Or, if you're worried about byte buffers being mutable, you can use
asReadOnlyBuffer()
A byte buffer (at least a heap buffer) is just a wrapper around a byte array, and a byte array really is the simplest representation we have for a sequence of byte data in memory, so you won't find a less expensive general solution
Though in some specific scenarios you might be able to avoid byte array allocations using direct buffers
t
Basically, should I try to reuse these buffers, or is it better to allocate new buffers before sending them to a channel ?
s
Byte buffers can be used in many ways, so it's hard to give a general answer. If you're in control of the byte buffer, you can reuse it at will and set your own rules about who can modify it and when. But if it's a buffer that is passed to you by another library, that library might have its own system where it reuses the same buffer after modifying its contents and parameters. In that case you would need to read the library documentation to determine how and when you can safely interact with the buffer.
If you use the Ktor byte channel I believe it will always copy the data on send instead of reusing the buffer you pass in. (It's a bit more complicated on the receiving end because then the buffer you're receiving may be owned by the channel)
e
okio has its own Buffer abstraction, which manages "segments" to be passed between producers and consumers and reused
in practice their segments are backed by byte arrays
in most applications it is fine to allocate when needed, as long as you are able to re-use instead of re-allocated in the steady state
s
I haven't tried okio, I might give it ago in my own projects! Thanks for the suggestion @ephemient
e
I'm not sure if okio.Buffer is appropriate for realtime; I think it may to consolidate into full segments, preferring throughput over latency. but if it doesn't work out you can definitely use similar ideas
188 Views