1 /*
2 * Copyright (c) 2024-2025 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15 #ifndef LOG_TAG
16 #define LOG_TAG "OfflineAudioEffectManager"
17 #endif
18
19 #include "offline_audio_effect_chain_impl.h"
20
21 #include <securec.h>
22
23 #include "audio_errors.h"
24 #include "audio_service_log.h"
25 #include "audio_utils.h"
26
27 namespace OHOS {
28 namespace AudioStandard {
29 static constexpr size_t MAX_PARAM_SIZE = 1000;
OfflineAudioEffectChainImpl(const std::string & effectChainName)30 OfflineAudioEffectChainImpl::OfflineAudioEffectChainImpl(const std::string &effectChainName)
31 {
32 chainName_ = effectChainName;
33 offlineStreamInClient_ = OfflineStreamInClient::Create();
34 AUDIO_INFO_LOG("%{public}s offline effect chain created!", chainName_.c_str());
35 }
36
~OfflineAudioEffectChainImpl()37 OfflineAudioEffectChainImpl::~OfflineAudioEffectChainImpl()
38 {
39 Release();
40 }
41
InitDump()42 void OfflineAudioEffectChainImpl::InitDump()
43 {
44 static uint32_t chainId = 0;
45 std::string dumpFileName = "OfflineEffectClient";
46 std::string dumpFileInName = dumpFileName + "_" + std::to_string(chainId) + "_In.pcm";
47 std::string dumpFileOutName = dumpFileName + "_" + std::to_string(chainId) + "_Out.pcm";
48 DumpFileUtil::OpenDumpFile(DumpFileUtil::DUMP_CLIENT_PARA, dumpFileInName, &dumpFileIn_);
49 DumpFileUtil::OpenDumpFile(DumpFileUtil::DUMP_CLIENT_PARA, dumpFileOutName, &dumpFileOut_);
50 chainId++;
51 }
52
CreateEffectChain()53 int32_t OfflineAudioEffectChainImpl::CreateEffectChain()
54 {
55 std::lock_guard<std::mutex> lock(streamClientMutex_);
56 CHECK_AND_RETURN_RET_LOG(offlineStreamInClient_, ERR_ILLEGAL_STATE, "offline stream is null!");
57 int32_t ret = offlineStreamInClient_->CreateOfflineEffectChain(chainName_);
58 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ret, "InitIpcChainFailed!");
59 InitDump();
60 return SUCCESS;
61 }
62
Configure(const AudioStreamInfo & inInfo,const AudioStreamInfo & outInfo)63 int32_t OfflineAudioEffectChainImpl::Configure(const AudioStreamInfo &inInfo, const AudioStreamInfo &outInfo)
64 {
65 CHECK_AND_RETURN_RET_LOG(CheckSupportedParams(inInfo) == SUCCESS, ERR_INVALID_PARAM, "inInfo do not support");
66 CHECK_AND_RETURN_RET_LOG(CheckSupportedParams(outInfo) == SUCCESS, ERR_INVALID_PARAM, "outInfo do not support");
67 std::lock_guard<std::mutex> lock(streamClientMutex_);
68 CHECK_AND_RETURN_RET_LOG(offlineStreamInClient_, ERR_ILLEGAL_STATE, "offline stream is null!");
69 return offlineStreamInClient_->ConfigureOfflineEffectChain(inInfo, outInfo);
70 }
71
SetParam(const std::vector<uint8_t> & param)72 int32_t OfflineAudioEffectChainImpl::SetParam(const std::vector<uint8_t> ¶m)
73 {
74 CHECK_AND_RETURN_RET_LOG(param.size() <= MAX_PARAM_SIZE, ERR_INVALID_PARAM, "param size overflow");
75 std::lock_guard<std::mutex> lock(streamClientMutex_);
76 CHECK_AND_RETURN_RET_LOG(offlineStreamInClient_, ERR_ILLEGAL_STATE, "offline stream is null!");
77 return offlineStreamInClient_->SetParamOfflineEffectChain(param);
78 }
79
GetEffectBufferSize(uint32_t & inBufferSize,uint32_t & outBufferSize)80 int32_t OfflineAudioEffectChainImpl::GetEffectBufferSize(uint32_t &inBufferSize, uint32_t &outBufferSize)
81 {
82 std::lock_guard<std::mutex> lock(streamClientMutex_);
83 CHECK_AND_RETURN_RET_LOG(clientBufferIn_ && clientBufferOut_, ERR_ILLEGAL_STATE, "buffer not prepared");
84 inBufferSize = clientBufferIn_->GetSize();
85 outBufferSize = clientBufferOut_->GetSize();
86 return SUCCESS;
87 }
88
Prepare()89 int32_t OfflineAudioEffectChainImpl::Prepare()
90 {
91 std::lock_guard<std::mutex> lock(streamClientMutex_);
92 CHECK_AND_RETURN_RET_LOG(offlineStreamInClient_, ERR_ILLEGAL_STATE, "offline stream is null!");
93 int32_t ret = offlineStreamInClient_->PrepareOfflineEffectChain(clientBufferIn_, clientBufferOut_);
94 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_OPERATION_FAILED, "prepare failed, errCode is %{public}d", ret);
95 CHECK_AND_RETURN_RET_LOG(clientBufferIn_ && clientBufferOut_, ERR_ILLEGAL_STATE, "buffer not prepared");
96 inBufferBase_ = clientBufferIn_->GetBase();
97 outBufferBase_ = clientBufferOut_->GetBase();
98 return ret;
99 }
100
Process(uint8_t * inBuffer,int32_t inSize,uint8_t * outBuffer,int32_t outSize)101 int32_t OfflineAudioEffectChainImpl::Process(uint8_t *inBuffer, int32_t inSize, uint8_t *outBuffer, int32_t outSize)
102 {
103 std::lock_guard<std::mutex> lock(streamClientMutex_);
104 CHECK_AND_RETURN_RET_LOG(offlineStreamInClient_, ERR_ILLEGAL_STATE, "offline stream is null!");
105 CHECK_AND_RETURN_RET_LOG(inBufferBase_ && outBufferBase_ && clientBufferIn_ && clientBufferOut_,
106 ERR_ILLEGAL_STATE, "buffer not prepared");
107 int32_t inBufferSize = static_cast<int32_t>(clientBufferIn_->GetSize());
108 int32_t outBufferSize = static_cast<int32_t>(clientBufferOut_->GetSize());
109 CHECK_AND_RETURN_RET_LOG(inSize > 0 && inSize <= inBufferSize && outSize > 0 && outSize <= outBufferSize,
110 ERR_INVALID_PARAM, "buffer size invalid");
111 CHECK_AND_RETURN_RET_LOG(inBuffer && outBuffer, ERR_INVALID_PARAM, "buffer ptr invalid");
112
113 DumpFileUtil::WriteDumpFile(dumpFileIn_, inBufferBase_, inSize);
114
115 int32_t ret = memcpy_s(inBufferBase_, inBufferSize, inBuffer, inSize);
116 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_OPERATION_FAILED, "memcpy inbuffer failed");
117 ret = offlineStreamInClient_->ProcessOfflineEffectChain(inSize, outSize);
118 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_OPERATION_FAILED, "process effect failed");
119 ret = memcpy_s(outBuffer, outSize, outBufferBase_, outSize);
120 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_OPERATION_FAILED, "memcpy outBuffer failed");
121
122 DumpFileUtil::WriteDumpFile(dumpFileOut_, outBufferBase_, outSize);
123 return SUCCESS;
124 }
125
Release()126 void OfflineAudioEffectChainImpl::Release()
127 {
128 std::lock_guard<std::mutex> lock(streamClientMutex_);
129 if (offlineStreamInClient_ != nullptr) {
130 offlineStreamInClient_->ReleaseOfflineEffectChain();
131 offlineStreamInClient_ = nullptr;
132 }
133 inBufferBase_ = nullptr;
134 outBufferBase_ = nullptr;
135 clientBufferIn_ = nullptr;
136 clientBufferOut_ = nullptr;
137 DumpFileUtil::CloseDumpFile(&dumpFileIn_);
138 DumpFileUtil::CloseDumpFile(&dumpFileOut_);
139 }
140 } // namespace AudioStandard
141 } // namespace OHOS
142