home ~ projects ~ socials

Get The Decibel Level From A Mic In Rust

This is what I'm using for ASCII_BEAR to move the mouth when I speak into the mic with enough volume:

#!/usr/bin/env cargo +nightly -Zscript

//! ```cargo
//! [dependencies]
//! anyhow = "1.0.75"
//! clap = "4.4.7"
//! cpal = "0.15.2"
//! ```

use cpal::traits::{DeviceTrait, HostTrait, StreamTrait};

fn main() -> Result<(), anyhow::Error> {
    let host = cpal::default_host();
    let device = host.default_input_device().unwrap();
    let config: cpal::StreamConfig = device.default_input_config().unwrap().into();
    let input_sender = move |data: &[f32], _cb: &cpal::InputCallbackInfo| {
        let x: f32 = data[0];
        if x > 0.006 {
            println!("{}", x);
        }
    };
    let input_stream = device
        .build_input_stream(&config, input_sender, err_fn, None)
        .unwrap();
    let _ = input_stream.play();
    std::thread::sleep(std::time::Duration::from_secs(32536000));
    Ok(())
}

fn err_fn(err: cpal::StreamError) {
    eprintln!("an error occurred on stream: {}", err);
}

Notes

  • This outputs the dB level to the terminal
  • The samples happen non-stop. I put a check in place so the values only output if they are greater than 0.006
  • I've seen negative numbers coming from the float values as well. I'm not sure what's happening with those (I've only got a single channel in my setup so I don't think it's a stereo thing)
  • There's a very slight delay on my setup from the time I speak until the output shows up. I got through a DAC which might have something to do with it, or that might just be how it works. I'm not super worried about it for now
-- end of line --

References

  • My virtual avatar for streaming on Twitch. I set it up when I moved computers and didn't have a wire to connect the camera to the new machine and have just kina been running with it