Skip to content

Commit 538e0bc

Browse files
committed
Remember input processing params after reinit
1 parent 03ffaeb commit 538e0bc

File tree

2 files changed

+68
-3
lines changed

2 files changed

+68
-3
lines changed

src/backend/mod.rs

+9-3
Original file line numberDiff line numberDiff line change
@@ -2536,6 +2536,7 @@ struct CoreStreamData<'ctx> {
25362536
// Info of the I/O devices.
25372537
input_device: device_info,
25382538
output_device: device_info,
2539+
input_processing_params: InputProcessingParams,
25392540
input_buffer_manager: Option<BufferManager>,
25402541
// Listeners indicating what system events are monitored.
25412542
default_input_listener: Option<device_property_listener>,
@@ -2574,6 +2575,7 @@ impl<'ctx> Default for CoreStreamData<'ctx> {
25742575
output_unit: ptr::null_mut(),
25752576
input_device: device_info::default(),
25762577
output_device: device_info::default(),
2578+
input_processing_params: InputProcessingParams::NONE,
25772579
input_buffer_manager: None,
25782580
default_input_listener: None,
25792581
default_output_listener: None,
@@ -2618,6 +2620,7 @@ impl<'ctx> CoreStreamData<'ctx> {
26182620
output_unit: ptr::null_mut(),
26192621
input_device: in_dev,
26202622
output_device: out_dev,
2623+
input_processing_params: InputProcessingParams::NONE,
26212624
input_buffer_manager: None,
26222625
default_input_listener: None,
26232626
default_output_listener: None,
@@ -3439,12 +3442,14 @@ impl<'ctx> CoreStreamData<'ctx> {
34393442
);
34403443
}
34413444

3442-
// Always initiate to not use input processing.
3445+
// Always try to remember the applied input processing params. If they cannot
3446+
// be applied in the new device pair, we notify the client of an error and it
3447+
// will have to open a new stream.
34433448
if let Err(r) =
3444-
set_input_processing_params(self.input_unit, InputProcessingParams::NONE)
3449+
set_input_processing_params(self.input_unit, self.input_processing_params)
34453450
{
34463451
cubeb_log!(
3447-
"({:p}) Failed to enable bypass of voiceprocessing. Error: {}",
3452+
"({:p}) Failed to set params of voiceprocessing. Error: {}",
34483453
self.stm_ptr,
34493454
r
34503455
);
@@ -4323,6 +4328,7 @@ impl<'ctx> StreamOps for AudioUnitStream<'ctx> {
43234328
self as *const AudioUnitStream,
43244329
params
43254330
);
4331+
self.core_stream_data.input_processing_params = params;
43264332
Ok(())
43274333
}
43284334
#[cfg(target_os = "ios")]

src/backend/tests/interfaces.rs

+59
Original file line numberDiff line numberDiff line change
@@ -1061,6 +1061,65 @@ fn test_ops_duplex_voice_stream_set_input_processing_params_before_start() {
10611061
);
10621062
}
10631063

1064+
#[test]
1065+
fn test_ops_duplex_voice_stream_set_input_processing_params_before_start_with_reinit() {
1066+
test_default_duplex_voice_stream_operation(
1067+
"duplex voice stream: processing before start",
1068+
|stream| {
1069+
let params: ffi::cubeb_input_processing_params =
1070+
ffi::CUBEB_INPUT_PROCESSING_PARAM_ECHO_CANCELLATION
1071+
| ffi::CUBEB_INPUT_PROCESSING_PARAM_NOISE_SUPPRESSION
1072+
| ffi::CUBEB_INPUT_PROCESSING_PARAM_AUTOMATIC_GAIN_CONTROL;
1073+
assert_eq!(
1074+
unsafe { OPS.stream_set_input_processing_params.unwrap()(stream, params) },
1075+
ffi::CUBEB_OK
1076+
);
1077+
assert_eq!(unsafe { OPS.stream_start.unwrap()(stream) }, ffi::CUBEB_OK);
1078+
1079+
// Hacky cast, but testing this here was simplest for now.
1080+
let stm = unsafe { &mut *(stream as *mut AudioUnitStream) };
1081+
stm.reinit_async();
1082+
let queue = stm.queue.clone();
1083+
let mut params_after_reinit: ffi::cubeb_input_processing_params =
1084+
ffi::CUBEB_INPUT_PROCESSING_PARAM_NONE;
1085+
queue.run_sync(|| {
1086+
let mut params: ffi::cubeb_input_processing_params =
1087+
ffi::CUBEB_INPUT_PROCESSING_PARAM_NONE;
1088+
let mut agc: u32 = 0;
1089+
let r = audio_unit_get_property(
1090+
stm.core_stream_data.input_unit,
1091+
kAUVoiceIOProperty_VoiceProcessingEnableAGC,
1092+
kAudioUnitScope_Global,
1093+
AU_IN_BUS,
1094+
&mut agc,
1095+
&mut mem::size_of::<u32>(),
1096+
);
1097+
assert_eq!(r, NO_ERR);
1098+
if agc == 1 {
1099+
params = params | ffi::CUBEB_INPUT_PROCESSING_PARAM_AUTOMATIC_GAIN_CONTROL;
1100+
}
1101+
let mut bypass: u32 = 0;
1102+
let r = audio_unit_get_property(
1103+
stm.core_stream_data.input_unit,
1104+
kAUVoiceIOProperty_BypassVoiceProcessing,
1105+
kAudioUnitScope_Global,
1106+
AU_IN_BUS,
1107+
&mut bypass,
1108+
&mut mem::size_of::<u32>(),
1109+
);
1110+
assert_eq!(r, NO_ERR);
1111+
if bypass == 0 {
1112+
params = params
1113+
| ffi::CUBEB_INPUT_PROCESSING_PARAM_ECHO_CANCELLATION
1114+
| ffi::CUBEB_INPUT_PROCESSING_PARAM_NOISE_SUPPRESSION;
1115+
}
1116+
params_after_reinit = params;
1117+
});
1118+
assert_eq!(params, params_after_reinit);
1119+
},
1120+
);
1121+
}
1122+
10641123
#[test]
10651124
fn test_ops_duplex_voice_stream_set_input_processing_params_after_start() {
10661125
test_default_duplex_voice_stream_operation(

0 commit comments

Comments
 (0)