diff --git a/frameworks/native/audioeffect/include/audio_enhance_chain_adapter.h b/frameworks/native/audioeffect/include/audio_enhance_chain_adapter.h index 9f9db4fc1e745a1c9cee6a1b42b890d4e6017b09..783cc898d3591734756229d0794995f74b143a3f 100644 --- a/frameworks/native/audioeffect/include/audio_enhance_chain_adapter.h +++ b/frameworks/native/audioeffect/include/audio_enhance_chain_adapter.h @@ -29,7 +29,7 @@ int32_t EnhanceChainManagerCreateCb(const char *sceneType, const char *enhanceMo const char *downDevice); int32_t EnhanceChainManagerReleaseCb(const char *sceneType, const char *upDevice, const char *downDevice); bool EnhanceChainManagerExist(const char *sceneKey); -pa_sample_spec EnhanceChainManagerGetAlgoConfig(const char *sceneType, const char *upDevice, const char *downDevice); +int32_t EnhanceChainManagerGetAlgoConfig(const char *sceneKey, pa_sample_spec *spec); bool EnhanceChainManagerIsEmptyEnhanceChain(); int32_t EnhanceChainManagerInitEnhanceBuffer(); int32_t CopyToEnhanceBufferAdapter(void *data, uint32_t length); diff --git a/frameworks/native/audioeffect/include/audio_enhance_chain_manager.h b/frameworks/native/audioeffect/include/audio_enhance_chain_manager.h index f8c16b62007aeec2e9d314abc759aa54708e2f74..7ba2b52a5bddce3f2c1ed068fc8a676a7ef3c05b 100644 --- a/frameworks/native/audioeffect/include/audio_enhance_chain_manager.h +++ b/frameworks/native/audioeffect/include/audio_enhance_chain_manager.h @@ -42,8 +42,7 @@ public: int32_t ReleaseAudioEnhanceChainDynamic(const std::string &sceneType, const std::string &upDevice, const std::string &downDevice); bool ExistAudioEnhanceChain(const std::string &sceneKey); - AudioBufferConfig AudioEnhanceChainGetAlgoConfig(const std::string &sceneType, const std::string &upDevice, - const std::string &downDevice); + int32_t AudioEnhanceChainGetAlgoConfig(const std::string &sceneKey, AudioBufferConfig &config); bool IsEmptyEnhanceChain(); int32_t InitEnhanceBuffer(); int32_t CopyToEnhanceBuffer(void *data, uint32_t length); diff --git a/frameworks/native/audioeffect/src/audio_enhance_chain.cpp b/frameworks/native/audioeffect/src/audio_enhance_chain.cpp index 5a90c1ebefeae644fd6bca9226a2843d35d420f6..86b91259d373636f59d6b2df341ddf8d26667d19 100644 --- a/frameworks/native/audioeffect/src/audio_enhance_chain.cpp +++ b/frameworks/native/audioeffect/src/audio_enhance_chain.cpp @@ -116,6 +116,15 @@ void AudioEnhanceChain::AddEnhanceHandle(AudioEffectHandle handle, AudioEffectLi AudioEffectTransInfo cmdInfo = {}; AudioEffectTransInfo replyInfo = {}; + uint32_t maxSampleRate = DEFAULT_SAMPLE_RATE; + replyInfo.data = &maxSampleRate; + replyInfo.size = sizeof(maxSampleRate); + ret = (*handle)->command(handle, EFFECT_CMD_GET_CONFIG, &cmdInfo, &replyInfo); + if (ret) { + AUDIO_ERR_LOG("get algo maxSampleRate failed!"); + } + algoSupportedConfig_.sampleRate = maxSampleRate; + cmdInfo.data = static_cast(&algoSupportedConfig_); cmdInfo.size = sizeof(algoSupportedConfig_); diff --git a/frameworks/native/audioeffect/src/audio_enhance_chain_adapter.cpp b/frameworks/native/audioeffect/src/audio_enhance_chain_adapter.cpp index 3f0791f7dbb7f35f34ff09831a4087ea3d8b760e..03e8763d782451ecb8464ffe28d6540c927bfbdc 100644 --- a/frameworks/native/audioeffect/src/audio_enhance_chain_adapter.cpp +++ b/frameworks/native/audioeffect/src/audio_enhance_chain_adapter.cpp @@ -105,41 +105,31 @@ bool EnhanceChainManagerExist(const char *sceneKey) return audioEnhanceChainMananger->ExistAudioEnhanceChain(sceneKeyString); } -pa_sample_spec EnhanceChainManagerGetAlgoConfig(const char *sceneType, const char *upDevice, const char *downDevice) +int32_t EnhanceChainManagerGetAlgoConfig(const char *sceneKey, pa_sample_spec *spec) { - pa_sample_spec spec; - pa_sample_spec_init(&spec); AudioEnhanceChainManager *audioEnhanceChainMananger = AudioEnhanceChainManager::GetInstance(); CHECK_AND_RETURN_RET_LOG(audioEnhanceChainMananger != nullptr, - spec, "null audioEnhanceChainManager"); - std::string sceneTypeString = ""; - std::string upDeviceString = ""; - std::string downDeviceString = ""; - if (sceneType) { - sceneTypeString = sceneType; - } - if (upDevice) { - upDeviceString = upDevice; - } - if (downDevice) { - downDeviceString = downDevice; + ERROR, "null audioEnhanceChainManager"); + std::string sceneKeyString = ""; + if (sceneKey) { + sceneKeyString = sceneKey; } - AudioBufferConfig config = audioEnhanceChainMananger->AudioEnhanceChainGetAlgoConfig(sceneTypeString, - upDeviceString, downDeviceString); - if (config.samplingRate == 0) { - return spec; + AudioBufferConfig config = {}; + uint32_t ret = audioEnhanceChainMananger->AudioEnhanceChainGetAlgoConfig(sceneKeyString, config); + if (ret != 0 || config.samplingRate == 0) { + return ERROR; } - pa_sample_spec sampleSpec; - sampleSpec.rate = config.samplingRate; - sampleSpec.channels = static_cast(config.channels); + spec->rate = config.samplingRate; + spec->channels = static_cast(config.channels); auto item = FORMAT_CONVERT_MAP.find(config.format); if (item != FORMAT_CONVERT_MAP.end()) { - sampleSpec.format = item->second; + spec->format = item->second; } else { - sampleSpec.format = PA_SAMPLE_INVALID; + spec->format = PA_SAMPLE_INVALID; + return ERROR; } - return sampleSpec; + return SUCCESS; } bool EnhanceChainManagerIsEmptyEnhanceChain() diff --git a/frameworks/native/audioeffect/src/audio_enhance_chain_manager.cpp b/frameworks/native/audioeffect/src/audio_enhance_chain_manager.cpp index fc14b981717bdb7318658a37b8147bc86315031c..2f89f6d6f0e61fbe2376ba26c88652a5c1c117b5 100644 --- a/frameworks/native/audioeffect/src/audio_enhance_chain_manager.cpp +++ b/frameworks/native/audioeffect/src/audio_enhance_chain_manager.cpp @@ -312,22 +312,19 @@ bool AudioEnhanceChainManager::ExistAudioEnhanceChain(const std::string &sceneKe return !audioEnhanceChain->IsEmptyEnhanceHandles(); } -AudioBufferConfig AudioEnhanceChainManager::AudioEnhanceChainGetAlgoConfig(const std::string &sceneType, - const std::string &upDevice, const std::string &downDevice) +int32_t AudioEnhanceChainManager::AudioEnhanceChainGetAlgoConfig(const std::string &sceneKey, AudioBufferConfig &config) { std::lock_guard lock(chainManagerMutex_); - AudioBufferConfig config = {}; - CHECK_AND_RETURN_RET_LOG(isInitialized_, config, "has not been initialized"); - std::string sceneTypeAndDeviceKey = sceneType + "_&_" + upDevice + "_&_" + downDevice; - if (!sceneTypeToEnhanceChainMap_.count(sceneTypeAndDeviceKey)) { - AUDIO_ERR_LOG("sceneTypeToEnhanceChainMap_ have not %{public}s", sceneTypeAndDeviceKey.c_str()); - return config; + CHECK_AND_RETURN_RET_LOG(isInitialized_, ERROR, "has not been initialized"); + if (!sceneTypeToEnhanceChainMap_.count(sceneKey)) { + AUDIO_ERR_LOG("sceneTypeToEnhanceChainMap_ have not %{public}s", sceneKey.c_str()); + return ERROR; } - auto audioEnhanceChain = sceneTypeToEnhanceChainMap_[sceneTypeAndDeviceKey]; - CHECK_AND_RETURN_RET_LOG(audioEnhanceChain != nullptr, config, "[%{public}s] get config faild", - sceneTypeAndDeviceKey.c_str()); + auto audioEnhanceChain = sceneTypeToEnhanceChainMap_[sceneKey]; + CHECK_AND_RETURN_RET_LOG(audioEnhanceChain != nullptr, ERROR, "[%{public}s] get config faild", + sceneKey.c_str()); audioEnhanceChain->GetAlgoConfig(config); - return config; + return SUCCESS; } bool AudioEnhanceChainManager::IsEmptyEnhanceChain() diff --git a/frameworks/native/pulseaudio/modules/hdi/hdi_source.c b/frameworks/native/pulseaudio/modules/hdi/hdi_source.c index db21e411bb985b23c139b2f93a67c8e159175c2f..eb36e98412b1f2576de02505550eab248826666a 100644 --- a/frameworks/native/pulseaudio/modules/hdi/hdi_source.c +++ b/frameworks/native/pulseaudio/modules/hdi/hdi_source.c @@ -66,6 +66,8 @@ #define MAX_SCENE_NUM 5 const char *DEVICE_CLASS_REMOTE = "remote"; +const int32_t SUCCESS = 0; +const int32_t ERROR = -1; static int PaHdiCapturerInit(struct Userdata *u); static void PaHdiCapturerExit(struct Userdata *u); @@ -121,6 +123,9 @@ static void UserdataFree(struct Userdata *u) if (u->sceneToCountMap) { pa_hashmap_free(u->sceneToCountMap); } + if (u->sceneToResamplerMap) { + pa_hashmap_free(u->sceneToResamplerMap); + } pa_xfree(u); } @@ -330,6 +335,22 @@ static int GetCapturerFrameFromHdi(pa_memchunk *chunk, const struct Userdata *u) return 0; } +static int32_t SampleAlignment(const char *sceneKey, pa_memchunk *enhanceChunk, pa_memchunk *rChunk, struct Userdata *u) +{ + CHECK_AND_RETURN_RET_LOG(sceneKey != NULL, ERROR, "sceneKey is null"); + CHECK_AND_RETURN_RET_LOG(enhanceChunk != NULL, ERROR, "enhanceChunk is null"); + CHECK_AND_RETURN_RET_LOG(u != NULL, ERROR, "Userdata is null"); + + pa_resampler *resampler = (pa_resampler *)pa_hashmap_get(u->sceneToResamplerMap, sceneKey); + if (resampler != NULL) { + pa_resampler_run(resampler, enhanceChunk, rChunk); + } else { + *rChunk = *enhanceChunk; + pa_memblock_ref(rChunk->memblock); + } + return SUCCESS; +} + static int32_t GetCapturerFrameFromHdiAndProcess(pa_memchunk *chunk, struct Userdata *u) { if (GetCapturerFrameFromHdi(chunk, u) != 0) { @@ -353,12 +374,16 @@ static int32_t GetCapturerFrameFromHdiAndProcess(pa_memchunk *chunk, struct User char *sceneKey = (char *)scene; AUDIO_DEBUG_LOG("Now sceneKey is : %{public}s", sceneKey); - pa_memchunk enhanceChunk; + pa_memchunk enhanceChunk, rChunk; enhanceChunk.length = chunk->length; enhanceChunk.memblock = pa_memblock_new(u->core->mempool, enhanceChunk.length); pa_memchunk_memcpy(&enhanceChunk, chunk); - EnhanceProcessAndPost(u->source, sceneKey, &enhanceChunk); + SampleAlignment(sceneKey, &enhanceChunk, &rChunk, u); + EnhanceProcessAndPost(u->source, sceneKey, &rChunk); pa_memblock_unref(enhanceChunk.memblock); + if (rChunk.memblock) { + pa_memblock_unref(rChunk.memblock); + } } pa_memblock_unref(chunk->memblock); @@ -629,6 +654,9 @@ static void InitUserdataAttrs(pa_modargs *ma, struct Userdata *u, const pa_sampl u->sceneToCountMap = pa_hashmap_new_full(pa_idxset_string_hash_func, pa_idxset_string_compare_func, pa_xfree, pa_xfree); + + u->sceneToResamplerMap = pa_hashmap_new_full(pa_idxset_string_hash_func, pa_idxset_string_compare_func, + NULL, (pa_free_cb_t) pa_resampler_free); } static void InitEcAndMicRefAttrs(pa_modargs *ma, struct Userdata *u) diff --git a/frameworks/native/pulseaudio/modules/hdi/module_hdi_source.c b/frameworks/native/pulseaudio/modules/hdi/module_hdi_source.c index 4ca312332774586fcd97a6ac2e2fa4e64187ccc5..74d5f58751eee150e4d002b4fc27978bd559afae 100644 --- a/frameworks/native/pulseaudio/modules/hdi/module_hdi_source.c +++ b/frameworks/native/pulseaudio/modules/hdi/module_hdi_source.c @@ -110,8 +110,8 @@ static bool DecreaseScenekeyCount(pa_hashmap *sceneMap, const char *key) (*num)--; if (*num == 0) { pa_hashmap_remove_and_free(sceneMap, key); + return true; } - return true; } return false; } @@ -128,8 +128,30 @@ static pa_hook_result_t SourceOutputProplistChangedCb(pa_core *c, pa_source_outp return PA_HOOK_OK; } +static void SetResampler(pa_source_output *so, const pa_sample_spec *algoConfig, + const char *sceneKey, pa_hashmap *resamplerMap) +{ + AUDIO_INFO_LOG("SOURCE rate = %{public}d ALGO rate = %{public}d ", + so->source->sample_spec.rate, algoConfig->rate); + if (!pa_sample_spec_equal(&so->source->sample_spec, algoConfig)) { + pa_resampler *preResampler = pa_resampler_new(so->source->core->mempool, + &so->source->sample_spec, &so->source->channel_map, + algoConfig, &so->source->channel_map, + so->source->core->lfe_crossover_freq, + PA_RESAMPLER_AUTO, + PA_RESAMPLER_VARIABLE_RATE); + pa_hashmap_put(resamplerMap, pa_xstrdup(sceneKey), preResampler); + pa_resampler_set_input_rate(so->thread_info.resampler, algoConfig->rate); + } +} + static pa_hook_result_t SourceOutputPutCb(pa_core *c, pa_source_output *so) { + struct Userdata *u = (struct Userdata *)so->source->userdata; + if (u == NULL) { + AUDIO_ERR_LOG("Get Userdata failed! userdata is NULL"); + return PA_HOOK_OK; + } AUDIO_INFO_LOG("Trigger SourceOutputPutCb"); pa_assert(c); const char *sceneType = pa_proplist_gets(so->proplist, "scene.type"); @@ -143,11 +165,6 @@ static pa_hook_result_t SourceOutputPutCb(pa_core *c, pa_source_output *so) return PA_HOOK_OK; } EnhanceChainManagerInitEnhanceBuffer(); - struct Userdata *u = (struct Userdata *)so->source->userdata; - if (u == NULL) { - AUDIO_ERR_LOG("Get Userdata failed! userdata is NULL"); - return PA_HOOK_OK; - } char sceneKey[MAX_SCENE_NAME_LEN]; ret = ConcatStr(sceneType, upDevice, downDevice, sceneKey, MAX_SCENE_NAME_LEN); if (ret != 0) { @@ -155,6 +172,14 @@ static pa_hook_result_t SourceOutputPutCb(pa_core *c, pa_source_output *so) return PA_HOOK_OK; } IncreaseScenekeyCount(u->sceneToCountMap, sceneKey); + pa_sample_spec algoConfig; + pa_sample_spec_init(&algoConfig); + ret = EnhanceChainManagerGetAlgoConfig(sceneKey, &algoConfig); + if (ret != 0) { + AUDIO_ERR_LOG("Get algo config failed"); + return PA_HOOK_OK; + } + SetResampler(so, &algoConfig, sceneKey, u->sceneToResamplerMap); return PA_HOOK_OK; } @@ -177,7 +202,9 @@ static pa_hook_result_t SourceOutputUnlinkCb(pa_core *c, pa_source_output *so) AUDIO_ERR_LOG("Get sceneKey of sourceOutput to unlink failed"); return PA_HOOK_OK; } - DecreaseScenekeyCount(u->sceneToCountMap, sceneKey); + if (DecreaseScenekeyCount(u->sceneToCountMap, sceneKey)) { + pa_hashmap_remove_and_free(u->sceneToResamplerMap, sceneKey); + } return PA_HOOK_OK; } diff --git a/frameworks/native/pulseaudio/modules/hdi/userdata.h b/frameworks/native/pulseaudio/modules/hdi/userdata.h index a23cc5bc280a140c76384a2a08e6189e44658450..bd9a09fd1cf1535971bfa4b9330f65693143f648 100644 --- a/frameworks/native/pulseaudio/modules/hdi/userdata.h +++ b/frameworks/native/pulseaudio/modules/hdi/userdata.h @@ -53,6 +53,7 @@ struct Userdata { struct CapturerSourceAdapter *sourceAdapter; pa_usec_t delayTime; pa_hashmap *sceneToCountMap; + pa_hashmap *sceneToResamplerMap; }; #endif \ No newline at end of file diff --git a/interfaces/inner_api/native/audiocommon/include/audio_source_type.h b/interfaces/inner_api/native/audiocommon/include/audio_source_type.h index ba569343482dac88c4a251e4c982b648ced6e356..7db3b6020d981979b3978dbb0d77fd52590a87a8 100644 --- a/interfaces/inner_api/native/audiocommon/include/audio_source_type.h +++ b/interfaces/inner_api/native/audiocommon/include/audio_source_type.h @@ -35,7 +35,8 @@ enum SourceType { SOURCE_TYPE_VIRTUAL_CAPTURE = 9, // only for voice call SOURCE_TYPE_VOICE_MESSAGE = 10, SOURCE_TYPE_REMOTE_CAST = 11, - SOURCE_TYPE_MAX = SOURCE_TYPE_REMOTE_CAST + SOURCE_TYPE_VOICE_TRANSCRIPTION = 12, + SOURCE_TYPE_MAX = SOURCE_TYPE_VOICE_TRANSCRIPTION }; typedef enum { diff --git a/services/audio_service/server/src/pa_adapter_manager.cpp b/services/audio_service/server/src/pa_adapter_manager.cpp index 2657800821c41bc5899073c8ba9d07d1d0a7c126..243f960abd114dc374cf0fc69d5df2c78876de0b 100644 --- a/services/audio_service/server/src/pa_adapter_manager.cpp +++ b/services/audio_service/server/src/pa_adapter_manager.cpp @@ -839,6 +839,9 @@ const std::string PaAdapterManager::GetEnhanceSceneName(SourceType sourceType) case SOURCE_TYPE_VOICE_COMMUNICATION: name = "SCENE_VOIP_UP"; break; + case SOURCE_TYPE_VOICE_TRANSCRIPTION: + name = "SCENE_PRE_ENHANCE"; + break; default: name = "SCENE_OTHERS"; }