1 /*
2 * Copyright (c) 2022 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 "alsa_soundcard.h"
17 #include "alsa_snd_capture.h"
18
19 #define HDF_LOG_TAG HDF_AUDIO_HAL_CAPTURE
20
21 #define AUDIO_TIMESTAMP_FREQ 8 /* Hz */
22 #define AUDIO_SAMPLE_FREQ 48000
23 #define AUDIO_PERIOD ((AUDIO_SAMPLE_FREQ) / (AUDIO_TIMESTAMP_FREQ))
24 #define AUDIO_PCM_WAIT 100
25 #define AUDIO_RESUME_POLL (10 * (AUDIO_PCM_WAIT)) // 1s
26 #define ALSA_CAP_BUFFER_SIZE (2 * 2 * 6000) // format(S16LE) * channels(2) * period.
27
28 #define POLL_EVENT_DEF false
29 #define AUDIO_BUFFER_TIME_DEF 500000
30 #define AUDIO_PERIOD_TIME_DEF 100000
31
32 static struct AlsaCapture *g_alsaCaptureList = NULL;
33 static void RegisterCaptureImpl(struct AlsaCapture *captureIns);
34
CaptureSetPriData(struct AlsaCapture * captureIns,CapturePriData data)35 void CaptureSetPriData(struct AlsaCapture *captureIns, CapturePriData data)
36 {
37 captureIns->priData = data;
38 }
39
CaptureGetPriData(struct AlsaCapture * captureIns)40 CapturePriData CaptureGetPriData(struct AlsaCapture *captureIns)
41 {
42 return captureIns->priData;
43 }
44
CaptureFreeMemory(void)45 static int32_t CaptureFreeMemory(void)
46 {
47 int32_t i;
48
49 if (g_alsaCaptureList != NULL) {
50 for (i = 0; i < MAX_CARD_NUM; i++) {
51 if (g_alsaCaptureList[i].soundCard.cardStatus != 0) {
52 AUDIO_FUNC_LOGE("refCount is not zero, Sound card in use!");
53 return HDF_ERR_DEVICE_BUSY;
54 }
55 if (g_alsaCaptureList[i].priData != NULL) {
56 OsalMemFree(g_alsaCaptureList[i].priData);
57 g_alsaCaptureList[i].priData = NULL;
58 }
59 }
60 AudioMemFree((void **)&g_alsaCaptureList);
61 g_alsaCaptureList = NULL;
62 }
63
64 return HDF_SUCCESS;
65 }
66
SetHWParamsSub(struct AlsaSoundCard * cardIns,snd_pcm_hw_params_t * params,snd_pcm_access_t access)67 static int32_t SetHWParamsSub(
68 struct AlsaSoundCard *cardIns, snd_pcm_hw_params_t *params, snd_pcm_access_t access)
69 {
70 int32_t ret;
71 snd_pcm_format_t pcmFormat;
72 snd_pcm_t *handle = cardIns->pcmHandle;
73 struct AlsaCapture *captureIns = (struct AlsaCapture *)cardIns;
74 CHECK_NULL_PTR_RETURN_DEFAULT(cardIns);
75 CHECK_NULL_PTR_RETURN_DEFAULT(params);
76
77 ret = snd_pcm_hw_params_set_rate_resample(handle, params, captureIns->resample);
78 if (ret < 0) {
79 AUDIO_FUNC_LOGE("Resampling setup failed for capture: %{public}s", snd_strerror(ret));
80 return HDF_FAILURE;
81 }
82
83 /* set the interleaved read/write format */
84 ret = snd_pcm_hw_params_set_access(handle, params, access);
85 if (ret < 0) {
86 AUDIO_FUNC_LOGE("Access type not available for capture: %{public}s", snd_strerror(ret));
87 return HDF_FAILURE;
88 }
89 ret = SndConverAlsaPcmFormat(&cardIns->hwParams, &pcmFormat);
90 if (ret != HDF_SUCCESS) {
91 AUDIO_FUNC_LOGE("SndConverAlsaPcmFormat error.");
92 return ret;
93 }
94
95 /* set the sample format */
96 ret = snd_pcm_hw_params_set_format(handle, params, pcmFormat);
97 if (ret < 0) {
98 AUDIO_FUNC_LOGE("Sample format not available for capture: %{public}s", snd_strerror(ret));
99 return HDF_FAILURE;
100 }
101
102 /* set the count of channels */
103 ret = snd_pcm_hw_params_set_channels(handle, params, cardIns->hwParams.channels);
104 if (ret < 0) {
105 AUDIO_FUNC_LOGE("Channels count (%{public}u) not available for capture: %{public}s", cardIns->hwParams.channels,
106 snd_strerror(ret));
107 return HDF_FAILURE;
108 }
109
110 return HDF_SUCCESS;
111 }
112
SetHWRate(struct AlsaSoundCard * cardIns,snd_pcm_hw_params_t * params)113 static int32_t SetHWRate(struct AlsaSoundCard *cardIns, snd_pcm_hw_params_t *params)
114 {
115 int32_t ret;
116 uint32_t rRate;
117 int32_t dir = 0; /* dir Value range (-1,0,1) */
118 CHECK_NULL_PTR_RETURN_DEFAULT(cardIns);
119 CHECK_NULL_PTR_RETURN_DEFAULT(params);
120
121 /* set the stream rate */
122 rRate = cardIns->hwParams.rate;
123 ret = snd_pcm_hw_params_set_rate_near(cardIns->pcmHandle, params, &rRate, &dir);
124 if (ret < 0) {
125 AUDIO_FUNC_LOGE("Rate %{public}uHz not available for capture: %{public}s",
126 cardIns->hwParams.rate, snd_strerror(ret));
127 return HDF_FAILURE;
128 }
129
130 if (rRate != cardIns->hwParams.rate) {
131 ret = snd_pcm_hw_params_set_rate_near(cardIns->pcmHandle, params, &rRate, &dir);
132 if (ret < 0) {
133 AUDIO_FUNC_LOGE("Rate %{public}uHz not available for capture: %{public}s",
134 cardIns->hwParams.rate, snd_strerror(ret));
135 return HDF_FAILURE;
136 }
137 }
138 /* Update to hardware supported rate */
139 cardIns->hwParams.rate = rRate;
140
141 return HDF_SUCCESS;
142 }
143
SetHWBuffer(struct AlsaSoundCard * cardIns,snd_pcm_hw_params_t * params)144 static int32_t SetHWBuffer(struct AlsaSoundCard *cardIns, snd_pcm_hw_params_t *params)
145 {
146 int32_t ret;
147 int32_t dir = 0; /* dir Value range (-1,0,1) */
148 snd_pcm_uframes_t size = 0;
149 struct AlsaCapture *captureIns = (struct AlsaCapture *)cardIns;
150 CHECK_NULL_PTR_RETURN_DEFAULT(cardIns);
151 CHECK_NULL_PTR_RETURN_DEFAULT(params);
152
153 ret = snd_pcm_hw_params_set_buffer_time_near(cardIns->pcmHandle, params, &captureIns->bufferTime, &dir);
154 if (ret < 0) {
155 AUDIO_FUNC_LOGE("Unable to set buffer time %{public}u for capture: %{public}s",
156 captureIns->bufferTime, snd_strerror(ret));
157 return HDF_FAILURE;
158 }
159
160 ret = snd_pcm_hw_params_get_buffer_size(params, &size);
161 if (ret < 0) {
162 AUDIO_FUNC_LOGE("Unable to get buffer size for capture: %{public}s", snd_strerror(ret));
163 return HDF_FAILURE;
164 }
165 captureIns->bufferSize = size;
166
167 return HDF_SUCCESS;
168 }
169
SetHWPeriod(struct AlsaSoundCard * cardIns,snd_pcm_hw_params_t * params)170 static int32_t SetHWPeriod(struct AlsaSoundCard *cardIns, snd_pcm_hw_params_t *params)
171 {
172 int32_t ret;
173 int32_t dir = 0; /* dir Value range (-1,0,1) */
174 snd_pcm_uframes_t size = 0;
175 struct AlsaCapture *captureIns = (struct AlsaCapture*)cardIns;
176 CHECK_NULL_PTR_RETURN_DEFAULT(cardIns);
177 CHECK_NULL_PTR_RETURN_DEFAULT(params);
178
179 ret = snd_pcm_hw_params_set_period_time_near(cardIns->pcmHandle, params, &captureIns->periodTime, &dir);
180 if (ret < 0) {
181 AUDIO_FUNC_LOGE("Unable to set period time %{public}u for capture: %{public}s",
182 captureIns->periodTime, snd_strerror(ret));
183 return HDF_FAILURE;
184 }
185
186 ret = snd_pcm_hw_params_get_period_size(params, &size, &dir);
187 if (ret < 0) {
188 AUDIO_FUNC_LOGE("Unable to get period size for capture: %{public}s", snd_strerror(ret));
189 return HDF_FAILURE;
190 }
191 captureIns->periodSize = size;
192
193 return HDF_SUCCESS;
194 }
195
SetHWParams(struct AlsaSoundCard * cardIns,snd_pcm_access_t access)196 static int32_t SetHWParams(struct AlsaSoundCard *cardIns, snd_pcm_access_t access)
197 {
198 int32_t ret;
199 snd_pcm_hw_params_t *hwParams = NULL;
200 snd_pcm_t *handle = cardIns->pcmHandle;
201 CHECK_NULL_PTR_RETURN_DEFAULT(cardIns);
202 CHECK_NULL_PTR_RETURN_DEFAULT(handle);
203
204 snd_pcm_hw_params_alloca(&hwParams);
205 ret = snd_pcm_hw_params_any(handle, hwParams); // choose all parameters
206 if (ret < 0) {
207 AUDIO_FUNC_LOGE("Broken configuration for capture: no configurations available: %{public}s.",
208 snd_strerror(ret));
209 return HDF_FAILURE;
210 }
211
212 ret = SetHWParamsSub(cardIns, hwParams, access);
213 if (ret != HDF_SUCCESS) {
214 AUDIO_FUNC_LOGE("SetHWParamsSub failed!");
215 return ret;
216 }
217
218 ret = SetHWRate(cardIns, hwParams);
219 if (ret != HDF_SUCCESS) {
220 AUDIO_FUNC_LOGE("SetHWRate failed!");
221 return ret;
222 }
223
224 ret = SetHWBuffer(cardIns, hwParams);
225 if (ret != HDF_SUCCESS) {
226 AUDIO_FUNC_LOGE("SetHWBuffer failed!");
227 return ret;
228 }
229
230 ret = SetHWPeriod(cardIns, hwParams);
231 if (ret != HDF_SUCCESS) {
232 AUDIO_FUNC_LOGE("SetHWPeriod failed!");
233 return ret;
234 }
235
236 /* write the parameters to device. */
237 ret = snd_pcm_hw_params(handle, hwParams);
238 if (ret < 0) {
239 AUDIO_FUNC_LOGE("Unable to set hw params for capture: %{public}s", snd_strerror(ret));
240 return HDF_FAILURE;
241 }
242
243 cardIns->canPause = snd_pcm_hw_params_can_pause(hwParams);
244 AUDIO_FUNC_LOGI("hardware driver %{public}s support pause",cardIns->canPause ? "is" : "is not");
245
246 return HDF_SUCCESS;
247 }
248
SetSWParams(struct AlsaSoundCard * cardIns)249 static int32_t SetSWParams(struct AlsaSoundCard *cardIns)
250 {
251 int32_t ret;
252 /* The time when the application starts reading data */
253 snd_pcm_sframes_t startThresholdSize = 1;
254 snd_pcm_sw_params_t *swParams = NULL;
255 snd_pcm_t *handle = cardIns->pcmHandle;
256 struct AlsaCapture *captureIns = (struct AlsaCapture *)cardIns;
257 CHECK_NULL_PTR_RETURN_DEFAULT(cardIns);
258 CHECK_NULL_PTR_RETURN_DEFAULT(handle);
259
260 snd_pcm_sw_params_alloca(&swParams);
261 /* get the current swparams */
262 ret = snd_pcm_sw_params_current(handle, swParams);
263 if (ret < 0) {
264 AUDIO_FUNC_LOGE("Unable to determine current swparams for capture: %{public}s.", snd_strerror(ret));
265 return HDF_FAILURE;
266 }
267 if (captureIns->periodSize == 0) {
268 AUDIO_FUNC_LOGE("error: g_periodSize cannot be zero!");
269 return HDF_FAILURE;
270 }
271 /* start the transfer when the buffer is 1 frames */
272 ret = snd_pcm_sw_params_set_start_threshold(handle, swParams, startThresholdSize);
273 if (ret < 0) {
274 AUDIO_FUNC_LOGE("Unable to set start threshold mode for capture: %{public}s.", snd_strerror(ret));
275 return HDF_FAILURE;
276 }
277
278 /* allow the transfer when at least period_size samples can be processed */
279 /* or disable this mechanism when period event is enabled (aka interrupt like style processing) */
280 ret = snd_pcm_sw_params_set_avail_min(handle, swParams,
281 captureIns->periodEvent ? captureIns->bufferSize : captureIns->periodSize);
282 if (ret < 0) {
283 AUDIO_FUNC_LOGE("Unable to set avail min for capture: %{public}s", snd_strerror(ret));
284 return HDF_FAILURE;
285 }
286
287 /* enable period events when requested */
288 if (captureIns->periodEvent) {
289 ret = snd_pcm_sw_params_set_period_event(handle, swParams, 1);
290 if (ret < 0) {
291 AUDIO_FUNC_LOGE("Unable to set period event: %{public}s", snd_strerror(ret));
292 return HDF_FAILURE;
293 }
294 }
295 /* write the parameters to the capture device */
296 ret = snd_pcm_sw_params(handle, swParams);
297 if (ret < 0) {
298 AUDIO_FUNC_LOGE("Unable to set sw params for capture: %{public}s", snd_strerror(ret));
299 return HDF_FAILURE;
300 }
301
302 return HDF_SUCCESS;
303 }
304
ResetCaptureParams(struct AlsaSoundCard * cardIns,snd_pcm_access_t access)305 static int32_t ResetCaptureParams(struct AlsaSoundCard *cardIns, snd_pcm_access_t access)
306 {
307 int32_t ret;
308 CHECK_NULL_PTR_RETURN_DEFAULT(cardIns);
309 CHECK_NULL_PTR_RETURN_DEFAULT(cardIns->pcmHandle);
310
311 ret = SetHWParams(cardIns, access);
312 if (ret != HDF_SUCCESS) {
313 AUDIO_FUNC_LOGE("Setting of hwparams failed: %{public}d.", ret);
314 return ret;
315 }
316
317 ret = SetSWParams(cardIns);
318 if (ret != HDF_SUCCESS) {
319 AUDIO_FUNC_LOGE("Setting of swparams failed: %{public}d.", ret);
320 return ret;
321 }
322
323 return HDF_SUCCESS;
324 }
325
UpdateSetParams(struct AlsaSoundCard * cardIns)326 static int32_t UpdateSetParams(struct AlsaSoundCard *cardIns)
327 {
328 int32_t ret;
329 CHECK_NULL_PTR_RETURN_DEFAULT(cardIns);
330 CHECK_NULL_PTR_RETURN_DEFAULT(cardIns->pcmHandle);
331
332 cardIns->mmapFlag = false;
333 ret = ResetCaptureParams(cardIns, SND_PCM_ACCESS_MMAP_INTERLEAVED);
334 if (ret != HDF_SUCCESS) {
335 AUDIO_FUNC_LOGE("AudioSetParamsMmap failed!");
336 return ret;
337 }
338
339 ret = snd_pcm_start(cardIns->pcmHandle);
340 if (ret < 0) {
341 AUDIO_FUNC_LOGE("snd_pcm_start fail. %{public}s.", snd_strerror(ret));
342 return HDF_FAILURE;
343 }
344
345 return HDF_SUCCESS;
346 }
347
SaveHwParams(struct AlsaSoundCard * cardIns,const struct AudioHwCaptureParam * handleData)348 static int32_t SaveHwParams(struct AlsaSoundCard *cardIns, const struct AudioHwCaptureParam *handleData)
349 {
350 CHECK_NULL_PTR_RETURN_DEFAULT(cardIns);
351 CHECK_NULL_PTR_RETURN_DEFAULT(handleData);
352
353 cardIns->hwParams.streamType = AUDIO_CAPTURE_STREAM;
354 cardIns->hwParams.channels = handleData->frameCaptureMode.attrs.channelCount;
355 cardIns->hwParams.rate = handleData->frameCaptureMode.attrs.sampleRate;
356 cardIns->hwParams.periodSize = handleData->frameCaptureMode.periodSize;
357 cardIns->hwParams.periodCount = handleData->frameCaptureMode.periodCount;
358 cardIns->hwParams.format = handleData->frameCaptureMode.attrs.format;
359 cardIns->hwParams.period = handleData->frameCaptureMode.attrs.period;
360 cardIns->hwParams.frameSize = handleData->frameCaptureMode.attrs.frameSize;
361 cardIns->hwParams.isBigEndian = handleData->frameCaptureMode.attrs.isBigEndian;
362 cardIns->hwParams.isSignedData = handleData->frameCaptureMode.attrs.isSignedData;
363 cardIns->hwParams.startThreshold = handleData->frameCaptureMode.attrs.startThreshold;
364 cardIns->hwParams.stopThreshold = handleData->frameCaptureMode.attrs.stopThreshold;
365 cardIns->hwParams.silenceThreshold = handleData->frameCaptureMode.attrs.silenceThreshold;
366
367 return HDF_SUCCESS;
368 }
369
CaptureSetParams(struct AlsaCapture * captureIns,const struct AudioHwCaptureParam * handleData)370 int32_t CaptureSetParams(struct AlsaCapture *captureIns, const struct AudioHwCaptureParam *handleData)
371 {
372 int32_t ret;
373 struct AlsaSoundCard *cardIns = (struct AlsaSoundCard *)captureIns;
374 CHECK_NULL_PTR_RETURN_DEFAULT(cardIns);
375 CHECK_NULL_PTR_RETURN_DEFAULT(handleData);
376
377 SaveHwParams(cardIns, handleData);
378 ret = SetHWParams(cardIns, SND_PCM_ACCESS_RW_INTERLEAVED);
379 if (ret < 0) {
380 AUDIO_FUNC_LOGE("Setting of hwparams failed.");
381 return HDF_FAILURE;
382 }
383
384 ret = SetSWParams(cardIns);
385 if (ret < 0) {
386 AUDIO_FUNC_LOGE("Setting of swparams failed.");
387 return HDF_FAILURE;
388 }
389
390 return HDF_SUCCESS;
391 }
392
GetCaptureInsByName(const char * adapterName)393 static struct AlsaCapture *GetCaptureInsByName(const char *adapterName)
394 {
395 int32_t ret;
396 int32_t i;
397 struct AlsaCapture *captureIns = NULL;
398 struct AlsaSoundCard *alsaSnd = NULL;
399
400 /*
401 fine the instance with the corresponding adapter name, or create one if none.
402 */
403 for (i = 0; i < MAX_CARD_NUM; i++) {
404 alsaSnd = (struct AlsaSoundCard *)&g_alsaCaptureList[i];
405 if (alsaSnd->cardStatus) {
406 if (0 == strcmp(alsaSnd->adapterName, adapterName)) {
407 return &g_alsaCaptureList[i];
408 }
409 }
410 }
411
412 for (i = 0; i < MAX_CARD_NUM; i++) {
413 captureIns = &g_alsaCaptureList[i];
414 alsaSnd = (struct AlsaSoundCard *)&g_alsaCaptureList[i];
415 if (alsaSnd->cardStatus == 0) {
416 (void)memset_s(captureIns, sizeof(struct AlsaCapture), 0, sizeof(struct AlsaCapture));
417 ret = strncpy_s(alsaSnd->adapterName, MAX_CARD_NAME_LEN + 1, adapterName, strlen(adapterName));
418 if (ret != 0) {
419 AUDIO_FUNC_LOGE("strncpy_s failed!");
420 return NULL;
421 }
422 alsaSnd->cardStatus++;
423 captureIns->periodEvent = POLL_EVENT_DEF;
424 captureIns->periodTime = AUDIO_PERIOD_TIME_DEF;
425 captureIns->bufferTime = AUDIO_BUFFER_TIME_DEF;
426 captureIns->descPins = PIN_NONE;
427 captureIns->resample = 1;
428 return captureIns;
429 }
430 }
431 AUDIO_FUNC_LOGE("Failed to AddCardIns!");
432 return NULL;
433 }
434
CaptureCreateInstance(const char * adapterName)435 struct AlsaCapture *CaptureCreateInstance(const char* adapterName)
436 {
437 int32_t ret;
438 struct AlsaCapture *captureIns = NULL;
439 if (adapterName == NULL || strlen(adapterName) == 0) {
440 AUDIO_FUNC_LOGE("Invalid adapterName!");
441 return NULL;
442 }
443
444 if (g_alsaCaptureList == NULL) {
445 g_alsaCaptureList = (struct AlsaCapture *)OsalMemCalloc(MAX_CARD_NUM * sizeof(struct AlsaCapture));
446 if (g_alsaCaptureList == NULL) {
447 AUDIO_FUNC_LOGE("Failed to allocate memory!");
448 return NULL;
449 }
450 }
451
452 captureIns = GetCaptureInsByName(adapterName);
453 if (captureIns == NULL) {
454 AUDIO_FUNC_LOGE("Get capture instance failed.");
455 return NULL;
456 }
457 RegisterCaptureImpl(captureIns);
458
459 ret = SndSaveCardListInfo(SND_PCM_STREAM_CAPTURE);
460 if (ret != HDF_SUCCESS) {
461 AUDIO_FUNC_LOGE("Failed to save card device info.");
462 return NULL;
463 }
464
465 ret = SndMatchSelAdapter(&captureIns->soundCard, adapterName);
466 if (ret != HDF_SUCCESS) {
467 SndCloseHandle(&captureIns->soundCard);
468 CaptureFreeMemory();
469 return NULL;
470 }
471 CaptureOverrideFunc(captureIns);
472
473 return captureIns;
474 }
475
CaptureGetInstance(const char * adapterName)476 struct AlsaCapture *CaptureGetInstance(const char *adapterName)
477 {
478 int32_t i;
479
480 if (adapterName == NULL || strlen(adapterName) == 0) {
481 AUDIO_FUNC_LOGE("Invalid cardName!");
482 return NULL;
483 }
484
485 if (g_alsaCaptureList == NULL) {
486 AUDIO_FUNC_LOGE("g_alsaCaptureList is NULL!");
487 return NULL;
488 }
489
490 for (i = 0; i < MAX_CARD_NUM; i++) {
491 if (strcmp(g_alsaCaptureList[i].soundCard.adapterName, adapterName) == 0) {
492 return &(g_alsaCaptureList[i]);
493 }
494 }
495
496 return NULL;
497 }
498
CheckCapFrameBufferSize(struct AudioHwCaptureParam * handleData,snd_pcm_uframes_t * periodSize)499 static int32_t CheckCapFrameBufferSize(struct AudioHwCaptureParam *handleData, snd_pcm_uframes_t *periodSize)
500 {
501 uint32_t capFrameSize;
502 uint64_t capReqBufferSize;
503 CHECK_NULL_PTR_RETURN_DEFAULT(handleData);
504 CHECK_NULL_PTR_RETURN_DEFAULT(periodSize);
505
506 capFrameSize = handleData->frameCaptureMode.attrs.channelCount * handleData->frameCaptureMode.attrs.format;
507 if (capFrameSize == 0) {
508 AUDIO_FUNC_LOGE("Capture frame size is zero!");
509 return HDF_FAILURE;
510 }
511 capReqBufferSize = capFrameSize * (*periodSize);
512 if (capReqBufferSize > FRAME_DATA) {
513 *periodSize = FRAME_DATA / capFrameSize;
514 }
515
516 return HDF_SUCCESS;
517 }
518
CheckPcmStatus(snd_pcm_t * capturePcmHandle)519 static int32_t CheckPcmStatus(snd_pcm_t *capturePcmHandle)
520 {
521 int32_t ret;
522 CHECK_NULL_PTR_RETURN_DEFAULT(capturePcmHandle);
523
524 ret = snd_pcm_wait(capturePcmHandle, -1); /* -1 for timeout, Waiting forever */
525 if (ret < 0) {
526 AUDIO_FUNC_LOGE("snd_pcm_wait failed: %{public}s.", snd_strerror(ret));
527 return HDF_FAILURE;
528 }
529
530 if (snd_pcm_state(capturePcmHandle) == SND_PCM_STATE_SETUP) {
531 ret = snd_pcm_prepare(capturePcmHandle);
532 if (ret < 0) {
533 AUDIO_FUNC_LOGE("snd_pcm_prepare fail: %{public}s", snd_strerror(ret));
534 return HDF_FAILURE;
535 }
536 }
537
538 return HDF_SUCCESS;
539 }
540
CapturePcmReadi(snd_pcm_t * pcm,uint64_t * frameCnt,char * dataBuf,snd_pcm_uframes_t bufSize)541 static int32_t CapturePcmReadi(snd_pcm_t *pcm, uint64_t *frameCnt, char *dataBuf, snd_pcm_uframes_t bufSize)
542 {
543 int32_t ret;
544 long frames;
545 int32_t tryNum = AUDIO_ALSALIB_RETYR;
546 CHECK_NULL_PTR_RETURN_DEFAULT(pcm);
547 CHECK_NULL_PTR_RETURN_DEFAULT(frameCnt);
548 CHECK_NULL_PTR_RETURN_DEFAULT(dataBuf);
549 if (bufSize == 0) {
550 AUDIO_FUNC_LOGE("Capture data buf is empty.");
551 return HDF_FAILURE;
552 }
553
554 do {
555 /* Read interleaved frames to a PCM. */
556 frames = snd_pcm_readi(pcm, dataBuf, bufSize);
557 if (frames > 0) {
558 *frameCnt = (uint64_t)frames;
559 return HDF_SUCCESS;
560 }
561
562 if (frames == -EBADFD) {
563 AUDIO_FUNC_LOGE("Capture PCM is not in the right state: %{public}s", snd_strerror(frames));
564 ret = snd_pcm_prepare(pcm);
565 if (ret < 0) {
566 AUDIO_FUNC_LOGE("Capture snd_pcm_prepare fail: %{public}s", snd_strerror(ret));
567 return HDF_FAILURE;
568 }
569 } else {
570 /* -ESTRPIPE: a suspend event occurred,
571 * stream is suspended and waiting for an application recovery.
572 * -EPIPE: an underrun occurred.
573 */
574 ret = snd_pcm_recover(pcm, frames, 0); // 0 for open capture recover log.
575 if (ret < 0) {
576 AUDIO_FUNC_LOGE("snd_pcm_readi failed: %{public}s", snd_strerror(ret));
577 return HDF_FAILURE;
578 }
579 }
580 ret = snd_pcm_start(pcm);
581 if (ret < 0) {
582 AUDIO_FUNC_LOGE("snd_pcm_start fail. %{public}s", snd_strerror(ret));
583 return HDF_FAILURE;
584 }
585 tryNum--;
586 } while (tryNum > 0);
587
588 return HDF_SUCCESS;
589 }
590
CaptureDataCopy(struct AudioHwCaptureParam * handleData,char * buffer,uint64_t frames)591 static int32_t CaptureDataCopy(struct AudioHwCaptureParam *handleData, char *buffer, uint64_t frames)
592 {
593 int32_t ret;
594 uint32_t channels;
595 uint32_t format;
596 uint64_t recvDataSize;
597 CHECK_NULL_PTR_RETURN_DEFAULT(handleData);
598 CHECK_NULL_PTR_RETURN_DEFAULT(buffer);
599 if (frames == 0) {
600 AUDIO_FUNC_LOGE("Capture buffer size is empty!");
601 return HDF_FAILURE;
602 }
603
604 if (handleData->frameCaptureMode.buffer == NULL) {
605 AUDIO_FUNC_LOGE("frameCaptureMode.buffer is NULL!");
606 return HDF_FAILURE;
607 }
608 channels = handleData->frameCaptureMode.attrs.channelCount;
609 format = (uint32_t)handleData->frameCaptureMode.attrs.format;
610 recvDataSize = (uint64_t)(frames * channels * format);
611 ret = memcpy_s(handleData->frameCaptureMode.buffer, FRAME_DATA, buffer, recvDataSize);
612 if (ret != EOK) {
613 AUDIO_FUNC_LOGE("memcpy frame data failed!");
614 return HDF_FAILURE;
615 }
616 handleData->frameCaptureMode.bufferSize = recvDataSize;
617 handleData->frameCaptureMode.bufferFrameSize = frames;
618
619 return HDF_SUCCESS;
620 }
621
CaptureOpenImpl(struct AlsaCapture * captureIns)622 static int32_t CaptureOpenImpl(struct AlsaCapture *captureIns)
623 {
624 int32_t ret;
625 CHECK_NULL_PTR_RETURN_DEFAULT(captureIns);
626
627 if (SndisBusy(&captureIns->soundCard)) {
628 AUDIO_FUNC_LOGE("Resource busy!!");
629 SndCloseHandle(&captureIns->soundCard);
630 return HDF_ERR_DEVICE_BUSY;
631 }
632
633 ret = snd_pcm_open(&captureIns->soundCard.pcmHandle, captureIns->soundCard.devName,
634 SND_PCM_STREAM_CAPTURE, SND_PCM_NONBLOCK);
635 if (ret < 0) {
636 AUDIO_FUNC_LOGE("snd_pcm_open fail: %{public}s!", snd_strerror(ret));
637 CaptureFreeMemory();
638 return HDF_FAILURE;
639 }
640
641 ret = snd_pcm_nonblock(captureIns->soundCard.pcmHandle, 1);
642 if (ret < 0) {
643 AUDIO_FUNC_LOGE("snd_pcm_nonblock fail: %{public}s!", snd_strerror(ret));
644 SndCloseHandle(&captureIns->soundCard);
645 CaptureFreeMemory();
646 return HDF_FAILURE;
647 }
648
649 ret = SndOpenMixer(&captureIns->soundCard);
650 if (ret != HDF_SUCCESS) {
651 AUDIO_FUNC_LOGE("SndOpenMixer failed");
652 SndCloseHandle(&captureIns->soundCard);
653 CaptureFreeMemory();
654 return HDF_FAILURE;
655 }
656
657 return HDF_SUCCESS;
658 }
659
CaptureCloseImpl(struct AlsaCapture * captureIns)660 static int32_t CaptureCloseImpl(struct AlsaCapture *captureIns)
661 {
662 CHECK_NULL_PTR_RETURN_DEFAULT(captureIns);
663 SndCloseHandle(&captureIns->soundCard);
664 CaptureFreeMemory();
665 return HDF_SUCCESS;
666 }
667
CaptureCheckMmapMode(struct AlsaSoundCard * cardIns)668 static int32_t CaptureCheckMmapMode(struct AlsaSoundCard *cardIns)
669 {
670 int32_t ret;
671 CHECK_NULL_PTR_RETURN_DEFAULT(cardIns);
672
673 if (!cardIns->mmapFlag) {
674 ret = ResetCaptureParams(cardIns, SND_PCM_ACCESS_RW_INTERLEAVED);
675 if (ret != HDF_SUCCESS) {
676 AUDIO_FUNC_LOGE("AudioSetParamsMmap failed!");
677 return ret;
678 }
679
680 ret = snd_pcm_start(cardIns->pcmHandle);
681 if (ret < 0) {
682 AUDIO_FUNC_LOGE("snd_pcm_start fail. %{public}s", snd_strerror(ret));
683 return HDF_FAILURE;
684 }
685 cardIns->mmapFlag = true;
686 }
687 return HDF_SUCCESS;
688 }
689
CaptureReadImpl(struct AlsaCapture * captureIns,struct AudioHwCaptureParam * handleData)690 static int32_t CaptureReadImpl(struct AlsaCapture *captureIns, struct AudioHwCaptureParam *handleData)
691 {
692 int32_t ret;
693 uint64_t frames = 0;
694 char *buffer = NULL;
695 snd_pcm_uframes_t bufferSize = 0;
696 snd_pcm_uframes_t periodSize = 0;
697 struct AlsaSoundCard *cardIns = (struct AlsaSoundCard *)captureIns;
698 CHECK_NULL_PTR_RETURN_DEFAULT(captureIns);
699 CHECK_NULL_PTR_RETURN_DEFAULT(handleData);
700
701 if (cardIns->pauseState) {
702 AUDIO_FUNC_LOGE("Currently in pause, please check!");
703 return HDF_FAILURE;
704 }
705
706 ret = snd_pcm_get_params(cardIns->pcmHandle, &bufferSize, &periodSize);
707 if (ret < 0) {
708 AUDIO_FUNC_LOGE("Get capture params error: %{public}s.", snd_strerror(ret));
709 return HDF_FAILURE;
710 }
711 if (CaptureCheckMmapMode(cardIns) != HDF_SUCCESS) {
712 return HDF_FAILURE;
713 }
714
715 if (CheckCapFrameBufferSize(handleData, &periodSize) != HDF_SUCCESS) {
716 AUDIO_FUNC_LOGE("CheckCapFrameBufferSize failed.");
717 return HDF_FAILURE;
718 }
719 if (CheckPcmStatus(cardIns->pcmHandle) != HDF_SUCCESS) {
720 AUDIO_FUNC_LOGE("CheckPcmStatus failed.");
721 return HDF_FAILURE;
722 }
723 buffer = OsalMemCalloc(ALSA_CAP_BUFFER_SIZE);
724 if (buffer == NULL) {
725 AUDIO_FUNC_LOGE("Failed to Calloc buffer");
726 return HDF_FAILURE;
727 }
728 ret = CapturePcmReadi(cardIns->pcmHandle, &frames, buffer, periodSize);
729 if (ret != HDF_SUCCESS) {
730 AUDIO_FUNC_LOGE("CapturePcmReadi is error!");
731 AudioMemFree((void **)&buffer);
732 return ret;
733 }
734 ret = CaptureDataCopy(handleData, buffer, frames);
735 if (ret != HDF_SUCCESS) {
736 AUDIO_FUNC_LOGE("Failed to copy data. It may be paused. Check the status!");
737 AudioMemFree((void **)&buffer);
738 return ret;
739 }
740
741 AudioMemFree((void **)&buffer);
742 return HDF_SUCCESS;
743 }
744
CaptureGetMmapPositionImpl(struct AlsaCapture * captureIns)745 static int32_t CaptureGetMmapPositionImpl(struct AlsaCapture *captureIns)
746 {
747 return captureIns->soundCard.mmapFrames;
748 }
749
CaptureMmapReadImpl(struct AlsaCapture * captureIns,const struct AudioHwCaptureParam * handleData)750 static int32_t CaptureMmapReadImpl(struct AlsaCapture *captureIns, const struct AudioHwCaptureParam *handleData)
751 {
752 char *mmapAddr;
753 uint32_t frameSize;
754 snd_pcm_sframes_t xfer;
755 snd_pcm_uframes_t size;
756 struct AlsaSoundCard *cardIns = (struct AlsaSoundCard *)captureIns;
757 CHECK_NULL_PTR_RETURN_DEFAULT(captureIns);
758 CHECK_NULL_PTR_RETURN_DEFAULT(handleData);
759
760 if (cardIns->pauseState) {
761 AUDIO_FUNC_LOGE("Currently in pause, please check!");
762 return HDF_FAILURE;
763 }
764
765 if (UpdateSetParams(cardIns) != HDF_SUCCESS) {
766 AUDIO_FUNC_LOGE("Update set params failed!");
767 return HDF_FAILURE;
768 }
769
770 mmapAddr = (char *)handleData->frameCaptureMode.mmapBufDesc.memoryAddress;
771 if (mmapAddr == NULL) {
772 AUDIO_FUNC_LOGE("mmapAddr is NULL!");
773 return HDF_FAILURE;
774 }
775 size = (snd_pcm_sframes_t)handleData->frameCaptureMode.mmapBufDesc.totalBufferFrames;
776 frameSize = handleData->frameCaptureMode.attrs.channelCount * handleData->frameCaptureMode.attrs.format;
777 while (size > 0) {
778 xfer = snd_pcm_mmap_readi(cardIns->pcmHandle, mmapAddr, size);
779 if (xfer < 0) {
780 if (xfer == -EAGAIN) {
781 snd_pcm_wait(cardIns->pcmHandle, AUDIO_PCM_WAIT);
782 continue;
783 }
784 AUDIO_FUNC_LOGE("snd_pcm_mmap_readi: %{public}s", snd_strerror(xfer));
785 return HDF_FAILURE;
786 }
787
788 if (xfer > 0) {
789 mmapAddr += xfer * frameSize;
790 size -= xfer;
791 cardIns->mmapFrames += xfer;
792 }
793 }
794
795 return HDF_SUCCESS;
796 }
797
CaptureInitImpl(struct AlsaCapture * captureIns)798 static int32_t CaptureInitImpl(struct AlsaCapture* captureIns)
799 {
800 AUDIO_FUNC_LOGE("Not yet realized");
801 return HDF_SUCCESS;
802 }
803
CaptureSelectSceneImpl(struct AlsaCapture * captureIns,enum AudioPortPin descPins,const struct PathDeviceInfo * deviceInfo)804 static int32_t CaptureSelectSceneImpl(struct AlsaCapture *captureIns, enum AudioPortPin descPins,
805 const struct PathDeviceInfo *deviceInfo)
806 {
807 AUDIO_FUNC_LOGE("Not yet realized");
808 return HDF_SUCCESS;
809 }
810
CaptureStartImpl(struct AlsaCapture * captureIns)811 static int32_t CaptureStartImpl(struct AlsaCapture *captureIns)
812 {
813 AUDIO_FUNC_LOGE("Not yet realized");
814 return HDF_SUCCESS;
815 }
816
CaptureStopImpl(struct AlsaCapture * captureIns)817 static int32_t CaptureStopImpl(struct AlsaCapture *captureIns)
818 {
819 AUDIO_FUNC_LOGE("Not yet realized");
820 return HDF_SUCCESS;
821 }
822
CaptureGetVolThresholdImpl(struct AlsaCapture * captureIns,long * volMin,long * volMax)823 static int32_t CaptureGetVolThresholdImpl(struct AlsaCapture *captureIns, long *volMin, long *volMax)
824 {
825 AUDIO_FUNC_LOGE("Not yet realized");
826 return HDF_SUCCESS;
827 }
828
CaptureGetVolumeImpl(struct AlsaCapture * captureIns,long * volume)829 static int32_t CaptureGetVolumeImpl(struct AlsaCapture *captureIns, long *volume)
830 {
831 AUDIO_FUNC_LOGE("Not yet realized");
832 return HDF_SUCCESS;
833 }
834
CaptureSetVolumeImpl(struct AlsaCapture * captureIns,long volume)835 static int32_t CaptureSetVolumeImpl(struct AlsaCapture *captureIns, long volume)
836 {
837 AUDIO_FUNC_LOGE("Not yet realized");
838 return HDF_SUCCESS;
839 }
840
CaptureGetGainThresholdImpl(struct AlsaCapture * captureIns,float * gainMin,float * gainMax)841 static int32_t CaptureGetGainThresholdImpl(struct AlsaCapture *captureIns, float *gainMin, float *gainMax)
842 {
843 AUDIO_FUNC_LOGE("Not yet realized");
844 return HDF_SUCCESS;
845 }
846
CaptureGetGainImpl(struct AlsaCapture * captureIns,float * gain)847 static int32_t CaptureGetGainImpl(struct AlsaCapture *captureIns, float *gain)
848 {
849 AUDIO_FUNC_LOGE("Not yet realized");
850 return HDF_SUCCESS;
851 }
852
CaptureSetGainImpl(struct AlsaCapture * captureIns,float gain)853 static int32_t CaptureSetGainImpl(struct AlsaCapture *captureIns, float gain)
854 {
855 AUDIO_FUNC_LOGE("Not yet realized");
856 return HDF_SUCCESS;
857 }
858
CaptureGetMuteImpl(struct AlsaCapture * captureIns)859 static bool CaptureGetMuteImpl(struct AlsaCapture *captureIns)
860 {
861 AUDIO_FUNC_LOGE("Not yet realized");
862 return false;
863 }
864
CaptureSetMuteImpl(struct AlsaCapture * captureIns,bool muteFlag)865 static int32_t CaptureSetMuteImpl(struct AlsaCapture *captureIns, bool muteFlag)
866 {
867 AUDIO_FUNC_LOGE("Not yet realized");
868 return HDF_SUCCESS;
869 }
870
CaptureSetPauseStateImpl(struct AlsaCapture * captureIns,bool pauseFlag)871 static int32_t CaptureSetPauseStateImpl(struct AlsaCapture *captureIns, bool pauseFlag)
872 {
873 int32_t ret;
874 int pause = pauseFlag ? AUDIO_ALSALIB_IOCTRL_PAUSE : AUDIO_ALSALIB_IOCTRL_RESUME;
875 struct AlsaSoundCard *cardIns = (struct AlsaSoundCard *)captureIns;
876
877 if (cardIns->canPause) {
878 ret = snd_pcm_pause(cardIns->pcmHandle, pause);
879 if (ret < 0) {
880 AUDIO_FUNC_LOGE("snd_pcm_pause failed!");
881 return HDF_FAILURE;
882 }
883 } else {
884 if (pause == AUDIO_ALSALIB_IOCTRL_RESUME) {
885 ret = snd_pcm_prepare(cardIns->pcmHandle);
886 if (ret < 0) {
887 AUDIO_FUNC_LOGE("snd_pcm_prepare fail: %{public}s", snd_strerror(ret));
888 return HDF_FAILURE;
889 }
890 ret = snd_pcm_start(cardIns->pcmHandle);
891 if (ret < 0) {
892 AUDIO_FUNC_LOGE("snd_pcm_start fail. %{public}s", snd_strerror(ret));
893 return HDF_FAILURE;
894 }
895 }
896 if (pause == AUDIO_ALSALIB_IOCTRL_PAUSE) {
897 ret = snd_pcm_drop(cardIns->pcmHandle);
898 if (ret < 0) {
899 AUDIO_FUNC_LOGE("Pause fail: %{public}s", snd_strerror(ret));
900 return HDF_FAILURE;
901 }
902 }
903 }
904 cardIns->pauseState = pauseFlag;
905
906 return HDF_SUCCESS;
907 }
908
RegisterCaptureImpl(struct AlsaCapture * captureIns)909 static void RegisterCaptureImpl(struct AlsaCapture *captureIns)
910 {
911 if (captureIns == NULL) {
912 AUDIO_FUNC_LOGE("captureIns is NULL!");
913 }
914
915 captureIns->Init = CaptureInitImpl;
916 captureIns->Open = CaptureOpenImpl;
917 captureIns->Close = CaptureCloseImpl;
918 captureIns->SelectScene = CaptureSelectSceneImpl;
919 captureIns->Start = CaptureStartImpl;
920 captureIns->Stop = CaptureStopImpl;
921 captureIns->Read = CaptureReadImpl;
922 captureIns->GetMmapPosition = CaptureGetMmapPositionImpl;
923 captureIns->MmapRead = CaptureMmapReadImpl;
924 captureIns->GetVolThreshold = CaptureGetVolThresholdImpl;
925 captureIns->GetVolume = CaptureGetVolumeImpl;
926 captureIns->SetVolume = CaptureSetVolumeImpl;
927 captureIns->GetGainThreshold = CaptureGetGainThresholdImpl;
928 captureIns->GetGain = CaptureGetGainImpl;
929 captureIns->SetGain = CaptureSetGainImpl;
930 captureIns->GetMute = CaptureGetMuteImpl;
931 captureIns->SetMute = CaptureSetMuteImpl;
932 captureIns->SetPauseState = CaptureSetPauseStateImpl;
933 }
934