Csound Csound-dev Csound-tekno Search About

[Csnd] OT: canonical way of doing audio IO with portaudio in big systems

Date2012-05-12 19:01
FromAnton Kholomiov
Subject[Csnd] OT: canonical way of doing audio IO with portaudio in big systems
It's not a csound question, but I know that there are
many audio dsp developers on this forum, so here I ask
for some help with portaudio.

There are unit generators. They process buffers
and I can link them in graph. I can invoke tick
function that executes all ugens from sources to
sinks. The thing I can not understand: how can I
put portaudio in this picture. Portaudio fetches
audio samples in callback function, it is called by
some external process.

I can imagine two ways of doing things:
1) call tick-function in callback
(but if there are many portaudio-sinks)
2) portaudio sink-ugen is writing to buffer
and callback function reads the buffer.

But how can I do it properly?
I have seen only toy portaudio examples (2-4 ugens in graph),
but how can one use portaudio in
big systems? or maybe you can tell me how csound is
doing these things. Or maybe you can point out
some resources that discuss this topic
(possible caveats).


Anton




Date2012-05-12 20:51
FromMichael Gogins
SubjectRe: [Csnd] OT: canonical way of doing audio IO with portaudio in big systems
Conceptually, a signal flow graph consists of nodes that process
signals, connected by directed edges that transfer signals from node
to node. In the general case, these edges are not necessarily signal
buffers, they are first-in, first-out queues of "tokens" which might
be signals, buffers of signals, or whatever. In Csound, there is
always one audio signal buffer at each end of each audio signal edge,
and there is always one control signal sample at each end of each
control signal edge. So, queues as such are not needed internally to
Csound. Each "queue" is always just one buffer of the right size.

So, how does this work with PortAudio? Csound uses PortAudio's
callback mode. Csound is processing its graph in its thread, and the
PortAudio callback is firing in its thread. The two threads are
synchronized with two locks. It is a "tick-tock" system. Tick - Csound
produces the PortAudio buffer, unlocks the PortAudio lock, and waits
on the Csound lock. Tock - the PortAudio callback consumes the
PortAudio buffer, unlocks the Csound lock, and waits on the PortAudio
lock. Tick, tock, tick, tock, tick, tock... until Csound is done and
closes the PortAudio stream.

There is no reason this should not work with any number of PortAudio
nodes in the graph, but only if only one of them ever says Tock, and
only if all of the PortAudio nodes stay in sync with each other.

Hope this helps,
Mike

On Sat, May 12, 2012 at 2:01 PM, Anton Kholomiov
 wrote:
> It's not a csound question, but I know that there are
> many audio dsp developers on this forum, so here I ask
> for some help with portaudio.
>
> There are unit generators. They process buffers
> and I can link them in graph. I can invoke tick
> function that executes all ugens from sources to
> sinks. The thing I can not understand: how can I
> put portaudio in this picture. Portaudio fetches
> audio samples in callback function, it is called by
> some external process.
>
> I can imagine two ways of doing things:
> 1) call tick-function in callback
> (but if there are many portaudio-sinks)
> 2) portaudio sink-ugen is writing to buffer
> and callback function reads the buffer.
>
> But how can I do it properly?
> I have seen only toy portaudio examples (2-4 ugens in graph),
> but how can one use portaudio in
> big systems? or maybe you can tell me how csound is
> doing these things. Or maybe you can point out
> some resources that discuss this topic
> (possible caveats).
>
>
> Anton
>
>
>



-- 
Michael Gogins
Irreducible Productions
http://www.michael-gogins.com
Michael dot Gogins at gmail dot com