Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions .github/workflows/coreaudio-rs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,28 @@ jobs:
# - name: cargo test - all features
# run: cargo test --all-features --verbose

macos-clippy:
runs-on: macOS-latest
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@master
with:
toolchain: stable
components: clippy
- name: cargo clippy
run: cargo clippy -- -D warnings

macos-rustfmt:
runs-on: macOS-latest
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@master
with:
toolchain: stable
components: rustfmt
- name: cargo fmt
run: cargo fmt --all -- --check

security-audit:
runs-on: ubuntu-latest
steps:
Expand Down
5 changes: 4 additions & 1 deletion examples/sine_advanced.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,11 @@ 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,
toggle_hog_mode, AliveListener, RateListener,
};
// This import is not needed since the use of set_device_sample_rate
// is commented out and left as an example.
// use coreaudio::audio_unit::macos_helpers::set_device_sample_rate;
use coreaudio::audio_unit::render_callback::{self, data};
use coreaudio::audio_unit::{Element, SampleFormat, Scope, StreamFormat};
use objc2_audio_toolbox::kAudioUnitProperty_StreamFormat;
Expand Down
10 changes: 5 additions & 5 deletions src/audio_unit/macos_helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ pub fn get_default_device_id(input: bool) -> Option<AudioDeviceID> {
NonNull::from(&mut audio_device_id).cast(),
)
};
if status != kAudioHardwareNoError as i32 {
if status != kAudioHardwareNoError {
return None;
}

Expand Down Expand Up @@ -248,7 +248,7 @@ pub fn get_audio_device_supports_scope(devid: AudioDeviceID, scope: Scope) -> Re
NonNull::from(&data_size),
NonNull::new(buffers).unwrap().cast(),
);
if status != kAudioHardwareNoError as i32 {
if status != kAudioHardwareNoError {
return Err(Error::Unknown(status));
}

Expand Down Expand Up @@ -333,7 +333,7 @@ pub fn set_device_sample_rate(device_id: AudioDeviceID, new_rate: f64) -> Result
Error::from_os_status(status)?;
let n_ranges = data_size as usize / mem::size_of::<AudioValueRange>();
let mut ranges: Vec<AudioValueRange> = vec![];
ranges.reserve_exact(n_ranges as usize);
ranges.reserve_exact(n_ranges);
ranges.set_len(n_ranges);
let status = AudioObjectGetPropertyData(
device_id,
Expand Down Expand Up @@ -559,7 +559,7 @@ pub fn get_supported_physical_stream_formats(
Error::from_os_status(status)?;
let n_formats = data_size as usize / mem::size_of::<AudioStreamRangedDescription>();
let mut formats: Vec<AudioStreamRangedDescription> = vec![];
formats.reserve_exact(n_formats as usize);
formats.reserve_exact(n_formats);
formats.set_len(n_formats);

let status = AudioObjectGetPropertyData(
Expand Down Expand Up @@ -848,7 +848,7 @@ pub fn toggle_hog_mode(device_id: AudioDeviceID) -> Result<pid_t, Error> {
NonNull::from(&property_address),
0,
null(),
data_size as u32,
data_size,
NonNull::from(&temp_pid).cast(),
);
Error::from_os_status(status)?;
Expand Down
46 changes: 29 additions & 17 deletions src/audio_unit/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@ impl AudioUnit {
elem: Element,
maybe_data: Option<&T>,
) -> Result<(), Error> {
set_property(self.instance, id, scope, elem, maybe_data)
unsafe { set_property(self.instance, id, scope, elem, maybe_data) }
}

/// Gets the value of an **AudioUnit** property.
Expand All @@ -241,7 +241,7 @@ impl AudioUnit {
/// - **scope**: The audio unit scope for the property.
/// - **elem**: The audio unit element for the property.
pub fn get_property<T>(&self, id: u32, scope: Scope, elem: Element) -> Result<T, Error> {
get_property(self.instance, id, scope, elem)
unsafe { get_property(self.instance, id, scope, elem) }
}

/// Starts an I/O **AudioUnit**, which in turn starts the audio unit processing graph that it is
Expand Down Expand Up @@ -290,10 +290,10 @@ impl AudioUnit {
/// >
/// > - iOS input and output: Linear PCM with 16-bit integer samples.
/// > - iOS audio units and other audio processing: Noninterleaved linear PCM with 8.24-bit
/// fixed-point samples
/// > fixed-point samples
/// > - Mac input and output: Linear PCM with 32-bit floating point samples.
/// > - Mac audio units and other audio processing: Noninterleaved linear PCM with 32-bit
/// floating-point
/// > floating-point
pub fn set_stream_format(
&mut self,
stream_format: StreamFormat,
Expand Down Expand Up @@ -375,7 +375,14 @@ impl Drop for AudioUnit {
/// - **scope**: The audio unit scope for the property.
/// - **elem**: The audio unit element for the property.
/// - **maybe_data**: The value that you want to apply to the property.
pub fn set_property<T>(
///
/// Safety
/// ------
/// This function is safe as long as the **au** parameter is a valid pointer to an AudioUnit instance.
/// The caller is responsible for ensuring this.
/// For a safer alternative, consider using an [AudioUnit] instance
/// and calling the associated [AudioUnit::set_property] method.
pub unsafe fn set_property<T>(
au: InnerAudioUnit,
id: u32,
scope: Scope,
Expand All @@ -391,7 +398,7 @@ pub fn set_property<T>(
.unwrap_or_else(|| (::std::ptr::null(), 0));
let scope = scope as c_uint;
let elem = elem as c_uint;
unsafe { try_os_status!(AudioUnitSetProperty(au, id, scope, elem, data_ptr, size)) }
try_os_status!(AudioUnitSetProperty(au, id, scope, elem, data_ptr, size));
Ok(())
}

Expand All @@ -406,7 +413,14 @@ pub fn set_property<T>(
/// - **id**: The identifier of the property.
/// - **scope**: The audio unit scope for the property.
/// - **elem**: The audio unit element for the property.
pub fn get_property<T>(
///
/// Safety
/// ------
/// This function is safe as long as the **au** parameter is a valid pointer to an AudioUnit instance.
/// The caller is responsible for ensuring this.
/// For a safer alternative, consider using an [AudioUnit] instance
/// and calling the associated [AudioUnit::get_property] method.
pub unsafe fn get_property<T>(
au: InnerAudioUnit,
id: u32,
scope: Scope,
Expand All @@ -415,16 +429,14 @@ pub fn get_property<T>(
let scope = scope as c_uint;
let elem = elem as c_uint;
let mut size = ::std::mem::size_of::<T>() as u32;
unsafe {
let mut data_uninit = ::std::mem::MaybeUninit::<T>::uninit();
let data_ptr = NonNull::from(&mut data_uninit).cast::<c_void>();
let size_ptr = NonNull::from(&mut size);
try_os_status!(AudioUnitGetProperty(
au, id, scope, elem, data_ptr, size_ptr
));
let data: T = data_uninit.assume_init();
Ok(data)
}
let mut data_uninit = ::std::mem::MaybeUninit::<T>::uninit();
let data_ptr = NonNull::from(&mut data_uninit).cast::<c_void>();
let size_ptr = NonNull::from(&mut size);
try_os_status!(AudioUnitGetProperty(
au, id, scope, elem, data_ptr, size_ptr
));
let data: T = data_uninit.assume_init();
Ok(data)
}

/// Gets the value of a specified audio session property.
Expand Down
6 changes: 3 additions & 3 deletions src/audio_unit/render_callback.rs
Original file line number Diff line number Diff line change
Expand Up @@ -504,7 +504,7 @@ impl AudioUnit {
data,
time_stamp: in_time_stamp.read(),
flags,
bus_number: in_bus_number as u32,
bus_number: in_bus_number,
num_frames: in_number_frames as usize,
}
};
Expand Down Expand Up @@ -678,7 +678,7 @@ impl AudioUnit {
data,
time_stamp: in_time_stamp.read(),
flags,
bus_number: in_bus_number as u32,
bus_number: in_bus_number,
num_frames: in_number_frames as usize,
}
};
Expand Down Expand Up @@ -744,7 +744,7 @@ impl AudioUnit {
// Take ownership over the AudioBufferList in order to safely free it.
let buffer_list: Box<AudioBufferList> = Box::from_raw(buffer_list);
// Free the allocated data from the individual audio buffers.
let ptr = buffer_list.mBuffers.as_ptr() as *const AudioBuffer;
let ptr = buffer_list.mBuffers.as_ptr();
let len = buffer_list.mNumberBuffers as usize;
let buffers: &[AudioBuffer] = slice::from_raw_parts(ptr, len);
for &buffer in buffers {
Expand Down
10 changes: 5 additions & 5 deletions src/audio_unit/stream_format.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,18 +23,18 @@ use crate::error::{self, Error};
/// `bits_per_channel = size_of::<S>()` / channels_per_frame * 8
///
/// > A *packet* is a collection of one or more contiguous frames. In linear PCM audio, a packet is
/// always a single frame.
/// > always a single frame.
///
/// [from *Core Audio Overview*](https://developer.apple.com/library/ios/documentation/MusicAudio/Conceptual/CoreAudioOverview/WhatisCoreAudio/WhatisCoreAudio.html)
///
/// > The canonical formats in Core Audio are as follows:
/// >
/// > - iOS input and output: Linear PCM with 16-bit integer samples.
/// > - iOS audio units and other audio processing: Noninterleaved linear PCM with 8.24-bit
/// fixed-point samples
/// > fixed-point samples
/// > - Mac input and output: Linear PCM with 32-bit floating point samples.
/// > - Mac audio units and other audio processing: Noninterleaved linear PCM with 32-bit floating
/// point samples.
/// > point samples.
#[derive(Copy, Clone, Debug)]
pub struct StreamFormat {
/// The number of frames of audio data per second used to represent a signal.
Expand All @@ -61,7 +61,7 @@ impl StreamFormat {
/// specified in the documentation:
///
/// > Specify kAudioFormatLinearPCM for the mFormatID field. Audio units use uncompressed audio
/// data, so this is the correct format identifier to use whenever you work with audio units.
/// > data, so this is the correct format identifier to use whenever you work with audio units.
///
/// [*Audio Unit Hosting Guide for iOS*](https://developer.apple.com/library/ios/documentation/MusicAudio/Conceptual/AudioUnitHostingGuide_iOS/AudioUnitHostingFundamentals/AudioUnitHostingFundamentals.html)
///
Expand Down Expand Up @@ -118,7 +118,7 @@ impl StreamFormat {
let (format, maybe_flag) =
AudioFormat::LinearPCM(flags | LinearPcmFlags::IS_PACKED).as_format_and_flag();

let flag = maybe_flag.unwrap_or(::std::u32::MAX - 2147483647);
let flag = maybe_flag.unwrap_or(u32::MAX - 2147483647);

let non_interleaved = flags.contains(LinearPcmFlags::IS_NON_INTERLEAVED);
let bytes_per_frame = if non_interleaved {
Expand Down
19 changes: 10 additions & 9 deletions src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ pub mod audio {
Error::MemFull => "Memory full",
Error::Unknown => "An unknown error occurred",
};
write!(f, "{}", description)
write!(f, "{description}")
}
}
}
Expand Down Expand Up @@ -109,7 +109,7 @@ pub mod audio_codec {
Error::NotEnoughBufferSpace => "Not enough buffer space",
Error::Unknown => "Unknown error occurred",
};
write!(f, "{}", description)
write!(f, "{description}")
}
}
}
Expand Down Expand Up @@ -156,7 +156,7 @@ pub mod audio_format {
Error::UnknownFormat => "The specified data format is not a known format",
Error::Unknown => "Unknown error occurred",
};
write!(f, "{}", description)
write!(f, "{description}")
}
}
}
Expand Down Expand Up @@ -239,7 +239,7 @@ pub mod audio_unit {
Error::Unauthorized => "Unauthorized",
Error::Unknown => "Unknown error occurred",
};
write!(f, "{}", description)
write!(f, "{description}")
}
}
}
Expand Down Expand Up @@ -324,11 +324,12 @@ impl ::std::fmt::Display for Error {
Error::NonInterleavedInputOnlySupportsMono => write!(f, "In non-interleaved mode input only supports one channel"),
Error::UnsupportedSampleRate => write!(f, "The requested sample rate is not available"),
Error::UnsupportedStreamFormat => write!(f, "The requested stream format is not available"),
Error::Audio(ref err) => write!(f, "{}", err),
Error::AudioCodec(ref err) => write!(f, "{}", err),
Error::AudioFormat(ref err) => write!(f, "{}", err),
Error::AudioUnit(ref err) => write!(f, "{}", err),
Error::Unknown(os_status) => write!(f, "An error unknown to the coreaudio-rs API occurred, OSStatus: {}", os_status),
Error::Audio(ref err) => write!(f, "{err}"),
Error::AudioCodec(ref err) => write!(f, "{err}"),
Error::AudioFormat(ref err) => write!(f, "{err}"),
Error::AudioUnit(ref err) => write!(f, "{err}"),
Error::Unknown(os_status) => write!(f, "An error unknown to the coreaudio-rs API occurred, OSStatus: {os_status}"),

}
}
}
Loading