Merge pull request #413 from Heap-Hop/master
try to fix audio play noise;improve audio performance
This commit is contained in:
commit
69769cc123
@ -607,9 +607,12 @@ impl AudioHandler {
|
|||||||
config,
|
config,
|
||||||
move |data: &mut [T], _: &_| {
|
move |data: &mut [T], _: &_| {
|
||||||
let mut lock = audio_buffer.lock().unwrap();
|
let mut lock = audio_buffer.lock().unwrap();
|
||||||
let mut n = data.len();
|
let n = data.len();
|
||||||
if lock.len() < n {
|
if lock.len() < n {
|
||||||
n = lock.len();
|
// [data] -- the audio data consumer,size around 2500 in 48000/f32 (50ms),
|
||||||
|
// [audio_buffer] -- the audio data provider,must bigger than the consumer to avoid audio clipping noise
|
||||||
|
// the audio_buffer may have empty data when idle,there will always ZERO AUDIO DATA
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
let mut input = lock.drain(0..n);
|
let mut input = lock.drain(0..n);
|
||||||
for sample in data.iter_mut() {
|
for sample in data.iter_mut() {
|
||||||
|
14
src/ipc.rs
14
src/ipc.rs
@ -400,6 +400,20 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn send_raw(&mut self, data: Vec<u8>) -> ResultType<()> {
|
||||||
|
self.inner.send(bytes::Bytes::from(data)).await?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn next_raw(&mut self) -> ResultType<bytes::BytesMut> {
|
||||||
|
match self.inner.next().await {
|
||||||
|
Some(Ok(res)) => Ok(res),
|
||||||
|
_ => {
|
||||||
|
bail!("reset by the peer");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::main(flavor = "current_thread")]
|
#[tokio::main(flavor = "current_thread")]
|
||||||
|
@ -27,7 +27,7 @@ use std::{
|
|||||||
time::Duration,
|
time::Duration,
|
||||||
};
|
};
|
||||||
|
|
||||||
mod audio_service;
|
pub mod audio_service;
|
||||||
mod clipboard_service;
|
mod clipboard_service;
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
pub mod clipboard_file_service;
|
pub mod clipboard_file_service;
|
||||||
|
@ -16,6 +16,7 @@ use super::*;
|
|||||||
use magnum_opus::{Application::*, Channels::*, Encoder};
|
use magnum_opus::{Application::*, Channels::*, Encoder};
|
||||||
|
|
||||||
pub const NAME: &'static str = "audio";
|
pub const NAME: &'static str = "audio";
|
||||||
|
pub const AUDIO_DATA_SIZE_U8: usize = 960 * 4; // 10ms in 48000 stereo
|
||||||
|
|
||||||
#[cfg(not(target_os = "linux"))]
|
#[cfg(not(target_os = "linux"))]
|
||||||
pub fn new() -> GenericService {
|
pub fn new() -> GenericService {
|
||||||
@ -50,22 +51,25 @@ mod pa_impl {
|
|||||||
)))
|
)))
|
||||||
.await
|
.await
|
||||||
);
|
);
|
||||||
|
let zero_audio_frame: Vec<f32> = vec![0.; AUDIO_DATA_SIZE_U8 / 4];
|
||||||
while sp.ok() {
|
while sp.ok() {
|
||||||
sp.snapshot(|sps| {
|
sp.snapshot(|sps| {
|
||||||
sps.send(create_format_msg(crate::platform::linux::PA_SAMPLE_RATE, 2));
|
sps.send(create_format_msg(crate::platform::linux::PA_SAMPLE_RATE, 2));
|
||||||
Ok(())
|
Ok(())
|
||||||
})?;
|
})?;
|
||||||
if let Some(data) = stream.next_timeout2(1000).await {
|
if let Ok(data) = stream.next_raw().await {
|
||||||
match data? {
|
if data.len() == 0 {
|
||||||
Some(crate::ipc::Data::RawMessage(bytes)) => {
|
send_f32(&zero_audio_frame, &mut encoder, &sp);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if data.len() != AUDIO_DATA_SIZE_U8 {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
let data = unsafe {
|
let data = unsafe {
|
||||||
std::slice::from_raw_parts::<f32>(bytes.as_ptr() as _, bytes.len() / 4)
|
std::slice::from_raw_parts::<f32>(data.as_ptr() as _, data.len() / 4)
|
||||||
};
|
};
|
||||||
send_f32(data, &mut encoder, &sp);
|
send_f32(data, &mut encoder, &sp);
|
||||||
}
|
}
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
17
src/ui/cm.rs
17
src/ui/cm.rs
@ -390,6 +390,8 @@ async fn start_pa() {
|
|||||||
use hbb_common::config::APP_NAME;
|
use hbb_common::config::APP_NAME;
|
||||||
use libpulse_binding as pulse;
|
use libpulse_binding as pulse;
|
||||||
use libpulse_simple_binding as psimple;
|
use libpulse_simple_binding as psimple;
|
||||||
|
use crate::audio_service::AUDIO_DATA_SIZE_U8;
|
||||||
|
|
||||||
match new_listener("_pa").await {
|
match new_listener("_pa").await {
|
||||||
Ok(mut incoming) => {
|
Ok(mut incoming) => {
|
||||||
loop {
|
loop {
|
||||||
@ -422,7 +424,7 @@ async fn start_pa() {
|
|||||||
};
|
};
|
||||||
log::info!("pa monitor: {:?}", device);
|
log::info!("pa monitor: {:?}", device);
|
||||||
// systemctl --user status pulseaudio.service
|
// systemctl --user status pulseaudio.service
|
||||||
let mut buf: Vec<u8> = vec![0; 480 * 4];
|
let mut buf: Vec<u8> = vec![0; AUDIO_DATA_SIZE_U8];
|
||||||
match psimple::Simple::new(
|
match psimple::Simple::new(
|
||||||
None, // Use the default server
|
None, // Use the default server
|
||||||
APP_NAME, // Our application’s name
|
APP_NAME, // Our application’s name
|
||||||
@ -434,13 +436,16 @@ async fn start_pa() {
|
|||||||
None, // Use default buffering attributes
|
None, // Use default buffering attributes
|
||||||
) {
|
) {
|
||||||
Ok(s) => loop {
|
Ok(s) => loop {
|
||||||
if let Some(Err(_)) = stream.next_timeout2(1).await {
|
if let Ok(_) = s.read(&mut buf) {
|
||||||
|
let out = if buf.iter().filter(|x| **x != 0).next().is_none(){
|
||||||
|
vec![]
|
||||||
|
}else{
|
||||||
|
buf.clone()
|
||||||
|
};
|
||||||
|
if let Err(err) = stream.send_raw(out).await{
|
||||||
|
log::error!("Failed to send audio data:{}",err);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if let Ok(_) = s.read(&mut buf) {
|
|
||||||
allow_err!(
|
|
||||||
stream.send(&Data::RawMessage(buf.clone())).await
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user