Skip to main content

webrtc_sys/
audio_mixer.rs

1// Copyright 2025 LiveKit, Inc.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15use 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);