1use crate::{
2 arc, av, cm, define_obj_type,
3 ns::{self, Copying, CopyingMut},
4 objc,
5};
6
7#[cfg(feature = "mt")]
8use crate::mt;
9
10define_obj_type!(
11 #[doc(alias = "AVAudioMix")]
13 pub Mix(ns::Id),
14 AV_AUDIO_MIX
15);
16
17impl ns::Copying for Mix {}
18impl ns::CopyingMut for Mix {}
19
20impl Mix {
21 pub fn copy(&self) -> Option<arc::R<Mix>> {
22 unsafe { std::mem::transmute(self.copy_with_zone(std::ptr::null_mut())) }
23 }
24
25 pub fn copy_mut(&self) -> Option<arc::R<MixMut>> {
26 unsafe { std::mem::transmute(self.copy_with_zone_mut(std::ptr::null_mut())) }
27 }
28
29 #[objc::msg_send(inputParameters)]
30 pub fn input_params(&self) -> arc::R<ns::Array<InputParams>>;
31}
32
33define_obj_type!(
34 #[doc(alias = "AVMutableAudioMix")]
35 pub MixMut(Mix),
36 AV_MUTABLE_AUDIO_MIX
37);
38
39impl MixMut {
40 #[objc::msg_send(setInputParameters:)]
41 pub fn set_input_params(&mut self, val: &ns::Array<InputParams>);
42
43 #[objc::msg_send(setInputParameters:)]
44 pub fn set_input_params_mut(&mut self, val: &ns::Array<InputParamsMut>);
45}
46
47define_obj_type!(
48 #[doc(alias = "AVAudioMixInputParameters")]
49 pub InputParams(ns::Id),
50 AV_AUDIO_MIX_INPUT_PARAMETERS
51);
52
53impl ns::Copying for InputParams {}
54impl ns::CopyingMut for InputParams {}
55
56impl InputParams {
57 pub fn copy(&self) -> Option<arc::R<InputParams>> {
58 unsafe { std::mem::transmute(self.copy_with_zone(std::ptr::null_mut())) }
59 }
60
61 pub fn copy_mut(&self) -> Option<arc::R<InputParamsMut>> {
62 unsafe { std::mem::transmute(self.copy_with_zone_mut(std::ptr::null_mut())) }
63 }
64
65 #[objc::msg_send(trackID)]
67 pub fn track_id(&self) -> cm::PersistentTrackId;
68
69 #[objc::msg_send(audioTimePitchAlgorithm)]
70 pub fn time_pitch_algorithm(&self) -> Option<arc::R<av::AudioTimePitchAlgorithm>>;
71
72 #[cfg(all(feature = "mt", not(target_os = "watchos")))]
73 #[objc::msg_send(audioTapProcessor)]
74 pub fn tap(&self) -> Option<&mt::AudioProcessingTap>;
75
76 #[objc::msg_send(getVolumeRampForTime:startVolume:endVolume:timeRange:)]
77 pub fn volume_ramp_for_time(
78 &self,
79 time: cm::Time,
80 start_volume: *mut f32,
81 end_volume: *mut f32,
82 time_range: *mut cm::TimeRange,
83 ) -> bool;
84}
85
86define_obj_type!(
87 #[doc(alias = "AVMutableAudioMixInputParameters")]
88 pub InputParamsMut(InputParams),
89 AV_MUTABLE_AUDIO_MIX_INPUT_PARAMETERS
90);
91
92impl InputParamsMut {
93 #[objc::msg_send(audioMixInputParametersWithTrack:)]
94 pub fn with_track(track: Option<&av::AssetTrack>) -> arc::R<Self>;
95
96 #[objc::msg_send(setTrackID:)]
97 pub fn set_track_id(&mut self, val: cm::PersistentTrackId);
98
99 #[objc::msg_send(setAudioTimePitchAlgorithm:)]
100 pub fn set_time_pitch_algorithm(&mut self, val: Option<&av::AudioTimePitchAlgorithm>);
101
102 #[cfg(all(feature = "mt", not(target_os = "watchos")))]
103 #[objc::msg_send(setAudioTapProcessor:)]
104 pub fn set_tap(&mut self, val: Option<&mt::AudioProcessingTap>);
105
106 #[objc::msg_send(setVolumeRampFromStartVolume:toEndVolume:timeRange:)]
107 pub unsafe fn set_volume_ramp_throws(
108 &mut self,
109 start_volume: f32,
110 end_volume: f32,
111 time_range: cm::TimeRange,
112 );
113
114 pub fn set_volume_ramp<'ear>(
115 &mut self,
116 start_volume: f32,
117 end_volume: f32,
118 time_range: cm::TimeRange,
119 ) -> ns::ExResult<'ear> {
120 unsafe {
121 ns::try_catch(|| self.set_volume_ramp_throws(start_volume, end_volume, time_range))
122 }
123 }
124
125 #[objc::msg_send(setVolume:atTime:)]
126 pub unsafe fn set_volume_at_time_throws(&mut self, volume: f32, time: cm::Time);
127
128 pub fn set_volume_at_time<'ear>(&mut self, volume: f32, time: cm::Time) -> ns::ExResult<'ear> {
129 unsafe { ns::try_catch(|| self.set_volume_at_time_throws(volume, time)) }
130 }
131}
132
133unsafe extern "C" {
134 static AV_AUDIO_MIX: &'static objc::Class<Mix>;
135 static AV_MUTABLE_AUDIO_MIX: &'static objc::Class<MixMut>;
136 static AV_AUDIO_MIX_INPUT_PARAMETERS: &'static objc::Class<InputParams>;
137 static AV_MUTABLE_AUDIO_MIX_INPUT_PARAMETERS: &'static objc::Class<InputParamsMut>;
138}
139
140#[cfg(test)]
141mod tests {
142 use crate::av;
143
144 #[test]
145 fn basics() {
146 let mix = av::AudioMix::new();
147 let _copy = mix.copy().unwrap();
148 let _mut_copy = mix.copy_mut().unwrap();
149 }
150}