From 8b5d55025f9435b98ff7525749a9bceaec9b499c Mon Sep 17 00:00:00 2001 From: Kai Vogelgesang Date: Sun, 26 Sep 2021 00:57:38 +0200 Subject: [PATCH] Add pulse default sink name retrieval --- libpulse_aubio/src/main.rs | 92 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 89 insertions(+), 3 deletions(-) diff --git a/libpulse_aubio/src/main.rs b/libpulse_aubio/src/main.rs index 58057cb..6f4c438 100644 --- a/libpulse_aubio/src/main.rs +++ b/libpulse_aubio/src/main.rs @@ -1,16 +1,88 @@ -use anyhow::Result; +use anyhow::{anyhow, Result}; use psimple::Simple; +use pulse::context::{Context, FlagSet as ContextFlagSet}; +use pulse::mainloop::standard::{IterateResult, Mainloop}; use pulse::sample::{Format, Spec}; use pulse::stream::Direction; +use std::cell::RefCell; +use std::ops::Deref; +use std::rc::Rc; const BUF_SIZE: usize = 1024; const HOP_SIZE: usize = 512; const SAMPLE_RATE: u32 = 44100; +fn get_pulse_default_sink() -> Result { + let mainloop = Rc::new(RefCell::new( + Mainloop::new().ok_or(anyhow!("Failed to create mainloop"))?, + )); + let ctx = Rc::new(RefCell::new( + Context::new(mainloop.borrow().deref(), "gib_default_sink") + .ok_or(anyhow!("Failed to create context"))?, + )); + + ctx.borrow_mut() + .connect(None, ContextFlagSet::NOFLAGS, None)?; + + // Wait for context to be ready + loop { + match mainloop.borrow_mut().iterate(false) { + IterateResult::Quit(_) | IterateResult::Err(_) => { + return Err(anyhow!("Iterate state was not success")); + } + IterateResult::Success(_) => {} + } + + match ctx.borrow().get_state() { + pulse::context::State::Ready => { + break; + } + pulse::context::State::Failed | pulse::context::State::Terminated => { + return Err(anyhow!("Context was in failed/terminated state")); + } + _ => {} + } + } + + let result = Rc::new(RefCell::new(None)); + let cb_result_ref = result.clone(); + + ctx.borrow().introspect().get_server_info(move |info| { + *cb_result_ref.borrow_mut() = if let Some(sink_name) = info.default_sink_name.clone() { + Some(Ok(sink_name.to_string())) + } else { + Some(Err(())) + } + }); + + while result.borrow().is_none() { + match mainloop.borrow_mut().iterate(false) { + IterateResult::Quit(_) | IterateResult::Err(_) => { + return Err(anyhow!("Iterate state was not success")); + } + IterateResult::Success(_) => {} + } + } + + let result = result.borrow().clone(); + + result + .unwrap() + .map_err(|_| anyhow!("Default sink name was empty")) +} + fn main() -> Result<()> { + println!("AYAYA"); + let mut default_sink_name = get_pulse_default_sink()?; + default_sink_name.push_str(".monitor"); + println!( + "gotted pulse default sink (hopefully): {}", + default_sink_name + ); + let spec = Spec { format: Format::F32le, - channels: 2, + channels: 1, rate: 44100, }; assert!(spec.is_valid()); @@ -19,7 +91,7 @@ fn main() -> Result<()> { None, "AAAAAAAA", Direction::Record, - None, + Some(&default_sink_name), "BBBBBBBB", &spec, None, @@ -27,6 +99,8 @@ fn main() -> Result<()> { )?; let mut tempo = aubio::Tempo::new(aubio::OnsetMode::SpecFlux, BUF_SIZE, HOP_SIZE, SAMPLE_RATE)?; + + let mut onset = aubio::Onset::new(aubio::OnsetMode::Energy, BUF_SIZE, HOP_SIZE, SAMPLE_RATE)?; let mut data = [0u8; 4 * BUF_SIZE]; let mut float_data = [0f32; BUF_SIZE]; @@ -52,5 +126,17 @@ fn main() -> Result<()> { tempo.get_confidence() ); } + + /* + + let r = onset.do_result(&float_data)?; + + if r > 0f32 { + println!("onset i guess: {}", onset.get_last()); + } else { + println!("nope") + } + + */ } }