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