diff --git a/Cargo.lock b/Cargo.lock index 6fdb513e4..29c4ea8b9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4814,6 +4814,15 @@ dependencies = [ "winapi 0.3.9", ] +[[package]] +name = "ringbuf" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93ca10b9c9e53ac855a2d6953bce34cef6edbac32c4b13047a4d59d67299420a" +dependencies = [ + "crossbeam-utils", +] + [[package]] name = "rpassword" version = "2.1.0" @@ -4972,6 +4981,7 @@ dependencies = [ "rdev", "repng", "reqwest", + "ringbuf", "rpassword 7.2.0", "rubato", "runas", @@ -6773,12 +6783,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" dependencies = [ "windows_aarch64_gnullvm", - "windows_aarch64_msvc 0.42.1", - "windows_i686_gnu 0.42.1", - "windows_i686_msvc 0.42.1", - "windows_x86_64_gnu 0.42.1", + "windows_aarch64_msvc 0.42.2", + "windows_i686_gnu 0.42.2", + "windows_i686_msvc 0.42.2", + "windows_x86_64_gnu 0.42.2", "windows_x86_64_gnullvm", - "windows_x86_64_msvc 0.42.1", + "windows_x86_64_msvc 0.42.2", ] [[package]] @@ -6792,24 +6802,24 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.42.1" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e2522491fbfcd58cc84d47aeb2958948c4b8982e9a2d8a2a35bbaed431390e7" +checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" dependencies = [ "windows_aarch64_gnullvm", - "windows_aarch64_msvc 0.42.1", - "windows_i686_gnu 0.42.1", - "windows_i686_msvc 0.42.1", - "windows_x86_64_gnu 0.42.1", + "windows_aarch64_msvc 0.42.2", + "windows_i686_gnu 0.42.2", + "windows_i686_msvc 0.42.2", + "windows_x86_64_gnu 0.42.2", "windows_x86_64_gnullvm", - "windows_x86_64_msvc 0.42.1", + "windows_x86_64_msvc 0.42.2", ] [[package]] name = "windows_aarch64_gnullvm" -version = "0.42.1" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c9864e83243fdec7fc9c5444389dcbbfd258f745e7853198f365e3c4968a608" +checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" [[package]] name = "windows_aarch64_msvc" @@ -6837,9 +6847,9 @@ checksum = "2623277cb2d1c216ba3b578c0f3cf9cdebeddb6e66b1b218bb33596ea7769c3a" [[package]] name = "windows_aarch64_msvc" -version = "0.42.1" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c8b1b673ffc16c47a9ff48570a9d85e25d265735c503681332589af6253c6c7" +checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" [[package]] name = "windows_i686_gnu" @@ -6867,9 +6877,9 @@ checksum = "d3925fd0b0b804730d44d4b6278c50f9699703ec49bcd628020f46f4ba07d9e1" [[package]] name = "windows_i686_gnu" -version = "0.42.1" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de3887528ad530ba7bdbb1faa8275ec7a1155a45ffa57c37993960277145d640" +checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" [[package]] name = "windows_i686_msvc" @@ -6897,9 +6907,9 @@ checksum = "ce907ac74fe331b524c1298683efbf598bb031bc84d5e274db2083696d07c57c" [[package]] name = "windows_i686_msvc" -version = "0.42.1" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf4d1122317eddd6ff351aa852118a2418ad4214e6613a50e0191f7004372605" +checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" [[package]] name = "windows_x86_64_gnu" @@ -6927,15 +6937,15 @@ checksum = "2babfba0828f2e6b32457d5341427dcbb577ceef556273229959ac23a10af33d" [[package]] name = "windows_x86_64_gnu" -version = "0.42.1" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1040f221285e17ebccbc2591ffdc2d44ee1f9186324dd3e84e99ac68d699c45" +checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" [[package]] name = "windows_x86_64_gnullvm" -version = "0.42.1" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "628bfdf232daa22b0d64fdb62b09fcc36bb01f05a3939e20ab73aaf9470d0463" +checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" [[package]] name = "windows_x86_64_msvc" @@ -6963,9 +6973,9 @@ checksum = "f4dd6dc7df2d84cf7b33822ed5b86318fb1781948e9663bacd047fc9dd52259d" [[package]] name = "windows_x86_64_msvc" -version = "0.42.1" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "447660ad36a13288b1db4d4248e857b510e8c3a225c822ba4fb748c0aafecffd" +checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" [[package]] name = "winit" diff --git a/Cargo.toml b/Cargo.toml index bf81664e5..990ccb352 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -72,6 +72,7 @@ cidr-utils = "0.5.9" [target.'cfg(not(any(target_os = "android", target_os = "linux")))'.dependencies] cpal = "0.14" +ringbuf = "0.3" [target.'cfg(not(any(target_os = "android", target_os = "ios")))'.dependencies] machine-uid = "0.2" diff --git a/src/client.rs b/src/client.rs index 1ad996165..1efd8b18e 100644 --- a/src/client.rs +++ b/src/client.rs @@ -14,6 +14,8 @@ use cpal::{ Device, Host, StreamConfig, }; use magnum_opus::{Channels::*, Decoder as AudioDecoder}; +#[cfg(not(any(target_os = "android", target_os = "linux")))] +use ringbuf::{ring_buffer::RbBase, Rb}; use sha2::{Digest, Sha256}; use uuid::Uuid; @@ -701,7 +703,7 @@ pub struct AudioHandler { #[cfg(target_os = "linux")] simple: Option, #[cfg(not(any(target_os = "android", target_os = "linux")))] - audio_buffer: Arc>>, + audio_buffer: AudioBuffer, sample_rate: (u32, u32), #[cfg(not(any(target_os = "android", target_os = "linux")))] audio_stream: Option>, @@ -710,6 +712,18 @@ pub struct AudioHandler { ready: Arc>, } +#[cfg(not(any(target_os = "android", target_os = "linux")))] +struct AudioBuffer(pub Arc>>); + +#[cfg(not(any(target_os = "android", target_os = "linux")))] +impl Default for AudioBuffer { + fn default() -> Self { + Self(Arc::new(std::sync::Mutex::new( + ringbuf::HeapRb::::new(48000 * 2), // 48000hz, 2 channel, 1 second + ))) + } +} + impl AudioHandler { /// Start the audio playback. #[cfg(target_os = "linux")] @@ -816,11 +830,7 @@ impl AudioHandler { { let sample_rate0 = self.sample_rate.0; let sample_rate = self.sample_rate.1; - let audio_buffer = self.audio_buffer.clone(); - // avoiding memory overflow if audio_buffer consumer side has problem - if audio_buffer.lock().unwrap().len() as u32 > sample_rate * 120 { - *audio_buffer.lock().unwrap() = Default::default(); - } + let audio_buffer = self.audio_buffer.0.clone(); if sample_rate != sample_rate0 { let buffer = crate::resample_channels( &buffer[0..n], @@ -828,12 +838,12 @@ impl AudioHandler { sample_rate, channels, ); - audio_buffer.lock().unwrap().extend(buffer); + audio_buffer.lock().unwrap().push_slice_overwrite(&buffer); } else { audio_buffer .lock() .unwrap() - .extend(buffer[0..n].iter().cloned()); + .push_slice_overwrite(&buffer[0..n]); } } #[cfg(target_os = "android")] @@ -861,7 +871,7 @@ impl AudioHandler { // too many errors, will improve later log::trace!("an error occurred on stream: {}", err); }; - let audio_buffer = self.audio_buffer.clone(); + let audio_buffer = self.audio_buffer.0.clone(); let ready = self.ready.clone(); let stream = device.build_output_stream( config, @@ -871,10 +881,13 @@ impl AudioHandler { } let mut lock = audio_buffer.lock().unwrap(); let mut n = data.len(); - if lock.len() < n { - n = lock.len(); + if lock.occupied_len() < n { + n = lock.occupied_len(); } - let mut input = lock.drain(0..n); + let mut elems = vec![0.0f32; n]; + lock.pop_slice(&mut elems); + drop(lock); + let mut input = elems.into_iter(); for sample in data.iter_mut() { *sample = match input.next() { Some(x) => T::from(&x),