webrtc_sys/
audio_mixer.rs1use std::{pin::Pin, sync::Arc};
16
17use ffi::AudioFrameInfo;
18
19use crate::impl_thread_safety;
20
21#[cxx::bridge(namespace = "livekit_ffi")]
22pub mod ffi {
23 unsafe extern "C++" {
24 include!("livekit/audio_mixer.h");
25
26 type AudioMixer;
27
28 unsafe fn add_source(self: Pin<&mut AudioMixer>, src: Box<AudioMixerSourceWrapper>);
29
30 unsafe fn remove_source(self: Pin<&mut AudioMixer>, ssrc: i32);
31
32 unsafe fn mix(self: Pin<&mut AudioMixer>, num_channels: usize) -> usize;
33
34 unsafe fn data(self: &AudioMixer) -> *const i16;
35
36 fn create_audio_mixer() -> UniquePtr<AudioMixer>;
37
38 type NativeAudioFrame;
39
40 unsafe fn update_frame(
41 self: Pin<&mut NativeAudioFrame>,
42 timestamp: u32,
43 data: *const i16,
44 samples_per_channel: usize,
45 sample_rate_hz: i32,
46 num_channels: usize,
47 );
48 }
49
50 pub enum AudioFrameInfo {
51 Normal,
52 Muted,
53 Error,
54 }
55
56 extern "Rust" {
57 type AudioMixerSourceWrapper;
58
59 fn ssrc(self: &AudioMixerSourceWrapper) -> i32;
60 fn preferred_sample_rate(self: &AudioMixerSourceWrapper) -> i32;
61 fn get_audio_frame_with_info(
62 self: &AudioMixerSourceWrapper,
63 target_sample_rate: i32,
64 frame: Pin<&mut NativeAudioFrame>,
65 ) -> AudioFrameInfo;
66 }
67}
68
69pub trait AudioMixerSource {
70 fn ssrc(&self) -> i32;
71 fn preferred_sample_rate(&self) -> i32;
72 fn get_audio_frame_with_info(
73 &self,
74 target_sample_rate: i32,
75 frame: NativeAudioFrame,
76 ) -> AudioFrameInfo;
77}
78
79pub struct AudioMixerSourceWrapper {
80 source: Arc<dyn AudioMixerSource>,
81}
82
83pub type NativeAudioFrame<'a> = Pin<&'a mut ffi::NativeAudioFrame>;
84
85impl AudioMixerSourceWrapper {
86 pub fn new(source: Arc<dyn AudioMixerSource>) -> Self {
87 Self { source }
88 }
89
90 pub fn ssrc(&self) -> i32 {
91 self.source.ssrc()
92 }
93 pub fn preferred_sample_rate(&self) -> i32 {
94 self.source.preferred_sample_rate()
95 }
96
97 pub fn get_audio_frame_with_info(
98 &self,
99 target_sample_rate: i32,
100 frame: Pin<&mut ffi::NativeAudioFrame>,
101 ) -> AudioFrameInfo {
102 self.source.get_audio_frame_with_info(target_sample_rate, frame)
103 }
104}
105
106impl_thread_safety!(ffi::AudioMixer, Send + Sync);