diff --git a/cras/server/s2/s2.h b/cras/server/s2/s2.h index f1f29da14..c9d4766eb 100644 --- a/cras/server/s2/s2.h +++ b/cras/server/s2/s2.h @@ -43,6 +43,8 @@ void cras_s2_load_cras_config_dir(void); bool cras_s2_get_beamforming_supported(void); +bool cras_s2_get_beamforming_allowed(void); + char *cras_s2_dump_json(void); void cras_s2_reset_for_testing(void); diff --git a/cras/server/s2/src/global.rs b/cras/server/s2/src/global.rs index edfe3b38b..1434e37fc 100644 --- a/cras/server/s2/src/global.rs +++ b/cras/server/s2/src/global.rs @@ -94,6 +94,11 @@ pub extern "C" fn cras_s2_get_beamforming_supported() -> bool { state().output.beamforming_supported } +#[no_mangle] +pub extern "C" fn cras_s2_get_beamforming_allowed() -> bool { + state().output.beamforming_allowed +} + #[no_mangle] pub extern "C" fn cras_s2_dump_json() -> *mut c_char { let s = serde_json::to_string_pretty(state().deref()).expect("serde_json::to_string_pretty"); diff --git a/cras/server/s2/src/lib.rs b/cras/server/s2/src/lib.rs index 68c4e6836..563c12966 100644 --- a/cras/server/s2/src/lib.rs +++ b/cras/server/s2/src/lib.rs @@ -32,19 +32,27 @@ struct Output { style_transfer_allowed: bool, style_transfer_enabled: bool, beamforming_supported: bool, + beamforming_allowed: bool, } fn resolve(input: &Input) -> Output { // TODO(b/339785214): Decide this based on config file content. let beamforming_supported = input.cras_config_dir.ends_with(".3mic"); + let dlc_nc_ap_installed = input + .dlc_installed + .contains(CrasDlcId::CrasDlcNcAp.as_str()); Output { - ap_nc_allowed: input.ap_nc_featured_allowed + ap_nc_allowed: (input.ap_nc_featured_allowed || input.ap_nc_segmentation_allowed - || input.ap_nc_feature_tier_allowed, + || input.ap_nc_feature_tier_allowed) + && dlc_nc_ap_installed, style_transfer_supported: input.ap_nc_segmentation_allowed && !beamforming_supported, - style_transfer_allowed: input.style_transfer_featured_allowed, + style_transfer_allowed: input.style_transfer_featured_allowed && dlc_nc_ap_installed, style_transfer_enabled: input.style_transfer_enabled, beamforming_supported, + beamforming_allowed: input + .dlc_installed + .contains(CrasDlcId::CrasDlcIntelligoBeamforming.as_str()), } } @@ -138,6 +146,19 @@ mod tests { let mut s = S2::new(); assert_eq!(s.output.ap_nc_allowed, false); + s.set_ap_nc_featured_allowed(true); + assert_eq!(s.output.ap_nc_allowed, false); + + s.set_ap_nc_featured_allowed(false); + s.set_ap_nc_segmentation_allowed(true); + assert_eq!(s.output.ap_nc_allowed, false); + + s.set_ap_nc_segmentation_allowed(false); + s.set_ap_nc_feature_tier_allowed(true); + assert_eq!(s.output.ap_nc_allowed, false); + + s.set_dlc_installed(CrasDlcId::CrasDlcNcAp); + s.set_ap_nc_featured_allowed(true); assert_eq!(s.output.ap_nc_allowed, true); @@ -162,6 +183,21 @@ mod tests { assert_eq!(s.output.style_transfer_supported, false); } + #[test] + fn test_style_transfer_allowed() { + let mut s = S2::new(); + assert_eq!(s.output.style_transfer_allowed, false); + + s.set_style_transfer_featured_allowed(true); + assert_eq!(s.output.style_transfer_allowed, false); + + s.set_dlc_installed(CrasDlcId::CrasDlcNcAp); + assert_eq!(s.output.style_transfer_allowed, true); + + s.set_style_transfer_featured_allowed(false); + assert_eq!(s.output.style_transfer_allowed, false); + } + #[test] fn test_style_transfer_enabled() { let mut s = S2::new(); @@ -186,6 +222,10 @@ mod tests { assert!(s.output.beamforming_supported); assert!(!s.output.style_transfer_supported); + assert!(!s.output.beamforming_allowed); + s.set_dlc_installed(CrasDlcId::CrasDlcIntelligoBeamforming); + assert!(s.output.beamforming_allowed); + s.set_cras_config_dir("omniknight"); assert!(!s.output.beamforming_supported); assert!(s.output.style_transfer_supported); diff --git a/cras/src/server/cras_iodev_list.c b/cras/src/server/cras_iodev_list.c index fb42248c9..3ee557801 100644 --- a/cras/src/server/cras_iodev_list.c +++ b/cras/src/server/cras_iodev_list.c @@ -313,6 +313,7 @@ static void fill_dev_list(struct iodev_list* list, // Auxiliary information for fill_node_list. struct fill_node_list_auxiliary { bool dsp_nc_allowed; + bool bf_nc_allowed; bool ap_nc_allowed; bool ast_allowed; }; @@ -321,6 +322,7 @@ static struct fill_node_list_auxiliary get_fill_node_list_auxiliary() { struct fill_node_list_auxiliary aux = { .dsp_nc_allowed = !get_dsp_input_effects_blocked_state() || cras_system_get_bypass_block_noise_cancellation(), + .bf_nc_allowed = cras_s2_get_beamforming_allowed(), .ap_nc_allowed = cras_s2_get_ap_nc_allowed(), .ast_allowed = cras_s2_get_style_transfer_allowed(), }; @@ -362,11 +364,17 @@ static int fill_node_list(struct iodev_list* list, // Will affect UI toggle visibility, should handle together. if (node->nc_providers & CRAS_NC_PROVIDER_AST && aux->ast_allowed) { node_info->audio_effect |= EFFECT_TYPE_STYLE_TRANSFER; - } else if ((node->nc_providers & CRAS_NC_PROVIDER_DSP && - aux->dsp_nc_allowed) || - (node->nc_providers & CRAS_NC_PROVIDER_AP && - aux->ap_nc_allowed)) { + } else if (node->nc_providers & CRAS_NC_PROVIDER_DSP && + aux->dsp_nc_allowed) { node_info->audio_effect |= EFFECT_TYPE_NOISE_CANCELLATION; + } else if (node->nc_providers & CRAS_NC_PROVIDER_AP) { + const bool use_beamforming = + cras_s2_get_beamforming_supported() && + node_info->type_enum == NODE_POSITION_INTERNAL; + if ((use_beamforming && aux->bf_nc_allowed) || + (!use_beamforming && aux->ap_nc_allowed)) { + node_info->audio_effect |= EFFECT_TYPE_NOISE_CANCELLATION; + } } if (cras_system_get_sr_bt_supported() && diff --git a/cras/src/tests/iodev_list_unittest.cc b/cras/src/tests/iodev_list_unittest.cc index 61296212f..5f6bf7d93 100644 --- a/cras/src/tests/iodev_list_unittest.cc +++ b/cras/src/tests/iodev_list_unittest.cc @@ -14,6 +14,7 @@ #include "cras/src/common/cras_observer_ops.h" #include "cras/src/server/audio_thread.h" #include "cras/src/server/cras_iodev.h" +#include "cras/src/server/cras_iodev_list.h" #include "cras/src/server/cras_main_thread_log.h" #include "cras/src/server/cras_nc.h" #include "cras/src/server/cras_ramp.h" @@ -3515,6 +3516,7 @@ TEST_F(IoDevTestSuite, RequestFloop) { } TEST_F(IoDevTestSuite, StyleTransferSupported) { + cras_s2_reset_for_testing(); cras_s2_set_style_transfer_featured_allowed(true); cras_iodev_list_init(); @@ -3543,17 +3545,26 @@ TEST_F(IoDevTestSuite, StyleTransferSupported) { EXPECT_EQ(server_state_stub.num_output_nodes, 1); ASSERT_EQ(server_state_stub.input_nodes[1].iodev_idx, d1_.info.idx); - EXPECT_EQ(server_state_stub.input_nodes[1].audio_effect, - EFFECT_TYPE_STYLE_TRANSFER); + EXPECT_EQ(server_state_stub.input_nodes[1].audio_effect, 0); ASSERT_EQ(server_state_stub.input_nodes[0].iodev_idx, d2_.info.idx); EXPECT_EQ(server_state_stub.input_nodes[0].audio_effect, 0); ASSERT_EQ(server_state_stub.output_nodes[0].iodev_idx, d3_.info.idx); EXPECT_EQ(server_state_stub.output_nodes[0].audio_effect, 0); + cras_iodev_list_rm(&d1_); + cras_s2_set_dlc_installed(CrasDlcId::CrasDlcNcAp); + cras_iodev_list_add(&d1_); + EXPECT_EQ(server_state_stub.input_nodes[0].audio_effect, + EFFECT_TYPE_STYLE_TRANSFER); + cras_iodev_list_deinit(); } TEST_F(IoDevTestSuite, ResetForStyleTransfer) { + cras_s2_reset_for_testing(); + cras_s2_set_style_transfer_featured_allowed(true); + cras_s2_set_dlc_installed(CrasDlcId::CrasDlcNcAp); + struct cras_rstream rstream; int rc;