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:
parent
0d1d7a9b87
commit
b6ba9978e3
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user