Skip to content

Commit

Permalink
Instance AudioComponents
Browse files Browse the repository at this point in the history
Change-Id: I8ec5611c3c6cd1ed3e110c322876d6f6c74c4aa8
  • Loading branch information
alborrajo committed May 1, 2024
1 parent 83c71ab commit 37b8a04
Show file tree
Hide file tree
Showing 3 changed files with 145 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/dyld/function_lists.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ pub const FUNCTION_LISTS: &[super::FunctionExports] = &[
libc::unistd::FUNCTIONS,
libc::wchar::FUNCTIONS,
crate::objc::FUNCTIONS,
audio_toolbox::audio_components::FUNCTIONS,
audio_toolbox::audio_file::FUNCTIONS,
audio_toolbox::audio_queue::FUNCTIONS,
audio_toolbox::audio_services::FUNCTIONS,
Expand Down
2 changes: 2 additions & 0 deletions src/frameworks/audio_toolbox.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ macro_rules! return_if_null {
};
}

pub mod audio_components;
pub mod audio_file;
pub mod audio_queue;
pub mod audio_services;
Expand All @@ -33,6 +34,7 @@ pub mod audio_session;
pub struct State {
audio_file: audio_file::State,
audio_queue: audio_queue::State,
audio_components: audio_components::State,
al_device_and_context: Option<(*mut ALCdevice, *mut ALCcontext)>,
}
impl State {
Expand Down
142 changes: 142 additions & 0 deletions src/frameworks/audio_toolbox/audio_components.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
//! `AudioComponent.h` (Audio Component Services)

use std::collections::HashMap;

use crate::abi::GuestFunction;
use crate::dyld::FunctionExports;
use crate::environment::Environment;
use crate::export_c_func;
use crate::frameworks::carbon_core::{paramErr, OSStatus};
use crate::frameworks::core_audio_types::fourcc;
use crate::mem::{ConstPtr, ConstVoidPtr, MutPtr, SafeRead};
use crate::objc::nil;

const kAudioUnitType_Output: u32 = fourcc(b"auou");
const kAudioUnitSubType_RemoteIO: u32 = fourcc(b"rioc");
const kAudioUnitManufacturer_Apple: u32 = fourcc(b"appl");

#[derive(Default)]
pub struct State {
pub audio_component_instances:
HashMap<AudioComponentInstance, AudioComponentInstanceHostObject>,
}
impl State {
pub fn get(framework_state: &mut crate::frameworks::State) -> &mut Self {
&mut framework_state.audio_toolbox.audio_components
}
}

#[derive(Default, Clone)]
pub struct AudioComponentInstanceHostObject {}

#[derive(Clone)]
#[repr(C, packed)]
pub struct AURenderCallbackStruct {
pub input_proc: AURenderCallback,
pub input_proc_ref_con: ConstVoidPtr,
}
unsafe impl SafeRead for AURenderCallbackStruct {}

#[repr(C, packed)]
struct OpaqueAudioComponent {}
unsafe impl SafeRead for OpaqueAudioComponent {}

type AudioComponent = MutPtr<OpaqueAudioComponent>;

pub type AURenderCallback = GuestFunction;

#[repr(C, packed)]
pub struct OpaqueAudioComponentInstance {
_pad: u8,
}
unsafe impl SafeRead for OpaqueAudioComponentInstance {}

pub type AudioComponentInstance = MutPtr<OpaqueAudioComponentInstance>;

#[repr(C, packed)]
struct AudioComponentDescription {
component_type: u32,
component_sub_type: u32,
component_manufacturer: u32,
component_flags: u32,
component_flags_mask: u32,
}
unsafe impl SafeRead for AudioComponentDescription {}

fn AudioComponentFindNext(
env: &mut Environment,
in_component: AudioComponent,
in_desc: ConstPtr<AudioComponentDescription>,
) -> AudioComponent {
let audio_comp_descr = env.mem.read(in_desc);
assert!(audio_comp_descr.component_type == kAudioUnitType_Output);
assert!(audio_comp_descr.component_sub_type == kAudioUnitSubType_RemoteIO);
assert!(audio_comp_descr.component_manufacturer == kAudioUnitManufacturer_Apple);

let out_component = nil.cast();
log!(
"TODO: AudioComponentFindNext({:?}, {:?}) -> {:?}",
in_component,
in_desc,
out_component
);
out_component
}

fn AudioComponentInstanceNew(
env: &mut Environment,
in_component: AudioComponent,
out_instance: MutPtr<AudioComponentInstance>,
) -> OSStatus {
let host_object = AudioComponentInstanceHostObject::default();

let guest_instance: AudioComponentInstance = env
.mem
.alloc_and_write(OpaqueAudioComponentInstance { _pad: 0 });
State::get(&mut env.framework_state)
.audio_component_instances
.insert(guest_instance, host_object);

env.mem.write(out_instance, guest_instance);

let result = 0; // success
log_dbg!(
"AudioComponentInstanceNew({:?}, {:?}) -> {:?}",
in_component,
out_instance,
result
);
result
}

fn AudioComponentInstanceDispose(
env: &mut Environment,
in_instance: AudioComponentInstance,
) -> OSStatus {
let result = if in_instance.is_null() {
paramErr
} else {
State::get(&mut env.framework_state)
.audio_component_instances
.remove(&in_instance);
env.mem.free(in_instance.cast());
0
};
log_dbg!(
"AudioComponentInstanceDispose({:?}) -> {:?}",
in_instance,
result
);
result
}

pub const FUNCTIONS: FunctionExports = &[
export_c_func!(AudioComponentFindNext(_, _)),
export_c_func!(AudioComponentInstanceNew(_, _)),
export_c_func!(AudioComponentInstanceDispose(_)),
];

0 comments on commit 37b8a04

Please sign in to comment.