guide icon indicating copy to clipboard operation
guide copied to clipboard

Add a tutorial for working with audio streams

Open mitchmindtree opened this issue 5 years ago • 1 comments

Here are some comments related to sharing data between the GUI and audio threads I recently shared with another nannou user on slack - they might be useful to add after the basics have been introduced:

It's important to keep in mind that the audio function is called from a different thread than that which the main application and GUI runs on. On most platforms, audio I/O gets a dedicated, high-priority thread in order to meet the real-time requirements. In the simple_audio.rs examples, we can think about the Model struct as the state associated with the main GUI thread, and we can think about the Audio struct as the state that is associated with the audio thread.

If we require sharing some data between the two threads, we need to be careful about the way we do so to avoid data races. Fortunately, Rust helps out here by not letting us compile a program that would allow for a potential data race. There are two main approaches to sharing data between two threads:

  1. using a Mutex around the data you want to share to ensure that only one thread is accessing it at a time and
  2. using a thread-safe queue of some sort (e.g. see std::sync::mpsc::channel) to send messages between the threads.

There is a rule of thumb when working on the audio thread that is something along the lines of "never block your audio process". This is because the audio loop happens at such a high rate that, even if we block for just a few milliseconds, we may not finish writing to or reading from the buffer in time and in turn cause significant glitching. As a result, you normally want to avoid using Mutex s if possible (option 1) and prefer to use a non-blocking queue to pass messages (option 2). Nannou provides a way of doing this out of the box via the send method on the audio stream handle. This method allows you to send a closure to the audio thread that will get called as soon as the audio thread is free to do so. This is useful for updating the state of your Audio . The simple_audio.rs example demonstrates how send can be used to update the Audio state on key presses, however we can use the same approach to synchronise some state from our Model as well.

mitchmindtree avatar Dec 12 '19 16:12 mitchmindtree

Could be useful to refer to this on the importance of not blocking the audio thread http://www.rossbencina.com/code/real-time-audio-programming-101-time-waits-for-nothing

mitchmindtree avatar Dec 12 '19 16:12 mitchmindtree