Low-latency sound¶
This document explains how we achieve sound delivery with low-latency.
Triggering sounds¶
The state-machine running in the Arduino Due has the ability to send one output byte through a serial port (native
port on the board) when reaching a state. See enter_state()
function in statemachine.ino
.
This serial output serves as a trigger for the computer to generate a sound.
On the computer end, the sound module (object soundclient.SoundPlayer
) is always waiting for serial inputs. Whenever a serial input arrives, the system will play the sound with index specified by the byte sent.
Note that currently only one sound can be triggered per state.
Sound generation¶
We use the Python module “pyo” to generate sounds. In addition to having many functions for sound generation, this module works with Jack for low-latency delivery of sounds (see below). However, it is not clear if this module is still maintained, and documentation is limited.
Sound card¶
To be able to generate sound above 20kHz, we use a Xonar Essence STX sound-card from ASUS.
Achieving low-latency¶
In our experience, triggers through the serial port are very fast (<1ms). The delay bewteen the Arduino triggering a sound and the sound being produced by the sound-card is due mostly to the computer’s sound system.
To achieve lower latencies, we use a combination of:
- Low-latency Linux kernel: package
linux-lowlatency
in Ubuntu. - Jack: a low-latency sound server. Package
jackd
in Ubuntu.
We first run the Jack server (and keep it open), with the command:
pasuspender -- /usr/bin/jackd -R -dalsa -dhw:STX -r192000 -p512 -n2
In a paradigm, using the sound-client object (soundclient.SoundClient
) will start pyo
and generate all sounds through Jack.