-
Notifications
You must be signed in to change notification settings - Fork 93
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Change-Id: I8ec5611c3c6cd1ed3e110c322876d6f6c74c4aa8
- Loading branch information
Showing
3 changed files
with
145 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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(_)), | ||
]; |