audio input and fft
All checks were successful
Build legacy Nix package on Ubuntu / build (push) Successful in 4m17s
All checks were successful
Build legacy Nix package on Ubuntu / build (push) Successful in 4m17s
This commit is contained in:
parent
33907234fd
commit
86dfbd21f4
1247
Cargo.lock
generated
1247
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@ -8,3 +8,9 @@ pedantic = "warn"
|
||||
nursery = "warn"
|
||||
|
||||
[dependencies]
|
||||
env_logger = "0.11"
|
||||
log = "0.4"
|
||||
color-eyre = "0.6"
|
||||
|
||||
cpal = { version = "0.15", features = ["jack"] }
|
||||
rustfft = "6.2"
|
||||
|
@ -1,7 +1,10 @@
|
||||
(import (
|
||||
(import
|
||||
(
|
||||
fetchTarball {
|
||||
url = "https://github.com/edolstra/flake-compat/archive/99f1c2157fba4bfe6211a321fd0ee43199025dbf.tar.gz";
|
||||
sha256 = "0x2jn3vrawwv9xp15674wjz9pixwjyj3j771izayl962zziivbx2"; }
|
||||
) {
|
||||
sha256 = "0x2jn3vrawwv9xp15674wjz9pixwjyj3j771izayl962zziivbx2";
|
||||
}
|
||||
)
|
||||
{
|
||||
src = ./.;
|
||||
}).defaultNix
|
||||
|
@ -12,9 +12,13 @@
|
||||
naersk-lib = pkgs.callPackage naersk { };
|
||||
in
|
||||
{
|
||||
defaultPackage = naersk-lib.buildPackage ./.;
|
||||
defaultPackage = naersk-lib.buildPackage {
|
||||
src = ./.;
|
||||
buildInputs = with pkgs; [ alsa-lib libjack2 ];
|
||||
nativeBuildInputs = with pkgs; [ pkg-config ];
|
||||
};
|
||||
devShell = with pkgs; mkShell {
|
||||
buildInputs = [ cargo rustc rustfmt pre-commit rustPackages.clippy ];
|
||||
buildInputs = [ cargo rustc rustfmt pre-commit rustPackages.clippy alsa-lib pipewire ];
|
||||
RUST_SRC_PATH = rustPlatform.rustLibSrc;
|
||||
};
|
||||
}
|
||||
|
68
src/main.rs
68
src/main.rs
@ -1,3 +1,67 @@
|
||||
fn main() {
|
||||
println!("Hello, world!");
|
||||
use std::{thread::sleep, time::Duration};
|
||||
|
||||
use color_eyre::eyre::bail;
|
||||
use cpal::{
|
||||
traits::{DeviceTrait, HostTrait, StreamTrait},
|
||||
BufferSize, HostId, SupportedBufferSize,
|
||||
};
|
||||
use log::{debug, error, info, trace};
|
||||
use rustfft::{num_complex::Complex, FftPlanner};
|
||||
|
||||
fn main() -> color_eyre::Result<()> {
|
||||
env_logger::init();
|
||||
debug!("Starting");
|
||||
|
||||
let mut hosts = cpal::platform::available_hosts();
|
||||
hosts.sort_unstable_by_key(|host| match host {
|
||||
HostId::Jack => 0,
|
||||
HostId::Alsa => 1,
|
||||
});
|
||||
let host_id = hosts[0];
|
||||
info!("Selected {host_id:?} audio backend");
|
||||
let host = cpal::platform::host_from_id(host_id)?;
|
||||
|
||||
let Some(device) = host.default_input_device() else {
|
||||
error!("Unable to get default input device for {host_id:?}");
|
||||
bail!("Unable to get default input device")
|
||||
};
|
||||
debug!("Got default input device {:?}", device.name());
|
||||
|
||||
let default_config = device.default_input_config()?;
|
||||
trace!("Default config {:?}", default_config);
|
||||
let mut config = default_config.config();
|
||||
let buffer_size =
|
||||
if let SupportedBufferSize::Range { min, max: _ } = default_config.buffer_size() {
|
||||
*min
|
||||
} else {
|
||||
1024
|
||||
};
|
||||
config.buffer_size = BufferSize::Fixed(buffer_size);
|
||||
config.channels = 1;
|
||||
debug!("Using config {config:?}");
|
||||
|
||||
let mut planner = FftPlanner::<f32>::new();
|
||||
let fft = planner.plan_fft_forward(buffer_size as usize);
|
||||
let mut fft_data = vec![Complex::new(0.0, 0.0); buffer_size as usize];
|
||||
let mut fft_scratch = vec![Complex::new(0.0, 0.0); buffer_size as usize];
|
||||
|
||||
let stream = device.build_input_stream(
|
||||
&config,
|
||||
move |data: &[f32], _| {
|
||||
for i in 0..data.len() {
|
||||
fft_data[i] = Complex::new(data[i], 0.0);
|
||||
}
|
||||
fft.process_with_scratch(&mut fft_data[..], &mut fft_scratch[..]);
|
||||
},
|
||||
|err| {
|
||||
error!("input stream error: {err}");
|
||||
},
|
||||
None,
|
||||
)?;
|
||||
|
||||
stream.play()?;
|
||||
|
||||
loop {
|
||||
sleep(Duration::from_secs(1));
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user