How to record audio with LSL in Python?

Hi there,

I’m trying to record audio data with a Python script using pylsl inside a Python Bridge, itself connected to a Recorder component in RTMaps, but I think I have a sampling problem: as long as RTMaps runs, I get thousands of FIFO overflow messages per second.
I believe the lsl stream is too fast for RTMaps? (it is by default configured to 11025Hz, I can go down to 8kHz with 16 bits sampling).
Thank you for any help.

Hi Bruno,

Interesting point.
You can definitely work with audio data in RTMaps (and with low CPU resources). The only thing is like with any high frequency signal (and any other component-based software), you shouldn’t pass audio samples one by one between components. The little time it takes to switch threads (and even switch processes when it comes to Python, with shared memory exchange etc), multiplied by the audio sampling rate will introduce an important overhead.

Instead just packetize the samples and pass them through components as groups of audio samples.

In RTMaps audio data can be handled in two forms: with type “Stream8” (packets of bytes), or type “Float32”.
As Stream8, you would just copy your audio buffer in the RTMaps data sample buffer: let’s say 2 channels and 16 bits sampling will take 4 bytes per sample time in the Stream8 packet (2 bytes per sample, and one sample per channel).
As Float32, just provide a vector of Float32 elements, with values between -1.0 and 1.0, one element per channel.

When grouping such audio samples into RTMaps data samples, you’ll need to provide information about the sampling frequency of the N audio samples in the packet (indeed, the RTMaps data sample containing the packet will only carry one Timestamp, which by convention corresponds to the timestamp of the first sample in the packet).
You also need to tell how many channels have been sampled and potentially (at least for Stream8 data) the sampling bits.
Based on this information, any downstream component can interpret the incoming packet of bytes (or vector of float32 elements), know about its layout, compute the timestamp of each audio sample in the packet etc.

In order to provide this information like Frequency, Number of channels and Sampling bits, we will use optional fields “Frequency”, “Misc1” and “Misc2” in the RTMaps data samples.
And in order to tell that these optional fields are indeed specified, we have to add the FrequencyFlag and MiscFlag to our output type definition.
Our output type is then : Float32 + FrequencyFlag + MiscFlag.

Enough talking, here is an example of a Python script that generates a sinusoidal audio signal, with 2 channels, 44100 Hz and with very low CPU resources.