set max audio buffer to 150ms, clear audio buffer if full (#8947)

The device should have the capability to play a sufficient audio buffer during each period to meet the audio config, so the playback speed is not slow.

The audio delay is caused by network jitter. The controlled  side sends audio data every 10ms, but it often happens that multiple packets are sent together. During underrun periods, the controlling side plays extra silence data instead, resulting in the device playing more audio than the configured amount.
This commit is contained in:
21pages 2024-08-04 16:11:00 +08:00 committed by GitHub
parent 0d1d7a9b87
commit b6ba9978e3
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -113,6 +113,9 @@ pub const SCRAP_OTHER_VERSION_OR_X11_REQUIRED: &str =
pub const SCRAP_X11_REQUIRED: &str = "x11 expected";
pub const SCRAP_X11_REF_URL: &str = "https://rustdesk.com/docs/en/manual/linux/#x11-required";
#[cfg(not(any(target_os = "android", target_os = "linux")))]
pub const AUDIO_BUFFER_MS: usize = 150;
#[cfg(feature = "flutter")]
#[cfg(not(any(target_os = "android", target_os = "ios")))]
pub(crate) struct ClientClipboardContext;
@ -903,11 +906,33 @@ struct AudioBuffer(pub Arc<std::sync::Mutex<ringbuf::HeapRb<f32>>>);
impl Default for AudioBuffer {
fn default() -> Self {
Self(Arc::new(std::sync::Mutex::new(
ringbuf::HeapRb::<f32>::new(48000 * 2), // 48000hz, 2 channel, 1 second
ringbuf::HeapRb::<f32>::new(48000 * 2 * AUDIO_BUFFER_MS / 1000), // 48000hz, 2 channel
)))
}
}
#[cfg(not(any(target_os = "android", target_os = "linux")))]
impl AudioBuffer {
pub fn resize(&self, sample_rate: usize, channels: usize) {
let capacity = sample_rate * channels * AUDIO_BUFFER_MS / 1000;
let old_capacity = self.0.lock().unwrap().capacity();
if capacity != old_capacity {
*self.0.lock().unwrap() = ringbuf::HeapRb::<f32>::new(capacity);
log::info!("Audio buffer resized from {old_capacity} to {capacity}");
}
}
// clear when full to avoid long time noise
#[inline]
pub fn clear_if_full(&self) {
let full = self.0.lock().unwrap().is_full();
if full {
self.0.lock().unwrap().clear();
log::info!("Audio buffer cleared");
}
}
}
impl AudioHandler {
/// Start the audio playback.
#[cfg(target_os = "linux")]
@ -1052,6 +1077,7 @@ impl AudioHandler {
self.device_channel,
);
}
self.audio_buffer.clear_if_full();
audio_buffer.lock().unwrap().push_slice_overwrite(&buffer);
}
#[cfg(target_os = "android")]
@ -1080,6 +1106,8 @@ impl AudioHandler {
// too many errors, will improve later
log::trace!("an error occurred on stream: {}", err);
};
self.audio_buffer
.resize(config.sample_rate.0 as _, config.channels as _);
let audio_buffer = self.audio_buffer.0.clone();
let ready = self.ready.clone();
let timeout = None;