Skip to main content

cidre/av/audio/
mix.rs

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    /// Allows custom audio processing to be performed on audio tracks during playback or other operations.
12    #[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    /// Indicates the track id of the audio track to which the parameters should be applied.
66    #[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}