fix: different audio frame size than 10ms (#72)

This commit is contained in:
Théo Monnom
2023-05-16 08:42:40 +02:00
committed by GitHub
parent 3998dd4a49
commit 97dde044b5
2 changed files with 64 additions and 11 deletions
+8 -3
View File
@@ -12,6 +12,7 @@ struct FrameData {
pub sample_rate: u32,
pub freq: f64,
pub amplitude: f64,
pub phase: u64,
}
impl Default for FrameData {
@@ -20,6 +21,7 @@ impl Default for FrameData {
sample_rate: 48000,
freq: 440.0,
amplitude: 1.0,
phase: 0,
}
}
}
@@ -98,7 +100,7 @@ impl SineTrack {
loop {
interval.tick().await;
let data = frame_options.lock();
let mut data = frame_options.lock();
let samples_count_10ms = (data.sample_rate / 100) as usize;
if samples_10ms.capacity() != samples_count_10ms {
@@ -108,10 +110,13 @@ impl SineTrack {
for i in 0..samples_count_10ms {
let val = data.amplitude
* f64::sin(
std::f64::consts::PI * 2.0 * data.freq * i as f64
/ samples_count_10ms as f64,
std::f64::consts::PI
* 2.0
* data.freq
* (data.phase as f64 / data.sample_rate as f64),
);
data.phase += 1;
// WebRTC uses 16-bit signed PCM
samples_10ms[i] = (val * 32768.0) as i16;
}
+56 -8
View File
@@ -1,16 +1,27 @@
use crate::audio_frame::AudioFrame;
use cxx::SharedPtr;
use std::sync::{Arc, Mutex};
use webrtc_sys::media_stream as sys_ms;
#[derive(Clone)]
pub struct NativeAudioSource {
sys_handle: SharedPtr<sys_ms::ffi::AudioTrackSource>,
inner: Arc<Mutex<AudioSourceInner>>,
}
#[derive(Default)]
struct AudioSourceInner {
buf: Vec<i16>,
offset: usize,
sample_rate: u32,
num_channels: u32,
}
impl Default for NativeAudioSource {
fn default() -> Self {
Self {
sys_handle: sys_ms::ffi::new_audio_track_source(),
inner: Default::default(),
}
}
}
@@ -21,14 +32,51 @@ impl NativeAudioSource {
}
pub fn capture_frame(&self, frame: &AudioFrame) {
// TODO(theomonnom): Should we check for 10ms worth of data here?
unsafe {
self.sys_handle.on_captured_frame(
frame.data.as_ptr(),
frame.sample_rate as i32,
frame.num_channels as usize,
frame.samples_per_channel as usize,
)
let mut inner = self.inner.lock().unwrap();
let samples_10ms = (frame.sample_rate / 100 * frame.num_channels) as usize;
if inner.sample_rate != frame.sample_rate || inner.num_channels != frame.num_channels {
inner.buf.resize(samples_10ms as usize, 0);
inner.offset = 0;
}
// Split the frame into 10ms chunks
let mut i = 0;
loop {
let buf_offset = inner.offset;
let remaining_data = frame.data.len() - i; // Remaining data to read inside the frame
let needed_data = samples_10ms - buf_offset; // Needed data of "frame.data" to make a complete 10ms from inner.buf
if remaining_data < needed_data {
if remaining_data > 0 {
// Not enough data to make a complete 10ms frame, store the remaining data inside inner.buf
// It'll be used on the next capture.
inner.buf[buf_offset..buf_offset + remaining_data]
.copy_from_slice(&frame.data[i..]);
inner.offset += remaining_data;
}
break;
}
let data = if inner.offset != 0 {
// Use the data from the previous capture
let data = &mut inner.buf[buf_offset..];
data.copy_from_slice(&frame.data[i..i + needed_data]);
inner.offset = 0;
&inner.buf
} else {
&frame.data[i..i + samples_10ms]
};
unsafe {
self.sys_handle.on_captured_frame(
data.as_ptr(),
frame.sample_rate as i32,
frame.num_channels as usize,
samples_10ms,
)
}
i += needed_data;
}
}
}