Skip to content

Instantly share code, notes, and snippets.

@yury
Forked from MBoui/main.rs
Last active March 21, 2025 08:22
Show Gist options
  • Save yury/d38f68470c82f3b8244f6b872481b5bf to your computer and use it in GitHub Desktop.
Save yury/d38f68470c82f3b8244f6b872481b5bf to your computer and use it in GitHub Desktop.
Cidre experiment
use cidre::{arc, av, ns};
use cidre::{
at::{
self, au,
audio::component::{InitializedState, UninitializedState},
},
core_audio, os,
};
struct Ctx {
file: arc::R<av::AudioFile>,
format: arc::R<av::AudioFormat>,
output: Option<au::Output<InitializedState>>,
data: Vec<f32>,
}
impl Ctx {
fn start(&mut self, mut output: au::Output<UninitializedState>) -> os::Result<()> {
output.set_io_enabled(au::Scope::INPUT, 1, true)?;
output.set_io_enabled(au::Scope::OUTPUT, 0, false)?;
output.set_should_allocate_input_buf(false)?;
output.set_should_allocate_output_buf(false)?;
output.set_input_cb(Ctx::input_cb, self as *mut Self)?;
let output = output.allocate_resources().unwrap();
self.data = vec![0f32; output.unit().max_frames_per_slice()? as usize];
self.output = Some(output);
let output = unsafe { self.output.as_mut().unwrap_unchecked() };
output.start()
}
extern "C-unwind" fn input_cb(
ctx: *mut Ctx,
_io_action_flags: &mut au::RenderActionFlags,
_in_timestamp: &at::AudioTimeStamp,
_in_bus_num: u32,
in_number_frames: u32,
_io_data: *mut at::AudioBufList<1>,
) -> os::Status {
if ctx.is_null() {
return au::err::NO_CONNECTION.into();
}
let ctx = unsafe { &mut *ctx };
if ctx.output.is_none() {
return au::err::NO_CONNECTION.into();
}
let output = unsafe { ctx.output.as_mut().unwrap_unchecked() };
let mut buf_list = at::AudioBufList::<1>::new();
buf_list.buffers[0] = at::AudioBuf {
number_channels: ctx.format.channel_count(),
data_bytes_size: std::mem::size_of_val(&ctx.data[..]) as u32,
data: ctx.data.as_mut_ptr() as *mut _,
};
if let Err(e) = output.render(in_number_frames, &mut buf_list, 1) {
return e.status();
}
let buf = av::AudioPcmBuf::with_buf_list_no_copy(&ctx.format, &buf_list, None).unwrap();
ctx.file.write(&buf).unwrap();
os::Status::NO_ERR
}
}
#[tokio::main]
pub async fn main() {
let _input = core_audio::System::default_input_device().unwrap();
let output = au::Output::new_apple_vp().unwrap();
let input_device = output.input_device().unwrap();
let asbd = output
.input_stream_format(1)
.expect("Failed to get input stream format");
println!("format {:#?}", asbd);
let name = input_device.name().expect("Failed to device name property");
println!("input device: {name}");
let buf_list = input_device.input_stream_cfg().unwrap();
println!("stream cfg: {:?}", buf_list);
let format = av::AudioFormat::with_asbd(&asbd).unwrap();
// let format = av::AudioFormat::standard_with_sample_rate_and_channels(44100.0, 2).unwrap();
println!("format.settings() cfg: {:?}", format.settings());
let url = ns::Url::with_fs_path_string(ns::str!(c"/tmp/record_bb_3.wav"), false);
let file = av::AudioFile::open_write_common_format(
&url,
&format.settings(),
av::audio::CommonFormat::PcmF32,
format.is_interleaved(),
)
.unwrap();
let mut ctx = Box::new(Ctx {
data: vec![],
output: None,
file,
format,
});
ctx.start(output).unwrap();
tokio::signal::ctrl_c().await.unwrap();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment