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