Vendor dependencies for 0.3.0 release

This commit is contained in:
2025-09-27 10:29:08 -05:00
parent 0c8d39d483
commit 82ab7f317b
26803 changed files with 16134934 additions and 0 deletions

139
vendor/coreaudio-rs/examples/feedback.rs vendored Normal file
View File

@@ -0,0 +1,139 @@
//! A basic input + output stream example, copying the mic input stream to the default output stream
extern crate coreaudio;
use std::collections::VecDeque;
use std::sync::{Arc, Mutex};
use coreaudio::audio_unit::audio_format::LinearPcmFlags;
use coreaudio::audio_unit::macos_helpers::{audio_unit_from_device_id, get_default_device_id};
use coreaudio::audio_unit::render_callback::{self, data};
use coreaudio::audio_unit::{Element, SampleFormat, Scope, StreamFormat};
use coreaudio::sys::*;
const SAMPLE_RATE: f64 = 44100.0;
type S = f32;
const SAMPLE_FORMAT: SampleFormat = SampleFormat::F32;
// type S = i32; const SAMPLE_FORMAT: SampleFormat = SampleFormat::I32;
// type S = i16; const SAMPLE_FORMAT: SampleFormat = SampleFormat::I16;
// type S = i8; const SAMPLE_FORMAT: SampleFormat = SampleFormat::I8;
fn main() -> Result<(), coreaudio::Error> {
let mut input_audio_unit =
audio_unit_from_device_id(get_default_device_id(true).unwrap(), true)?;
let mut output_audio_unit =
audio_unit_from_device_id(get_default_device_id(false).unwrap(), false)?;
let format_flag = match SAMPLE_FORMAT {
SampleFormat::F32 => LinearPcmFlags::IS_FLOAT,
SampleFormat::I32 | SampleFormat::I16 | SampleFormat::I8 => {
LinearPcmFlags::IS_SIGNED_INTEGER
}
_ => {
unimplemented!("Other formats are not implemented for this example.");
}
};
// Using IS_NON_INTERLEAVED everywhere because data::Interleaved is commented out / not implemented
let in_stream_format = StreamFormat {
sample_rate: SAMPLE_RATE,
sample_format: SAMPLE_FORMAT,
flags: format_flag | LinearPcmFlags::IS_PACKED | LinearPcmFlags::IS_NON_INTERLEAVED,
// audio_unit.set_input_callback is hardcoded to 1 buffer, and when using non_interleaved
// we are forced to 1 channel
channels: 1,
};
let out_stream_format = StreamFormat {
sample_rate: SAMPLE_RATE,
sample_format: SAMPLE_FORMAT,
flags: format_flag | LinearPcmFlags::IS_PACKED | LinearPcmFlags::IS_NON_INTERLEAVED,
// you can change this to 1
channels: 2,
};
println!("input={:#?}", &in_stream_format);
println!("output={:#?}", &out_stream_format);
println!("input_asbd={:#?}", &in_stream_format.to_asbd());
println!("output_asbd={:#?}", &out_stream_format.to_asbd());
let id = kAudioUnitProperty_StreamFormat;
let asbd = in_stream_format.to_asbd();
input_audio_unit.set_property(id, Scope::Output, Element::Input, Some(&asbd))?;
let asbd = out_stream_format.to_asbd();
output_audio_unit.set_property(id, Scope::Input, Element::Output, Some(&asbd))?;
let buffer_left = Arc::new(Mutex::new(VecDeque::<S>::new()));
let producer_left = buffer_left.clone();
let consumer_left = buffer_left.clone();
let buffer_right = Arc::new(Mutex::new(VecDeque::<S>::new()));
let producer_right = buffer_right.clone();
let consumer_right = buffer_right.clone();
// seed roughly 1 second of data to create a delay in the feedback loop for easier testing
for buffer in vec![buffer_left, buffer_right] {
let mut buffer = buffer.lock().unwrap();
for _ in 0..(out_stream_format.sample_rate as i32) {
buffer.push_back(0 as S);
}
}
type Args = render_callback::Args<data::NonInterleaved<S>>;
input_audio_unit.set_input_callback(move |args| {
let Args {
num_frames,
mut data,
..
} = args;
// Print the number of frames the callback provides.
// Included to aid understanding, don't use println and other things
// that may block for an unknown amount of time inside the callback
// of a real application.
println!("input cb {} frames", num_frames);
let buffer_left = producer_left.lock().unwrap();
let buffer_right = producer_right.lock().unwrap();
let mut buffers = vec![buffer_left, buffer_right];
for i in 0..num_frames {
for (ch, channel) in data.channels_mut().enumerate() {
let value: S = channel[i];
buffers[ch].push_back(value);
}
}
Ok(())
})?;
input_audio_unit.start()?;
output_audio_unit.set_render_callback(move |args: Args| {
let Args {
num_frames,
mut data,
..
} = args;
// Print the number of frames the callback requests.
// Included to aid understanding, don't use println and other things
// that may block for an unknown amount of time inside the callback
// of a real application.
println!("output cb {} frames", num_frames);
let buffer_left = consumer_left.lock().unwrap();
let buffer_right = consumer_right.lock().unwrap();
let mut buffers = vec![buffer_left, buffer_right];
for i in 0..num_frames {
// Default other channels to copy value from first channel as a fallback
let zero: S = 0 as S;
let f: S = *buffers[0].front().unwrap_or(&zero);
for (ch, channel) in data.channels_mut().enumerate() {
let sample: S = buffers[ch].pop_front().unwrap_or(f);
channel[i] = sample;
}
}
Ok(())
})?;
output_audio_unit.start()?;
std::thread::sleep(std::time::Duration::from_millis(100000));
Ok(())
}

View File

@@ -0,0 +1,152 @@
//! A basic input + output stream example, copying the mic input stream to the default output stream
extern crate coreaudio;
use std::collections::VecDeque;
use std::sync::{Arc, Mutex};
use coreaudio::audio_unit::audio_format::LinearPcmFlags;
use coreaudio::audio_unit::macos_helpers::{
audio_unit_from_device_id, get_default_device_id, get_device_name, RateListener,
};
use coreaudio::audio_unit::render_callback::{self, data};
use coreaudio::audio_unit::{Element, SampleFormat, Scope, StreamFormat};
use coreaudio::sys::*;
const SAMPLE_RATE: f64 = 44100.0;
type S = f32;
const SAMPLE_FORMAT: SampleFormat = SampleFormat::F32;
// type S = i32; const SAMPLE_FORMAT: SampleFormat = SampleFormat::I32;
// type S = i16; const SAMPLE_FORMAT: SampleFormat = SampleFormat::I16;
// type S = i8; const SAMPLE_FORMAT: SampleFormat = SampleFormat::I8;
fn main() -> Result<(), coreaudio::Error> {
let input_device_id = get_default_device_id(true).unwrap();
let output_device_id = get_default_device_id(false).unwrap();
println!(
"Input device: {}",
get_device_name(input_device_id).unwrap()
);
println!(
"Output device: {}",
get_device_name(output_device_id).unwrap()
);
let mut input_audio_unit = audio_unit_from_device_id(input_device_id, true)?;
let mut output_audio_unit = audio_unit_from_device_id(output_device_id, false)?;
let format_flag = match SAMPLE_FORMAT {
SampleFormat::F32 => LinearPcmFlags::IS_FLOAT | LinearPcmFlags::IS_PACKED,
SampleFormat::I32 | SampleFormat::I16 | SampleFormat::I8 => {
LinearPcmFlags::IS_SIGNED_INTEGER | LinearPcmFlags::IS_PACKED
}
_ => {
unimplemented!("Please use one of the packed formats");
}
};
let in_stream_format = StreamFormat {
sample_rate: SAMPLE_RATE,
sample_format: SAMPLE_FORMAT,
flags: format_flag,
channels: 2,
};
let out_stream_format = StreamFormat {
sample_rate: SAMPLE_RATE,
sample_format: SAMPLE_FORMAT,
flags: format_flag,
channels: 2,
};
println!("input={:#?}", &in_stream_format);
println!("output={:#?}", &out_stream_format);
println!("input_asbd={:#?}", &in_stream_format.to_asbd());
println!("output_asbd={:#?}", &out_stream_format.to_asbd());
let id = kAudioUnitProperty_StreamFormat;
let asbd = in_stream_format.to_asbd();
input_audio_unit.set_property(id, Scope::Output, Element::Input, Some(&asbd))?;
let asbd = out_stream_format.to_asbd();
output_audio_unit.set_property(id, Scope::Input, Element::Output, Some(&asbd))?;
let buffer_left = Arc::new(Mutex::new(VecDeque::<S>::new()));
let producer_left = buffer_left.clone();
let consumer_left = buffer_left.clone();
let buffer_right = Arc::new(Mutex::new(VecDeque::<S>::new()));
let producer_right = buffer_right.clone();
let consumer_right = buffer_right.clone();
// Register a rate listener for playback
let mut listener_pb = RateListener::new(output_device_id, None);
listener_pb.register()?;
// Register a rate listener for capture
let mut listener_cap = RateListener::new(input_device_id, None);
listener_cap.register()?;
// seed roughly 1 second of data to create a delay in the feedback loop for easier testing
for buffer in vec![buffer_left, buffer_right] {
let mut buffer = buffer.lock().unwrap();
for _ in 0..(out_stream_format.sample_rate as i32) {
buffer.push_back(0 as S);
}
}
type Args = render_callback::Args<data::Interleaved<S>>;
input_audio_unit.set_input_callback(move |args| {
let Args {
num_frames, data, ..
} = args;
// Print the number of frames the callback requests.
// Included to aid understanding, don't use println and other things
// that may block for an unknown amount of time inside the callback
// of a real application.
println!("input cb {} frames", num_frames);
let buffer_left = producer_left.lock().unwrap();
let buffer_right = producer_right.lock().unwrap();
let mut buffers = vec![buffer_left, buffer_right];
for i in 0..num_frames {
for channel in 0..2 {
let value: S = data.buffer[2 * i + channel];
buffers[channel].push_back(value);
}
}
Ok(())
})?;
input_audio_unit.start()?;
output_audio_unit.set_render_callback(move |args: Args| {
let Args {
num_frames, data, ..
} = args;
// Print the number of frames the callback requests.
println!("output cb {} frames", num_frames);
let buffer_left = consumer_left.lock().unwrap();
let buffer_right = consumer_right.lock().unwrap();
let mut buffers = vec![buffer_left, buffer_right];
for i in 0..num_frames {
// Default other channels to copy value from first channel as a fallback
let zero: S = 0 as S;
let f: S = *buffers[0].front().unwrap_or(&zero);
for channel in 0..2 {
let sample: S = buffers[channel].pop_front().unwrap_or(f);
data.buffer[2 * i + channel] = sample;
}
}
Ok(())
})?;
output_audio_unit.start()?;
for _ in 0..1000 {
std::thread::sleep(std::time::Duration::from_millis(100));
if listener_cap.get_nbr_values() > 0 {
println!("capture rate change: {:?}", listener_cap.drain_values());
}
if listener_pb.get_nbr_values() > 0 {
println!("playback rate change: {:?}", listener_pb.drain_values());
}
}
Ok(())
}

73
vendor/coreaudio-rs/examples/sine.rs vendored Normal file
View File

@@ -0,0 +1,73 @@
//! A basic output stream example, using an Output AudioUnit to generate a sine wave.
extern crate coreaudio;
use coreaudio::audio_unit::render_callback::{self, data};
use coreaudio::audio_unit::{AudioUnit, IOType, SampleFormat};
use std::f64::consts::PI;
struct SineWaveGenerator {
time: f64,
/// generated frequency in Hz
freq: f64,
/// magnitude of generated signal
volume: f64,
}
impl SineWaveGenerator {
fn new(freq: f64, volume: f64) -> Self {
SineWaveGenerator {
time: 0.,
freq,
volume,
}
}
}
impl Iterator for SineWaveGenerator {
type Item = f32;
fn next(&mut self) -> Option<f32> {
self.time += 1. / 44_100.;
let output = ((self.freq * self.time * PI * 2.).sin() * self.volume) as f32;
Some(output)
}
}
fn main() -> Result<(), coreaudio::Error> {
let frequency_hz = 440.;
let volume = 0.15;
let mut samples = SineWaveGenerator::new(frequency_hz, volume);
// Construct an Output audio unit that delivers audio to the default output device.
let mut audio_unit = AudioUnit::new(IOType::DefaultOutput)?;
// Read the input format. This is counterintuitive, but it's the format used when sending
// audio data to the AudioUnit representing the output device. This is separate from the
// format the AudioUnit later uses to send the data to the hardware device.
let stream_format = audio_unit.input_stream_format()?;
println!("{:#?}", &stream_format);
// For this example, our sine wave expects `f32` data.
assert!(SampleFormat::F32 == stream_format.sample_format);
type Args = render_callback::Args<data::NonInterleaved<f32>>;
audio_unit.set_render_callback(move |args| {
let Args {
num_frames,
mut data,
..
} = args;
for i in 0..num_frames {
let sample = samples.next().unwrap();
for channel in data.channels_mut() {
channel[i] = sample;
}
}
Ok(())
})?;
audio_unit.start()?;
std::thread::sleep(std::time::Duration::from_millis(3000));
Ok(())
}

View File

@@ -0,0 +1,217 @@
//! An output stream example showing more advanced usage.
//! Tries to use hog mode to get exclusive access to the device.
extern crate coreaudio;
use coreaudio::audio_unit::audio_format::LinearPcmFlags;
use coreaudio::audio_unit::macos_helpers::{
audio_unit_from_device_id, find_matching_physical_format, get_default_device_id,
get_hogging_pid, get_supported_physical_stream_formats, set_device_physical_stream_format,
set_device_sample_rate, toggle_hog_mode, AliveListener, RateListener,
};
use coreaudio::audio_unit::render_callback::{self, data};
use coreaudio::audio_unit::{Element, SampleFormat, Scope, StreamFormat};
use coreaudio::sys::kAudioUnitProperty_StreamFormat;
use std::f64::consts::PI;
use std::process;
const SAMPLE_FORMAT: SampleFormat = SampleFormat::F32;
// type S = i32; const SAMPLE_FORMAT: SampleFormat = SampleFormat::I32;
// type S = i16; const SAMPLE_FORMAT: SampleFormat = SampleFormat::I16;
// type S = i8; const SAMPLE_FORMAT: SampleFormat = SampleFormat::I8;
const SAMPLE_RATE: f64 = 44100.0;
const INTERLEAVED: bool = true;
struct SineWaveGenerator {
time: f64,
/// generated frequency in Hz
freq: f64,
/// magnitude of generated signal
volume: f64,
}
impl SineWaveGenerator {
fn new(freq: f64, volume: f64) -> Self {
SineWaveGenerator {
time: 0.,
freq,
volume,
}
}
}
impl Iterator for SineWaveGenerator {
type Item = f32;
fn next(&mut self) -> Option<f32> {
self.time += 1. / SAMPLE_RATE;
let output = ((self.freq * self.time * PI * 2.).sin() * self.volume) as f32;
Some(output)
}
}
fn main() -> Result<(), coreaudio::Error> {
let frequency_hz_l = 1000.;
let frequency_hz_r = 1200.;
let volume = 0.95;
let mut samples_l = SineWaveGenerator::new(frequency_hz_l, volume);
let mut samples_r = SineWaveGenerator::new(frequency_hz_r, volume);
// Construct an Output audio unit that delivers audio to the default output device.
let audio_unit_id = get_default_device_id(false).unwrap();
let mut audio_unit = audio_unit_from_device_id(audio_unit_id, false)?;
let pid = get_hogging_pid(audio_unit_id)?;
if pid != -1 {
println!("Device is owned by another process with pid {}!", pid);
} else {
println!("Device is free, trying to get exclusive access..");
let new_pid = toggle_hog_mode(audio_unit_id)?;
let process_id = process::id();
if new_pid == process_id as i32 {
println!("We have exclusive access.");
} else {
println!(
"Could not get exclusive access. Process pid: {}, new pid value: {}",
process_id, new_pid
);
}
}
let mut format_flag = match SAMPLE_FORMAT {
SampleFormat::F32 => LinearPcmFlags::IS_FLOAT | LinearPcmFlags::IS_PACKED,
SampleFormat::I32 | SampleFormat::I16 | SampleFormat::I8 => {
LinearPcmFlags::IS_SIGNED_INTEGER | LinearPcmFlags::IS_PACKED
}
_ => {
unimplemented!("Please use one of the packed formats");
}
};
if !INTERLEAVED {
format_flag = format_flag | LinearPcmFlags::IS_NON_INTERLEAVED;
}
let stream_format = StreamFormat {
sample_rate: SAMPLE_RATE,
sample_format: SAMPLE_FORMAT,
flags: format_flag,
// you can change this to 1
channels: 2,
};
println!("stream format={:#?}", &stream_format);
println!("asbd={:#?}", &stream_format.to_asbd());
// Lets print all supported formats, disabled for now since it often crashes.
println!("All supported formats");
let formats = get_supported_physical_stream_formats(audio_unit_id)?;
for fmt in formats {
println!("{:?}", &fmt);
}
// set the sample rate. This isn't actually needed since the sample rate
// will anyway be changed when setting the sample format later.
// Keeping it here as an example.
//println!("set device sample rate");
//set_device_sample_rate(audio_unit_id, SAMPLE_RATE)?;
println!("setting hardware (physical) format");
let hw_stream_format = StreamFormat {
sample_rate: SAMPLE_RATE,
sample_format: SampleFormat::I16,
flags: LinearPcmFlags::empty(),
channels: 2,
};
let hw_asbd = find_matching_physical_format(audio_unit_id, hw_stream_format)
.ok_or(coreaudio::Error::UnsupportedStreamFormat)?;
println!("asbd: {:?}", hw_asbd);
// Note that using a StreamFormat here is convenient, but it only supports a few sample formats.
// Setting the format to for example 24 bit integers requires using an ASBD.
set_device_physical_stream_format(audio_unit_id, hw_asbd)?;
println!("write audio unit StreamFormat property");
let id = kAudioUnitProperty_StreamFormat;
let asbd = stream_format.to_asbd();
audio_unit.set_property(id, Scope::Input, Element::Output, Some(&asbd))?;
// For this example, our sine wave expects `f32` data.
assert!(SampleFormat::F32 == stream_format.sample_format);
// Register rate and alive listeners
let mut rate_listener = RateListener::new(audio_unit_id, None);
rate_listener.register()?;
let mut alive_listener = AliveListener::new(audio_unit_id);
alive_listener.register()?;
if INTERLEAVED {
println!("Register interleaved callback");
type Args = render_callback::Args<data::Interleaved<f32>>;
audio_unit.set_render_callback(move |args| {
let Args {
num_frames, data, ..
} = args;
// Print the number of frames the callback requests.
// Included to aid understanding, don't use println and other things
// that may block for an unknown amount of time inside the callback
// of a real application.
println!("frames: {}", num_frames);
for i in 0..num_frames {
let sample_l = samples_l.next().unwrap();
let sample_r = samples_r.next().unwrap();
data.buffer[2 * i] = sample_l;
data.buffer[2 * i + 1] = sample_r;
}
Ok(())
})?;
} else {
println!("Register non-interleaved callback");
type Args = render_callback::Args<data::NonInterleaved<f32>>;
audio_unit.set_render_callback(move |args| {
let Args {
num_frames,
mut data,
..
} = args;
for i in 0..num_frames {
let sample_l = samples_l.next().unwrap();
let sample_r = samples_r.next().unwrap();
let mut channels = data.channels_mut();
let left = channels.next().unwrap();
left[i] = sample_l;
let right = channels.next().unwrap();
right[i] = sample_r;
}
Ok(())
})?;
}
audio_unit.start()?;
for _ in 0..100 {
std::thread::sleep(std::time::Duration::from_millis(100));
// print all sample change events
println!("rate events: {:?}", rate_listener.copy_values());
println!("alive state: {}", alive_listener.is_alive());
}
// Release exclusive access, not really needed as the process exits anyway after this.
let owner_pid = get_hogging_pid(audio_unit_id)?;
let process_id = process::id();
if owner_pid == process_id as i32 {
println!("Releasing exclusive access");
let new_pid = toggle_hog_mode(audio_unit_id)?;
if new_pid == -1 {
println!("Exclusive access released.");
} else {
println!(
"Could not release exclusive access. Process pid: {}, new pid value: {}",
process_id, new_pid
);
}
}
Ok(())
}