# Synchonous and asynchronous streaming in aRts

There are various requirements how a module can do streaming. To see the difference, here some examples:

- scale a signal by factor two
- sample frequency conversations
- decompressing encoded signal, run length encoded to make it difficult
- read midi events from /dev/midi00 and put them into a stream

The first case is the simplest. On getting 200 samples input, the module produces 200 samples output. It only produces output when it gets input.

The second case produces different output sizes on 200 samples input, depending what conversion is performed.

The third case is even worse, from the outside you can not even guess how much data 200 bytes in will generate (probably a lot more than 200 bytes, but...)

The last case is a module which becomes active by itself, and sometimes produces some data.

In aRts-0.3.4, only streams of the first type where handled, and most things worked nicely. So this is probably what you need most when writing modules that process audio. The problem with the other, more complex types of streaming is that they are hard to program, and that you don't need the features most of the time.

That is why I'll to this with two different stream types:

- ### synchronous streams:

  - modules must be able to calculate data of any length, given they have enough input
  - all streams have the same sampling rate
  - the calculateBlock function will be called when enough data is available, and the module can rely on the pointers pointing to data
  - there is no allocation and deallocation to be done

- ### asynchronous streams:

  - modules may produce data sometimes, or with varying sampling rate, or only if they have input from some filedescriptor - they are not bound to the rule "must be able to satisfy requests of any size"
  - asynchronous streams of a module may have entierly different sampling rate
  - outgoing streams: there are explicit functions to allocate packets, to send packets - and an optional polling mechanism that will tell you when you should create some more data
  - incoming streams: you get a call when you received a new packet - you have to say when you are through with processing all data of that packet, which must not happen at once (you can say that anytime later, and if everybody has processed a packet, it will be freed/reused)

When you declare streams, you use the keyword "async" to indicate you want to make an asynchronous stream. So for instance assume you want to convert an asynchronous stream of bytes into a synchronous stream of samples, your interface could look like:

    interface ByteStreamToAudio : SynthModule {
        async in byte stream indata;   // the asynchonous input sample stream

        out audio stream left,right;   // the synchronous output sample streams
    };

back to index