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
20 changes: 18 additions & 2 deletions src/audio_unit/macos_helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,12 +91,28 @@ pub fn get_device_id_from_name(name: &str, input: bool) -> Option<AudioDeviceID>
}

/// Create an AudioUnit instance from a device id.
/// Set `input` to `true` to create a playback device, or `false` for a capture device.
/// Set `input` to `true` to create a capture device, or `false` for a playback device.
pub fn audio_unit_from_device_id(
device_id: AudioDeviceID,
input: bool,
) -> Result<AudioUnit, Error> {
let mut audio_unit = AudioUnit::new(IOType::HalOutput)?;
let mut audio_unit = audio_unit_from_device_id_uninitialized(device_id, input)?;
audio_unit.initialize()?;
Ok(audio_unit)
}

/// Create an AudioUnit instance from a device id without initializing it.
/// Set `input` to `true` to create a capture device, or `false` for a playback device.
pub fn audio_unit_from_device_id_uninitialized(
device_id: AudioDeviceID,
input: bool,
) -> Result<AudioUnit, Error> {
let output_type = if !input && get_default_device_id(false).is_some_and(|d| d == device_id) {
IOType::DefaultOutput
} else {
IOType::HalOutput
};
let mut audio_unit = AudioUnit::new_uninitialized(output_type)?;

if input {
// Enable input processing.
Expand Down
42 changes: 39 additions & 3 deletions src/audio_unit/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -124,9 +124,36 @@ impl AudioUnit {
AudioUnit::new_with_flags(ty, 0, 0)
}

/// Construct a new AudioUnit with any type that may be automatically converted into
/// [**Type**](./enum.Type). This constructor leaves the audio unit uninitialized
/// for the caller to decide when to do it manually!
///
/// Here is a list of compatible types:
///
/// - [**Type**](./types/enum.Type)
/// - [**IOType**](./types/enum.IOType)
/// - [**MusicDeviceType**](./types/enum.MusicDeviceType)
/// - [**GeneratorType**](./types/enum.GeneratorType)
/// - [**FormatConverterType**](./types/enum.FormatConverterType)
/// - [**EffectType**](./types/enum.EffectType)
/// - [**MixerType**](./types/enum.MixerType)
///
/// To construct the **AudioUnit** with some component flags, see
/// [**AudioUnit::new_with_flags**](./struct.AudioUnit#method.new_with_flags).
///
/// Note: the `AudioUnit` is constructed with the `kAudioUnitManufacturer_Apple` Manufacturer
/// Identifier, as this is the only Audio Unit Manufacturer Identifier documented by Apple in
/// the AudioUnit reference (see [here](https://developer.apple.com/library/prerelease/mac/documentation/AudioUnit/Reference/AUComponentServicesReference/index.html#//apple_ref/doc/constant_group/Audio_Unit_Manufacturer_Identifier)).
pub fn new_uninitialized<T>(ty: T) -> Result<AudioUnit, Error>
where
T: Into<Type>,
{
AudioUnit::new_with_flags_uninitialized(ty, 0, 0)
}

/// The same as [**AudioUnit::new**](./struct.AudioUnit#method.new) but with the given
/// component flags and mask.
pub fn new_with_flags<T>(ty: T, flags: u32, mask: u32) -> Result<AudioUnit, Error>
pub fn new_with_flags_uninitialized<T>(ty: T, flags: u32, mask: u32) -> Result<AudioUnit, Error>
where
T: Into<Type>,
{
Expand Down Expand Up @@ -168,8 +195,6 @@ impl AudioUnit {
));
let instance: InnerAudioUnit = instance_uninit.assume_init();

// Initialise the audio unit!
try_os_status!(AudioUnitInitialize(instance));
Ok(AudioUnit {
instance,
maybe_render_callback: None,
Expand All @@ -178,6 +203,17 @@ impl AudioUnit {
}
}

/// The same as [**AudioUnit::new**](./struct.AudioUnit#method.new) but with the given
/// component flags and mask.
pub fn new_with_flags<T>(ty: T, flags: u32, mask: u32) -> Result<AudioUnit, Error>
where
T: Into<Type>,
{
let mut audio_unit = AudioUnit::new_with_flags_uninitialized(ty, flags, mask)?;
audio_unit.initialize()?;
Ok(audio_unit)
}

/// On successful initialization, the audio formats for input and output are valid
/// and the audio unit is ready to render. During initialization, an audio unit
/// allocates memory according to the maximum number of audio frames it can produce
Expand Down
Loading