Merge pull request #4137 from 21pages/audio-rechannel

Audio rechannel
This commit is contained in:
RustDesk
2023-04-21 08:59:43 +08:00
committed by GitHub
5 changed files with 252 additions and 57 deletions

View File

@@ -754,6 +754,7 @@ pub struct AudioHandler {
#[cfg(not(any(target_os = "android", target_os = "linux")))]
audio_stream: Option<Box<dyn StreamTrait>>,
channels: u16,
device_channel: u16,
#[cfg(not(any(target_os = "android", target_os = "linux")))]
ready: Arc<std::sync::Mutex<bool>>,
}
@@ -826,22 +827,33 @@ impl AudioHandler {
let sample_format = config.sample_format();
log::info!("Default output format: {:?}", config);
log::info!("Remote input format: {:?}", format0);
let mut config: StreamConfig = config.into();
config.channels = format0.channels as _;
match sample_format {
cpal::SampleFormat::I8 => self.build_output_stream::<i8>(&config, &device)?,
cpal::SampleFormat::I16 => self.build_output_stream::<i16>(&config, &device)?,
cpal::SampleFormat::I32 => self.build_output_stream::<i32>(&config, &device)?,
cpal::SampleFormat::I64 => self.build_output_stream::<i64>(&config, &device)?,
cpal::SampleFormat::U8 => self.build_output_stream::<u8>(&config, &device)?,
cpal::SampleFormat::U16 => self.build_output_stream::<u16>(&config, &device)?,
cpal::SampleFormat::U32 => self.build_output_stream::<u32>(&config, &device)?,
cpal::SampleFormat::U64 => self.build_output_stream::<u64>(&config, &device)?,
cpal::SampleFormat::F32 => self.build_output_stream::<f32>(&config, &device)?,
cpal::SampleFormat::F64 => self.build_output_stream::<f64>(&config, &device)?,
f => bail!("unsupported audio format: {:?}", f),
}
let config: StreamConfig = config.into();
self.sample_rate = (format0.sample_rate, config.sample_rate.0);
let mut build_output_stream = |config: StreamConfig| match sample_format {
cpal::SampleFormat::I8 => self.build_output_stream::<i8>(&config, &device),
cpal::SampleFormat::I16 => self.build_output_stream::<i16>(&config, &device),
cpal::SampleFormat::I32 => self.build_output_stream::<i32>(&config, &device),
cpal::SampleFormat::I64 => self.build_output_stream::<i64>(&config, &device),
cpal::SampleFormat::U8 => self.build_output_stream::<u8>(&config, &device),
cpal::SampleFormat::U16 => self.build_output_stream::<u16>(&config, &device),
cpal::SampleFormat::U32 => self.build_output_stream::<u32>(&config, &device),
cpal::SampleFormat::U64 => self.build_output_stream::<u64>(&config, &device),
cpal::SampleFormat::F32 => self.build_output_stream::<f32>(&config, &device),
cpal::SampleFormat::F64 => self.build_output_stream::<f64>(&config, &device),
f => bail!("unsupported audio format: {:?}", f),
};
if config.channels > format0.channels as _ {
let no_rechannel_config = StreamConfig {
channels: format0.channels as _,
..config.clone()
};
if let Err(_) = build_output_stream(no_rechannel_config) {
build_output_stream(config)?;
}
} else {
build_output_stream(config)?;
}
Ok(())
}
@@ -885,20 +897,25 @@ impl AudioHandler {
let sample_rate0 = self.sample_rate.0;
let sample_rate = self.sample_rate.1;
let audio_buffer = self.audio_buffer.0.clone();
let mut buffer = buffer[0..n].to_owned();
if sample_rate != sample_rate0 {
let buffer = crate::resample_channels(
buffer = crate::audio_resample(
&buffer[0..n],
sample_rate0,
sample_rate,
channels,
);
audio_buffer.lock().unwrap().push_slice_overwrite(&buffer);
} else {
audio_buffer
.lock()
.unwrap()
.push_slice_overwrite(&buffer[0..n]);
}
if self.channels != self.device_channel {
buffer = crate::audio_rechannel(
buffer,
sample_rate,
sample_rate,
self.channels,
self.device_channel,
);
}
audio_buffer.lock().unwrap().push_slice_overwrite(&buffer);
}
#[cfg(target_os = "android")]
{
@@ -921,6 +938,7 @@ impl AudioHandler {
config: &StreamConfig,
device: &Device,
) -> ResultType<()> {
self.device_channel = config.channels;
let err_fn = move |err| {
// too many errors, will improve later
log::trace!("an error occurred on stream: {}", err);