diff --git a/bundle.json b/bundle.json index 4d18a160b6a75e3526294d27d268cfc7e63ac74b..9b3c6453e6a3e4427992401ee4c709ffad693f8b 100644 --- a/bundle.json +++ b/bundle.json @@ -65,7 +65,8 @@ "resource_schedule_service", "safwk", "samgr", - "sensor" + "sensor", + "window_manager" ], "third_party": [ "bounds_checking_function", diff --git a/frameworks/native/audioeffect/BUILD.gn b/frameworks/native/audioeffect/BUILD.gn index dde437aa8d51fcf7595865263c2ef0d6a98683cf..b88eb3c54f854eff1171b23bf3bd6cf80f82c295 100644 --- a/frameworks/native/audioeffect/BUILD.gn +++ b/frameworks/native/audioeffect/BUILD.gn @@ -15,6 +15,7 @@ import("//build/ohos.gni") import("../../../audio_ohcore.gni") import("../../../config.gni") import("../../../sensor.gni") +import("../../../window_manager.gni") pulseaudio_dir = "//third_party/pulseaudio" pulseaudio_build_path = "//third_party/pulseaudio/ohosbuild" @@ -40,6 +41,10 @@ config("audio_effect_config") { if (sensor_enable == true) { cflags += [ "-DSENSOR_ENABLE" ] } + + if (window_manager_enable == true) { + cflags += [ "-DWINDOW_MANAGER_ENABLE" ] + } } ohos_shared_library("audio_effect") { @@ -58,6 +63,9 @@ ohos_shared_library("audio_effect") { sources = [ "src/audio_effect_chain_manager.cpp", + "src/audio_effect_hdi_param.cpp", + "src/audio_effect_rotation.cpp", + "src/audio_effect_volume.cpp", "src/audio_head_tracker.cpp", ] @@ -75,6 +83,10 @@ ohos_shared_library("audio_effect") { external_deps += [ "sensor:sensor_interface_native" ] } + if (window_manager_enable == true) { + external_deps += [ "window_manager:libdm" ] + } + version_script = "../../../audio_framework.versionscript" part_name = "audio_framework" diff --git a/frameworks/native/audioeffect/include/audio_effect_chain_adapter.h b/frameworks/native/audioeffect/include/audio_effect_chain_adapter.h index e83afe79e98142f164d13a663946dad70f58c87c..3a0a49ffab6e3c30611fb2b2d05ec860c2ff8aac 100644 --- a/frameworks/native/audioeffect/include/audio_effect_chain_adapter.h +++ b/frameworks/native/audioeffect/include/audio_effect_chain_adapter.h @@ -40,6 +40,7 @@ typedef struct SessionInfoPack { const char *channelLayout; const char *sceneMode; const char *spatializationEnabled; + uint32_t volume; } SessionInfoPack; int32_t EffectChainManagerProcess(char *sceneType, BufferAttr *bufferAttr); @@ -57,6 +58,8 @@ bool EffectChainManagerCheckA2dpOffload(); int32_t EffectChainManagerDeleteSessionInfo(const char *sceneType, const char *sessionID); int32_t EffectChainManagerReturnEffectChannelInfo(const char *sceneType, uint32_t *channels, uint64_t *channelLayout); int32_t EffectChainManagerReturnMultiChannelInfo(uint32_t *channels, uint64_t *channelLayout); +int32_t EffectChainManagerVolumeUpdate(const char *sessionID, const uint32_t volume); +int32_t EffectChainManagerRotationUpdate(const uint32_t rotationState); #ifdef __cplusplus } diff --git a/frameworks/native/audioeffect/include/audio_effect_chain_manager.h b/frameworks/native/audioeffect/include/audio_effect_chain_manager.h index 72c6d98f5e1d242c3ffb821de4ce4abecd4dedaa..27c55d8e13225b9d8344071c3df647134f79481e 100644 --- a/frameworks/native/audioeffect/include/audio_effect_chain_manager.h +++ b/frameworks/native/audioeffect/include/audio_effect_chain_manager.h @@ -29,18 +29,22 @@ #include #include -#include "v1_0/ieffect_model.h" #include "audio_effect_chain_adapter.h" #include "audio_effect.h" #ifdef SENSOR_ENABLE #include "audio_head_tracker.h" #endif +#include "audio_effect_hdi_param.h" +#ifdef WINDOW_MANAGER_ENABLE +#include "audio_effect_rotation.h" +#endif +#include "audio_effect_volume.h" namespace OHOS { namespace AudioStandard { -const uint32_t NUM_SET_EFFECT_PARAM = 3; +const uint32_t NUM_SET_EFFECT_PARAM = 5; const uint32_t DEFAULT_FRAMELEN = 1440; const uint32_t DEFAULT_SAMPLE_RATE = 48000; const uint32_t DEFAULT_NUM_CHANNEL = STEREO; @@ -51,8 +55,6 @@ const uint32_t FACTOR_TWO = 2; const uint32_t BASE_TEN = 10; const std::string DEFAULT_DEVICE_SINK = "Speaker"; const uint32_t SIZE_OF_SPATIALIZATION_STATE = 2; -const uint32_t SEND_HDI_COMMAND_LEN = 20; -const uint32_t GET_HDI_BUFFER_LEN = 10; const uint32_t HDI_ROOM_MODE_INDEX_TWO = 2; typedef struct sessionEffectInfo { @@ -61,6 +63,7 @@ typedef struct sessionEffectInfo { uint32_t channels; uint64_t channelLayout; std::string spatializationEnabled; + uint32_t volume; } sessionEffectInfo; const std::vector HVS_SUPPORTED_CHANNELLAYOUTS { @@ -75,22 +78,6 @@ const std::vector HVS_SUPPORTED_CHANNELLAYOUTS { CH_LAYOUT_9POINT1POINT6 }; -class AudioEffectHdi { -public: - AudioEffectHdi(); - ~AudioEffectHdi(); - void InitHdi(); - int32_t UpdateHdiState(int8_t *effectHdiInput); -private: - std::string libName; - std::string effectId; - int8_t input[SEND_HDI_COMMAND_LEN]; - int8_t output[GET_HDI_BUFFER_LEN]; - uint32_t replyLen; - IEffectModel *hdiModel_ = nullptr; - IEffectControl *hdiControl_ = nullptr; -}; - struct AudioEffectProcInfo { bool headTrackingEnabled; bool offloadEnabled; @@ -121,7 +108,7 @@ public: void InitEffectChain(); void SetHeadTrackingDisabled(); uint32_t GetLatency(); - + int32_t SetEffectParam(); private: std::mutex reloadMutex; std::string sceneType; @@ -169,12 +156,20 @@ public: int32_t ReturnEffectChannelInfo(const std::string &sceneType, uint32_t *channels, uint64_t *channelLayout); int32_t ReturnMultiChannelInfo(uint32_t *channels, uint64_t *channelLayout); void RegisterEffectChainCountBackupMap(std::string sceneType, std::string operation); + int32_t EffectRotationUpdate(const uint32_t rotationState); + int32_t EffectVolumeUpdate(const std::string sessionIDString, const uint32_t volume); uint32_t GetLatency(std::string sessionId); private: void UpdateSensorState(); void DeleteAllChains(); void RecoverAllChains(); + int32_t EffectDspVolumeUpdate(AudioEffectVolume *audioEffectVolume); + int32_t EffectApVolumeUpdate(AudioEffectVolume *audioEffectVolume); +#ifdef WINDOW_MANAGER_ENABLE + int32_t EffectDspRotationUpdate(AudioEffectRotation *audioEffectRotation, const uint32_t rotationState); + int32_t EffectApRotationUpdate(AudioEffectRotation *audioEffectRotation, const uint32_t rotationState); +#endif std::map EffectToLibraryEntryMap_; std::map EffectToLibraryNameMap_; std::map> EffectChainToEffectsMap_; @@ -199,7 +194,7 @@ private: std::shared_ptr headTracker_; #endif - std::shared_ptr audioEffectHdi_; + std::shared_ptr audioEffectHdiParam_; int8_t effectHdiInput[SEND_HDI_COMMAND_LEN]; }; } // namespace AudioStandard diff --git a/frameworks/native/audioeffect/include/audio_effect_hdi_param.h b/frameworks/native/audioeffect/include/audio_effect_hdi_param.h new file mode 100644 index 0000000000000000000000000000000000000000..8ebc0c39061cce25d5bb8a9f403b69fc6566e3a7 --- /dev/null +++ b/frameworks/native/audioeffect/include/audio_effect_hdi_param.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef AUDIO_EFFECT_HDI_PARAM_H +#define AUDIO_EFFECT_HDI_PARAM_H + +#include +#include "v1_0/ieffect_model.h" + +const uint32_t SEND_HDI_COMMAND_LEN = 20; + +namespace OHOS { +namespace AudioStandard { +class AudioEffectHdiParam { +public: + AudioEffectHdiParam(); + ~AudioEffectHdiParam(); + void InitHdi(); + int32_t UpdateHdiState(int8_t *effectHdiInput); +private: + static const uint32_t GET_HDI_BUFFER_LEN = 10; + void CreateHdiControl(); + int8_t input_[SEND_HDI_COMMAND_LEN]; + int8_t output_[GET_HDI_BUFFER_LEN]; + uint32_t replyLen_; + std::string libName_; + std::string effectId_; + IEffectModel *hdiModel_; + std::vector libHdiControls_; +}; +} // namespace AudioStandard +} // namespace OHOS +#endif // AUDIO_EFFECT_HDI_PARAM_H \ No newline at end of file diff --git a/frameworks/native/audioeffect/include/audio_effect_rotation.h b/frameworks/native/audioeffect/include/audio_effect_rotation.h new file mode 100644 index 0000000000000000000000000000000000000000..c92bddd87eb68968c82ca320f28320835b1fa1ee --- /dev/null +++ b/frameworks/native/audioeffect/include/audio_effect_rotation.h @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef AUDIO_EFFECT_ROTATION_H +#define AUDIO_EFFECT_ROTATION_H + +#include +#include +#ifdef WINDOW_MANAGER_ENABLE +#include "display_manager.h" +#include "dm_common.h" +#endif + +namespace OHOS { +namespace AudioStandard { +#ifdef WINDOW_MANAGER_ENABLE +class AudioEffectRotation { +public: + AudioEffectRotation(); + ~AudioEffectRotation(); + static AudioEffectRotation *GetInstance(); + void Init(); + void SetRotation(uint32_t rotationState); + uint32_t GetRotation(); +private: + class AudioRotationListener : public OHOS::Rosen::DisplayManager::IDisplayListener { + public: + void OnCreate(Rosen::DisplayId displayId) override; + void OnDestroy(Rosen::DisplayId displayId) override; + void OnChange(Rosen::DisplayId displayId) override; + }; + + void OnCreate(Rosen::DisplayId displayId); + void OnDestroy(Rosen::DisplayId displayId); + void OnChange(Rosen::DisplayId displayId); + + sptr audioRotationListener_; + uint32_t rotationState_; +}; +#endif +} // namespace AudioStandard +} // namespace OHOS +#endif // AUDIO_EFFECT_ROTATION_H \ No newline at end of file diff --git a/frameworks/native/audioeffect/include/audio_effect_volume.h b/frameworks/native/audioeffect/include/audio_effect_volume.h new file mode 100644 index 0000000000000000000000000000000000000000..dfc38cc87145c056f9c100e4a926e0c938342e82 --- /dev/null +++ b/frameworks/native/audioeffect/include/audio_effect_volume.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef AUDIO_EFFECT_VOLUME_H +#define AUDIO_EFFECT_VOLUME_H + +#include +#include +#include + +namespace OHOS { +namespace AudioStandard { +class AudioEffectVolume { +public: + AudioEffectVolume(); + ~AudioEffectVolume(); + static AudioEffectVolume *GetInstance(); + void SetApVolume(std::string sceneType, uint32_t volume); + uint32_t GetApVolume(std::string sceneType); + void SetDspVolume(uint32_t volume); + uint32_t GetDspVolume(); +private: + uint32_t dspVolume_; + std::mapSceneTypeToVolumeMap_; +}; +} // namespace AudioStandard +} // namespace OHOS +#endif // AUDIO_EFFECT_ROTATION_H \ No newline at end of file diff --git a/frameworks/native/audioeffect/src/audio_effect_chain_manager.cpp b/frameworks/native/audioeffect/src/audio_effect_chain_manager.cpp index 3298ce7167b10caaac230aed8fa72bfcb47058ee..b72ebcbd078fd4693dfd7c66010b051c4134bbff 100644 --- a/frameworks/native/audioeffect/src/audio_effect_chain_manager.cpp +++ b/frameworks/native/audioeffect/src/audio_effect_chain_manager.cpp @@ -165,6 +165,30 @@ int32_t EffectChainManagerMultichannelUpdate(const char *sceneType) return SUCCESS; } +int32_t EffectChainManagerVolumeUpdate(const char *sessionID, const uint32_t volume) +{ + AudioEffectChainManager *audioEffectChainManager = AudioEffectChainManager::GetInstance(); + CHECK_AND_RETURN_RET_LOG(audioEffectChainManager != nullptr, ERR_INVALID_HANDLE, "null audioEffectChainManager"); + std::string sessionIDString = ""; + sessionIDString = sessionID; + if (audioEffectChainManager->EffectVolumeUpdate(sessionIDString, volume) != SUCCESS) { + return ERROR; + } + return SUCCESS; +} + +#ifdef WINDOW_MANAGER_ENABLE +int32_t EffectChainManagerRotationUpdate(const uint32_t rotationState) +{ + AudioEffectChainManager *audioEffectChainManager = AudioEffectChainManager::GetInstance(); + CHECK_AND_RETURN_RET_LOG(audioEffectChainManager != nullptr, ERR_INVALID_HANDLE, "null audioEffectChainManager"); + if (audioEffectChainManager->EffectRotationUpdate(rotationState) != SUCCESS) { + return ERROR; + } + return SUCCESS; +} +#endif + bool IsChannelLayoutHVSSupported(const uint64_t channelLayout) { return find(HVS_SUPPORTED_CHANNELLAYOUTS.begin(), HVS_SUPPORTED_CHANNELLAYOUTS.end(), @@ -268,6 +292,7 @@ int32_t EffectChainManagerAddSessionInfo(const char *sceneType, const char *sess info.channels = pack.channels; info.channelLayout = channelLayoutNum; info.spatializationEnabled = spatializationEnabledString; + info.volume = pack.volume; return audioEffectChainManager->SessionInfoMapAdd(sessionIDString, info); } @@ -431,6 +456,24 @@ void AudioEffectChain::AddEffectHandle(AudioEffectHandle handle, AudioEffectLibr *data++ = EFFECT_SET_PARAM; *data++ = GetKeyFromValue(AUDIO_SUPPORTED_SCENE_TYPES, sceneType); *data++ = GetKeyFromValue(AUDIO_SUPPORTED_SCENE_MODES, effectMode); +#ifdef WINDOW_MANAGER_ENABLE + AudioEffectRotation *audioEffectRotation = AudioEffectRotation::GetInstance(); + if (audioEffectRotation == nullptr) { + *data++ = 0; + } else { + *data++ = audioEffectRotation->GetRotation(); + } +#else + *data++ = 0; +#endif + AUDIO_DEBUG_LOG("set ap integration rotation: %{public}u", *(data - 1)); + AudioEffectVolume *audioEffectVolume = AudioEffectVolume::GetInstance(); + if (audioEffectVolume == nullptr) { + *data++ = 0; + } else { + *data++ = audioEffectVolume->GetApVolume(sceneType); + } + AUDIO_DEBUG_LOG("set ap integration volume: %{public}u", *(data - 1)); cmdInfo = {sizeof(AudioEffectParam) + sizeof(int32_t) * NUM_SET_EFFECT_PARAM, effectParam}; ret = (*handle)->command(handle, EFFECT_CMD_SET_PARAM, &cmdInfo, &replyInfo); delete[] effectParam; @@ -441,6 +484,50 @@ void AudioEffectChain::AddEffectHandle(AudioEffectHandle handle, AudioEffectLibr latency_ += static_cast(replyData); } +int32_t AudioEffectChain::SetEffectParam() +{ + std::lock_guard lock(reloadMutex); + for (AudioEffectHandle handle: standByEffectHandles) { + AudioEffectParam *effectParam = new AudioEffectParam[sizeof(AudioEffectParam) + + NUM_SET_EFFECT_PARAM * sizeof(int32_t)]; + effectParam->status = 0; + effectParam->paramSize = sizeof(int32_t); + effectParam->valueSize = 0; + int32_t *data = &(effectParam->data[0]); + *data++ = EFFECT_SET_PARAM; + *data++ = GetKeyFromValue(AUDIO_SUPPORTED_SCENE_TYPES, sceneType); + *data++ = GetKeyFromValue(AUDIO_SUPPORTED_SCENE_MODES, effectMode); +#ifdef WINDOW_MANAGER_ENABLE + AudioEffectRotation *audioEffectRotation = AudioEffectRotation::GetInstance(); + if (audioEffectRotation == nullptr) { + AUDIO_DEBUG_LOG("null audioEffectRotation"); + *data++ = 0; + } else { + *data++ = audioEffectRotation->GetRotation(); + } +#else + *data++ = 0; +#endif + AUDIO_DEBUG_LOG("set ap integration rotation: %{public}u", *(data - 1)); + AudioEffectVolume *audioEffectVolume = AudioEffectVolume::GetInstance(); + if (audioEffectVolume == nullptr) { + AUDIO_DEBUG_LOG("null audioEffectVolume"); + *data++ = 0; + } else { + *data++ = audioEffectVolume->GetApVolume(sceneType); + } + AUDIO_DEBUG_LOG("set ap integration volume: %{public}u", *(data - 1)); + int32_t replyData = 0; + AudioEffectTransInfo cmdInfo = {sizeof(AudioEffectParam) + sizeof(int32_t) * NUM_SET_EFFECT_PARAM, + effectParam}; + AudioEffectTransInfo replyInfo = {sizeof(int32_t), &replyData}; + int32_t ret = (*handle)->command(handle, EFFECT_CMD_SET_PARAM, &cmdInfo, &replyInfo); + delete[] effectParam; + CHECK_AND_RETURN_RET_LOG(ret == 0, ERROR, "set rotation EFFECT_CMD_SET_PARAM fail"); + } + return SUCCESS; +} + void AudioEffectChain::AddEffectHandleEnd() { reloadMutex.unlock(); @@ -654,7 +741,7 @@ AudioEffectChainManager::AudioEffectChainManager() headTracker_ = std::make_shared(); #endif - audioEffectHdi_ = std::make_shared(); + audioEffectHdiParam_ = std::make_shared(); memset_s(static_cast(effectHdiInput), sizeof(effectHdiInput), 0, sizeof(effectHdiInput)); } @@ -823,9 +910,22 @@ void AudioEffectChainManager::InitAudioEffectChainManager(std::vectorInitHdi(); - + audioEffectHdiParam_->InitHdi(); + effectHdiInput[0] = HDI_BLUETOOTH_MODE; + effectHdiInput[1] = 1; + AUDIO_INFO_LOG("set hdi bluetooth mode: %{public}d", effectHdiInput[1]); + int32_t ret = audioEffectHdiParam_->UpdateHdiState(effectHdiInput); + if (ret != 0) { + AUDIO_WARNING_LOG("set hdi bluetooth mode failed"); + } +#ifdef WINDOW_MANAGER_ENABLE + AudioEffectRotation *audioEffectRotation = AudioEffectRotation::GetInstance(); + if (audioEffectRotation == nullptr) { + AUDIO_DEBUG_LOG("null audioEffectRotation"); + } else { + audioEffectRotation->Init(); + } +#endif isInitialized_ = true; } @@ -1040,6 +1140,140 @@ void AudioEffectChainManager::Dump() } } +int32_t AudioEffectChainManager::EffectDspVolumeUpdate(AudioEffectVolume *audioEffectVolume) +{ + // update dsp volume + AUDIO_DEBUG_LOG("send volume to dsp."); + CHECK_AND_RETURN_RET_LOG(audioEffectVolume != nullptr, ERROR, "null audioEffectVolume"); + uint32_t volumeMax = 0; + for (auto it = SceneTypeToSessionIDMap_.begin(); it != SceneTypeToSessionIDMap_.end(); it++) { + std::set sessions = SceneTypeToSessionIDMap_[it->first]; + for (auto s = sessions.begin(); s != sessions.end(); s++) { + sessionEffectInfo info = SessionIDToEffectInfoMap_[*s]; + volumeMax = info.volume > volumeMax ? info.volume : volumeMax; + } + } + // send volume to dsp + if (audioEffectVolume->GetDspVolume() != volumeMax) { + audioEffectVolume->SetDspVolume(volumeMax); + effectHdiInput[0] = HDI_VOLUME; + effectHdiInput[1] = volumeMax; + AUDIO_INFO_LOG("set hdi volume: %{public}d", effectHdiInput[1]); + int32_t ret = audioEffectHdiParam_->UpdateHdiState(effectHdiInput); + CHECK_AND_RETURN_RET_LOG(ret == 0, ERROR, "set hdi volume failed"); + } + return SUCCESS; +} + +int32_t AudioEffectChainManager::EffectApVolumeUpdate(AudioEffectVolume *audioEffectVolume) +{ + // send to ap + AUDIO_DEBUG_LOG("send volume to ap."); + CHECK_AND_RETURN_RET_LOG(audioEffectVolume != nullptr, ERROR, "null audioEffectVolume"); + for (auto it = SceneTypeToSessionIDMap_.begin(); it != SceneTypeToSessionIDMap_.end(); it++) { + uint32_t volumeMax = 0; + std::set sessions = SceneTypeToSessionIDMap_[it->first]; + for (auto s = sessions.begin(); s != sessions.end(); s++) { + sessionEffectInfo info = SessionIDToEffectInfoMap_[*s]; + volumeMax = info.volume > volumeMax ? info.volume : volumeMax; + } + if (audioEffectVolume->GetApVolume(it->first) != volumeMax) { + audioEffectVolume->SetApVolume(it->first, volumeMax); + std::string sceneTypeAndDeviceKey = it->first + "_&_" + GetDeviceTypeName(); + if (!SceneTypeToEffectChainMap_.count(sceneTypeAndDeviceKey)) { + return ERROR; + } + auto *audioEffectChain = SceneTypeToEffectChainMap_[sceneTypeAndDeviceKey]; + if (audioEffectChain == nullptr) { + return ERROR; + } + AUDIO_INFO_LOG("set ap volume: %{public}d sceneType: %{public}s", volumeMax, it->first.c_str()); + int32_t ret = audioEffectChain->SetEffectParam(); + CHECK_AND_RETURN_RET_LOG(ret == 0, ERROR, "set ap volume failed"); + } + } + return SUCCESS; +} + +int32_t AudioEffectChainManager::EffectVolumeUpdate(const std::string sessionIDString, const uint32_t volume) +{ + std::lock_guard lock(dynamicMutex_); + // update session info + if (SessionIDToEffectInfoMap_.count(sessionIDString)) { + if (SessionIDToEffectInfoMap_[sessionIDString].volume != volume) { + SessionIDToEffectInfoMap_[sessionIDString].volume = volume; + } + } + AudioEffectVolume *audioEffectVolume = AudioEffectVolume::GetInstance(); + int32_t ret; + if (offloadEnabled_) { + ret = EffectDspVolumeUpdate(audioEffectVolume); + } else { + ret = EffectApVolumeUpdate(audioEffectVolume); + } + return ret; +} + +#ifdef WINDOW_MANAGER_ENABLE +int32_t AudioEffectChainManager::EffectDspRotationUpdate(AudioEffectRotation *audioEffectRotation, + const uint32_t rotationState) +{ + // send rotation to dsp + AUDIO_DEBUG_LOG("send rotation to dsp."); + CHECK_AND_RETURN_RET_LOG(audioEffectRotation != nullptr, ERROR, "null audioEffectRotation"); + if (audioEffectRotation->GetRotation() != rotationState) { + AUDIO_DEBUG_LOG("rotationState change, new state: %{public}d, previous state: %{public}d", + rotationState, audioEffectRotation->GetRotation()); + audioEffectRotation->SetRotation(rotationState); + effectHdiInput[0] = HDI_ROTATION; + effectHdiInput[1] = rotationState; + AUDIO_INFO_LOG("set hdi rotation: %{public}d", effectHdiInput[1]); + int32_t ret = audioEffectHdiParam_->UpdateHdiState(effectHdiInput); + CHECK_AND_RETURN_RET_LOG(ret == 0, ERROR, "set hdi rotation failed"); + } + return SUCCESS; +} + +int32_t AudioEffectChainManager::EffectApRotationUpdate(AudioEffectRotation *audioEffectRotation, + const uint32_t rotationState) +{ + // send rotation to ap + AUDIO_DEBUG_LOG("send rotation to ap."); + CHECK_AND_RETURN_RET_LOG(audioEffectRotation != nullptr, ERROR, "null audioEffectRotation"); + if (audioEffectRotation->GetRotation() != rotationState) { + AUDIO_DEBUG_LOG("rotationState change, new state: %{public}d, previous state: %{public}d", + rotationState, audioEffectRotation->GetRotation()); + audioEffectRotation->SetRotation(rotationState); + for (auto it = SceneTypeToSessionIDMap_.begin(); it != SceneTypeToSessionIDMap_.end(); it++) { + std::string sceneTypeAndDeviceKey = it->first + "_&_" + GetDeviceTypeName(); + if (!SceneTypeToEffectChainMap_.count(sceneTypeAndDeviceKey)) { + return ERROR; + } + auto *audioEffectChain = SceneTypeToEffectChainMap_[sceneTypeAndDeviceKey]; + if (audioEffectChain == nullptr) { + return ERROR; + } + int32_t ret = audioEffectChain->SetEffectParam(); + CHECK_AND_RETURN_RET_LOG(ret == 0, ERROR, "set ap rotation failed"); + } + } + return SUCCESS; +} + +int32_t AudioEffectChainManager::EffectRotationUpdate(const uint32_t rotationState) +{ + std::lock_guard lock(dynamicMutex_); + AudioEffectRotation *audioEffectRotation = AudioEffectRotation::GetInstance(); + int32_t ret; + if (offloadEnabled_) { + ret = EffectDspRotationUpdate(audioEffectRotation, rotationState); + } else { + ret = EffectApRotationUpdate(audioEffectRotation, rotationState); + } + return ret; +} +#endif + int32_t AudioEffectChainManager::UpdateMultichannelConfig(const std::string &sceneType) { std::lock_guard lock(dynamicMutex_); @@ -1090,9 +1324,9 @@ int32_t AudioEffectChainManager::UpdateSpatializationState(AudioSpatializationSt memset_s(static_cast(effectHdiInput), sizeof(effectHdiInput), 0, sizeof(effectHdiInput)); if (spatializationEnabled_) { effectHdiInput[0] = HDI_INIT; - int32_t ret = audioEffectHdi_->UpdateHdiState(effectHdiInput); + int32_t ret = audioEffectHdiParam_->UpdateHdiState(effectHdiInput); if (ret != 0) { - AUDIO_ERR_LOG("set hdi init failed, backup spatialization entered"); + AUDIO_WARNING_LOG("set hdi init failed, backup spatialization entered"); offloadEnabled_ = false; } else { AUDIO_INFO_LOG("set hdi init succeeded, normal spatialization entered"); @@ -1102,9 +1336,9 @@ int32_t AudioEffectChainManager::UpdateSpatializationState(AudioSpatializationSt } else { effectHdiInput[0] = HDI_DESTROY; AUDIO_INFO_LOG("set hdi destroy."); - int32_t ret = audioEffectHdi_->UpdateHdiState(effectHdiInput); + int32_t ret = audioEffectHdiParam_->UpdateHdiState(effectHdiInput); if (ret != 0) { - AUDIO_ERR_LOG("set hdi destroy failed"); + AUDIO_WARNING_LOG("set hdi destroy failed"); } offloadEnabled_ = false; RecoverAllChains(); @@ -1179,7 +1413,8 @@ int32_t AudioEffectChainManager::SessionInfoMapAdd(std::string sessionID, sessio SceneTypeToSessionIDMap_[info.sceneType].insert(sessionID); SessionIDToEffectInfoMap_[sessionID] = info; } else if (SessionIDToEffectInfoMap_[sessionID].sceneMode != info.sceneMode || - SessionIDToEffectInfoMap_[sessionID].spatializationEnabled != info.spatializationEnabled) { + SessionIDToEffectInfoMap_[sessionID].spatializationEnabled != info.spatializationEnabled || + SessionIDToEffectInfoMap_[sessionID].volume != info.volume) { SessionIDToEffectInfoMap_[sessionID] = info; } else { return ERROR; @@ -1221,7 +1456,7 @@ int32_t AudioEffectChainManager::SetHdiParam(std::string sceneType, std::string effectHdiInput[0] = HDI_BYPASS; effectHdiInput[1] = enabled == true ? 0 : 1; AUDIO_INFO_LOG("set hdi bypass: %{public}d", effectHdiInput[1]); - int32_t ret = audioEffectHdi_->UpdateHdiState(effectHdiInput); + int32_t ret = audioEffectHdiParam_->UpdateHdiState(effectHdiInput); if (ret != 0) { AUDIO_WARNING_LOG("set hdi bypass failed"); return ret; @@ -1232,7 +1467,7 @@ int32_t AudioEffectChainManager::SetHdiParam(std::string sceneType, std::string effectHdiInput[HDI_ROOM_MODE_INDEX_TWO] = GetKeyFromValue(AUDIO_SUPPORTED_SCENE_MODES, effectMode); AUDIO_INFO_LOG("set hdi room mode sceneType: %{public}d, effectMode: %{public}d", effectHdiInput[1], effectHdiInput[HDI_ROOM_MODE_INDEX_TWO]); - ret = audioEffectHdi_->UpdateHdiState(effectHdiInput); + ret = audioEffectHdiParam_->UpdateHdiState(effectHdiInput); if (ret != 0) { AUDIO_WARNING_LOG("set hdi room mode failed"); return ret; @@ -1240,88 +1475,28 @@ int32_t AudioEffectChainManager::SetHdiParam(std::string sceneType, std::string return SUCCESS; } -AudioEffectHdi::AudioEffectHdi() -{ - AUDIO_INFO_LOG("AudioEffectHdi constructor!"); - memset_s(static_cast(input), sizeof(input), 0, sizeof(input)); - memset_s(static_cast(output), sizeof(output), 0, sizeof(output)); - replyLen = GET_HDI_BUFFER_LEN; -} - -AudioEffectHdi::~AudioEffectHdi() -{ - AUDIO_INFO_LOG("AudioEffectHdi destructor!"); -} - -void AudioEffectHdi::InitHdi() -{ - hdiModel_ = IEffectModelGet(false); - if (hdiModel_ == nullptr) { - AUDIO_WARNING_LOG("IEffectModelGet failed"); - hdiControl_ = nullptr; - return; - } - libName = strdup("libspatialization_processing_dsp"); - effectId = strdup("aaaabbbb-8888-9999-6666-aabbccdd9966gg"); - EffectInfo info = { - .libName = &libName[0], - .effectId = &effectId[0], - .ioDirection = 1, - }; - ControllerId controllerId; - int32_t ret = hdiModel_->CreateEffectController(hdiModel_, &info, &hdiControl_, &controllerId); - if ((ret != 0) || (hdiControl_ == nullptr)) { - AUDIO_WARNING_LOG("hdi init failed"); - hdiControl_ = nullptr; - return; - } - - uint32_t replyLen = GET_HDI_BUFFER_LEN; - input[0] = HDI_BLUETOOTH_MODE; - input[1] = 1; - AUDIO_INFO_LOG("set hdi bluetooth mode."); - ret = hdiControl_->SendCommand(hdiControl_, HDI_SET_PATAM, input, SEND_HDI_COMMAND_LEN, output, &replyLen); - if (ret != 0) { - AUDIO_WARNING_LOG("set hdi bluetooth mode failed"); - hdiControl_ = nullptr; - return; - } -} - -int32_t AudioEffectHdi::UpdateHdiState(int8_t *effectHdiInput) -{ - if (hdiControl_ == nullptr) { - AUDIO_WARNING_LOG("hdiControl_ is nullptr."); - return ERROR; - } - memcpy_s(static_cast(input), sizeof(input), static_cast(effectHdiInput), sizeof(input)); - uint32_t replyLen = GET_HDI_BUFFER_LEN; - int32_t ret = hdiControl_->SendCommand(hdiControl_, HDI_SET_PATAM, input, SEND_HDI_COMMAND_LEN, output, &replyLen); - if (ret != 0) { - AUDIO_WARNING_LOG("hdi send command failed"); - return ret; - } - return ret; -} - void AudioEffectChainManager::UpdateSensorState() { effectHdiInput[0] = HDI_HEAD_MODE; effectHdiInput[1] = headTrackingEnabled_ == true ? 1 : 0; AUDIO_INFO_LOG("set hdi head mode: %{public}d", effectHdiInput[1]); - int32_t ret = audioEffectHdi_->UpdateHdiState(effectHdiInput); + int32_t ret = audioEffectHdiParam_->UpdateHdiState(effectHdiInput); if (ret != 0) { - AUDIO_ERR_LOG("set hdi head mode failed"); + AUDIO_WARNING_LOG("set hdi head mode failed"); } if (headTrackingEnabled_) { #ifdef SENSOR_ENABLE if (offloadEnabled_) { headTracker_->SensorInit(); - headTracker_->SensorSetConfig(DSP_SPATIALIZER_ENGINE); + ret = headTracker_->SensorSetConfig(DSP_SPATIALIZER_ENGINE); } else { headTracker_->SensorInit(); - headTracker_->SensorSetConfig(ARM_SPATIALIZER_ENGINE); + ret = headTracker_->SensorSetConfig(ARM_SPATIALIZER_ENGINE); + } + + if (ret != 0) { + AUDIO_ERR_LOG("SensorSetConfig error!"); } if (headTracker_->SensorActive() != 0) { diff --git a/frameworks/native/audioeffect/src/audio_effect_hdi_param.cpp b/frameworks/native/audioeffect/src/audio_effect_hdi_param.cpp new file mode 100644 index 0000000000000000000000000000000000000000..f376907ebcff829451fbb7f22df7155aa6903d3b --- /dev/null +++ b/frameworks/native/audioeffect/src/audio_effect_hdi_param.cpp @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "audio_effect.h" +#include "audio_effect_hdi_param.h" +#include "audio_errors.h" +#include "audio_log.h" +#include "securec.h" + +namespace OHOS { +namespace AudioStandard { +AudioEffectHdiParam::AudioEffectHdiParam() +{ + AUDIO_DEBUG_LOG("constructor."); + libHdiControls_.clear(); + int32_t ret = memset_s(static_cast(input_), sizeof(input_), 0, sizeof(input_)); + if (ret == 0) { + AUDIO_ERR_LOG("hdi constructor memset input failed"); + } + ret = memset_s(static_cast(output_), sizeof(output_), 0, sizeof(output_)); + if (ret == 0) { + AUDIO_ERR_LOG("hdi constructor memset output failed"); + } + replyLen_ = GET_HDI_BUFFER_LEN; + hdiModel_ = nullptr; +} + +AudioEffectHdiParam::~AudioEffectHdiParam() +{ + AUDIO_DEBUG_LOG("destructor!"); +} + +void AudioEffectHdiParam::CreateHdiControl() +{ + // todo read from vendor/... + libName_ = strdup("libspatialization_processing_dsp"); + effectId_ = strdup("aaaabbbb-8888-9999-6666-aabbccdd9966gg"); + EffectInfo info = { + .libName = &libName_[0], + .effectId = &effectId_[0], + .ioDirection = 1, + }; + ControllerId controllerId; + IEffectControl *hdiControl = nullptr; + int32_t ret = hdiModel_->CreateEffectController(hdiModel_, &info, &hdiControl, &controllerId); + if ((ret != 0) || (hdiControl == nullptr)) { + AUDIO_WARNING_LOG("hdi init failed"); + } else { + libHdiControls_.emplace_back(hdiControl); + } + + return; +} + +void AudioEffectHdiParam::InitHdi() +{ + hdiModel_ = IEffectModelGet(false); + if (hdiModel_ == nullptr) { + AUDIO_ERR_LOG("IEffectModelGet failed"); + return; + } + + CreateHdiControl(); +} + +int32_t AudioEffectHdiParam::UpdateHdiState(int8_t *effectHdiInput) +{ + int32_t ret; + for (IEffectControl *hdiControl : libHdiControls_) { + if (hdiControl == nullptr) { + AUDIO_WARNING_LOG("hdiControl is nullptr."); + continue; + } + ret = memcpy_s(static_cast(input_), sizeof(input_), + static_cast(effectHdiInput), sizeof(input_)); + CHECK_AND_CONTINUE_LOG(ret == 0, "hdi memcpy failed"); + uint32_t replyLen = GET_HDI_BUFFER_LEN; + ret = hdiControl->SendCommand(hdiControl, HDI_SET_PATAM, input_, SEND_HDI_COMMAND_LEN, + output_, &replyLen); + CHECK_AND_CONTINUE_LOG(ret == 0, "hdi send command failed"); + } + return ret; +} +} // namespace AudioStandard +} // namespace OHOS \ No newline at end of file diff --git a/frameworks/native/audioeffect/src/audio_effect_rotation.cpp b/frameworks/native/audioeffect/src/audio_effect_rotation.cpp new file mode 100644 index 0000000000000000000000000000000000000000..d992a21debe6247311c485482d30a85226cb9375 --- /dev/null +++ b/frameworks/native/audioeffect/src/audio_effect_rotation.cpp @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "audio_effect_chain_adapter.h" +#include "audio_effect_rotation.h" +#include "audio_log.h" + +namespace OHOS { +namespace AudioStandard { +#ifdef WINDOW_MANAGER_ENABLE +void AudioEffectRotation::AudioRotationListener::OnCreate(Rosen::DisplayId displayId) +{ + AudioEffectRotation *audioEffectRotation = GetInstance(); + if (audioEffectRotation != nullptr) { + audioEffectRotation->OnCreate(displayId); + } +} +void AudioEffectRotation::AudioRotationListener::OnDestroy(Rosen::DisplayId displayId) +{ + AudioEffectRotation *audioEffectRotation = GetInstance(); + if (audioEffectRotation != nullptr) { + audioEffectRotation->OnDestroy(displayId); + } +} +void AudioEffectRotation::AudioRotationListener::OnChange(Rosen::DisplayId displayId) +{ + AudioEffectRotation *audioEffectRotation = GetInstance(); + if (audioEffectRotation != nullptr) { + audioEffectRotation->OnChange(displayId); + } +} + +AudioEffectRotation::AudioEffectRotation() +{ + AUDIO_DEBUG_LOG("created!"); + rotationState_ = 0; +} + +AudioEffectRotation::~AudioEffectRotation() +{ + AUDIO_DEBUG_LOG("destroyed!"); +} + +AudioEffectRotation *AudioEffectRotation::GetInstance() +{ + static AudioEffectRotation audioEffectRotation; + return &audioEffectRotation; +} + +void AudioEffectRotation::Init() +{ + AUDIO_DEBUG_LOG("Call RegisterDisplayListener."); + audioRotationListener_ = new AudioRotationListener(); + Rosen::DisplayManager::GetInstance().RegisterDisplayListener(audioRotationListener_); +} + +void AudioEffectRotation::SetRotation(uint32_t rotationState) +{ + rotationState_ = rotationState; +} + +uint32_t AudioEffectRotation::GetRotation() +{ + return rotationState_; +} + +void AudioEffectRotation::OnCreate(Rosen::DisplayId displayId) +{ + AUDIO_DEBUG_LOG("Onchange displayId: %{public}d.", static_cast(displayId)); +} + +void AudioEffectRotation::OnDestroy(Rosen::DisplayId displayId) +{ + AUDIO_DEBUG_LOG("Onchange displayId: %{public}d.", static_cast(displayId)); +} + +void AudioEffectRotation::OnChange(Rosen::DisplayId displayId) +{ + // get display + auto display = Rosen::DisplayManager::GetInstance().GetDisplayById(displayId); + if (!display) { + AUDIO_WARNING_LOG("Get display by displayId: %{public}d failed.", + static_cast(displayId)); + return; + } + // get rotation + Rosen::Rotation newRotationState = display->GetRotation(); + AUDIO_DEBUG_LOG("Onchange displayId: %{public}d rotationState: %{public}u.", + static_cast(displayId), static_cast(newRotationState)); + EffectChainManagerRotationUpdate(static_cast(newRotationState)); +} +#endif +} // namespace AudioStandard +} // namespace OHOS \ No newline at end of file diff --git a/frameworks/native/audioeffect/src/audio_effect_volume.cpp b/frameworks/native/audioeffect/src/audio_effect_volume.cpp new file mode 100644 index 0000000000000000000000000000000000000000..3b3c002273c19ccfd32a4bb560580d4279a0cef4 --- /dev/null +++ b/frameworks/native/audioeffect/src/audio_effect_volume.cpp @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "audio_effect_volume.h" +#include "audio_log.h" + +namespace OHOS { +namespace AudioStandard { +AudioEffectVolume::AudioEffectVolume() +{ + AUDIO_DEBUG_LOG("created!"); + SceneTypeToVolumeMap_.clear(); + dspVolume_ = 0; +} + +AudioEffectVolume::~AudioEffectVolume() +{ + AUDIO_DEBUG_LOG("destructor!"); +} + +AudioEffectVolume *AudioEffectVolume::GetInstance() +{ + static AudioEffectVolume audioEffectVolume; + return &audioEffectVolume; +} + +void AudioEffectVolume::SetApVolume(std::string sceneType, uint32_t volume) +{ + if (!SceneTypeToVolumeMap_.count(sceneType)) { + SceneTypeToVolumeMap_.insert(std::make_pair(sceneType, volume)); + } else { + SceneTypeToVolumeMap_[sceneType] = volume; + } +} + +uint32_t AudioEffectVolume::GetApVolume(std::string sceneType) +{ + if (!SceneTypeToVolumeMap_.count(sceneType)) { + return 0; + } else { + return SceneTypeToVolumeMap_[sceneType]; + } +} + +void AudioEffectVolume::SetDspVolume(uint32_t volume) +{ + AUDIO_DEBUG_LOG("setDspVolume: %{public}u", volume); + dspVolume_ = volume; +} + +uint32_t AudioEffectVolume::GetDspVolume() +{ + return dspVolume_; +} +} // namespace AudioStandard +} // namespace OHOS \ No newline at end of file diff --git a/frameworks/native/pulseaudio/modules/hdi/hdi_sink.c b/frameworks/native/pulseaudio/modules/hdi/hdi_sink.c index 9a0ef234054761c6aed8951e6321e35038e1ae43..ad530ef4a739169b236064abcb94ea1a82470671 100644 --- a/frameworks/native/pulseaudio/modules/hdi/hdi_sink.c +++ b/frameworks/native/pulseaudio/modules/hdi/hdi_sink.c @@ -146,7 +146,7 @@ struct Userdata { size_t processSize; char *sinkSceneType; char *sinkSceneMode; - bool spatialEnabled; + bool hdiEffectEnabled; pthread_mutex_t mutexPa; pthread_mutex_t mutexPa2; pthread_rwlock_t rwlockSleep; @@ -2590,7 +2590,7 @@ static void SetHdiParam(struct Userdata *userdata) int sessionIDMax = -1; char *sinkSceneTypeMax = ""; char *sinkSceneModeMax = ""; - bool spatialEnabledMax = false; + bool hdiEffectEnabledMax = false; while ((i = pa_hashmap_iterate(userdata->sink->thread_info.inputs, &state, NULL))) { pa_sink_input_assert_ref(i); const char *clientUid = pa_proplist_gets(i->proplist, "stream.client.uid"); @@ -2604,13 +2604,15 @@ static void SetHdiParam(struct Userdata *userdata) const char *sinkSessionStr = pa_proplist_gets(i->proplist, "stream.sessionID"); bool spatializationEnabled = pa_safe_streq(sinkSpatialization, "1") ? true : false; bool effectEnabled = pa_safe_streq(sinkSceneMode, "EFFECT_DEFAULT") ? true : false; - bool spatialEnabled = spatializationEnabled && effectEnabled; + bool hdiEffectEnabled = spatializationEnabled && effectEnabled; int sessionID = atoi(sinkSessionStr == NULL ? "-1" : sinkSessionStr); - if (sessionID > sessionIDMax && sinkSceneType && sinkSceneMode && sinkSpatialization) { - sessionIDMax = sessionID; - sinkSceneTypeMax = (char *)sinkSceneType; - sinkSceneModeMax = (char *)sinkSceneMode; - spatialEnabledMax = spatialEnabled; + if (sinkSceneType && sinkSceneMode && sinkSpatialization) { + if (sessionID > sessionIDMax) { + sessionIDMax = sessionID; + sinkSceneTypeMax = (char *)sinkSceneType; + sinkSceneModeMax = (char *)sinkSceneMode; + hdiEffectEnabledMax = hdiEffectEnabled; + } } } @@ -2621,12 +2623,12 @@ static void SetHdiParam(struct Userdata *userdata) if (!pa_safe_streq(userdata->sinkSceneType, sinkSceneTypeMax) || !pa_safe_streq(userdata->sinkSceneMode, sinkSceneModeMax) || - (userdata->spatialEnabled != spatialEnabledMax)) { - userdata->sinkSceneMode = sinkSceneModeMax; - userdata->sinkSceneType = sinkSceneTypeMax; - userdata->spatialEnabled = spatialEnabledMax; - EffectChainManagerSetHdiParam(userdata->sinkSceneType, userdata->sinkSceneMode, userdata->spatialEnabled); - } + (userdata->hdiEffectEnabled != hdiEffectEnabledMax)) { + userdata->sinkSceneMode = sinkSceneModeMax; + userdata->sinkSceneType = sinkSceneTypeMax; + userdata->hdiEffectEnabled = hdiEffectEnabledMax; + EffectChainManagerSetHdiParam(userdata->sinkSceneType, userdata->sinkSceneMode, userdata->hdiEffectEnabled); + } } static void ThreadFuncRendererTimerLoop(struct Userdata *u, int64_t *sleepForUsec) @@ -3355,7 +3357,7 @@ static void PaHdiSinkUserdataInit(struct Userdata *u) u->bufferAttr->numChanOut = u->ss.channels; u->sinkSceneMode = ""; u->sinkSceneType = ""; - u->spatialEnabled = false; + u->hdiEffectEnabled = false; } static pa_sink *PaHdiSinkInit(struct Userdata *u, pa_modargs *ma, const char *driver) diff --git a/frameworks/native/pulseaudio/modules/hdi/module_hdi_sink.c b/frameworks/native/pulseaudio/modules/hdi/module_hdi_sink.c index 3cae3497d7973778cb7acd4b3a90c35a65199252..e344218e2b260a441d63a1497c998994a8489cd0 100644 --- a/frameworks/native/pulseaudio/modules/hdi/module_hdi_sink.c +++ b/frameworks/native/pulseaudio/modules/hdi/module_hdi_sink.c @@ -25,6 +25,7 @@ #include #include #include "audio_effect_chain_adapter.h" +#include "audio_log.h" #include "playback_capturer_adapter.h" pa_sink *PaHdiSinkNew(pa_module *m, pa_modargs *ma, const char *driver); @@ -89,6 +90,7 @@ static pa_hook_result_t SinkInputNewCb(pa_core *c, pa_sink_input *si) const uint32_t channels = si->sample_spec.channels; const char *channelLayout = pa_proplist_gets(si->proplist, "stream.channelLayout"); const char *spatializationEnabled = pa_proplist_gets(si->proplist, "spatialization.enabled"); + uint32_t volume = si->volume.values[0]; if (pa_safe_streq(deviceString, "remote")) { EffectChainManagerReleaseCb(sceneType, sessionID); return PA_HOOK_OK; @@ -106,7 +108,7 @@ static pa_hook_result_t SinkInputNewCb(pa_core *c, pa_sink_input *si) EffectChainManagerInitCb(sceneType); } EffectChainManagerCreateCb(sceneType, sessionID); - SessionInfoPack pack = {channels, channelLayout, sceneMode, spatializationEnabled}; + SessionInfoPack pack = {channels, channelLayout, sceneMode, spatializationEnabled, volume}; if (si->state == PA_SINK_INPUT_RUNNING && !EffectChainManagerAddSessionInfo(sceneType, sessionID, pack)) { EffectChainManagerMultichannelUpdate(sceneType); } @@ -114,7 +116,7 @@ static pa_hook_result_t SinkInputNewCb(pa_core *c, pa_sink_input *si) return PA_HOOK_OK; } -static pa_hook_result_t SinkInputUnlinkCb(pa_core *c, pa_sink_input *si) +static pa_hook_result_t SinkInputUnlinkCb(pa_core *c, pa_sink_input *si, void *u) { pa_assert(c); @@ -141,7 +143,7 @@ static pa_hook_result_t SinkInputUnlinkCb(pa_core *c, pa_sink_input *si) return PA_HOOK_OK; } -static pa_hook_result_t SourceOutputStateChangedCb(pa_core *c, pa_source_output *so) +static pa_hook_result_t SourceOutputStateChangedCb(pa_core *c, pa_source_output *so, void *u) { pa_assert(c); pa_assert(so); @@ -164,7 +166,7 @@ static pa_hook_result_t SourceOutputStateChangedCb(pa_core *c, pa_source_output return PA_HOOK_OK; } -static pa_hook_result_t SinkInputStateChangedCb(pa_core *c, pa_sink_input *si) +static pa_hook_result_t SinkInputStateChangedCb(pa_core *c, pa_sink_input *si, void *u) { pa_assert(c); pa_sink_input_assert_ref(si); @@ -177,9 +179,10 @@ static pa_hook_result_t SinkInputStateChangedCb(pa_core *c, pa_sink_input *si) const char *spatializationEnabled = pa_proplist_gets(si->proplist, "spatialization.enabled"); const char *clientUid = pa_proplist_gets(si->proplist, "stream.client.uid"); const char *bootUpMusic = "1003"; + uint32_t volume = si->volume.values[0]; if (si->state == PA_SINK_INPUT_RUNNING && si->sink && !pa_safe_streq(clientUid, bootUpMusic)) { - SessionInfoPack pack = {channels, channelLayout, sceneMode, spatializationEnabled}; + SessionInfoPack pack = {channels, channelLayout, sceneMode, spatializationEnabled, volume}; if (!EffectChainManagerAddSessionInfo(sceneType, sessionID, pack)) { EffectChainManagerMultichannelUpdate(sceneType); } @@ -194,6 +197,15 @@ static pa_hook_result_t SinkInputStateChangedCb(pa_core *c, pa_sink_input *si) return PA_HOOK_OK; } +static pa_hook_result_t SinkInputVolumeChangedCb(pa_core *c, pa_sink_input *si, void *u) +{ + AUDIO_DEBUG_LOG("volume changed."); + const char *sessionID = pa_proplist_gets(si->proplist, "stream.sessionID"); + const uint32_t volume = si->volume.values[0]; + EffectChainManagerVolumeUpdate(sessionID, volume); + return PA_HOOK_OK; +} + int pa__init(pa_module *m) { pa_modargs *ma = NULL; @@ -216,6 +228,8 @@ int pa__init(pa_module *m) (pa_hook_cb_t)SourceOutputStateChangedCb, NULL); pa_module_hook_connect(m, &m->core->hooks[PA_CORE_HOOK_SINK_INPUT_STATE_CHANGED], PA_HOOK_LATE, (pa_hook_cb_t)SinkInputStateChangedCb, NULL); + pa_module_hook_connect(m, &m->core->hooks[PA_CORE_HOOK_SINK_INPUT_VOLUME_CHANGED], PA_HOOK_LATE, + (pa_hook_cb_t)SinkInputVolumeChangedCb, NULL); pa_modargs_free(ma); diff --git a/interfaces/inner_api/native/audiocommon/include/audio_effect.h b/interfaces/inner_api/native/audiocommon/include/audio_effect.h index e803e9b1385f87f2f4ac0d0a4c1adf07097b3007..32eb9b0bf61670cbd80ee1a8577f5c60b0755842 100644 --- a/interfaces/inner_api/native/audiocommon/include/audio_effect.h +++ b/interfaces/inner_api/native/audiocommon/include/audio_effect.h @@ -44,6 +44,8 @@ constexpr int32_t HDI_HEAD_MODE = 2; constexpr int32_t HDI_ROOM_MODE = 3; constexpr int32_t HDI_BLUETOOTH_MODE = 4; constexpr int32_t HDI_DESTROY = 5; +constexpr int32_t HDI_VOLUME = 7; +constexpr int32_t HDI_ROTATION = 8; enum AudioSpatialDeviceType { EARPHONE_TYPE_NONE = 0, diff --git a/services/audio_service/BUILD.gn b/services/audio_service/BUILD.gn index cd3f6b73271c81669eb522a982f43951d9b3e380..41dc29e27192772d0d0d5b4aeb8debf0f49a0131 100644 --- a/services/audio_service/BUILD.gn +++ b/services/audio_service/BUILD.gn @@ -15,6 +15,7 @@ import("//build/ohos.gni") import("../../config.gni") import("../../ressche_part.gni") import("../../sensor.gni") +import("../../window_manager.gni") pulseaudio_dir = "//third_party/pulseaudio" pulseaudio_build_path = "//third_party/pulseaudio/ohosbuild" @@ -390,6 +391,10 @@ ohos_shared_library("audio_service") { external_deps += [ "sensor:sensor_interface_native" ] } + if (window_manager_enable == true) { + external_deps += [ "window_manager:libdm" ] + } + if (ressche_enable == true) { external_deps += [ "resource_schedule_service:ressched_client" ] } diff --git a/window_manager.gni b/window_manager.gni new file mode 100644 index 0000000000000000000000000000000000000000..451bb74ae8b2346b5c6c344cd9ee1dc0308a7c3d --- /dev/null +++ b/window_manager.gni @@ -0,0 +1,19 @@ +# Copyright (c) 2024 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +if (defined(global_parts_info) && + defined(global_parts_info.window_window_manager)) { + window_manager_enable = true +} else { + window_manager_enable = false +}