1 /*
2 * Copyright (c) 2024 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 {
OfflineAudioEffectChainImpl(const std::string & effectChainName)29 OfflineAudioEffectChainImpl::OfflineAudioEffectChainImpl(const std::string &effectChainName)
30 {
31 chainName_ = effectChainName;
32 offlineStreamInClient_ = OfflineStreamInClient::Create();
33 AUDIO_INFO_LOG("%{public}s offline effect chain created!", chainName_.c_str());
34 }
35
~OfflineAudioEffectChainImpl()36 OfflineAudioEffectChainImpl::~OfflineAudioEffectChainImpl()
37 {
38 Release();
39 }
40
InitDump()41 void OfflineAudioEffectChainImpl::InitDump()
42 {
43 static uint32_t chainId = 0;
44 std::string dumpFileName = "OfflineEffectClient";
45 std::string dumpFileInName = dumpFileName + "_" + std::to_string(chainId) + "_In.pcm";
46 std::string dumpFileOutName = dumpFileName + "_" + std::to_string(chainId) + "_Out.pcm";
47 DumpFileUtil::OpenDumpFile(DUMP_CLIENT_PARA, dumpFileInName, &dumpFileIn_);
48 DumpFileUtil::OpenDumpFile(DUMP_CLIENT_PARA, dumpFileOutName, &dumpFileOut_);
49 chainId++;
50 }
51
CreateEffectChain()52 int32_t OfflineAudioEffectChainImpl::CreateEffectChain()
53 {
54 std::lock_guard<std::mutex> lock(streamClientMutex_);
55 CHECK_AND_RETURN_RET_LOG(offlineStreamInClient_, ERR_ILLEGAL_STATE, "offline stream is null!");
56 int32_t ret = offlineStreamInClient_->CreateOfflineEffectChain(chainName_);
57 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ret, "InitIpcChainFailed!");
58 InitDump();
59 return SUCCESS;
60 }
61
Configure(const AudioStreamInfo & inInfo,const AudioStreamInfo & outInfo)62 int32_t OfflineAudioEffectChainImpl::Configure(const AudioStreamInfo &inInfo, const AudioStreamInfo &outInfo)
63 {
64 std::lock_guard<std::mutex> lock(streamClientMutex_);
65 CHECK_AND_RETURN_RET_LOG(offlineStreamInClient_, ERR_ILLEGAL_STATE, "offline stream is null!");
66 return offlineStreamInClient_->ConfigureOfflineEffectChain(inInfo, outInfo);
67 }
68
GetEffectBufferSize(uint32_t & inBufferSize,uint32_t & outBufferSize)69 int32_t OfflineAudioEffectChainImpl::GetEffectBufferSize(uint32_t &inBufferSize, uint32_t &outBufferSize)
70 {
71 std::lock_guard<std::mutex> lock(streamClientMutex_);
72 CHECK_AND_RETURN_RET_LOG(clientBufferIn_ && clientBufferOut_, ERR_ILLEGAL_STATE, "buffer not prepared");
73 inBufferSize = clientBufferIn_->GetSize();
74 outBufferSize = clientBufferOut_->GetSize();
75 return SUCCESS;
76 }
77
Prepare()78 int32_t OfflineAudioEffectChainImpl::Prepare()
79 {
80 std::lock_guard<std::mutex> lock(streamClientMutex_);
81 CHECK_AND_RETURN_RET_LOG(offlineStreamInClient_, ERR_ILLEGAL_STATE, "offline stream is null!");
82 int32_t ret = offlineStreamInClient_->PrepareOfflineEffectChain(clientBufferIn_, clientBufferOut_);
83 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_OPERATION_FAILED, "prepare failed, errCode is %{public}d", ret);
84 CHECK_AND_RETURN_RET_LOG(clientBufferIn_ && clientBufferOut_, ERR_ILLEGAL_STATE, "buffer not prepared");
85 inBufferBase_ = clientBufferIn_->GetBase();
86 outBufferBase_ = clientBufferOut_->GetBase();
87 return ret;
88 }
89
Process(uint8_t * inBuffer,int32_t inSize,uint8_t * outBuffer,int32_t outSize)90 int32_t OfflineAudioEffectChainImpl::Process(uint8_t *inBuffer, int32_t inSize, uint8_t *outBuffer, int32_t outSize)
91 {
92 std::lock_guard<std::mutex> lock(streamClientMutex_);
93 CHECK_AND_RETURN_RET_LOG(offlineStreamInClient_, ERR_ILLEGAL_STATE, "offline stream is null!");
94 CHECK_AND_RETURN_RET_LOG(inBufferBase_ && outBufferBase_ && clientBufferIn_ && clientBufferOut_,
95 ERR_ILLEGAL_STATE, "buffer not prepared");
96 int32_t inBufferSize = static_cast<int32_t>(clientBufferIn_->GetSize());
97 int32_t outBufferSize = static_cast<int32_t>(clientBufferOut_->GetSize());
98 CHECK_AND_RETURN_RET_LOG(inSize > 0 && inSize <= inBufferSize && outSize > 0 && outSize <= outBufferSize,
99 ERR_INVALID_PARAM, "buffer size invalid");
100 CHECK_AND_RETURN_RET_LOG(inBuffer && outBuffer, ERR_INVALID_PARAM, "buffer ptr invalid");
101
102 DumpFileUtil::WriteDumpFile(dumpFileIn_, inBufferBase_, inSize);
103
104 int32_t ret = memcpy_s(inBufferBase_, inBufferSize, inBuffer, inSize);
105 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_OPERATION_FAILED, "memcpy inbuffer failed");
106 ret = offlineStreamInClient_->ProcessOfflineEffectChain(inSize, outSize);
107 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_OPERATION_FAILED, "process effect failed");
108 ret = memcpy_s(outBuffer, outSize, outBufferBase_, outSize);
109 CHECK_AND_RETURN_RET_LOG(ret == SUCCESS, ERR_OPERATION_FAILED, "memcpy outBuffer failed");
110
111 DumpFileUtil::WriteDumpFile(dumpFileOut_, outBufferBase_, outSize);
112 return SUCCESS;
113 }
114
Release()115 void OfflineAudioEffectChainImpl::Release()
116 {
117 std::lock_guard<std::mutex> lock(streamClientMutex_);
118 if (offlineStreamInClient_ != nullptr) {
119 offlineStreamInClient_->ReleaseOfflineEffectChain();
120 offlineStreamInClient_ = nullptr;
121 }
122 inBufferBase_ = nullptr;
123 outBufferBase_ = nullptr;
124 clientBufferIn_ = nullptr;
125 clientBufferOut_ = nullptr;
126 DumpFileUtil::CloseDumpFile(&dumpFileIn_);
127 DumpFileUtil::CloseDumpFile(&dumpFileOut_);
128 }
129 } // namespace AudioStandard
130 } // namespace OHOS
131