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