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_capturer_session.h"
17
18 #include <algorithm>
19 #include <functional>
20 #include <thread>
21 #include "audio_record.h"
22 #include "audio_session_manager.h"
23 #include "audio_deferred_process.h"
24 #include "camera_log.h"
25 #include "datetime_ex.h"
26 #include "ipc_skeleton.h"
27 #include "sample_info.h"
28 #include "token_setproc.h"
29
30 namespace OHOS {
31 namespace CameraStandard {
32
AudioCapturerSession()33 AudioCapturerSession::AudioCapturerSession()
34 : audioBufferQueue_("audioBuffer", DEFAULT_AUDIO_CACHE_NUMBER)
35 {
36 }
37
getMicNum()38 AudioChannel AudioCapturerSession::getMicNum()
39 {
40 MEDIA_INFO_LOG("AudioCapturerSession::getMicNum");
41 std::string mainKey = "device_status";
42 std::vector<std::string> subKeys = {"hardware_info#mic_num"};
43 std::vector<std::pair<std::string, std::string>> result = {};
44 AudioSystemManager* audioSystemMgr = AudioSystemManager::GetInstance();
45 if (audioSystemMgr == nullptr) {
46 MEDIA_WARNING_LOG("AudioCapturerSession::getMicNum GetAudioSystemManagerInstance err");
47 return AudioChannel::STEREO;
48 }
49 int32_t ret = audioSystemMgr->GetExtraParameters(mainKey, subKeys, result);
50 if (ret != 0) {
51 MEDIA_WARNING_LOG("AudioCapturerSession::getMicNum GetExtraParameters err");
52 return AudioChannel::STEREO;
53 }
54 if (result.empty() || result[0].second.empty() || result[0].first.empty()) {
55 MEDIA_WARNING_LOG("AudioCapturerSession::getMicNum result empty");
56 return AudioChannel::STEREO;
57 }
58 for (auto i: result[0].second) {
59 if (!std::isdigit(i)) {
60 MEDIA_WARNING_LOG("AudioCapturerSession::getMicNum result illegal");
61 return AudioChannel::STEREO;
62 }
63 }
64 int32_t micNum = std::stoi(result[0].second);
65 MEDIA_INFO_LOG("AudioCapturerSession::getMicNum %{public}d + %{public}d", micNum, micNum % I32_TWO);
66 // odd channel should + 1
67 return static_cast<AudioChannel>(micNum + (micNum % I32_TWO));
68 }
69
CreateAudioCapturer()70 bool AudioCapturerSession::CreateAudioCapturer()
71 {
72 auto callingTokenID = IPCSkeleton::GetCallingTokenID();
73 SetFirstCallerTokenID(callingTokenID);
74 AudioCapturerOptions capturerOptions;
75 capturerOptions.streamInfo.samplingRate = static_cast<AudioSamplingRate>(AudioSamplingRate::SAMPLE_RATE_48000);
76 capturerOptions.streamInfo.encoding = AudioEncodingType::ENCODING_PCM;
77 capturerOptions.streamInfo.format = AudioSampleFormat::SAMPLE_S16LE;
78 capturerOptions.streamInfo.channels = getMicNum();
79 capturerOptions.capturerInfo.sourceType = SourceType::SOURCE_TYPE_UNPROCESSED;
80 capturerOptions.capturerInfo.capturerFlags = 0;
81 audioCapturer_ = AudioCapturer::Create(capturerOptions);
82 if (audioCapturer_ == nullptr) {
83 MEDIA_ERR_LOG("AudioCapturerSession::Create AudioCapturer failed");
84 return false;
85 }
86 AudioSessionStrategy sessionStrategy;
87 sessionStrategy.concurrencyMode = AudioConcurrencyMode::MIX_WITH_OTHERS;
88 AudioSessionManager::GetInstance()->ActivateAudioSession(sessionStrategy);
89 audioDeferredProcess_ = new AudioDeferredProcess();
90 if (!audioDeferredProcess_ || audioDeferredProcess_->GetOfflineEffectChain() != 0) {
91 return false;
92 }
93 AudioStreamInfo outputOptions;
94 outputOptions.samplingRate = static_cast<AudioSamplingRate>(AudioSamplingRate::SAMPLE_RATE_32000);
95 outputOptions.encoding = AudioEncodingType::ENCODING_PCM;
96 outputOptions.format = AudioSampleFormat::SAMPLE_S16LE;
97 outputOptions.channels = AudioChannel::MONO;
98 if (audioDeferredProcess_->ConfigOfflineAudioEffectChain(capturerOptions.streamInfo, outputOptions) != 0) {
99 return false;
100 }
101 if (audioDeferredProcess_->PrepareOfflineAudioEffectChain() != 0) {
102 return false;
103 }
104 if (audioDeferredProcess_->GetMaxBufferSize(capturerOptions.streamInfo, outputOptions) != 0) {
105 return false;
106 }
107 return true;
108 }
109
~AudioCapturerSession()110 AudioCapturerSession::~AudioCapturerSession()
111 {
112 MEDIA_INFO_LOG("~AudioCapturerSession enter");
113 audioBufferQueue_.SetActive(false);
114 audioBufferQueue_.Clear();
115 Stop();
116 }
117
StartAudioCapture()118 bool AudioCapturerSession::StartAudioCapture()
119 {
120 MEDIA_INFO_LOG("Starting moving photo audio stream");
121 CHECK_ERROR_RETURN_RET_LOG(startAudioCapture_, true, "AudioCapture is already started.");
122 if (audioCapturer_ == nullptr && !CreateAudioCapturer()) {
123 MEDIA_INFO_LOG("audioCapturer is not create");
124 return false;
125 }
126 if (!audioCapturer_->Start()) {
127 MEDIA_INFO_LOG("Start stream failed");
128 audioCapturer_->Release();
129 startAudioCapture_ = false;
130 return false;
131 }
132 if (audioThread_ && audioThread_->joinable()) {
133 MEDIA_INFO_LOG("audioThread_ is already start, reset");
134 startAudioCapture_ = false;
135 audioThread_->join();
136 audioThread_.reset();
137 }
138 startAudioCapture_ = true;
139 audioThread_ = std::make_unique<std::thread>([this]() { this->ProcessAudioBuffer(); });
140 if (audioThread_ == nullptr) {
141 MEDIA_ERR_LOG("Create auido thread failed");
142 return false;
143 }
144 return true;
145 }
146
GetAudioRecords(int64_t startTime,int64_t endTime,vector<sptr<AudioRecord>> & audioRecords)147 void AudioCapturerSession::GetAudioRecords(int64_t startTime, int64_t endTime, vector<sptr<AudioRecord>> &audioRecords)
148 {
149 vector<sptr<AudioRecord>> allRecords = audioBufferQueue_.GetAllElements();
150 for (const auto& record : allRecords) {
151 if (record->GetTimeStamp() >= startTime && record->GetTimeStamp() < endTime) {
152 audioRecords.push_back(record);
153 }
154 }
155 }
156
ProcessAudioBuffer()157 void AudioCapturerSession::ProcessAudioBuffer()
158 {
159 CHECK_ERROR_RETURN_LOG(audioCapturer_ == nullptr, "AudioCapturer_ is not init");
160 size_t bufferLen = audioDeferredProcess_->GetOneUnprocessedSize();
161 while (true) {
162 CHECK_AND_BREAK_LOG(startAudioCapture_, "Audio capture work done, thread out");
163 auto buffer = std::make_unique<uint8_t[]>(bufferLen);
164 CHECK_ERROR_RETURN_LOG(buffer == nullptr, "Failed to allocate buffer");
165 size_t bytesRead = 0;
166 while (bytesRead < bufferLen) {
167 MEDIA_DEBUG_LOG("ProcessAudioBuffer loop");
168 CHECK_AND_BREAK_LOG(startAudioCapture_, "ProcessAudioBuffer loop, break out");
169 int32_t len = audioCapturer_->Read(*(buffer.get() + bytesRead), bufferLen - bytesRead, true);
170 if (len >= 0) {
171 bytesRead += static_cast<size_t>(len);
172 } else {
173 MEDIA_ERR_LOG("ProcessAudioBuffer loop read error: %{public}d", len);
174 startAudioCapture_ = false;
175 break;
176 }
177 }
178 if (!startAudioCapture_) {
179 buffer.reset();
180 MEDIA_INFO_LOG("Audio capture work done, thread out");
181 break;
182 }
183 if (audioBufferQueue_.Full()) {
184 sptr<AudioRecord> audioRecord = audioBufferQueue_.Pop();
185 audioRecord->ReleaseAudioBuffer();
186 MEDIA_DEBUG_LOG("audio release popBuffer");
187 }
188 int64_t timeOffset = 32;
189 sptr<AudioRecord> audioRecord = new AudioRecord(GetTickCount() - timeOffset);
190 audioRecord->SetAudioBuffer(buffer.get());
191 MEDIA_DEBUG_LOG("audio push buffer frameId: %{public}s", audioRecord->GetFrameId().c_str());
192 buffer.release();
193 audioBufferQueue_.Push(audioRecord);
194 }
195 }
196
Stop()197 void AudioCapturerSession::Stop()
198 {
199 CAMERA_SYNC_TRACE;
200 MEDIA_INFO_LOG("Audio capture stop enter");
201 startAudioCapture_ = false;
202 if (audioThread_ && audioThread_->joinable()) {
203 audioThread_->join();
204 audioThread_.reset();
205 }
206 AudioSessionManager::GetInstance()->DeactivateAudioSession();
207 MEDIA_INFO_LOG("Audio capture stop out");
208 Release();
209 }
210
Release()211 void AudioCapturerSession::Release()
212 {
213 CAMERA_SYNC_TRACE;
214 if (audioCapturer_ != nullptr) {
215 MEDIA_INFO_LOG("Audio capture Release enter");
216 audioCapturer_->Release();
217 }
218 audioCapturer_ = nullptr;
219 MEDIA_INFO_LOG("Audio capture released");
220 }
221
GetAudioDeferredProcess()222 sptr<AudioDeferredProcess> AudioCapturerSession::GetAudioDeferredProcess()
223 {
224 return audioDeferredProcess_;
225 }
226 } // namespace CameraStandard
227 } // namespace OHOS
228