Struggling to capture audio using nannou_audio despite successfully opening stream

Hello all! I'm trying to get very basic audio capture working using nannou, similar to this old example.

Here is my full source:

use std::sync::Arc;
use nannou::prelude::*;
use nannou_audio as audio;
use ringbuf::{Producer, Consumer, HeapRb};

struct Model {
    consumer: Consumer<f32, Arc<HeapRb<f32>>>,

struct CaptureModel {
    producer: Producer<f32, Arc<HeapRb<f32>>>,

fn capture(model: &mut CaptureModel, buffer: &audio::Buffer) {
    for frame in buffer.frames() {

fn main() {

fn model(app: &App) -> Model {

    let audio_host = audio::Host::new();

    let samples = 1024;
    let buffer = HeapRb::<f32>::new(samples * 2);
    let (mut producer, consumer) = buffer.split();
    for _ in 0..samples {

    let capture_model = CaptureModel {
    let stream = audio_host.new_input_stream(capture_model)

    Model {

fn update(_app: &App, model: &mut Model, _update: Update) {
    let mut buffer = [0.0; 1024];
    model.consumer.pop_slice(&mut buffer);

fn view(app: &App, model: &Model, frame: Frame) {

The code compiles and runs, however, it seems that my capture function is never called and no samples are written to the ring buffer - the result is the same with all possible input devices. I also tried creating the input stream using the CPAL API directly, encountering the same issue.

I'm using stock Pop!_OS 22.04. Any ideas as to why this is happening or how to fix it?

I assume that your input stream gets immediately closed after you created your app model. Try adding the stream to your your Model type:

struct Model {
    consumer: Consumer<f32, Arc<HeapRb<f32>>>,
    stream: audio::Stream<CaptureModel>

and simply assign the stream you already correctly started via .play() to your model: Model { consumer, stream }

This should keep the stream alive.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.