• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_lib_capture.h"
17 #include "audio_common.h"
18 #include "osal_mem.h"
19 #include "securec.h"
20 
21 #define HDF_LOG_TAG HDF_AUDIO_HAL_LIB
22 
23 #define AUDIO_TIMESTAMP_FREQ 8 /* Hz */
24 #define AUDIO_SAMPLE_FREQ    48000
25 #define AUDIO_PERIOD         ((AUDIO_SAMPLE_FREQ) / (AUDIO_TIMESTAMP_FREQ))
26 #define AUDIO_PCM_WAIT       100
27 #define AUDIO_RESUME_POLL    (10 * (AUDIO_PCM_WAIT)) // 1s
28 #define ALSA_CAP_BUFFER_SIZE (2 * 2 * 6000)        // format(S16LE) * channels(2) * period.
29 
30 static unsigned int g_bufferTime = 500000; /* (0.5s): ring buffer length in us */
31 static unsigned int g_periodTime = 100000; /* (0.1s): period time in us */
32 static snd_pcm_sframes_t g_bufferSize = 0;
33 static snd_pcm_sframes_t g_periodSize = 0;
34 static int g_resample = 1;    /* enable alsa-lib resampling */
35 static bool g_periodEvent = false; /* produce poll event after each period */
36 static int g_canPause = 0;    /* 0 Hardware doesn't support pause, 1 Hardware supports pause */
37 
AudioSetMixerCapVolume(snd_mixer_elem_t * pcmElemen,long vol)38 static int32_t AudioSetMixerCapVolume(snd_mixer_elem_t *pcmElemen, long vol)
39 {
40     int32_t ret;
41 
42     if (pcmElemen == NULL) {
43         AUDIO_FUNC_LOGE("parameter is NULL!");
44         return HDF_FAILURE;
45     }
46 
47     /* Judge whether it is mono or stereo */
48     ret = snd_mixer_selem_is_capture_mono(pcmElemen);
49     if (ret == 1) { // mono
50         ret = snd_mixer_selem_set_capture_volume(pcmElemen, SND_MIXER_SCHN_MONO, vol);
51         if (ret < 0) {
52             AUDIO_FUNC_LOGE("Failed to set volume: %{public}s.", snd_strerror(ret));
53             return HDF_FAILURE;
54         }
55     } else { // ret == 0: is not mono. (stereo)
56         ret = snd_mixer_selem_set_capture_volume_all(pcmElemen, vol);
57         if (ret < 0) {
58             AUDIO_FUNC_LOGE("Failed to set all channel volume: %{public}s.", snd_strerror(ret));
59             return HDF_FAILURE;
60         }
61     }
62 
63     return HDF_SUCCESS;
64 }
65 
AudioCaptureSetPauseState(snd_pcm_t * pcm,int32_t pause)66 static int32_t AudioCaptureSetPauseState(snd_pcm_t *pcm, int32_t pause)
67 {
68     int32_t ret;
69 
70     if (pcm == NULL) {
71         AUDIO_FUNC_LOGE("Param is NULL!");
72         return HDF_FAILURE;
73     }
74 
75     if (pause == AUDIO_ALSALIB_IOCTRL_RESUME) {
76         ret = snd_pcm_prepare(pcm);
77         if (ret < 0) {
78             AUDIO_FUNC_LOGE("snd_pcm_prepare fail: %{public}s", snd_strerror(ret));
79             return HDF_FAILURE;
80         }
81         ret = snd_pcm_start(pcm);
82         if (ret < 0) {
83             AUDIO_FUNC_LOGE("snd_pcm_start fail. %{public}s", snd_strerror(ret));
84             return HDF_FAILURE;
85         }
86     } else if (pause == AUDIO_ALSALIB_IOCTRL_PAUSE) {
87         ret = snd_pcm_drop(pcm);
88         if (ret < 0) {
89             AUDIO_FUNC_LOGE("Pause fail: %{public}s", snd_strerror(ret));
90             return HDF_FAILURE;
91         }
92     } else {
93         /* Nothing to do! */
94     }
95 
96     return HDF_SUCCESS;
97 }
98 
AudioCtlCaptureSetPauseStu(const struct DevHandleCapture * handle,int cmdId,const struct AudioHwCaptureParam * handleData)99 int32_t AudioCtlCaptureSetPauseStu(
100     const struct DevHandleCapture *handle, int cmdId, const struct AudioHwCaptureParam *handleData)
101 {
102     int32_t ret;
103     int32_t pause;
104     struct AudioCardInfo *cardIns;
105 
106     (void)cmdId;
107     if (handle == NULL || handleData == NULL) {
108         AUDIO_FUNC_LOGE("Param is NULL!");
109         return HDF_FAILURE;
110     }
111 
112     const char *adapterName = handleData->captureMode.hwInfo.adapterName;
113     cardIns = GetCardIns(adapterName);
114     if (cardIns == NULL) {
115         AUDIO_FUNC_LOGE("cardIns or capturePcmHandle is NULL!");
116         return HDF_FAILURE;
117     }
118 
119     pause = handleData->captureMode.ctlParam.pause ? AUDIO_ALSALIB_IOCTRL_PAUSE : AUDIO_ALSALIB_IOCTRL_RESUME;
120     ret = AudioCaptureSetPauseState(cardIns->capturePcmHandle, pause);
121     if (ret != HDF_SUCCESS) {
122         AUDIO_FUNC_LOGE("set pause error!");
123         return HDF_FAILURE;
124     }
125 
126     return HDF_SUCCESS;
127 }
128 
AudioCtlCaptureGetVolume(const struct DevHandleCapture * handle,int cmdId,struct AudioHwCaptureParam * handleData)129 int32_t AudioCtlCaptureGetVolume(
130     const struct DevHandleCapture *handle, int cmdId, struct AudioHwCaptureParam *handleData)
131 {
132     int32_t ret;
133     long volEverage;
134     long volLeft = 0;
135     long volRight = 0;
136     struct AudioCardInfo *cardIns;
137 
138     (void)cmdId;
139     if (handle == NULL || handleData == NULL) {
140         AUDIO_FUNC_LOGE("AudioCtlCaptureSetVolume parameter is NULL!");
141         return HDF_FAILURE;
142     }
143 
144     const char *adapterName = handleData->captureMode.hwInfo.adapterName;
145     cardIns = GetCardIns(adapterName);
146     if (cardIns == NULL) {
147         AUDIO_FUNC_LOGE("Unable to obtain correct sound card information!");
148         return HDF_FAILURE;
149     }
150 
151     if (strncmp(adapterName, USB, strlen(USB)) == 0) {
152         handleData->captureMode.ctlParam.volume = MAX_VOLUME;
153         return HDF_SUCCESS;
154     }
155 
156     ret = snd_mixer_handle_events(cardIns->mixer);
157     if (ret < 0) {
158         AUDIO_FUNC_LOGE("snd_mixer_handle_events fail: %{public}s.", snd_strerror(ret));
159         return HDF_FAILURE;
160     }
161 
162     /* Read the two channel volume */
163     ret = snd_mixer_selem_get_capture_volume(cardIns->ctrlLeftVolume, SND_MIXER_SCHN_FRONT_LEFT, &volLeft);
164     if (ret < 0) {
165         AUDIO_FUNC_LOGE("Get left channel volume fail: %{public}s.", snd_strerror(ret));
166     }
167     ret = snd_mixer_selem_get_capture_volume(cardIns->ctrlLeftVolume, SND_MIXER_SCHN_FRONT_RIGHT, &volRight);
168     if (ret < 0) {
169         AUDIO_FUNC_LOGE("Get right channel volume fail: %{public}s.", snd_strerror(ret));
170     }
171     volEverage = (volLeft + volRight) >> 1;
172     handleData->captureMode.ctlParam.volume = (float)(volEverage);
173 
174     return HDF_SUCCESS;
175 }
176 
AudioCtlCaptureSetVolume(const struct DevHandleCapture * handle,int cmdId,const struct AudioHwCaptureParam * handleData)177 int32_t AudioCtlCaptureSetVolume(
178     const struct DevHandleCapture *handle, int cmdId, const struct AudioHwCaptureParam *handleData)
179 {
180     int32_t ret;
181     int32_t vol;
182     struct AudioCardInfo *cardIns;
183 
184     (void)cmdId;
185     if (handle == NULL || handleData == NULL) {
186         AUDIO_FUNC_LOGE("parameter is NULL!");
187         return HDF_FAILURE;
188     }
189 
190     vol = (int32_t)handleData->captureMode.ctlParam.volume;
191     const char *adapterName = handleData->captureMode.hwInfo.adapterName;
192     cardIns = GetCardIns(adapterName);
193     if (cardIns == NULL) {
194         AUDIO_FUNC_LOGE("cardIns is NULL!");
195         return HDF_FAILURE;
196     }
197 
198     if (strncmp(adapterName, USB, strlen(USB)) == 0) {
199         /* The external Settings. */
200         return HDF_SUCCESS;
201     }
202 
203     ret = AudioSetMixerCapVolume(cardIns->ctrlLeftVolume, vol);
204     if (ret != HDF_SUCCESS) {
205         AUDIO_FUNC_LOGE("AudioSetMixerVolume left fail!");
206         return ret;
207     }
208 
209     ret = AudioSetMixerCapVolume(cardIns->ctrlRightVolume, vol);
210     if (ret != HDF_SUCCESS) {
211         AUDIO_FUNC_LOGE("AudioSetMixerVolume right fail!");
212         return ret;
213     }
214 
215     return HDF_SUCCESS;
216 }
217 
AudioCtlCaptureSetMuteStu(const struct DevHandleCapture * handle,int cmdId,const struct AudioHwCaptureParam * handleData)218 int32_t AudioCtlCaptureSetMuteStu(
219     const struct DevHandleCapture *handle, int cmdId, const struct AudioHwCaptureParam *handleData)
220 {
221     int32_t ret;
222     bool muteState;
223 
224     (void)cmdId;
225     if (handle == NULL || handleData == NULL) {
226         AUDIO_FUNC_LOGE("param is NULL!");
227         return HDF_FAILURE;
228     }
229 
230     const char *adapterName = handleData->captureMode.hwInfo.adapterName;
231     struct AudioCardInfo *cardIns = GetCardIns(adapterName);
232     if (cardIns == NULL) {
233         AUDIO_FUNC_LOGE("cardIns is empty pointer!!!");
234         return HDF_FAILURE;
235     }
236 
237     muteState = (bool)cardIns->captureMuteValue;
238     if (muteState == false) {
239         ret =
240             AudioMixerSetCtrlMode(cardIns, adapterName, "Digital Capture mute", SND_CAP_MIC_PATH, SND_IN_CARD_MIC_OFF);
241     } else {
242         ret =
243             AudioMixerSetCtrlMode(cardIns, adapterName, "Digital Capture mute", SND_CAP_MIC_PATH, SND_IN_CARD_MAIN_MIC);
244     }
245     if (ret != HDF_SUCCESS) {
246         AUDIO_FUNC_LOGE("AudioMixerSetCtrlMode failed!");
247         return ret;
248     }
249     cardIns->captureMuteValue = (int32_t)handleData->captureMode.ctlParam.mute;
250 
251     return HDF_SUCCESS;
252 }
253 
AudioCtlCaptureGetMuteStu(const struct DevHandleCapture * handle,int cmdId,struct AudioHwCaptureParam * handleData)254 int32_t AudioCtlCaptureGetMuteStu(
255     const struct DevHandleCapture *handle, int cmdId, struct AudioHwCaptureParam *handleData)
256 {
257     struct AudioCardInfo *cardInstance;
258 
259     (void)cmdId;
260     if (handle == NULL || handleData == NULL) {
261         AUDIO_FUNC_LOGE("param is NULL!");
262         return HDF_FAILURE;
263     }
264 
265     const char *adapterName = handleData->captureMode.hwInfo.adapterName;
266     cardInstance = GetCardIns(adapterName);
267     if (cardInstance == NULL) {
268         AUDIO_FUNC_LOGE("cardInsance is null pointer!!");
269         return HDF_FAILURE;
270     }
271 
272     if (strncmp(adapterName, USB, strlen(USB)) == 0) {
273         /* The external Settings. */
274         return HDF_SUCCESS;
275     }
276     handleData->captureMode.ctlParam.mute = (bool)cardInstance->captureMuteValue;
277 
278     return HDF_SUCCESS;
279 }
280 
AudioCtlCaptureSetGainStu(const struct DevHandleCapture * handle,int cmdId,const struct AudioHwCaptureParam * handleData)281 int32_t AudioCtlCaptureSetGainStu(
282     const struct DevHandleCapture *handle, int cmdId, const struct AudioHwCaptureParam *handleData)
283 {
284     (void)cmdId;
285     if (handle == NULL || handleData == NULL) {
286         AUDIO_FUNC_LOGE("param is NULL!");
287         return HDF_FAILURE;
288     }
289 
290     return HDF_SUCCESS;
291 }
292 
AudioCtlCaptureGetGainStu(const struct DevHandleCapture * handle,int cmdId,struct AudioHwCaptureParam * handleData)293 int32_t AudioCtlCaptureGetGainStu(
294     const struct DevHandleCapture *handle, int cmdId, struct AudioHwCaptureParam *handleData)
295 {
296     (void)cmdId;
297     if (handle == NULL || handleData == NULL) {
298         AUDIO_FUNC_LOGE("param is NULL!");
299         return HDF_FAILURE;
300     }
301 
302     return HDF_SUCCESS;
303 }
304 
AudioCtlCaptureSceneSelect(const struct DevHandleCapture * handle,int cmdId,const struct AudioHwCaptureParam * handleData)305 int32_t AudioCtlCaptureSceneSelect(
306     const struct DevHandleCapture *handle, int cmdId, const struct AudioHwCaptureParam *handleData)
307 {
308     int32_t deviceNum;
309 
310     (void)cmdId;
311     if (handle == NULL || handleData == NULL) {
312         AUDIO_FUNC_LOGE("param is NULL!");
313         return HDF_FAILURE;
314     }
315 
316     deviceNum = handleData->captureMode.hwInfo.pathSelect.deviceInfo.deviceNum;
317     if (deviceNum < AUDIO_MIN_CARD_NUM) {
318         AUDIO_FUNC_LOGE("Not find device!");
319         return HDF_FAILURE;
320     }
321 
322     return HDF_SUCCESS;
323 }
324 
AudioCtlCaptureGetGainThreshold(const struct DevHandleCapture * handle,int cmdId,struct AudioHwCaptureParam * handleData)325 int32_t AudioCtlCaptureGetGainThreshold(
326     const struct DevHandleCapture *handle, int cmdId, struct AudioHwCaptureParam *handleData)
327 {
328     (void)cmdId;
329     if (handle == NULL || handleData == NULL) {
330         AUDIO_FUNC_LOGE("param is NULL!");
331         return HDF_FAILURE;
332     }
333 
334     return HDF_SUCCESS;
335 }
336 
AudioCtlCaptureGetVolThreshold(const struct DevHandleCapture * handle,int cmdId,struct AudioHwCaptureParam * handleData)337 int32_t AudioCtlCaptureGetVolThreshold(
338     const struct DevHandleCapture *handle, int cmdId, struct AudioHwCaptureParam *handleData)
339 {
340     int32_t ret;
341     long volMax = MIN_VOLUME;
342     long volMin = MIN_VOLUME;
343 
344     (void)cmdId;
345     if (handle == NULL || handleData == NULL) {
346         AUDIO_FUNC_LOGE("Param is NULL!");
347         return HDF_FAILURE;
348     }
349 
350     const char *adapterName = handleData->captureMode.hwInfo.adapterName;
351     struct AudioCardInfo *cardIns = GetCardIns(adapterName);
352     if (cardIns == NULL) {
353         AUDIO_FUNC_LOGE("cardIns is NULL!!!");
354         return HDF_FAILURE;
355     }
356 
357     if (strncmp(adapterName, USB, strlen(USB)) == 0) {
358         handleData->captureMode.ctlParam.volThreshold.volMax = MAX_VOLUME;
359         handleData->captureMode.ctlParam.volThreshold.volMin = MIN_VOLUME;
360         return HDF_SUCCESS;
361     }
362 
363     ret = snd_mixer_selem_get_capture_volume_range(cardIns->ctrlLeftVolume, &volMin, &volMax);
364     if (ret < 0) {
365         AUDIO_FUNC_LOGE("Get capture volume range fail: %{public}s.", snd_strerror(ret));
366         return HDF_FAILURE;
367     }
368     handleData->captureMode.ctlParam.volThreshold.volMax = (int)volMax;
369     handleData->captureMode.ctlParam.volThreshold.volMin = (int)volMin;
370 
371     return HDF_SUCCESS;
372 }
373 
AudioInterfaceLibCtlCapture(const struct DevHandleCapture * handle,int cmdId,struct AudioHwCaptureParam * handleData)374 int32_t AudioInterfaceLibCtlCapture(
375     const struct DevHandleCapture *handle, int cmdId, struct AudioHwCaptureParam *handleData)
376 {
377     int32_t ret;
378 
379     if (handle == NULL || handleData == NULL) {
380         AUDIO_FUNC_LOGE("param is NULL!");
381         return HDF_FAILURE;
382     }
383 
384     switch (cmdId) {
385         /* setPara: */
386         case AUDIODRV_CTL_IOCTL_ELEM_WRITE_CAPTURE:
387             ret = AudioCtlCaptureSetVolume(handle, cmdId, handleData);
388             break;
389         case AUDIODRV_CTL_IOCTL_MUTE_WRITE_CAPTURE:
390             ret = AudioCtlCaptureSetMuteStu(handle, cmdId, handleData);
391             break;
392         case AUDIODRV_CTL_IOCTL_MUTE_READ_CAPTURE:
393             ret = AudioCtlCaptureGetMuteStu(handle, cmdId, handleData);
394             break;
395         /* getPara: */
396         case AUDIODRV_CTL_IOCTL_ELEM_READ_CAPTURE:
397             ret = AudioCtlCaptureGetVolume(handle, cmdId, handleData);
398             break;
399         case AUDIODRV_CTL_IOCTL_GAIN_WRITE_CAPTURE:
400             ret = AudioCtlCaptureSetGainStu(handle, cmdId, handleData);
401             break;
402         case AUDIODRV_CTL_IOCTL_GAIN_READ_CAPTURE:
403             ret = AudioCtlCaptureGetGainStu(handle, cmdId, handleData);
404             break;
405         case AUDIODRV_CTL_IOCTL_SCENESELECT_CAPTURE:
406             ret = AudioCtlCaptureSceneSelect(handle, cmdId, handleData);
407             break;
408         case AUDIODRV_CTL_IOCTL_GAINTHRESHOLD_CAPTURE:
409             ret = AudioCtlCaptureGetGainThreshold(handle, cmdId, handleData);
410             break;
411         case AUDIODRV_CTL_IOCTL_VOL_THRESHOLD_CAPTURE:
412             ret = AudioCtlCaptureGetVolThreshold(handle, cmdId, handleData);
413             break;
414         default:
415             AUDIO_FUNC_LOGE("Ctl Mode not support!");
416             ret = HDF_FAILURE;
417             break;
418     }
419 
420     return ret;
421 }
422 
GetCapHwParams(struct AudioCardInfo * cardIns,const struct AudioHwCaptureParam * handleData)423 static int32_t GetCapHwParams(struct AudioCardInfo *cardIns, const struct AudioHwCaptureParam *handleData)
424 {
425     if (cardIns == NULL || handleData == NULL) {
426         AUDIO_FUNC_LOGE("Parameter is NULL!");
427         return HDF_FAILURE;
428     }
429 
430     cardIns->hwCaptureParams.streamType = AUDIO_CAPTURE_STREAM;
431     cardIns->hwCaptureParams.channels = handleData->frameCaptureMode.attrs.channelCount;
432     cardIns->hwCaptureParams.rate = handleData->frameCaptureMode.attrs.sampleRate;
433     cardIns->hwCaptureParams.periodSize = handleData->frameCaptureMode.periodSize;
434     cardIns->hwCaptureParams.periodCount = handleData->frameCaptureMode.periodCount;
435     cardIns->hwCaptureParams.format = handleData->frameCaptureMode.attrs.format;
436     cardIns->hwCaptureParams.period = handleData->frameCaptureMode.attrs.period;
437     cardIns->hwCaptureParams.frameSize = handleData->frameCaptureMode.attrs.frameSize;
438     cardIns->hwCaptureParams.isBigEndian = handleData->frameCaptureMode.attrs.isBigEndian;
439     cardIns->hwCaptureParams.isSignedData = handleData->frameCaptureMode.attrs.isSignedData;
440     cardIns->hwCaptureParams.startThreshold = handleData->frameCaptureMode.attrs.startThreshold;
441     cardIns->hwCaptureParams.stopThreshold = handleData->frameCaptureMode.attrs.stopThreshold;
442     cardIns->hwCaptureParams.silenceThreshold = handleData->frameCaptureMode.attrs.silenceThreshold;
443 
444     return HDF_SUCCESS;
445 }
446 
SetHWParamsSub(snd_pcm_t * handle,snd_pcm_hw_params_t * params,struct AudioPcmHwParams hwCapParams,snd_pcm_access_t access)447 static int32_t SetHWParamsSub(
448     snd_pcm_t *handle, snd_pcm_hw_params_t *params, struct AudioPcmHwParams hwCapParams, snd_pcm_access_t access)
449 {
450     int32_t ret;
451     snd_pcm_format_t pcmFormat;
452 
453     if (handle == NULL || params == NULL) {
454         AUDIO_FUNC_LOGE("SetHWParamsSub parameter is null!");
455         return HDF_FAILURE;
456     }
457 
458     ret = snd_pcm_hw_params_set_rate_resample(handle, params, g_resample);
459     if (ret < 0) {
460         AUDIO_FUNC_LOGE("Resampling setup failed for capture: %{public}s", snd_strerror(ret));
461         return HDF_FAILURE;
462     }
463 
464     /* set the interleaved read/write format */
465     ret = snd_pcm_hw_params_set_access(handle, params, access);
466     if (ret < 0) {
467         AUDIO_FUNC_LOGE("Access type not available for capture: %{public}s", snd_strerror(ret));
468         return HDF_FAILURE;
469     }
470     ret = CheckParaFormat(hwCapParams, &pcmFormat);
471     if (ret != HDF_SUCCESS) {
472         AUDIO_FUNC_LOGE("CheckParaFormat error.");
473         return ret;
474     }
475     /* set the sample format */
476     ret = snd_pcm_hw_params_set_format(handle, params, pcmFormat);
477     if (ret < 0) {
478         AUDIO_FUNC_LOGE("Sample format not available for capture: %{public}s", snd_strerror(ret));
479         return HDF_FAILURE;
480     }
481 
482     /* set the count of channels */
483     ret = snd_pcm_hw_params_set_channels(handle, params, hwCapParams.channels);
484     if (ret < 0) {
485         AUDIO_FUNC_LOGE("Channels count (%{public}u) not available for capture: %{public}s", hwCapParams.channels,
486             snd_strerror(ret));
487         return HDF_FAILURE;
488     }
489 
490     return HDF_SUCCESS;
491 }
492 
SetHWRate(snd_pcm_t * handle,snd_pcm_hw_params_t * params,uint32_t * rate)493 static int32_t SetHWRate(snd_pcm_t *handle, snd_pcm_hw_params_t *params, uint32_t *rate)
494 {
495     int32_t ret;
496     uint32_t rRate;
497     int32_t dir = 0; /* dir Value range (-1,0,1) */
498 
499     if (handle == NULL || params == NULL || rate == NULL) {
500         AUDIO_FUNC_LOGE("SetHWParams parameter is null!");
501         return HDF_FAILURE;
502     }
503 
504     /* set the stream rate */
505     rRate = *rate;
506     ret = snd_pcm_hw_params_set_rate_near(handle, params, &rRate, &dir);
507     if (ret < 0) {
508         AUDIO_FUNC_LOGE("Rate %{public}uHz not available for capture: %{public}s", *rate, snd_strerror(ret));
509         return HDF_FAILURE;
510     }
511 
512     if (rRate != *rate) {
513         ret = snd_pcm_hw_params_set_rate_near(handle, params, &rRate, &dir);
514         if (ret < 0) {
515             AUDIO_FUNC_LOGE("Rate %{public}uHz not available for capture: %{public}s", *rate, snd_strerror(ret));
516             return HDF_FAILURE;
517         }
518     }
519     /* Update to hardware supported rate */
520     *rate = rRate;
521 
522     g_canPause = snd_pcm_hw_params_can_pause(params);
523 
524     return HDF_SUCCESS;
525 }
526 
SetHWBuffer(snd_pcm_t * handle,snd_pcm_hw_params_t * params)527 static int32_t SetHWBuffer(snd_pcm_t *handle, snd_pcm_hw_params_t *params)
528 {
529     int32_t ret;
530     int32_t dir = 0; /* dir Value range (-1,0,1) */
531     snd_pcm_uframes_t size = 0;
532 
533     if (handle == NULL || params == NULL) {
534         AUDIO_FUNC_LOGE("SetHWParams parameter is null!");
535         return HDF_FAILURE;
536     }
537 
538     ret = snd_pcm_hw_params_set_buffer_time_near(handle, params, &g_bufferTime, &dir);
539     if (ret < 0) {
540         AUDIO_FUNC_LOGE(
541             "Unable to set buffer time %{public}u for capture: %{public}s", g_bufferTime, snd_strerror(ret));
542         return HDF_FAILURE;
543     }
544 
545     ret = snd_pcm_hw_params_get_buffer_size(params, &size);
546     if (ret < 0) {
547         AUDIO_FUNC_LOGE("Unable to get buffer size for capture: %{public}s", snd_strerror(ret));
548         return HDF_FAILURE;
549     }
550     g_bufferSize = size;
551 
552     return HDF_SUCCESS;
553 }
554 
SetHWPeriod(snd_pcm_t * handle,snd_pcm_hw_params_t * params)555 static int32_t SetHWPeriod(snd_pcm_t *handle, snd_pcm_hw_params_t *params)
556 {
557     int32_t ret;
558     int32_t dir = 0; /* dir Value range (-1,0,1) */
559     snd_pcm_uframes_t size = 0;
560 
561     if (handle == NULL || params == NULL) {
562         AUDIO_FUNC_LOGE("SetHWParams parameter is null!");
563         return HDF_FAILURE;
564     }
565 
566     ret = snd_pcm_hw_params_set_period_time_near(handle, params, &g_periodTime, &dir);
567     if (ret < 0) {
568         AUDIO_FUNC_LOGE(
569             "Unable to set period time %{public}u for capture: %{public}s", g_periodTime, snd_strerror(ret));
570         return HDF_FAILURE;
571     }
572 
573     ret = snd_pcm_hw_params_get_period_size(params, &size, &dir);
574     if (ret < 0) {
575         AUDIO_FUNC_LOGE("Unable to get period size for capture: %{public}s", snd_strerror(ret));
576         return HDF_FAILURE;
577     }
578     g_periodSize = size;
579 
580     return HDF_SUCCESS;
581 }
582 
SetHWParams(snd_pcm_t * handle,snd_pcm_hw_params_t * params,struct AudioPcmHwParams hwCapParams,snd_pcm_access_t access)583 static int32_t SetHWParams(
584     snd_pcm_t *handle, snd_pcm_hw_params_t *params, struct AudioPcmHwParams hwCapParams, snd_pcm_access_t access)
585 {
586     int32_t ret;
587 
588     if (handle == NULL || params == NULL) {
589         AUDIO_FUNC_LOGE("SetHWParams parameter is null!");
590         return HDF_FAILURE;
591     }
592 
593     ret = snd_pcm_hw_params_any(handle, params); // choose all parameters
594     if (ret < 0) {
595         AUDIO_FUNC_LOGE(
596             "Broken configuration for capture: no configurations available: %{public}s.", snd_strerror(ret));
597         return HDF_FAILURE;
598     }
599 
600     ret = SetHWParamsSub(handle, params, hwCapParams, access);
601     if (ret != HDF_SUCCESS) {
602         AUDIO_FUNC_LOGE("SetHWParamsSub failed!");
603         return ret;
604     }
605 
606     ret = SetHWRate(handle, params, &(hwCapParams.rate));
607     if (ret != HDF_SUCCESS) {
608         AUDIO_FUNC_LOGE("SetHWRate failed!");
609         return ret;
610     }
611 
612     ret = SetHWBuffer(handle, params);
613     if (ret != HDF_SUCCESS) {
614         AUDIO_FUNC_LOGE("SetHWBuffer failed!");
615         return ret;
616     }
617 
618     ret = SetHWPeriod(handle, params);
619     if (ret != HDF_SUCCESS) {
620         AUDIO_FUNC_LOGE("SetHWPeriod failed!");
621         return ret;
622     }
623 
624     /* write the parameters to device. */
625     ret = snd_pcm_hw_params(handle, params);
626     if (ret < 0) {
627         AUDIO_FUNC_LOGE("Unable to set hw params for capture: %{public}s", snd_strerror(ret));
628         return HDF_FAILURE;
629     }
630 
631     return HDF_SUCCESS;
632 }
633 
SetSWParams(snd_pcm_t * handle,snd_pcm_sw_params_t * swparams)634 static int32_t SetSWParams(snd_pcm_t *handle, snd_pcm_sw_params_t *swparams)
635 {
636     int32_t ret;
637 
638     if (handle == NULL || swparams == NULL) {
639         AUDIO_FUNC_LOGE("SetHWParams parameter is null!");
640         return HDF_FAILURE;
641     }
642 
643     /* get the current swparams */
644     ret = snd_pcm_sw_params_current(handle, swparams);
645     if (ret < 0) {
646         AUDIO_FUNC_LOGE("Unable to determine current swparams for capture: %{public}s.", snd_strerror(ret));
647         return HDF_FAILURE;
648     }
649 
650     if (g_periodSize == 0) {
651         AUDIO_FUNC_LOGE("error: g_periodSize cannot be zero!");
652         return HDF_FAILURE;
653     }
654     /* start the transfer when the buffer is almost full: */
655     /* (buffer_size / avail_min) * avail_min */
656     ret = snd_pcm_sw_params_set_start_threshold(handle, swparams, (g_bufferSize / g_periodSize) * g_periodSize);
657     if (ret < 0) {
658         AUDIO_FUNC_LOGE("Unable to set start threshold mode for capture: %{public}s.", snd_strerror(ret));
659         return HDF_FAILURE;
660     }
661 
662     /* allow the transfer when at least period_size samples can be processed */
663     /* or disable this mechanism when period event is enabled (aka interrupt like style processing) */
664     ret = snd_pcm_sw_params_set_avail_min(handle, swparams, g_periodEvent ? g_bufferSize : g_periodSize);
665     if (ret < 0) {
666         AUDIO_FUNC_LOGE("Unable to set avail min for capture: %{public}s", snd_strerror(ret));
667         return HDF_FAILURE;
668     }
669 
670     /* enable period events when requested */
671     if (g_periodEvent) {
672         ret = snd_pcm_sw_params_set_period_event(handle, swparams, 1);
673         if (ret < 0) {
674             AUDIO_FUNC_LOGE("Unable to set period event: %{public}s", snd_strerror(ret));
675             return HDF_FAILURE;
676         }
677     }
678 
679     /* write the parameters to the capture device */
680     ret = snd_pcm_sw_params(handle, swparams);
681     if (ret < 0) {
682         AUDIO_FUNC_LOGE("Unable to set sw params for capture: %{public}s", snd_strerror(ret));
683         return HDF_FAILURE;
684     }
685 
686     return HDF_SUCCESS;
687 }
688 
AudioOutputCaptureHwParams(const struct DevHandleCapture * handle,int cmdId,const struct AudioHwCaptureParam * handleData)689 int32_t AudioOutputCaptureHwParams(
690     const struct DevHandleCapture *handle, int cmdId, const struct AudioHwCaptureParam *handleData)
691 {
692     int32_t ret;
693     struct AudioCardInfo *cardIns;
694     snd_pcm_hw_params_t *hwParams = NULL;
695     snd_pcm_sw_params_t *swParams = NULL;
696 
697     (void)cmdId;
698     if (handle == NULL || handleData == NULL) {
699         AUDIO_FUNC_LOGE("The parameter is empty");
700         return HDF_FAILURE;
701     }
702 
703     const char *adapterName = handleData->captureMode.hwInfo.adapterName;
704     cardIns = GetCardIns(adapterName);
705     if (cardIns == NULL) {
706         AUDIO_FUNC_LOGE("cardIns is NULL!");
707         return HDF_FAILURE;
708     }
709 
710     ret = (int32_t)snd_pcm_state(cardIns->capturePcmHandle);
711     if (ret >= SND_PCM_STATE_RUNNING) {
712         AUDIO_FUNC_LOGE("Unable to set parameters during capture!");
713         return HDF_FAILURE;
714     }
715 
716     ret = GetCapHwParams(cardIns, handleData);
717     if (ret != HDF_SUCCESS) {
718         AUDIO_FUNC_LOGE("GetCapHwParams error.");
719         return ret;
720     }
721 
722     snd_pcm_hw_params_alloca(&hwParams);
723     snd_pcm_sw_params_alloca(&swParams);
724     ret = SetHWParams(cardIns->capturePcmHandle, hwParams, cardIns->hwCaptureParams, SND_PCM_ACCESS_RW_INTERLEAVED);
725     if (ret != HDF_SUCCESS) {
726         AUDIO_FUNC_LOGE("Setting of hwparams failed: %{public}d.", ret);
727         return ret;
728     }
729     ret = SetSWParams(cardIns->capturePcmHandle, swParams);
730     if (ret != HDF_SUCCESS) {
731         AUDIO_FUNC_LOGE("Setting of swparams failed: %{public}d.", ret);
732         return ret;
733     }
734 
735     return HDF_SUCCESS;
736 }
737 
InitMixerCtrlCapVolumeRange(const char * adapterName,struct AudioCardInfo * cardIns)738 static int32_t InitMixerCtrlCapVolumeRange(const char *adapterName, struct AudioCardInfo *cardIns)
739 {
740     int32_t ret;
741 
742     if (cardIns == NULL || adapterName == NULL) {
743         AUDIO_FUNC_LOGE("The parameter is NULL");
744         return HDF_FAILURE;
745     }
746 
747     if (strncmp(adapterName, USB, strlen(USB)) == 0) {
748         /* The external Settings. */
749         return HDF_SUCCESS;
750     }
751 
752     if (cardIns->ctrlLeftVolume != NULL) {
753         ret = snd_mixer_selem_set_capture_volume_range(cardIns->ctrlLeftVolume, MIN_VOLUME, MAX_VOLUME);
754         if (ret < 0) {
755             AUDIO_FUNC_LOGE("Failed to set capture left volume range: %{public}s.", snd_strerror(ret));
756             return HDF_FAILURE;
757         }
758     }
759 
760     if (cardIns->ctrlRightVolume != NULL) {
761         ret = snd_mixer_selem_set_capture_volume_range(cardIns->ctrlRightVolume, MIN_VOLUME, MAX_VOLUME);
762         if (ret < 0) {
763             AUDIO_FUNC_LOGE("Failed to set capture right volume range: %{public}s.", snd_strerror(ret));
764             return HDF_FAILURE;
765         }
766     }
767 
768     return HDF_SUCCESS;
769 }
770 
InitMixerCtlElement(const char * adapterName,struct AudioCardInfo * cardIns,snd_mixer_t * mixer)771 static int32_t InitMixerCtlElement(const char *adapterName, struct AudioCardInfo *cardIns, snd_mixer_t *mixer)
772 {
773     int32_t ret;
774 
775     if (adapterName == NULL || cardIns == NULL || mixer == NULL) {
776         AUDIO_FUNC_LOGE("The parameter is empty.");
777         return HDF_FAILURE;
778     }
779 
780     snd_mixer_elem_t *pcmElement = snd_mixer_first_elem(mixer);
781     if (strncmp(adapterName, PRIMARY, strlen(PRIMARY)) == 0) {
782         ret = GetPriMixerCtlElement(cardIns, pcmElement);
783         if (ret != HDF_SUCCESS) {
784             AUDIO_FUNC_LOGE("Capture GetPriMixerCtlElement failed.");
785             return ret;
786         }
787     } else if (strncmp(adapterName, USB, strlen(USB)) == 0) {
788         cardIns->ctrlLeftVolume = AudioUsbFindElement(mixer);
789     } else {
790         AUDIO_FUNC_LOGE("The selected sound card not supported, please check!");
791         return HDF_FAILURE;
792     }
793 
794     ret = InitMixerCtrlCapVolumeRange(adapterName, cardIns);
795     if (ret != HDF_SUCCESS) {
796         AUDIO_FUNC_LOGE("InitMixerCtrlCapVolumeRange fail!");
797         return ret;
798     }
799 
800     ret = AudioMixerSetCtrlMode(cardIns, adapterName, "Capture MIC Path", SND_CAP_MIC_PATH, SND_IN_CARD_MAIN_MIC);
801     if (ret != HDF_SUCCESS) {
802         AUDIO_FUNC_LOGE("AudioMixerSetCtrlMode failed!");
803         return ret;
804     }
805 
806     return HDF_SUCCESS;
807 }
808 
809 /*
810  * brief: Opens a capture PCM
811  * param mode Open mode (see #SND_PCM_NONBLOCK, #SND_PCM_ASYNC)
812  */
AudioOutputCaptureOpen(const struct DevHandleCapture * handle,int cmdId,const struct AudioHwCaptureParam * handleData)813 int32_t AudioOutputCaptureOpen(
814     const struct DevHandleCapture *handle, int cmdId, const struct AudioHwCaptureParam *handleData)
815 {
816     int32_t ret;
817     struct AudioCardInfo *cardIns;
818 
819     (void)cmdId;
820     if (handle == NULL || handleData == NULL) {
821         AUDIO_FUNC_LOGE("Function parameter is NULL!");
822         return HDF_FAILURE;
823     }
824 
825     const char *adapterName = handleData->captureMode.hwInfo.adapterName;
826     cardIns = AudioGetCardInfo(adapterName, SND_PCM_STREAM_CAPTURE);
827     if (cardIns == NULL) {
828         AUDIO_FUNC_LOGE("AudioCaptureGetCardIns failed.");
829         return HDF_FAILURE;
830     }
831 
832     if (cardIns->capturePcmHandle != NULL) {
833         AUDIO_FUNC_LOGE("Resource busy!!");
834         return HDF_ERR_DEVICE_BUSY;
835     }
836     ret = snd_pcm_open(&cardIns->capturePcmHandle, cardIns->devName, SND_PCM_STREAM_CAPTURE, SND_PCM_NONBLOCK);
837     if (ret < 0) {
838         AUDIO_FUNC_LOGE("Capture open device error: %{public}s.", snd_strerror(ret));
839         CheckCardStatus(cardIns);
840         (void)DestroyCardList();
841         return HDF_FAILURE;
842     }
843 
844     InitSound(&cardIns->mixer, cardIns->ctrlName);
845     ret = InitMixerCtlElement(adapterName, cardIns, cardIns->mixer);
846     if (ret != HDF_SUCCESS) {
847         AUDIO_FUNC_LOGE("capture InitMixerCtlElement failed!");
848         (void)CloseMixerHandle(cardIns->mixer);
849         CheckCardStatus(cardIns);
850         (void)DestroyCardList();
851         return ret;
852     }
853 
854     return HDF_SUCCESS;
855 }
856 
AudioCaptureResetParams(snd_pcm_t * handle,struct AudioPcmHwParams audioHwParams,snd_pcm_access_t access)857 int32_t AudioCaptureResetParams(snd_pcm_t *handle, struct AudioPcmHwParams audioHwParams, snd_pcm_access_t access)
858 {
859     int32_t ret;
860     snd_pcm_hw_params_t *hwParams = NULL;
861     snd_pcm_sw_params_t *swParams = NULL;
862 
863     if (handle == NULL) {
864         AUDIO_FUNC_LOGE("handle is NULL!");
865         return HDF_FAILURE;
866     }
867 
868     snd_pcm_hw_params_alloca(&hwParams);
869     snd_pcm_sw_params_alloca(&swParams);
870     ret = SetHWParams(handle, hwParams, audioHwParams, access);
871     if (ret != HDF_SUCCESS) {
872         AUDIO_FUNC_LOGE("Setting of hwparams failed: %{public}d.", ret);
873         return ret;
874     }
875 
876     ret = SetSWParams(handle, swParams);
877     if (ret != HDF_SUCCESS) {
878         AUDIO_FUNC_LOGE("Setting of swparams failed: %{public}d.", ret);
879         return ret;
880     }
881 
882     return HDF_SUCCESS;
883 }
884 
CaptureDataCopy(struct AudioHwCaptureParam * handleData,char * buffer,uint64_t frames)885 static int32_t CaptureDataCopy(struct AudioHwCaptureParam *handleData, char *buffer, uint64_t frames)
886 {
887     int32_t ret;
888     uint32_t channels;
889     uint32_t format;
890     uint64_t recvDataSize;
891 
892     if (handleData == NULL || buffer == NULL || frames == 0) {
893         AUDIO_FUNC_LOGE("Param is NULL!");
894         return HDF_FAILURE;
895     }
896 
897     if (handleData->frameCaptureMode.buffer == NULL) {
898         AUDIO_FUNC_LOGE("frameCaptureMode.buffer is NULL!");
899         return HDF_FAILURE;
900     }
901     channels = handleData->frameCaptureMode.attrs.channelCount;
902     format = (uint32_t)handleData->frameCaptureMode.attrs.format;
903     recvDataSize = (uint64_t)(frames * channels * format);
904     ret = memcpy_s(handleData->frameCaptureMode.buffer, FRAME_DATA, buffer, recvDataSize);
905     if (ret != EOK) {
906         AUDIO_FUNC_LOGE("memcpy frame data failed!");
907         return HDF_FAILURE;
908     }
909     handleData->frameCaptureMode.bufferSize = recvDataSize;
910     handleData->frameCaptureMode.bufferFrameSize = frames;
911 
912     return HDF_SUCCESS;
913 }
914 
CheckCapFrameBufferSize(struct AudioHwCaptureParam * handleData,snd_pcm_uframes_t * periodSize)915 static int32_t CheckCapFrameBufferSize(struct AudioHwCaptureParam *handleData, snd_pcm_uframes_t *periodSize)
916 {
917     uint32_t capFrameSize;
918     uint64_t capReqBufferSize;
919 
920     if (handleData == NULL || periodSize == NULL) {
921         AUDIO_FUNC_LOGE("Param is NULL!");
922         return HDF_FAILURE;
923     }
924 
925     capFrameSize = handleData->frameCaptureMode.attrs.channelCount * handleData->frameCaptureMode.attrs.format;
926     if (capFrameSize == 0) {
927         AUDIO_FUNC_LOGE("capFrameSize is zero.");
928         return HDF_FAILURE;
929     }
930     capReqBufferSize = capFrameSize * (*periodSize);
931     if (capReqBufferSize > FRAME_DATA) {
932         *periodSize = FRAME_DATA / capFrameSize;
933     }
934 
935     return HDF_SUCCESS;
936 }
937 
CheckPcmStatus(snd_pcm_t * capturePcmHandle)938 static int32_t CheckPcmStatus(snd_pcm_t *capturePcmHandle)
939 {
940     int32_t ret;
941 
942     if (capturePcmHandle == NULL) {
943         AUDIO_FUNC_LOGE("Param is NULL.");
944         return HDF_FAILURE;
945     }
946 
947     ret = snd_pcm_wait(capturePcmHandle, -1); /* -1 for timeout, Waiting forever */
948     if (ret < 0) {
949         AUDIO_FUNC_LOGE("snd_pcm_wait failed: %{public}s.", snd_strerror(ret));
950         return HDF_FAILURE;
951     }
952 
953     if (snd_pcm_state(capturePcmHandle) == SND_PCM_STATE_SETUP) {
954         ret = snd_pcm_prepare(capturePcmHandle);
955         if (ret < 0) {
956             AUDIO_FUNC_LOGE("snd_pcm_prepare fail: %{public}s", snd_strerror(ret));
957             return HDF_FAILURE;
958         }
959     }
960 
961     return HDF_SUCCESS;
962 }
963 
AudioCaptureReadFrameSub(snd_pcm_t * pcm,uint64_t * frameCnt,char * dataBuf,snd_pcm_uframes_t bufSize)964 static int32_t AudioCaptureReadFrameSub(snd_pcm_t *pcm, uint64_t *frameCnt, char *dataBuf, snd_pcm_uframes_t bufSize)
965 {
966     int32_t ret;
967     long frames;
968     int32_t tryNum = AUDIO_ALSALIB_RETYR;
969 
970     if (pcm == NULL || frameCnt == NULL || dataBuf == NULL || bufSize == 0) {
971         AUDIO_FUNC_LOGE("The parameter is error.");
972         return HDF_FAILURE;
973     }
974 
975     do {
976         /* Read interleaved frames to a PCM. */
977         frames = snd_pcm_readi(pcm, dataBuf, bufSize);
978         if (frames > 0) {
979             *frameCnt = (uint64_t)frames;
980             return HDF_SUCCESS;
981         }
982 
983         if (frames == -EBADFD) {
984             AUDIO_FUNC_LOGE("capture PCM is not in the right state: %{public}s", snd_strerror(frames));
985             ret = snd_pcm_prepare(pcm);
986             if (ret < 0) {
987                 AUDIO_FUNC_LOGE("capture snd_pcm_prepare fail: %{public}s", snd_strerror(ret));
988                 return HDF_FAILURE;
989             }
990         } else {
991             /* -ESTRPIPE: a suspend event occurred,
992              * stream is suspended and waiting for an application recovery.
993              * -EPIPE: an underrun occurred.
994              */
995             ret = snd_pcm_recover(pcm, frames, 0); // 0 for open capture recover log.
996             if (ret < 0) {
997                 AUDIO_FUNC_LOGE("snd_pcm_readi failed: %{public}s", snd_strerror(ret));
998                 return HDF_FAILURE;
999             }
1000         }
1001         ret = snd_pcm_start(pcm);
1002         if (ret < 0) {
1003             AUDIO_FUNC_LOGE("snd_pcm_start fail. %{public}s", snd_strerror(ret));
1004             return HDF_FAILURE;
1005         }
1006         tryNum--;
1007     } while (tryNum > 0);
1008 
1009     return HDF_SUCCESS;
1010 }
1011 
AudioCaptureReadFrame(struct AudioHwCaptureParam * handleData,struct AudioCardInfo * cardIns,snd_pcm_uframes_t periodSize)1012 static int32_t AudioCaptureReadFrame(
1013     struct AudioHwCaptureParam *handleData, struct AudioCardInfo *cardIns, snd_pcm_uframes_t periodSize)
1014 {
1015     int32_t ret;
1016     uint64_t frames = 0;
1017     char *buffer = NULL;
1018 
1019     if (handleData == NULL || cardIns == NULL) {
1020         AUDIO_FUNC_LOGE("Param is NULL!");
1021         return HDF_FAILURE;
1022     }
1023 
1024     buffer = OsalMemCalloc(ALSA_CAP_BUFFER_SIZE);
1025     if (buffer == NULL) {
1026         AUDIO_FUNC_LOGE("Failed to Calloc buffer");
1027         return HDF_FAILURE;
1028     }
1029 
1030     ret = CheckCapFrameBufferSize(handleData, &periodSize);
1031     if (ret != HDF_SUCCESS) {
1032         AUDIO_FUNC_LOGE("CheckCapFrameBufferSize failed.");
1033         AudioMemFree((void **)&buffer);
1034         return ret;
1035     }
1036 
1037     ret = CheckPcmStatus(cardIns->capturePcmHandle);
1038     if (ret != HDF_SUCCESS) {
1039         AUDIO_FUNC_LOGE("CheckPcmStatus failed.");
1040         AudioMemFree((void **)&buffer);
1041         return ret;
1042     }
1043 
1044     ret = AudioCaptureReadFrameSub(cardIns->capturePcmHandle, &frames, buffer, periodSize);
1045     if (ret != HDF_SUCCESS) {
1046         AUDIO_FUNC_LOGE("AudioCaptureReadFrameSub is error!");
1047         AudioMemFree((void **)&buffer);
1048         return ret;
1049     }
1050 
1051     ret = CaptureDataCopy(handleData, buffer, frames);
1052     if (ret != HDF_SUCCESS) {
1053         AUDIO_FUNC_LOGE("Failed to copy data. It may be paused. Check the status!");
1054         AudioMemFree((void **)&buffer);
1055         return ret;
1056     }
1057     AudioMemFree((void **)&buffer);
1058 
1059     return HDF_SUCCESS;
1060 }
1061 
AudioOutputCaptureRead(const struct DevHandleCapture * handle,int cmdId,struct AudioHwCaptureParam * handleData)1062 int32_t AudioOutputCaptureRead(const struct DevHandleCapture *handle, int cmdId, struct AudioHwCaptureParam *handleData)
1063 {
1064     int32_t ret;
1065     snd_pcm_uframes_t bufferSize = 0;
1066     snd_pcm_uframes_t periodSize = 0;
1067 
1068     (void)cmdId;
1069     if (handle == NULL || handleData == NULL) {
1070         AUDIO_FUNC_LOGE("Param is NULL!");
1071         return HDF_FAILURE;
1072     }
1073 
1074     const char *sndCardName = handleData->captureMode.hwInfo.adapterName;
1075     struct AudioCardInfo *cardIns = GetCardIns(sndCardName);
1076     if (cardIns == NULL) {
1077         AUDIO_FUNC_LOGE("cardIns is NULL!");
1078         return HDF_FAILURE;
1079     }
1080 
1081     ret = snd_pcm_get_params(cardIns->capturePcmHandle, &bufferSize, &periodSize);
1082     if (ret < 0) {
1083         AUDIO_FUNC_LOGE("Get capture params error: %{public}s.", snd_strerror(ret));
1084         return HDF_FAILURE;
1085     }
1086 
1087     if (!cardIns->captureMmapFlag) {
1088         ret =
1089             AudioCaptureResetParams(cardIns->capturePcmHandle, cardIns->hwCaptureParams, SND_PCM_ACCESS_RW_INTERLEAVED);
1090         if (ret != HDF_SUCCESS) {
1091             AUDIO_FUNC_LOGE("AudioSetParamsMmap failed!");
1092             return ret;
1093         }
1094         ret = snd_pcm_start(cardIns->capturePcmHandle);
1095         if (ret < 0) {
1096             AUDIO_FUNC_LOGE("snd_pcm_start fail. %{public}s", snd_strerror(ret));
1097             return HDF_FAILURE;
1098         }
1099         cardIns->captureMmapFlag = true;
1100     }
1101 
1102     ret = AudioCaptureReadFrame(handleData, cardIns, periodSize);
1103     if (ret != HDF_SUCCESS) {
1104         AUDIO_FUNC_LOGE("AudioOutputCaptureRead failed");
1105         return ret;
1106     }
1107 
1108     return HDF_SUCCESS;
1109 }
1110 
AudioOutputCaptureStart(const struct DevHandleCapture * handle,int cmdId,const struct AudioHwCaptureParam * handleData)1111 int32_t AudioOutputCaptureStart(
1112     const struct DevHandleCapture *handle, int cmdId, const struct AudioHwCaptureParam *handleData)
1113 {
1114     (void)cmdId;
1115     if (handle == NULL || handleData == NULL) {
1116         AUDIO_FUNC_LOGE("Param is NULL!");
1117         return HDF_FAILURE;
1118     }
1119 
1120     return HDF_SUCCESS;
1121 }
1122 
AudioOutputCapturePrepare(const struct DevHandleCapture * handle,int cmdId,const struct AudioHwCaptureParam * handleData)1123 int32_t AudioOutputCapturePrepare(
1124     const struct DevHandleCapture *handle, int cmdId, const struct AudioHwCaptureParam *handleData)
1125 {
1126     int32_t ret;
1127     struct AudioCardInfo *cardIns;
1128 
1129     (void)cmdId;
1130     if (handle == NULL || handleData == NULL) {
1131         AUDIO_FUNC_LOGE("Invalid parameters!!!");
1132         return HDF_FAILURE;
1133     }
1134 
1135     const char *adapterName = handleData->captureMode.hwInfo.adapterName;
1136     cardIns = GetCardIns(adapterName);
1137     if (cardIns == NULL) {
1138         AUDIO_FUNC_LOGE("Get cardIns is failed!!!");
1139         return HDF_FAILURE;
1140     }
1141 
1142     ret = snd_pcm_prepare(cardIns->capturePcmHandle);
1143     if (ret < 0) {
1144         AUDIO_FUNC_LOGE("snd_pcm_prepare fail! %{public}s.", snd_strerror(ret));
1145         return HDF_FAILURE;
1146     }
1147 
1148     return HDF_SUCCESS;
1149 }
1150 
AudioOutputCaptureClose(const struct DevHandleCapture * handle,int cmdId,const struct AudioHwCaptureParam * handleData)1151 int32_t AudioOutputCaptureClose(
1152     const struct DevHandleCapture *handle, int cmdId, const struct AudioHwCaptureParam *handleData)
1153 {
1154     int32_t ret;
1155     struct AudioCardInfo *cardIns;
1156 
1157     (void)cmdId;
1158     if (handle == NULL || handleData == NULL) {
1159         AUDIO_FUNC_LOGE("Parameter is NULL!");
1160         return HDF_FAILURE;
1161     }
1162 
1163     const char *adapterName = handleData->captureMode.hwInfo.adapterName;
1164     cardIns = GetCardIns(adapterName);
1165     if (cardIns == NULL) {
1166         AUDIO_FUNC_LOGE("cardIns is NULL!");
1167         return HDF_FAILURE;
1168     }
1169 
1170     if (cardIns->capturePcmHandle != NULL) {
1171         (void)snd_pcm_close(cardIns->capturePcmHandle);
1172         cardIns->capturePcmHandle = NULL;
1173     }
1174 
1175     if (cardIns->cardStatus > 0) {
1176         cardIns->cardStatus -= 1;
1177     }
1178     if (cardIns->cardStatus == 0) {
1179         if (cardIns->mixer != NULL) {
1180             (void)snd_mixer_close(cardIns->mixer);
1181             cardIns->mixer = NULL;
1182         }
1183         (void)memset_s(cardIns->cardName, MAX_CARD_NAME_LEN + 1, 0, MAX_CARD_NAME_LEN + 1);
1184         ret = DestroyCardList();
1185         if (ret != HDF_SUCCESS) {
1186             AUDIO_FUNC_LOGE("DestroyCardList failed: %{public}d.", ret);
1187             return ret;
1188         }
1189     }
1190 
1191     return HDF_SUCCESS;
1192 }
1193 
1194 // Stop capture first, and then close the resource
AudioOutputCaptureStop(const struct DevHandleCapture * handle,int cmdId,const struct AudioHwCaptureParam * handleData)1195 int32_t AudioOutputCaptureStop(
1196     const struct DevHandleCapture *handle, int cmdId, const struct AudioHwCaptureParam *handleData)
1197 {
1198     int32_t ret;
1199     struct AudioCardInfo *cardIns;
1200 
1201     (void)cmdId;
1202     if (handle == NULL || handleData == NULL) {
1203         AUDIO_FUNC_LOGE("Param is NULL!");
1204         return HDF_FAILURE;
1205     }
1206 
1207     const char *adapterName = handleData->captureMode.hwInfo.adapterName;
1208     cardIns = GetCardIns(adapterName);
1209     if (cardIns == NULL) {
1210         AUDIO_FUNC_LOGE("Can't find sound card instance!!!");
1211         return HDF_FAILURE;
1212     }
1213 
1214     /* pass the remaining samples, otherwise they're dropped in close */
1215     ret = snd_pcm_drop(cardIns->capturePcmHandle);
1216     if (ret < 0) {
1217         AUDIO_FUNC_LOGE("snd_pcm_drain failed: %{public}s.", snd_strerror(ret));
1218         return HDF_FAILURE;
1219     }
1220 
1221     return HDF_SUCCESS;
1222 }
1223 
UpdateSetParams(struct AudioCardInfo * cardIns)1224 static int32_t UpdateSetParams(struct AudioCardInfo *cardIns)
1225 {
1226     int32_t ret;
1227 
1228     if (cardIns == NULL) {
1229         AUDIO_FUNC_LOGE("param is NULL!");
1230         return HDF_FAILURE;
1231     }
1232 
1233     cardIns->captureMmapFlag = false;
1234     ret = AudioCaptureResetParams(cardIns->capturePcmHandle, cardIns->hwCaptureParams, SND_PCM_ACCESS_MMAP_INTERLEAVED);
1235     if (ret != HDF_SUCCESS) {
1236         AUDIO_FUNC_LOGE("AudioSetParamsMmap failed!");
1237         return ret;
1238     }
1239 
1240     ret = snd_pcm_start(cardIns->capturePcmHandle);
1241     if (ret < 0) {
1242         AUDIO_FUNC_LOGE("snd_pcm_start fail. %{public}s.", snd_strerror(ret));
1243         return HDF_FAILURE;
1244     }
1245 
1246     return HDF_SUCCESS;
1247 }
1248 
MmapDescWriteBufferCapture(const struct AudioHwCaptureParam * handleData)1249 static int32_t MmapDescWriteBufferCapture(const struct AudioHwCaptureParam *handleData)
1250 {
1251     int32_t ret;
1252     char *mmapAddr;
1253     uint32_t frameSize;
1254     snd_pcm_sframes_t xfer;
1255     snd_pcm_uframes_t size;
1256     struct AudioCardInfo *cardIns;
1257 
1258     if (handleData == NULL) {
1259         AUDIO_FUNC_LOGE("param is NULL!");
1260         return HDF_FAILURE;
1261     }
1262 
1263     const char *adapterName = handleData->captureMode.hwInfo.adapterName;
1264     cardIns = GetCardIns(adapterName);
1265     if (cardIns == NULL) {
1266         AUDIO_FUNC_LOGE("cardIns is NULL!");
1267         return HDF_FAILURE;
1268     }
1269 
1270     ret = UpdateSetParams(cardIns);
1271     if (ret != HDF_SUCCESS) {
1272         AUDIO_FUNC_LOGE("Update set params failed!");
1273         return ret;
1274     }
1275 
1276     mmapAddr = (char *)handleData->frameCaptureMode.mmapBufDesc.memoryAddress;
1277     if (mmapAddr == NULL) {
1278         AUDIO_FUNC_LOGE("mmapAddr is NULL!");
1279         return HDF_FAILURE;
1280     }
1281     size = (snd_pcm_sframes_t)handleData->frameCaptureMode.mmapBufDesc.totalBufferFrames;
1282     frameSize = handleData->frameCaptureMode.attrs.channelCount * handleData->frameCaptureMode.attrs.format;
1283     while (size > 0) {
1284         xfer = snd_pcm_mmap_readi(cardIns->capturePcmHandle, mmapAddr, size);
1285         if (xfer < 0) {
1286             if (xfer == -EAGAIN) {
1287                 snd_pcm_wait(cardIns->capturePcmHandle, AUDIO_PCM_WAIT);
1288                 continue;
1289             }
1290             AUDIO_FUNC_LOGE("snd_pcm_mmap_readi: %{public}s", snd_strerror(xfer));
1291             return HDF_FAILURE;
1292         }
1293 
1294         if (xfer > 0) {
1295             mmapAddr += xfer * frameSize;
1296             size -= xfer;
1297             cardIns->capMmapFrames += xfer;
1298         }
1299     }
1300 
1301     return HDF_SUCCESS;
1302 }
1303 
AudioOutputCaptureReqMmapBuffer(const struct DevHandleCapture * handle,int cmdId,const struct AudioHwCaptureParam * handleData)1304 int32_t AudioOutputCaptureReqMmapBuffer(
1305     const struct DevHandleCapture *handle, int cmdId, const struct AudioHwCaptureParam *handleData)
1306 {
1307     int32_t ret;
1308 
1309     (void)cmdId;
1310     if (handle == NULL || handleData == NULL) {
1311         AUDIO_FUNC_LOGE("param is NULL!");
1312         return HDF_FAILURE;
1313     }
1314 
1315     ret = MmapDescWriteBufferCapture(handleData);
1316     if (ret != HDF_SUCCESS) {
1317         AUDIO_FUNC_LOGE("Capture mmap write buffer failed!");
1318         return ret;
1319     }
1320 
1321     return HDF_SUCCESS;
1322 }
1323 
AudioOutputCaptureGetMmapPosition(const struct DevHandleCapture * handle,int cmdId,struct AudioHwCaptureParam * handleData)1324 int32_t AudioOutputCaptureGetMmapPosition(
1325     const struct DevHandleCapture *handle, int cmdId, struct AudioHwCaptureParam *handleData)
1326 {
1327     struct AudioCardInfo *cardIns;
1328 
1329     (void)cmdId;
1330     if (handle == NULL || handleData == NULL) {
1331         AUDIO_FUNC_LOGE("param is NULL!");
1332         return HDF_FAILURE;
1333     }
1334 
1335     const char *cardName = handleData->captureMode.hwInfo.adapterName;
1336     cardIns = GetCardIns(cardName);
1337     if (cardIns == NULL) {
1338         AUDIO_FUNC_LOGE("Get cardIns is NULL!");
1339         return HDF_FAILURE;
1340     }
1341     handleData->frameCaptureMode.frames = cardIns->capMmapFrames;
1342 
1343     return HDF_SUCCESS;
1344 }
1345 
AudioBindServiceCaptureObject(struct DevHandleCapture * const handle,const char * name)1346 static int32_t AudioBindServiceCaptureObject(struct DevHandleCapture * const handle, const char *name)
1347 {
1348     int32_t ret;
1349     char *serviceName;
1350     struct HdfIoService *service;
1351 
1352     if (handle == NULL || name == NULL) {
1353         AUDIO_FUNC_LOGE("service name or handle is NULL!");
1354         return HDF_FAILURE;
1355     }
1356 
1357     serviceName = (char *)OsalMemCalloc(NAME_LEN);
1358     if (serviceName == NULL) {
1359         AUDIO_FUNC_LOGE("Failed to alloc serviceName");
1360         return HDF_FAILURE;
1361     }
1362 
1363     ret = snprintf_s(serviceName, NAME_LEN - 1, SERVIC_NAME_MAX_LEN + 1, "hdf_audio_%s", name);
1364     if (ret < 0) {
1365         AudioMemFree((void **)&serviceName);
1366         return HDF_FAILURE;
1367     }
1368 
1369     service = HdfIoServiceBindName(serviceName);
1370     if (service == NULL) {
1371         AUDIO_FUNC_LOGE("Capture: Failed to get service!");
1372         AudioMemFree((void **)&serviceName);
1373         return HDF_FAILURE;
1374     }
1375     AudioMemFree((void **)&serviceName);
1376     handle->object = service;
1377 
1378     return HDF_SUCCESS;
1379 }
1380 
1381 /* CreatCapture for Bind handle */
AudioBindServiceCapture(const char * name)1382 struct DevHandleCapture *AudioBindServiceCapture(const char *name)
1383 {
1384     int32_t ret;
1385     struct DevHandleCapture *handle = NULL;
1386 
1387     if (name == NULL) {
1388         AUDIO_FUNC_LOGE("service name NULL!");
1389         return NULL;
1390     }
1391 
1392     handle = (struct DevHandleCapture *)OsalMemCalloc(sizeof(struct DevHandleCapture));
1393     if (handle == NULL) {
1394         AUDIO_FUNC_LOGE("Failed to alloc handle");
1395         return NULL;
1396     }
1397 
1398     ret = AudioBindServiceCaptureObject(handle, name);
1399     if (ret != HDF_SUCCESS) {
1400         AUDIO_FUNC_LOGE("AudioBindServiceCaptureObject failed!");
1401         AudioMemFree((void **)&handle);
1402         return NULL;
1403     }
1404 
1405     /* Capture: Parsing primary sound card from configuration file */
1406     ret = CardInfoParseFromConfig();
1407     if (ret != HDF_SUCCESS) {
1408         AUDIO_FUNC_LOGE("Capture: parse config file failed!");
1409         AudioMemFree((void **)&handle);
1410         return NULL;
1411     }
1412     AUDIO_FUNC_LOGI("BIND SERVICE SUCCESS!");
1413 
1414     return handle;
1415 }
1416 
AudioCloseServiceCapture(const struct DevHandleCapture * handle)1417 void AudioCloseServiceCapture(const struct DevHandleCapture *handle)
1418 {
1419     if (handle != NULL) {
1420         if (handle->object == NULL) {
1421             AUDIO_FUNC_LOGE("Capture handle or handle->object is NULL");
1422         }
1423         AudioMemFree((void **)&handle);
1424     }
1425 }
1426 
AudioInterfaceLibOutputCapture(const struct DevHandleCapture * handle,int cmdId,struct AudioHwCaptureParam * handleData)1427 int32_t AudioInterfaceLibOutputCapture(
1428     const struct DevHandleCapture *handle, int cmdId, struct AudioHwCaptureParam *handleData)
1429 {
1430     int32_t ret;
1431 
1432     if (handle == NULL || handleData == NULL) {
1433         AUDIO_FUNC_LOGE("Parameter is NULL!");
1434         return HDF_FAILURE;
1435     }
1436 
1437     switch (cmdId) {
1438         case AUDIO_DRV_PCM_IOCTL_HW_PARAMS:
1439             ret = AudioOutputCaptureHwParams(handle, cmdId, handleData);
1440             break;
1441         case AUDIO_DRV_PCM_IOCTL_READ:
1442             ret = AudioOutputCaptureRead(handle, cmdId, handleData);
1443             break;
1444         case AUDIO_DRV_PCM_IOCTRL_START_CAPTURE:
1445             ret = AudioOutputCaptureStart(handle, cmdId, handleData);
1446             break;
1447         case AUDIO_DRV_PCM_IOCTL_PREPARE_CAPTURE:
1448             ret = AudioOutputCapturePrepare(handle, cmdId, handleData);
1449             break;
1450         case AUDIO_DRV_PCM_IOCTRL_CAPTURE_CLOSE:
1451             ret = AudioOutputCaptureClose(handle, cmdId, handleData);
1452             break;
1453         case AUDIO_DRV_PCM_IOCTRL_CAPTURE_OPEN:
1454             ret = AudioOutputCaptureOpen(handle, cmdId, handleData);
1455             break;
1456         case AUDIO_DRV_PCM_IOCTRL_STOP_CAPTURE:
1457             ret = AudioOutputCaptureStop(handle, cmdId, handleData);
1458             break;
1459         case AUDIODRV_CTL_IOCTL_PAUSE_WRITE_CAPTURE:
1460             ret = AudioCtlCaptureSetPauseStu(handle, cmdId, handleData);
1461             break;
1462         case AUDIO_DRV_PCM_IOCTL_MMAP_BUFFER_CAPTURE:
1463             ret = AudioOutputCaptureReqMmapBuffer(handle, cmdId, handleData);
1464             break;
1465         case AUDIO_DRV_PCM_IOCTL_MMAP_POSITION_CAPTURE:
1466             ret = AudioOutputCaptureGetMmapPosition(handle, cmdId, handleData);
1467             break;
1468         default:
1469             AUDIO_FUNC_LOGE("Output Mode not support!");
1470             ret = HDF_FAILURE;
1471             break;
1472     }
1473 
1474     return ret;
1475 }
1476 
AudioInterfaceLibModeCapture(const struct DevHandleCapture * handle,struct AudioHwCaptureParam * handleData,int cmdId)1477 int32_t AudioInterfaceLibModeCapture(
1478     const struct DevHandleCapture *handle, struct AudioHwCaptureParam *handleData, int cmdId)
1479 {
1480     AUDIO_FUNC_LOGI();
1481     if (handle == NULL || handleData == NULL) {
1482         AUDIO_FUNC_LOGE("paras is NULL!");
1483         return HDF_FAILURE;
1484     }
1485 
1486     switch (cmdId) {
1487         case AUDIO_DRV_PCM_IOCTL_HW_PARAMS:
1488         case AUDIO_DRV_PCM_IOCTL_READ:
1489         case AUDIO_DRV_PCM_IOCTRL_START_CAPTURE:
1490         case AUDIO_DRV_PCM_IOCTRL_STOP_CAPTURE:
1491         case AUDIO_DRV_PCM_IOCTL_PREPARE_CAPTURE:
1492         case AUDIODRV_CTL_IOCTL_PAUSE_WRITE_CAPTURE:
1493         case AUDIO_DRV_PCM_IOCTL_MMAP_BUFFER_CAPTURE:
1494         case AUDIO_DRV_PCM_IOCTL_MMAP_POSITION_CAPTURE:
1495         case AUDIO_DRV_PCM_IOCTRL_CAPTURE_OPEN:
1496         case AUDIO_DRV_PCM_IOCTRL_CAPTURE_CLOSE:
1497             return (AudioInterfaceLibOutputCapture(handle, cmdId, handleData));
1498         case AUDIODRV_CTL_IOCTL_ELEM_WRITE_CAPTURE:
1499         case AUDIODRV_CTL_IOCTL_ELEM_READ_CAPTURE:
1500         case AUDIODRV_CTL_IOCTL_MUTE_WRITE_CAPTURE:
1501         case AUDIODRV_CTL_IOCTL_MUTE_READ_CAPTURE:
1502         case AUDIODRV_CTL_IOCTL_GAIN_WRITE_CAPTURE:
1503         case AUDIODRV_CTL_IOCTL_GAIN_READ_CAPTURE:
1504         case AUDIODRV_CTL_IOCTL_SCENESELECT_CAPTURE:
1505         case AUDIODRV_CTL_IOCTL_GAINTHRESHOLD_CAPTURE:
1506         case AUDIODRV_CTL_IOCTL_VOL_THRESHOLD_CAPTURE:
1507             return (AudioInterfaceLibCtlCapture(handle, cmdId, handleData));
1508         default:
1509             AUDIO_FUNC_LOGE("Mode Error!");
1510             break;
1511     }
1512 
1513     return HDF_ERR_NOT_SUPPORT;
1514 }
1515