1 /*
2 * Copyright (c) 2024-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
16 #include "audio_deferred_process.h"
17
18 #include "camera_log.h"
19 #include "camera_util.h"
20 #include <cstring>
21
22 namespace OHOS {
23 namespace CameraStandard {
24
AudioDeferredProcess()25 AudioDeferredProcess::AudioDeferredProcess()
26 {
27 MEDIA_INFO_LOG("AudioDeferredProcess() Enter");
28 }
29
~AudioDeferredProcess()30 AudioDeferredProcess::~AudioDeferredProcess()
31 {
32 MEDIA_INFO_LOG("~AudioDeferredProcess Enter");
33 Release();
34 }
35
GetOfflineEffectChain()36 int32_t AudioDeferredProcess::GetOfflineEffectChain()
37 {
38 CAMERA_SYNC_TRACE;
39 MEDIA_INFO_LOG("AudioDeferredProcess::GetOfflineEffectChain Enter");
40 if (!offlineAudioEffectManager_) {
41 offlineAudioEffectManager_ = std::make_unique<OfflineAudioEffectManager>();
42 }
43 vector<std::string> effectChains = offlineAudioEffectManager_->GetOfflineAudioEffectChains();
44 if (std::find(effectChains.begin(), effectChains.end(), chainName_) == effectChains.end()) {
45 MEDIA_ERR_LOG("AudioDeferredProcess::GetOfflineEffectChain no effectChain moving photo needed");
46 return -1;
47 }
48 offlineEffectChain_ = offlineAudioEffectManager_->CreateOfflineAudioEffectChain(chainName_);
49 if (!offlineEffectChain_) {
50 MEDIA_ERR_LOG("AudioDeferredProcess::GetOfflineEffectChain ERR");
51 return -1;
52 }
53 return CAMERA_OK;
54 }
55
StoreOptions(const AudioStreamInfo & inputOptions,const AudioStreamInfo & outputOptions)56 void AudioDeferredProcess::StoreOptions(const AudioStreamInfo& inputOptions,
57 const AudioStreamInfo& outputOptions)
58 {
59 CAMERA_SYNC_TRACE;
60 MEDIA_INFO_LOG("AudioDeferredProcess::StoreConfig Enter");
61 inputOptions_ = inputOptions;
62 outputOptions_ = outputOptions;
63 }
64
ConfigOfflineAudioEffectChain()65 int32_t AudioDeferredProcess::ConfigOfflineAudioEffectChain()
66 {
67 CAMERA_SYNC_TRACE;
68 MEDIA_INFO_LOG("AudioDeferredProcess::ConfigOfflineAudioEffectChain Enter");
69 if (offlineEffectChain_->Configure(inputOptions_, outputOptions_) != 0) {
70 MEDIA_ERR_LOG("AudioDeferredProcess::ConfigOfflineAudioEffectChain Err");
71 return -1;
72 }
73 return CAMERA_OK;
74 }
75
PrepareOfflineAudioEffectChain()76 int32_t AudioDeferredProcess::PrepareOfflineAudioEffectChain()
77 {
78 CAMERA_SYNC_TRACE;
79 MEDIA_INFO_LOG("AudioDeferredProcess::PrepareOfflineAudioEffectChain Enter");
80 CHECK_ERROR_RETURN_RET_LOG(offlineEffectChain_->Prepare() != 0, -1,
81 "AudioDeferredProcess::PrepareOfflineAudioEffectChain Err");
82 return CAMERA_OK;
83 }
84
GetMaxBufferSize(const AudioStreamInfo & inputOptions,const AudioStreamInfo & outputOptions)85 int32_t AudioDeferredProcess::GetMaxBufferSize(const AudioStreamInfo& inputOptions,
86 const AudioStreamInfo& outputOptions)
87 {
88 CAMERA_SYNC_TRACE;
89 MEDIA_INFO_LOG("AudioDeferredProcess::GetMaxBufferSize Enter");
90 uint32_t maxUnprocessedBufferSize_ = 0;
91 uint32_t maxProcessedBufferSize_ = 0;
92 CHECK_ERROR_RETURN_RET_LOG(offlineEffectChain_->GetEffectBufferSize(maxUnprocessedBufferSize_,
93 maxProcessedBufferSize_) != 0, -1, "AudioDeferredProcess::GetMaxBufferSize Err");
94 oneUnprocessedSize_ = inputOptions.samplingRate / ONE_THOUSAND *
95 inputOptions.channels * DURATION_EACH_AUDIO_FRAME * sizeof(short);
96 oneProcessedSize_ = outputOptions.samplingRate / ONE_THOUSAND *
97 outputOptions.channels * DURATION_EACH_AUDIO_FRAME * sizeof(short);
98 CHECK_ERROR_RETURN_RET_LOG(oneUnprocessedSize_ * PROCESS_BATCH_SIZE > maxUnprocessedBufferSize_ ||
99 oneProcessedSize_ * PROCESS_BATCH_SIZE > maxProcessedBufferSize_, -1,
100 "AudioDeferredProcess::GetMaxBufferSize MaxBufferSize Not Enough");
101 return CAMERA_OK;
102 }
103
GetOneUnprocessedSize()104 uint32_t AudioDeferredProcess::GetOneUnprocessedSize()
105 {
106 return oneUnprocessedSize_;
107 }
108
FadeOneBatch(std::array<uint8_t,MAX_PROCESSED_SIZE * PROCESS_BATCH_SIZE> & processedArr)109 void AudioDeferredProcess::FadeOneBatch(std::array<uint8_t, MAX_PROCESSED_SIZE * PROCESS_BATCH_SIZE>& processedArr)
110 {
111 float rate;
112 int16_t* data = reinterpret_cast<int16_t*>(processedArr.data());
113 int32_t temp;
114 int32_t oneSize = outputOptions_.samplingRate / ONE_THOUSAND * DURATION_EACH_AUDIO_FRAME;
115 CHECK_ERROR_RETURN_LOG(oneSize >= MAX_PROCESSED_SIZE * PROCESS_BATCH_SIZE,
116 "AudioDeferredProcess::FadeOneBatch arrSize overSize");
117 for (int k = 0; k < oneSize; k++) {
118 temp = static_cast<int32_t>(data[k]);
119 rate = static_cast<float>(k) / oneSize;
120 temp = temp - static_cast<int32_t>(temp * rate);
121 data[k] = static_cast<int16_t>(temp);
122 }
123 }
124
EffectChainProcess(std::array<uint8_t,MAX_UNPROCESSED_SIZE * PROCESS_BATCH_SIZE> & rawArr,std::array<uint8_t,MAX_PROCESSED_SIZE * PROCESS_BATCH_SIZE> & processedArr)125 void AudioDeferredProcess::EffectChainProcess(std::array<uint8_t, MAX_UNPROCESSED_SIZE * PROCESS_BATCH_SIZE>& rawArr,
126 std::array<uint8_t, MAX_PROCESSED_SIZE * PROCESS_BATCH_SIZE>& processedArr)
127 {
128 int32_t ret = offlineEffectChain_->Process(rawArr.data(), oneUnprocessedSize_ * PROCESS_BATCH_SIZE,
129 processedArr.data(), oneProcessedSize_ * PROCESS_BATCH_SIZE);
130 CHECK_ERROR_PRINT_LOG(ret != 0, "AudioDeferredProcess::Process err");
131 }
132
ReturnToRecords(std::array<uint8_t,MAX_PROCESSED_SIZE * PROCESS_BATCH_SIZE> & processedArr,vector<sptr<AudioRecord>> & processedRecords,uint32_t i,uint32_t batchSize)133 void AudioDeferredProcess::ReturnToRecords(std::array<uint8_t, MAX_PROCESSED_SIZE * PROCESS_BATCH_SIZE>& processedArr,
134 vector<sptr<AudioRecord>>& processedRecords, uint32_t i, uint32_t batchSize)
135 {
136 for (uint32_t j = 0; j < batchSize; ++ j) {
137 uint8_t* temp = new uint8_t[oneProcessedSize_];
138 int32_t ret = memcpy_s(temp, oneProcessedSize_, processedArr.data() + j * oneProcessedSize_, oneProcessedSize_);
139 CHECK_ERROR_PRINT_LOG(ret != 0, "AudioDeferredProcess::Process returnToRecords memcpy_s err");
140 CHECK_ERROR_RETURN_LOG(i + 1 + j - batchSize < 0, "ReturnToRecords unexpected error occured");
141 processedRecords[i + 1 + j - batchSize]->SetAudioBuffer(temp);
142 }
143 }
144
MemsetAndCheck(void * dest,size_t destMax,int c,size_t count)145 void MemsetAndCheck(void *dest, size_t destMax, int c, size_t count)
146 {
147 int32_t ret = memset_s(dest, destMax, c, count);
148 CHECK_ERROR_PRINT_LOG(ret != 0, "AudioDeferredProcess::Process memset_s err");
149 }
150
Process(vector<sptr<AudioRecord>> & audioRecords,vector<sptr<AudioRecord>> & processedRecords)151 int32_t AudioDeferredProcess::Process(vector<sptr<AudioRecord>>& audioRecords,
152 vector<sptr<AudioRecord>>& processedRecords)
153 {
154 CAMERA_SYNC_TRACE;
155 if (offlineEffectChain_ == nullptr) {
156 MEDIA_WARNING_LOG("AudioDeferredProcess::Process offlineEffectChain_ is nullptr.");
157 return -1;
158 }
159 MEDIA_INFO_LOG("AudioDeferredProcess::Process Enter");
160 uint32_t audioRecordsLen = audioRecords.size();
161 CHECK_ERROR_RETURN_RET_LOG(0 == audioRecordsLen, CAMERA_OK, "audioRecords.size == 0");
162 std::array<uint8_t, MAX_UNPROCESSED_SIZE * PROCESS_BATCH_SIZE> rawArr{};
163 std::array<uint8_t, MAX_PROCESSED_SIZE * PROCESS_BATCH_SIZE> processedArr{};
164
165 uint32_t count = 0;
166 lock_guard<std::mutex> lock(mutex_);
167 for (uint32_t i = 0; i < audioRecordsLen; i ++) {
168 int32_t ret = memcpy_s(rawArr.data() + count * oneUnprocessedSize_, oneUnprocessedSize_,
169 audioRecords[i]->GetAudioBuffer(), oneUnprocessedSize_);
170 CHECK_ERROR_PRINT_LOG(ret != 0, "AudioDeferredProcess::Process memcpy_s err");
171 if (audioRecordsLen - 1 == i) {
172 MemsetAndCheck(rawArr.data(), MAX_UNPROCESSED_SIZE * PROCESS_BATCH_SIZE,
173 0, PROCESS_BATCH_SIZE * oneUnprocessedSize_);
174 EffectChainProcess(rawArr, processedArr);
175 MemsetAndCheck(processedArr.data(), MAX_PROCESSED_SIZE * PROCESS_BATCH_SIZE,
176 0, PROCESS_BATCH_SIZE * oneProcessedSize_);
177 ReturnToRecords(processedArr, processedRecords, i, count + 1);
178 } else if (i >= audioRecordsLen - PROCESS_BATCH_SIZE - 1 && count == PROCESS_BATCH_SIZE - 1) {
179 EffectChainProcess(rawArr, processedArr);
180 FadeOneBatch(processedArr);
181 MemsetAndCheck(processedArr.data() + oneProcessedSize_, MAX_PROCESSED_SIZE * PROCESS_BATCH_SIZE,
182 0, (PROCESS_BATCH_SIZE - 1) * oneProcessedSize_);
183 ReturnToRecords(processedArr, processedRecords, i, PROCESS_BATCH_SIZE);
184 } else if (count == PROCESS_BATCH_SIZE - 1) {
185 EffectChainProcess(rawArr, processedArr);
186 ReturnToRecords(processedArr, processedRecords, i, PROCESS_BATCH_SIZE);
187 }
188 count = (count + 1) % PROCESS_BATCH_SIZE;
189 }
190
191 return CAMERA_OK;
192 }
193
Release()194 void AudioDeferredProcess::Release()
195 {
196 CAMERA_SYNC_TRACE;
197 lock_guard<std::mutex> lock(mutex_);
198 MEDIA_INFO_LOG("AudioDeferredProcess::Release Enter");
199 CHECK_EXECUTE(offlineEffectChain_, offlineEffectChain_->Release());
200 offlineEffectChain_ = nullptr;
201 offlineAudioEffectManager_ = nullptr;
202 }
203
204 } // CameraStandard
205 } // OHOS