diff --git a/Cargo.lock b/Cargo.lock index 5e14f72bb..505a6f2d6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -65,14 +65,14 @@ dependencies = [ [[package]] name = "alsa" -version = "0.6.0" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5915f52fe2cf65e83924d037b6c5290b7cee097c6b5c8700746e6168a343fd6b" +checksum = "8512c9117059663fb5606788fbca3619e2a91dac0e3fe516242eab1fa6be5e44" dependencies = [ "alsa-sys", "bitflags", "libc", - "nix 0.23.2", + "nix 0.24.3", ] [[package]] @@ -401,12 +401,6 @@ dependencies = [ "rustc-demangle", ] -[[package]] -name = "base-x" -version = "0.2.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4cbbc9d0964165b47557570cce6c952866c2678457aca742aafc9fb771d30270" - [[package]] name = "base64" version = "0.21.0" @@ -626,7 +620,7 @@ checksum = "4acbb09d9ee8e23699b9634375c72795d095bf268439da88562cf9b501f181fa" dependencies = [ "camino", "cargo-platform", - "semver 1.0.17", + "semver", "serde 1.0.159", "serde_json 1.0.95", ] @@ -995,6 +989,12 @@ dependencies = [ "libc", ] +[[package]] +name = "core-foundation-sys" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7ca8a5221364ef15ce201e8ed2f609fc312682a8f4e0e3d4aa5879764e0fa3b" + [[package]] name = "core-foundation-sys" version = "0.7.0" @@ -1059,11 +1059,12 @@ dependencies = [ [[package]] name = "coreaudio-rs" -version = "0.10.0" +version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11894b20ebfe1ff903cbdc52259693389eea03b94918a2def2c30c3bf227ad88" +checksum = "cb17e2d1795b1996419648915df94bc7103c28f7b48062d7acf4652fc371b2ff" dependencies = [ "bitflags", + "core-foundation-sys 0.6.2", "coreaudio-sys", ] @@ -1078,26 +1079,27 @@ dependencies = [ [[package]] name = "cpal" -version = "0.14.2" +version = "0.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f342c1b63e185e9953584ff2199726bf53850d96610a310e3aca09e9405a2d0b" +checksum = "6d959d90e938c5493000514b446987c07aed46c668faaa7d34d6c7a67b1a578c" dependencies = [ "alsa", "core-foundation-sys 0.8.3", "coreaudio-rs", + "dasp_sample", "jni 0.19.0", "js-sys", "libc", - "mach", + "mach2", "ndk 0.7.0", "ndk-context", "oboe", "once_cell", "parking_lot 0.12.1", - "stdweb", - "thiserror", + "wasm-bindgen", + "wasm-bindgen-futures", "web-sys", - "windows 0.37.0", + "windows 0.46.0", ] [[package]] @@ -1575,12 +1577,6 @@ dependencies = [ "winapi 0.3.9", ] -[[package]] -name = "discard" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "212d0f5754cb6769937f4501cc0e67f4f4483c8d2c3e1e922ee9edbe4ab4c7c0" - [[package]] name = "dispatch" version = "0.2.0" @@ -1706,7 +1702,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e62abb876c07e4754fae5c14cafa77937841f01740637e17d78dc04352f32a5e" dependencies = [ "cc", - "rustc_version 0.4.0", + "rustc_version", "toml 0.5.11", "vswhom", "winreg 0.10.1", @@ -1961,7 +1957,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a3cf3a800ff6e860c863ca6d4b16fd999db8b752819c1606884047b73e468535" dependencies = [ "memoffset 0.8.0", - "rustc_version 0.4.0", + "rustc_version", ] [[package]] @@ -3444,10 +3440,10 @@ dependencies = [ ] [[package]] -name = "mach" -version = "0.3.2" +name = "mach2" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b823e83b2affd8f40a9ee8c29dbc56404c1e34cd2710921f2801e2cf29527afa" +checksum = "6d0d1830bcd151a6fc4aea1369af235b36c1528fe976b8ff678683c9995eade8" dependencies = [ "libc", ] @@ -4071,12 +4067,12 @@ dependencies = [ [[package]] name = "oboe" -version = "0.4.6" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "27f63c358b4fa0fbcfefd7c8be5cfc39c08ce2389f5325687e7762a48d30a5c1" +checksum = "8868cc237ee02e2d9618539a23a8d228b9bb3fc2e7a5b11eed3831de77c395d0" dependencies = [ - "jni 0.19.0", - "ndk 0.6.0", + "jni 0.20.0", + "ndk 0.7.0", "ndk-context", "num-derive", "num-traits 0.2.15", @@ -4085,9 +4081,9 @@ dependencies = [ [[package]] name = "oboe-sys" -version = "0.4.5" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3370abb7372ed744232c12954d920d1a40f1c4686de9e79e800021ef492294bd" +checksum = "7f44155e7fb718d3cfddcf70690b2b51ac4412f347cd9e4fbe511abe9cd7b5f2" dependencies = [ "cc", ] @@ -5085,22 +5081,13 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" -[[package]] -name = "rustc_version" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" -dependencies = [ - "semver 0.9.0", -] - [[package]] name = "rustc_version" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" dependencies = [ - "semver 1.0.17", + "semver", ] [[package]] @@ -5404,15 +5391,6 @@ dependencies = [ "libc", ] -[[package]] -name = "semver" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" -dependencies = [ - "semver-parser", -] - [[package]] name = "semver" version = "1.0.17" @@ -5422,12 +5400,6 @@ dependencies = [ "serde 1.0.159", ] -[[package]] -name = "semver-parser" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" - [[package]] name = "serde" version = "0.9.15" @@ -5521,15 +5493,6 @@ dependencies = [ "yaml-rust", ] -[[package]] -name = "sha1" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1da05c97445caa12d05e848c4a4fcbbea29e748ac28f7e80e9b010392063770" -dependencies = [ - "sha1_smol", -] - [[package]] name = "sha1" version = "0.10.5" @@ -5541,12 +5504,6 @@ dependencies = [ "digest", ] -[[package]] -name = "sha1_smol" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae1a47186c03a32177042e55dbc5fd5aee900b8e0069a8d70fba96a9375cd012" - [[package]] name = "sha2" version = "0.10.6" @@ -5719,55 +5676,6 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" -[[package]] -name = "stdweb" -version = "0.4.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d022496b16281348b52d0e30ae99e01a73d737b2f45d38fed4edf79f9325a1d5" -dependencies = [ - "discard", - "rustc_version 0.2.3", - "stdweb-derive", - "stdweb-internal-macros", - "stdweb-internal-runtime", - "wasm-bindgen", -] - -[[package]] -name = "stdweb-derive" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c87a60a40fccc84bef0652345bbbbbe20a605bf5d0ce81719fc476f5c03b50ef" -dependencies = [ - "proc-macro2 1.0.54", - "quote 1.0.26", - "serde 1.0.159", - "serde_derive", - "syn 1.0.109", -] - -[[package]] -name = "stdweb-internal-macros" -version = "0.2.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58fa5ff6ad0d98d1ffa8cb115892b6e69d67799f6763e162a1c9db421dc22e11" -dependencies = [ - "base-x", - "proc-macro2 1.0.54", - "quote 1.0.26", - "serde 1.0.159", - "serde_derive", - "serde_json 1.0.95", - "sha1 0.6.1", - "syn 1.0.109", -] - -[[package]] -name = "stdweb-internal-runtime" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "213701ba3370744dcd1a12960caa4843b3d68b4d1c0a5d575e0d65b2ee9d16c0" - [[package]] name = "str-buf" version = "1.0.6" @@ -6916,19 +6824,6 @@ dependencies = [ "windows_x86_64_msvc 0.34.0", ] -[[package]] -name = "windows" -version = "0.37.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57b543186b344cc61c85b5aab0d2e3adf4e0f99bc076eff9aa5927bcc0b8a647" -dependencies = [ - "windows_aarch64_msvc 0.37.0", - "windows_i686_gnu 0.37.0", - "windows_i686_msvc 0.37.0", - "windows_x86_64_gnu 0.37.0", - "windows_x86_64_msvc 0.37.0", -] - [[package]] name = "windows" version = "0.44.0" @@ -7059,12 +6954,6 @@ version = "0.34.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "17cffbe740121affb56fad0fc0e421804adf0ae00891205213b5cecd30db881d" -[[package]] -name = "windows_aarch64_msvc" -version = "0.37.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2623277cb2d1c216ba3b578c0f3cf9cdebeddb6e66b1b218bb33596ea7769c3a" - [[package]] name = "windows_aarch64_msvc" version = "0.42.2" @@ -7089,12 +6978,6 @@ version = "0.34.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2564fde759adb79129d9b4f54be42b32c89970c18ebf93124ca8870a498688ed" -[[package]] -name = "windows_i686_gnu" -version = "0.37.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3925fd0b0b804730d44d4b6278c50f9699703ec49bcd628020f46f4ba07d9e1" - [[package]] name = "windows_i686_gnu" version = "0.42.2" @@ -7119,12 +7002,6 @@ version = "0.34.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9cd9d32ba70453522332c14d38814bceeb747d80b3958676007acadd7e166956" -[[package]] -name = "windows_i686_msvc" -version = "0.37.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce907ac74fe331b524c1298683efbf598bb031bc84d5e274db2083696d07c57c" - [[package]] name = "windows_i686_msvc" version = "0.42.2" @@ -7149,12 +7026,6 @@ version = "0.34.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cfce6deae227ee8d356d19effc141a509cc503dfd1f850622ec4b0f84428e1f4" -[[package]] -name = "windows_x86_64_gnu" -version = "0.37.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2babfba0828f2e6b32457d5341427dcbb577ceef556273229959ac23a10af33d" - [[package]] name = "windows_x86_64_gnu" version = "0.42.2" @@ -7185,12 +7056,6 @@ version = "0.34.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d19538ccc21819d01deaf88d6a17eae6596a12e9aafdbb97916fb49896d89de9" -[[package]] -name = "windows_x86_64_msvc" -version = "0.37.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4dd6dc7df2d84cf7b33822ed5b86318fb1781948e9663bacd047fc9dd52259d" - [[package]] name = "windows_x86_64_msvc" version = "0.42.2" @@ -7396,7 +7261,7 @@ dependencies = [ "rand 0.8.5", "serde 1.0.159", "serde_repr", - "sha1 0.10.5", + "sha1", "static_assertions", "tracing", "uds_windows", diff --git a/Cargo.toml b/Cargo.toml index b8c4f59f0..3579501c7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -73,7 +73,7 @@ cidr-utils = "0.5" libloading = "0.7" [target.'cfg(not(any(target_os = "android", target_os = "linux")))'.dependencies] -cpal = "0.14" +cpal = "0.15" ringbuf = "0.3" [target.'cfg(not(any(target_os = "android", target_os = "ios")))'.dependencies] diff --git a/src/client.rs b/src/client.rs index 335fded0b..d889e86cd 100644 --- a/src/client.rs +++ b/src/client.rs @@ -644,7 +644,7 @@ impl Client { // `try_start_clipboard` is called by all session when connection is established. (When handling peer info). // This function only create one thread with a loop, the loop is shared by all sessions. // After all sessions are end, the loop exists. - // + // // If clipboard update is detected, the text will be sent to all sessions by `send_text_clipboard_msg`. #[cfg(not(any(target_os = "android", target_os = "ios")))] fn try_start_clipboard(_ctx: Option) { @@ -801,9 +801,17 @@ impl AudioHandler { let mut config: StreamConfig = config.into(); config.channels = format0.channels as _; match sample_format { - cpal::SampleFormat::F32 => self.build_output_stream::(&config, &device)?, + cpal::SampleFormat::I8 => self.build_output_stream::(&config, &device)?, cpal::SampleFormat::I16 => self.build_output_stream::(&config, &device)?, + cpal::SampleFormat::I32 => self.build_output_stream::(&config, &device)?, + cpal::SampleFormat::I64 => self.build_output_stream::(&config, &device)?, + cpal::SampleFormat::U8 => self.build_output_stream::(&config, &device)?, cpal::SampleFormat::U16 => self.build_output_stream::(&config, &device)?, + cpal::SampleFormat::U32 => self.build_output_stream::(&config, &device)?, + cpal::SampleFormat::U64 => self.build_output_stream::(&config, &device)?, + cpal::SampleFormat::F32 => self.build_output_stream::(&config, &device)?, + cpal::SampleFormat::F64 => self.build_output_stream::(&config, &device)?, + f => bail!("unsupported audio format: {:?}", f), } self.sample_rate = (format0.sample_rate, config.sample_rate.0); Ok(()) @@ -880,7 +888,7 @@ impl AudioHandler { /// Build audio output stream for current device. #[cfg(not(any(target_os = "android", target_os = "linux")))] - fn build_output_stream( + fn build_output_stream>( &mut self, config: &StreamConfig, device: &Device, @@ -891,6 +899,7 @@ impl AudioHandler { }; let audio_buffer = self.audio_buffer.0.clone(); let ready = self.ready.clone(); + let timeout = None; let stream = device.build_output_stream( config, move |data: &mut [T], _: &_| { @@ -908,12 +917,13 @@ impl AudioHandler { let mut input = elems.into_iter(); for sample in data.iter_mut() { *sample = match input.next() { - Some(x) => T::from(&x), - _ => T::from(&0.), + Some(x) => T::from_sample(x), + _ => T::from_sample(0.), }; } }, err_fn, + timeout, )?; stream.play()?; self.audio_stream = Some(Box::new(stream)); diff --git a/src/server/audio_service.rs b/src/server/audio_service.rs index d05b349e8..c2b1d80f9 100644 --- a/src/server/audio_service.rs +++ b/src/server/audio_service.rs @@ -104,7 +104,7 @@ mod cpal_impl { use super::*; use cpal::{ traits::{DeviceTrait, HostTrait, StreamTrait}, - Device, Host, SupportedStreamConfig, + BufferSize, Device, Host, InputCallbackInfo, StreamConfig, SupportedStreamConfig, }; lazy_static::lazy_static! { @@ -214,12 +214,9 @@ mod cpal_impl { } fn play(sp: &GenericService) -> ResultType<(Box, Arc)> { + use cpal::SampleFormat::*; let (device, config) = get_device()?; let sp = sp.clone(); - let err_fn = move |err| { - // too many UnknownErrno, will improve later - log::trace!("an error occurred on stream: {}", err); - }; // Sample rate must be one of 8000, 12000, 16000, 24000, or 48000. let sample_rate_0 = config.sample_rate().0; let sample_rate = if sample_rate_0 < 12000 { @@ -233,6 +230,40 @@ mod cpal_impl { } else { 48000 }; + let stream = match config.sample_format() { + I8 => build_input_stream::(device, &config, sp, sample_rate)?, + I16 => build_input_stream::(device, &config, sp, sample_rate)?, + I32 => build_input_stream::(device, &config, sp, sample_rate)?, + I64 => build_input_stream::(device, &config, sp, sample_rate)?, + U8 => build_input_stream::(device, &config, sp, sample_rate)?, + U16 => build_input_stream::(device, &config, sp, sample_rate)?, + U32 => build_input_stream::(device, &config, sp, sample_rate)?, + U64 => build_input_stream::(device, &config, sp, sample_rate)?, + F32 => build_input_stream::(device, &config, sp, sample_rate)?, + F64 => build_input_stream::(device, &config, sp, sample_rate)?, + f => bail!("unsupported audio format: {:?}", f), + }; + stream.play()?; + Ok(( + Box::new(stream), + Arc::new(create_format_msg(sample_rate, config.channels())), + )) + } + + fn build_input_stream( + device: cpal::Device, + config: &cpal::SupportedStreamConfig, + sp: GenericService, + sample_rate: u32, + ) -> ResultType + where + T: cpal::SizedSample + dasp::sample::ToSample, + { + let err_fn = move |err| { + // too many UnknownErrno, will improve later + log::trace!("an error occurred on stream: {}", err); + }; + let sample_rate_0 = config.sample_rate().0; log::debug!("Audio sample rate : {}", sample_rate); unsafe { AUDIO_ZERO_COUNT = 0; @@ -247,54 +278,34 @@ mod cpal_impl { // https://chromium.googlesource.com/chromium/deps/opus/+/1.1.1/include/opus.h let encode_len = sample_rate as usize * channels as usize / 100; // 10 ms INPUT_BUFFER.lock().unwrap().clear(); - let mut send_input_stream = move || { - let mut lock = INPUT_BUFFER.lock().unwrap(); - while lock.len() >= encode_len { - let frame: Vec = lock.drain(0..encode_len).collect(); - send( - &frame, - sample_rate_0, - sample_rate, - channels, - &mut encoder, - &sp, - ); - } + let timeout = None; + let stream_config = StreamConfig { + channels, + sample_rate: config.sample_rate(), + buffer_size: BufferSize::Default, }; - - let stream = match config.sample_format() { - cpal::SampleFormat::F32 => device.build_input_stream( - &config.into(), - move |data, _: &_| { - INPUT_BUFFER.lock().unwrap().extend(data); - send_input_stream(); - }, - err_fn, - )?, - cpal::SampleFormat::I16 => device.build_input_stream( - &config.into(), - move |data: &[i16], _: &_| { - let buffer: Vec<_> = data.iter().map(|s| cpal::Sample::to_f32(s)).collect(); - INPUT_BUFFER.lock().unwrap().extend(buffer); - send_input_stream(); - }, - err_fn, - )?, - cpal::SampleFormat::U16 => device.build_input_stream( - &config.into(), - move |data: &[u16], _: &_| { - let buffer: Vec<_> = data.iter().map(|s| cpal::Sample::to_f32(s)).collect(); - INPUT_BUFFER.lock().unwrap().extend(buffer); - send_input_stream(); - }, - err_fn, - )?, - }; - stream.play()?; - Ok(( - Box::new(stream), - Arc::new(create_format_msg(sample_rate, channels)), - )) + let stream = device.build_input_stream( + &stream_config, + move |data: &[T], _: &InputCallbackInfo| { + let buffer: Vec = data.iter().map(|s| T::to_sample(*s)).collect(); + let mut lock = INPUT_BUFFER.lock().unwrap(); + lock.extend(buffer); + while lock.len() >= encode_len { + let frame: Vec = lock.drain(0..encode_len).collect(); + send( + &frame, + sample_rate_0, + sample_rate, + channels, + &mut encoder, + &sp, + ); + } + }, + err_fn, + timeout, + )?; + Ok(stream) } }