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