1 /*
2 * Copyright (c) 2020-2021 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_source.h"
17 #include "media_log.h"
18 #include "securec.h"
19
20 namespace OHOS {
21 namespace Audio {
22 #define AUDIO_RETURN_VAL_IF_NULL(condition) \
23 do { \
24 if ((condition) == nullptr) { \
25 MEDIA_ERR_LOG("" #condition " is NULL"); \
26 return ERR_ILLEGAL_STATE; \
27 } \
28 } while (0)
29
30 using namespace OHOS::Media;
31 static AudioManager *g_audioManager = nullptr;
32
AudioSource()33 AudioSource::AudioSource()
34 : initialized_(false),
35 started_(false),
36 audioAdapter_(nullptr),
37 audioCapture_(nullptr)
38 {
39 if (g_audioManager == nullptr) {
40 g_audioManager = GetAudioManagerFuncs();
41 MEDIA_DEBUG_LOG("g_audioManager:%p", g_audioManager);
42 }
43 int size = 0;
44 struct AudioAdapterDescriptor *descs = nullptr;
45 g_audioManager->GetAllAdapters(g_audioManager, &descs, &size);
46 MEDIA_DEBUG_LOG("GetAllAdapters size:%d", size);
47
48 for (int index = 0; index < size; index++) {
49 struct AudioAdapterDescriptor *desc = &descs[index];
50 for (int port = 0; (desc != nullptr && port < static_cast<int>(desc->portNum)); port++) {
51 if (desc->ports[port].dir == PORT_IN &&
52 (g_audioManager->LoadAdapter(g_audioManager, desc, &audioAdapter_)) == 0) {
53 (void)audioAdapter_->InitAllPorts(audioAdapter_);
54 if (memcpy_s(&capturePort_, sizeof(struct AudioPort),
55 &desc->ports[port], sizeof(struct AudioPort)) != 0) {
56 MEDIA_WARNING_LOG("memcpy_s capturePort_ failed");
57 }
58 break;
59 }
60 }
61 }
62 MEDIA_DEBUG_LOG("LoadAdapter audioAdapter_:%p", audioAdapter_);
63 }
64
~AudioSource()65 AudioSource::~AudioSource()
66 {
67 MEDIA_DEBUG_LOG("in");
68 if (initialized_) {
69 Release();
70 }
71
72 if (audioAdapter_ != nullptr) {
73 MEDIA_INFO_LOG("UnloadModule audioAdapter_");
74 g_audioManager->UnloadAdapter(g_audioManager, audioAdapter_);
75 audioAdapter_ = nullptr;
76 }
77 }
78
InitCheck()79 int32_t AudioSource::InitCheck()
80 {
81 if (!initialized_) {
82 MEDIA_ERR_LOG("not initialized");
83 return ERR_ILLEGAL_STATE;
84 }
85 return SUCCESS;
86 }
87
GetMinFrameCount(int32_t sampleRate,int32_t channelCount,AudioCodecFormat audioFormat,size_t & frameCount)88 bool AudioSource::GetMinFrameCount(int32_t sampleRate, int32_t channelCount,
89 AudioCodecFormat audioFormat, size_t &frameCount)
90 {
91 if (sampleRate <= 0 || channelCount <= 0 || audioFormat < AUDIO_DEFAULT ||
92 audioFormat >= FORMAT_BUTT) {
93 MEDIA_ERR_LOG("invalid params sampleRate:%d channelCount:%d audioFormat:%d", sampleRate,
94 channelCount, audioFormat);
95 return false;
96 }
97 frameCount = 0;
98 return true;
99 }
100
GetFrameCount()101 uint64_t AudioSource::GetFrameCount()
102 {
103 int32_t ret;
104 if ((ret = InitCheck()) != SUCCESS) {
105 return ret;
106 }
107 AUDIO_RETURN_VAL_IF_NULL(audioCapture_);
108 uint64_t frameCount = 0;
109 ret = audioCapture_->attr.GetFrameCount(reinterpret_cast<AudioHandle>(audioCapture_), &frameCount);
110 if (ret != SUCCESS) {
111 MEDIA_ERR_LOG("attr GetFrameCount failed:0x%x ", ret);
112 return ret;
113 }
114 return frameCount;
115 }
116
EnumDeviceBySourceType(AudioSourceType inputSource,std::vector<AudioDeviceDesc> & devices)117 int32_t AudioSource::EnumDeviceBySourceType(AudioSourceType inputSource, std::vector<AudioDeviceDesc> &devices)
118 {
119 if (inputSource != AUDIO_MIC && inputSource != AUDIO_SOURCE_DEFAULT) {
120 MEDIA_ERR_LOG("AudioSource only support AUDIO_MIC");
121 return ERR_INVALID_PARAM;
122 }
123 AUDIO_RETURN_VAL_IF_NULL(audioAdapter_);
124
125 struct AudioPortCapability capability;
126 audioAdapter_->GetPortCapability(audioAdapter_, &capturePort_, &capability);
127 AudioDeviceDesc deviceDesc;
128 deviceDesc.deviceId = capability.deviceId;
129 deviceDesc.inputSourceType = AUDIO_MIC;
130 devices.push_back(deviceDesc);
131 return SUCCESS;
132 }
133
ConvertCodecFormatToAudioFormat(AudioCodecFormat codecFormat,AudioFormat * audioFormat)134 static bool ConvertCodecFormatToAudioFormat(AudioCodecFormat codecFormat, AudioFormat *audioFormat)
135 {
136 if (audioFormat == nullptr) {
137 MEDIA_ERR_LOG("audioFormat is NULL");
138 return false;
139 }
140
141 switch (codecFormat) {
142 case AUDIO_DEFAULT:
143 case PCM:
144 *audioFormat = AUDIO_FORMAT_PCM_16_BIT;
145 break;
146 case AAC_LC:
147 *audioFormat = AUDIO_FORMAT_AAC_LC;
148 break;
149 case AAC_LD:
150 *audioFormat = AUDIO_FORMAT_AAC_LD;
151 break;
152 case AAC_ELD:
153 *audioFormat = AUDIO_FORMAT_AAC_ELD;
154 break;
155 case AAC_HE_V1:
156 *audioFormat = AUDIO_FORMAT_AAC_HE_V1;
157 break;
158 case AAC_HE_V2:
159 *audioFormat = AUDIO_FORMAT_AAC_HE_V2;
160 break;
161 case G711A:
162 *audioFormat = AUDIO_FORMAT_G711A;
163 break;
164 case G711U:
165 *audioFormat = AUDIO_FORMAT_G711U;
166 break;
167 case G726:
168 *audioFormat = AUDIO_FORMAT_G726;
169 break;
170 default: {
171 MEDIA_ERR_LOG("not support this codecFormat:%d", codecFormat);
172 return false;
173 }
174 }
175 return true;
176 }
177
Initialize(const AudioSourceConfig & config)178 int32_t AudioSource::Initialize(const AudioSourceConfig &config)
179 {
180 AUDIO_RETURN_VAL_IF_NULL(audioAdapter_);
181 MEDIA_INFO_LOG("deviceId:0x%x config.sampleRate:%d", config.deviceId, config.sampleRate);
182 struct AudioDeviceDescriptor desc;
183 struct AudioSampleAttributes attrs;
184 if (config.streamUsage == TYPE_MEDIA || config.streamUsage == TYPE_DEFAULT) {
185 attrs.type = AUDIO_IN_MEDIA;
186 } else if (config.streamUsage == TYPE_VOICE_COMMUNICATION) {
187 attrs.type = AUDIO_IN_COMMUNICATION;
188 }
189 if (config.bitWidth != BIT_WIDTH_16) {
190 MEDIA_ERR_LOG("not support bitWidth:%d, only support 16 bit width", config.bitWidth);
191 return ERR_INVALID_PARAM;
192 }
193 if (ConvertCodecFormatToAudioFormat(config.audioFormat, &(attrs.format)) == false) {
194 MEDIA_ERR_LOG("not support audioFormat:%d", config.audioFormat);
195 return ERR_INVALID_PARAM;
196 }
197 attrs.sampleRate = config.sampleRate;
198 attrs.channelCount = config.channelCount;
199 attrs.interleaved = config.interleaved;
200 int32_t ret = audioAdapter_->CreateCapture(audioAdapter_, &desc, &attrs, &audioCapture_);
201 if (ret != SUCCESS || audioCapture_ == nullptr) {
202 MEDIA_ERR_LOG("CreateCapture failed:0x%x", ret);
203 return ret;
204 }
205 initialized_ = true;
206 return SUCCESS;
207 }
208
SetInputDevice(uint32_t deviceId)209 int32_t AudioSource::SetInputDevice(uint32_t deviceId)
210 {
211 return SUCCESS;
212 }
213
GetCurrentDeviceId(uint32_t & deviceId)214 int32_t AudioSource::GetCurrentDeviceId(uint32_t &deviceId)
215 {
216 AUDIO_RETURN_VAL_IF_NULL(audioCapture_);
217 int32_t ret = audioCapture_->attr.GetCurrentChannelId(reinterpret_cast<AudioHandle>(audioCapture_), &deviceId);
218 if (ret != SUCCESS) {
219 MEDIA_ERR_LOG("GetCurrentChannelId failed:0x%x", ret);
220 return ret;
221 }
222 MEDIA_INFO_LOG("deviceId:0x%x", deviceId);
223 return SUCCESS;
224 }
225
Start()226 int32_t AudioSource::Start()
227 {
228 int32_t ret;
229 if ((ret = InitCheck()) != SUCCESS) {
230 return ret;
231 }
232
233 AUDIO_RETURN_VAL_IF_NULL(audioCapture_);
234 ret = audioCapture_->control.Start(reinterpret_cast<AudioHandle>(audioCapture_));
235 if (ret != SUCCESS) {
236 MEDIA_ERR_LOG("audioCapture_ Start failed:0x%x", ret);
237 return ret;
238 }
239 started_ = true;
240 return SUCCESS;
241 }
242
ReadFrame(AudioFrame & frame,bool isBlockingRead)243 int32_t AudioSource::ReadFrame(AudioFrame &frame, bool isBlockingRead)
244 {
245 if (!started_) {
246 MEDIA_ERR_LOG("AudioSource not Start");
247 return ERR_ILLEGAL_STATE;
248 }
249 AUDIO_RETURN_VAL_IF_NULL(audioCapture_);
250 uint64_t readlen = ERR_INVALID_READ;
251 int32_t ret = audioCapture_->CaptureFrame(audioCapture_, frame.buffer, frame.bufferLen, &readlen);
252 if (ret != SUCCESS) {
253 MEDIA_ERR_LOG("audioCapture_::CaptureFrame failed:0x%x", ret);
254 return ERR_INVALID_READ;
255 }
256 ret = audioCapture_->GetCapturePosition(audioCapture_, &frame.frames, &frame.time);
257 if (ret != SUCCESS) {
258 MEDIA_ERR_LOG("audioCapture_::GetCapturePosition failed:0x%x", ret);
259 return ERR_INVALID_READ;
260 }
261 return readlen;
262 }
263
Stop()264 int32_t AudioSource::Stop()
265 {
266 MEDIA_INFO_LOG("AudioSource::Stop");
267 if (!started_) {
268 MEDIA_ERR_LOG("AudioSource not Start");
269 return ERR_ILLEGAL_STATE;
270 }
271
272 AUDIO_RETURN_VAL_IF_NULL(audioCapture_);
273 int32_t ret = audioCapture_->control.Stop(reinterpret_cast<AudioHandle>(audioCapture_));
274 if (ret != SUCCESS) {
275 MEDIA_ERR_LOG("Stop failed:0x%x", ret);
276 return ret;
277 }
278 started_ = false;
279 return SUCCESS;
280 }
281
Release()282 int32_t AudioSource::Release()
283 {
284 int32_t ret;
285 if ((ret = InitCheck()) != SUCCESS) {
286 return ret;
287 }
288 if (audioCapture_) {
289 audioAdapter_->DestroyCapture(audioAdapter_, audioCapture_);
290 audioCapture_ = nullptr;
291 }
292 initialized_ = false;
293 MEDIA_INFO_LOG("AudioSource Released");
294 return SUCCESS;
295 }
296 } // namespace Audio
297 } // namespace OHOS
298