• 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_render.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 MAX_PERIOD_SIZE            (8 * 1024)
24 #define MIN_PERIOD_SIZE            (4 * 1024)
25 #define AUDIO_RENDER_RECOVER_DELAY (10 * 1000)
26 
27 static snd_pcm_sframes_t g_bufferSize = 0;
28 static snd_pcm_sframes_t g_periodSize = 0;
29 static unsigned int g_bufferTime = 500000; /* (0.5s): ring buffer length in us */
30 static unsigned int g_periodTime = 100000; /* (0.1s): period time in us */
31 static int g_resample = 1;                 /* enable alsa-lib resampling */
32 static bool g_periodEvent = false;              /* produce poll event after each period */
33 static int g_canPause = 0;                 /* 0 Hardware doesn't support pause, 1 Hardware supports pause */
34 
GetHwParams(struct AudioCardInfo * cardIns,const struct AudioHwRenderParam * handleData)35 static int32_t GetHwParams(struct AudioCardInfo *cardIns, const struct AudioHwRenderParam *handleData)
36 {
37     if (cardIns == NULL || handleData == NULL) {
38         AUDIO_FUNC_LOGE("Parameter error!");
39         return HDF_FAILURE;
40     }
41 
42     cardIns->hwRenderParams.streamType = AUDIO_RENDER_STREAM;
43     cardIns->hwRenderParams.channels = handleData->frameRenderMode.attrs.channelCount;
44     cardIns->hwRenderParams.rate = handleData->frameRenderMode.attrs.sampleRate;
45     cardIns->hwRenderParams.periodSize = handleData->frameRenderMode.periodSize;
46     cardIns->hwRenderParams.periodCount = handleData->frameRenderMode.periodCount;
47     cardIns->hwRenderParams.format = handleData->frameRenderMode.attrs.format;
48     cardIns->hwRenderParams.period = handleData->frameRenderMode.attrs.period;
49     cardIns->hwRenderParams.frameSize = handleData->frameRenderMode.attrs.frameSize;
50     cardIns->hwRenderParams.isBigEndian = handleData->frameRenderMode.attrs.isBigEndian;
51     cardIns->hwRenderParams.isSignedData = handleData->frameRenderMode.attrs.isSignedData;
52     cardIns->hwRenderParams.startThreshold = handleData->frameRenderMode.attrs.startThreshold;
53     cardIns->hwRenderParams.stopThreshold = handleData->frameRenderMode.attrs.stopThreshold;
54     cardIns->hwRenderParams.silenceThreshold = handleData->frameRenderMode.attrs.silenceThreshold;
55     return HDF_SUCCESS;
56 }
57 
AudioSetMixerVolume(snd_mixer_elem_t * pcmElemen,long vol)58 static int32_t AudioSetMixerVolume(snd_mixer_elem_t *pcmElemen, long vol)
59 {
60     int32_t ret;
61 
62     if (pcmElemen == NULL) {
63         AUDIO_FUNC_LOGE("Parameter error!");
64         return HDF_FAILURE;
65     }
66 
67     // Judge whether it is mono or stereo
68     if (snd_mixer_selem_is_playback_mono(pcmElemen)) {
69         ret = snd_mixer_selem_set_playback_volume(pcmElemen, SND_MIXER_SCHN_FRONT_LEFT, vol);
70         if (ret < 0) {
71             AUDIO_FUNC_LOGE("AudioSetMixerVolume failed: %{public}s.", snd_strerror(ret));
72             return HDF_FAILURE;
73         }
74     } else {
75         ret = snd_mixer_selem_set_playback_volume_all(pcmElemen, vol);
76         if (ret < 0) {
77             AUDIO_FUNC_LOGE("AudioSetMixerVolume failed: %{public}s.", snd_strerror(ret));
78             return HDF_FAILURE;
79         }
80     }
81 
82     return HDF_SUCCESS;
83 }
84 
AudioCtlRenderSetVolume(const struct DevHandle * handle,int cmdId,const struct AudioHwRenderParam * handleData)85 int32_t AudioCtlRenderSetVolume(const struct DevHandle *handle, int cmdId, const struct AudioHwRenderParam *handleData)
86 {
87     long vol;
88     int32_t ret;
89     struct AudioCardInfo *cardIns = NULL;
90 
91     (void)cmdId;
92     if (handle == NULL || handleData == NULL) {
93         AUDIO_FUNC_LOGE("Invalid parameters!!");
94         return HDF_FAILURE;
95     }
96 
97     const char *adapterName = handleData->renderMode.hwInfo.adapterName;
98     cardIns = GetCardIns(adapterName);
99     if (cardIns == NULL) {
100         AUDIO_FUNC_LOGE("Get card instance failed!");
101         return HDF_FAILURE;
102     }
103 
104     vol = (long)handleData->renderMode.ctlParam.volume;
105     if (cardIns->ctrlLeftVolume != NULL) {
106         ret = AudioSetMixerVolume(cardIns->ctrlLeftVolume, vol);
107         if (ret < 0) {
108             AUDIO_FUNC_LOGE("AudioSetMixerVolume left fail!");
109             return HDF_FAILURE;
110         }
111     }
112 
113     if (cardIns->ctrlRightVolume != NULL) {
114         ret = AudioSetMixerVolume(cardIns->ctrlRightVolume, vol);
115         if (ret < 0) {
116             AUDIO_FUNC_LOGE("AudioSetMixerVolume right fail!");
117             return HDF_FAILURE;
118         }
119     }
120 
121     return HDF_SUCCESS;
122 }
123 
AudioRenderGetVolumeSub(struct AudioCardInfo * cardIns,long * vol)124 static int32_t AudioRenderGetVolumeSub(struct AudioCardInfo *cardIns, long *vol)
125 {
126     long volLeft = MIN_VOLUME;
127     long volRight = MIN_VOLUME;
128 
129     if (cardIns == NULL || vol == NULL) {
130         AUDIO_FUNC_LOGE("Parameter error!");
131         return HDF_FAILURE;
132     }
133 
134     if (cardIns->ctrlLeftVolume == NULL || cardIns->mixer == NULL) {
135         AUDIO_FUNC_LOGE("cardIns's ctrlLeftVolume or mixer is null!");
136         return HDF_FAILURE;
137     }
138 
139     // Handling events
140     int32_t ret = snd_mixer_handle_events(cardIns->mixer);
141     if (ret < 0) {
142         AUDIO_FUNC_LOGE("snd_mixer_handle_events fail!");
143         return HDF_FAILURE;
144     }
145 
146     // Left channel
147     ret = snd_mixer_selem_get_playback_volume(cardIns->ctrlLeftVolume, SND_MIXER_SCHN_FRONT_LEFT, &volLeft);
148     if (ret < 0) {
149         AUDIO_FUNC_LOGE("Set left channel fail!");
150         return HDF_FAILURE;
151     }
152     // right channel
153     ret = snd_mixer_selem_get_playback_volume(cardIns->ctrlLeftVolume, SND_MIXER_SCHN_FRONT_RIGHT, &volRight);
154     if (ret < 0) {
155         AUDIO_FUNC_LOGE("Set right channel fail!");
156         return HDF_FAILURE;
157     }
158     *vol = (volLeft + volRight) >> 1;
159 
160     return HDF_SUCCESS;
161 }
162 
AudioCtlRenderGetVolume(const struct DevHandle * handle,int cmdId,struct AudioHwRenderParam * handleData)163 int32_t AudioCtlRenderGetVolume(const struct DevHandle *handle, int cmdId, struct AudioHwRenderParam *handleData)
164 {
165     int32_t ret;
166     long vol;
167     struct AudioCardInfo *cardIns = NULL;
168 
169     (void)cmdId;
170     if (handle == NULL || handleData == NULL) {
171         AUDIO_FUNC_LOGE("Parameter error!");
172         return HDF_FAILURE;
173     }
174 
175     const char *adapterName = handleData->renderMode.hwInfo.adapterName;
176     cardIns = GetCardIns(adapterName);
177     ret = AudioRenderGetVolumeSub(cardIns, &vol);
178     if (ret != HDF_SUCCESS) {
179         AUDIO_FUNC_LOGE("AudioRenderGetVolumeSub failed!");
180         return HDF_FAILURE;
181     }
182 
183     handleData->renderMode.ctlParam.volume = (float)vol;
184 
185     return HDF_SUCCESS;
186 }
187 
AudioCtlRenderSetPauseStu(const struct DevHandle * handle,int cmdId,const struct AudioHwRenderParam * handleData)188 int32_t AudioCtlRenderSetPauseStu(
189     const struct DevHandle *handle, int cmdId, const struct AudioHwRenderParam *handleData)
190 {
191     (void)cmdId;
192     if (handle == NULL || handleData == NULL) {
193         AUDIO_FUNC_LOGE("Parameter error!");
194         return HDF_FAILURE;
195     }
196 
197     /* The hardware does not support pause/resume,
198      * so a success message is returned.
199      * The software processing scheme is implemented
200      * in AudioOutputRenderWrite interface.
201      */
202     return HDF_SUCCESS;
203 }
204 
RenderSetMuteStuSub(struct AudioCardInfo * cardIns,int32_t muteState)205 static int32_t RenderSetMuteStuSub(struct AudioCardInfo *cardIns, int32_t muteState)
206 {
207     int32_t ret;
208 
209     if (cardIns == NULL) {
210         AUDIO_FUNC_LOGE("cardIns is NULL!");
211         return HDF_FAILURE;
212     }
213 
214     /* Mono (Front left alias) */
215     if (cardIns->ctrlLeftVolume == NULL) {
216         AUDIO_FUNC_LOGE("Unable to get Mono.");
217         return HDF_FAILURE;
218     }
219 
220     ret = snd_mixer_selem_has_playback_switch(cardIns->ctrlLeftVolume);
221     if (ret == 1) { // 1: Controlled switch
222         ret = snd_mixer_selem_set_playback_switch_all(cardIns->ctrlLeftVolume, muteState);
223         if (ret < 0) {
224             AUDIO_FUNC_LOGE("Unable to play mixer  switch ");
225             return HDF_FAILURE;
226         }
227     } else { // 0: no control
228         AUDIO_FUNC_LOGE("it's no control is present");
229         return HDF_FAILURE;
230     }
231 
232     return HDF_SUCCESS;
233 }
234 
AudioPrimarySetMuteState(struct AudioCardInfo * cardIns,int32_t muteState,float volume)235 static int32_t AudioPrimarySetMuteState(struct AudioCardInfo *cardIns, int32_t muteState, float volume)
236 {
237     long vol;
238     long alsaVol;
239     float volRangeMin = 0.0;
240     float volRangeMax = 100.0;
241     if (cardIns == NULL) {
242         AUDIO_FUNC_LOGE("cardIns is NULL!");
243         return HDF_FAILURE;
244     }
245     int32_t ret = RenderSetMuteStuSub(cardIns, muteState);
246     /* ret return HDF_FAILURE : no control is present */
247     if (ret != HDF_SUCCESS) {
248         /* Try to set the volume is 0 to change the mute state */
249         ret = AudioRenderGetVolumeSub(cardIns, &vol);
250         if (ret != HDF_SUCCESS) {
251             AUDIO_FUNC_LOGE("AudioRenderGetVolumeSub error!");
252             return HDF_FAILURE;
253         }
254 
255         if (muteState == false) {
256             alsaVol = 0; /* 0 for mute */
257             cardIns->tempVolume = (float)vol;
258         } else {
259             if (volume > volRangeMin && volume <= volRangeMax) {
260                 alsaVol = (long)volume;
261             } else {
262                 alsaVol = (long)cardIns->tempVolume;
263             }
264         }
265 
266         if (cardIns->ctrlLeftVolume != NULL) {
267             ret = AudioSetMixerVolume(cardIns->ctrlLeftVolume, alsaVol);
268             if (ret < 0) {
269                 AUDIO_FUNC_LOGE("AudioSetMixerVolume left fail!");
270                 return HDF_FAILURE;
271             }
272         }
273 
274         if (cardIns->ctrlRightVolume != NULL) {
275             ret = AudioSetMixerVolume(cardIns->ctrlRightVolume, alsaVol);
276             if (ret < 0) {
277                 AUDIO_FUNC_LOGE("AudioSetMixerVolume right fail!");
278                 return HDF_FAILURE;
279             }
280         }
281     }
282 
283     return HDF_SUCCESS;
284 }
285 
AudioCtlRenderSetMuteStu(const struct DevHandle * handle,int cmdId,const struct AudioHwRenderParam * handleData)286 int32_t AudioCtlRenderSetMuteStu(const struct DevHandle *handle, int cmdId, const struct AudioHwRenderParam *handleData)
287 {
288     int32_t ret;
289     int32_t muteState;
290 
291     (void)cmdId;
292     if (handle == NULL || handleData == NULL) {
293         AUDIO_FUNC_LOGE("Parameter error!");
294         return HDF_FAILURE;
295     }
296 
297     const char *adapterName = handleData->renderMode.hwInfo.adapterName;
298     struct AudioCardInfo *cardIns = GetCardIns(adapterName);
299     if (cardIns == NULL) {
300         AUDIO_FUNC_LOGE("GetCardIns error!!!");
301         return HDF_FAILURE;
302     }
303 
304     muteState = cardIns->renderMuteValue;
305     if (strncmp(adapterName, PRIMARY, strlen(PRIMARY)) == 0) {
306         ret = AudioPrimarySetMuteState(cardIns, muteState, handleData->renderMode.ctlParam.volume);
307         if (ret < 0) {
308             AUDIO_FUNC_LOGE("Render primary sound card SetMute failed!");
309             return HDF_FAILURE;
310         }
311     }
312 
313     if (strncmp(adapterName, USB, strlen(USB)) == 0) {
314         ret = RenderSetMuteStuSub(cardIns, muteState);
315         if (ret < 0) {
316             AUDIO_FUNC_LOGE("Render usb sound card SetMute failed!");
317             return HDF_FAILURE;
318         }
319     }
320     cardIns->renderMuteValue = (int32_t)handleData->renderMode.ctlParam.mute;
321 
322     return HDF_SUCCESS;
323 }
324 
AudioCtlRenderGetMuteStu(const struct DevHandle * handle,int cmdId,struct AudioHwRenderParam * handleData)325 int32_t AudioCtlRenderGetMuteStu(const struct DevHandle *handle, int cmdId, struct AudioHwRenderParam *handleData)
326 {
327     struct AudioCardInfo *cardInstance = NULL;
328 
329     (void)cmdId;
330     if (handle == NULL || handleData == NULL) {
331         AUDIO_FUNC_LOGE("Parameter error!");
332         return HDF_FAILURE;
333     }
334 
335     const char *adapterName = handleData->renderMode.hwInfo.adapterName;
336     cardInstance = GetCardIns(adapterName);
337     if (cardInstance == NULL) {
338         AUDIO_FUNC_LOGE("cardInstance is NULL!");
339         return HDF_FAILURE;
340     }
341     handleData->renderMode.ctlParam.mute = (bool)cardInstance->renderMuteValue;
342 
343     return HDF_SUCCESS;
344 }
345 
AudioCtlRenderSetGainStu(const struct DevHandle * handle,int cmdId,const struct AudioHwRenderParam * handleData)346 int32_t AudioCtlRenderSetGainStu(const struct DevHandle *handle, int cmdId, const struct AudioHwRenderParam *handleData)
347 {
348     (void)cmdId;
349     if (handle == NULL || handleData == NULL) {
350         AUDIO_FUNC_LOGE("Parameter error!");
351         return HDF_FAILURE;
352     }
353 
354     return HDF_SUCCESS;
355 }
356 
AudioCtlRenderGetGainStu(const struct DevHandle * handle,int cmdId,struct AudioHwRenderParam * handleData)357 int32_t AudioCtlRenderGetGainStu(const struct DevHandle *handle, int cmdId, struct AudioHwRenderParam *handleData)
358 {
359     (void)cmdId;
360     if (handle == NULL || handleData == NULL) {
361         AUDIO_FUNC_LOGE("Parameter error!");
362         return HDF_FAILURE;
363     }
364 
365     return HDF_SUCCESS;
366 }
367 
AudioCtlRenderSceneSelect(const struct DevHandle * handle,int cmdId,const struct AudioHwRenderParam * handleData)368 int32_t AudioCtlRenderSceneSelect(
369     const struct DevHandle *handle, int cmdId, const struct AudioHwRenderParam *handleData)
370 {
371     enum AudioPortPin descPins;
372     struct AudioCardInfo *cardIns = NULL;
373 
374     (void)cmdId;
375     if (handle == NULL || handleData == NULL) {
376         AUDIO_FUNC_LOGE("Invalid parameters!");
377         return HDF_FAILURE;
378     }
379 
380     const char *adapterName = handleData->renderMode.hwInfo.adapterName;
381     cardIns = GetCardIns(adapterName);
382     if (cardIns == NULL) {
383         AUDIO_FUNC_LOGE("Cant't get card Instance!");
384         return HDF_FAILURE;
385     }
386 
387     descPins = handleData->renderMode.hwInfo.deviceDescript.pins;
388     switch (descPins) {
389         case PIN_OUT_SPEAKER:
390             return AudioMixerSetCtrlMode(
391                 cardIns, adapterName, "Digital Playback Path", SND_PLAY_PATH, SND_OUT_CARD_SPK);
392         case PIN_OUT_HEADSET:
393             return AudioMixerSetCtrlMode(cardIns, adapterName, "Digital Playback Path", SND_PLAY_PATH, SND_OUT_CARD_HP);
394         default:
395             AUDIO_FUNC_LOGE("This mode is not currently supported!");
396             break;
397     }
398 
399     return HDF_FAILURE;
400 }
401 
AudioCtlRenderSceneGetGainThreshold(const struct DevHandle * handle,int cmdId,struct AudioHwRenderParam * handleData)402 int32_t AudioCtlRenderSceneGetGainThreshold(
403     const struct DevHandle *handle, int cmdId, struct AudioHwRenderParam *handleData)
404 {
405     (void)cmdId;
406     if (handle == NULL || handleData == NULL) {
407         AUDIO_FUNC_LOGE("Parameter error!");
408         return HDF_FAILURE;
409     }
410 
411     return HDF_SUCCESS;
412 }
413 
AudioCtlRenderGetVolThreshold(const struct DevHandle * handle,int cmdId,struct AudioHwRenderParam * handleData)414 int32_t AudioCtlRenderGetVolThreshold(const struct DevHandle *handle, int cmdId, struct AudioHwRenderParam *handleData)
415 {
416     int32_t ret;
417     long volMin = MIN_VOLUME;
418     long volMax = MIN_VOLUME;
419     struct AudioCardInfo *cardIns = NULL;
420 
421     (void)cmdId;
422     if (handle == NULL || handleData == NULL) {
423         AUDIO_FUNC_LOGE("Parameter error!");
424         return HDF_FAILURE;
425     }
426 
427     char *adapterName = handleData->renderMode.hwInfo.adapterName;
428     cardIns = GetCardIns(adapterName);
429     if (cardIns == NULL) {
430         AUDIO_FUNC_LOGE("cardIns is NULL!");
431         return HDF_FAILURE;
432     }
433 
434     ret = snd_mixer_selem_get_playback_volume_range(cardIns->ctrlLeftVolume, &volMin, &volMax);
435     if (ret < 0) {
436         AUDIO_FUNC_LOGE("Get playback volume range fail: %{public}s.", snd_strerror(ret));
437         return HDF_FAILURE;
438     }
439     handleData->renderMode.ctlParam.volThreshold.volMin = (int)volMin;
440     handleData->renderMode.ctlParam.volThreshold.volMax = (int)volMax;
441 
442     return HDF_SUCCESS;
443 }
444 
AudioCtlRenderSetChannelMode(const struct DevHandle * handle,int cmdId,const struct AudioHwRenderParam * handleData)445 int32_t AudioCtlRenderSetChannelMode(
446     const struct DevHandle *handle, int cmdId, const struct AudioHwRenderParam *handleData)
447 {
448     (void)cmdId;
449     if (handle == NULL || handleData == NULL) {
450         AUDIO_FUNC_LOGE("Parameter error!");
451         return HDF_FAILURE;
452     }
453 
454     return HDF_SUCCESS;
455 }
456 
AudioCtlRenderGetChannelMode(const struct DevHandle * handle,int cmdId,struct AudioHwRenderParam * handleData)457 int32_t AudioCtlRenderGetChannelMode(const struct DevHandle *handle, int cmdId, struct AudioHwRenderParam *handleData)
458 {
459     (void)cmdId;
460     if (handle == NULL || handleData == NULL) {
461         AUDIO_FUNC_LOGE("Parameter error!");
462         return HDF_FAILURE;
463     }
464 
465     return HDF_SUCCESS;
466 }
467 
AudioInterfaceLibCtlRender(const struct DevHandle * handle,int cmdId,struct AudioHwRenderParam * handleData)468 int32_t AudioInterfaceLibCtlRender(const struct DevHandle *handle, int cmdId, struct AudioHwRenderParam *handleData)
469 {
470     if (handle == NULL || handleData == NULL) {
471         AUDIO_FUNC_LOGE("Parameter error!");
472         return HDF_FAILURE;
473     }
474 
475     if (cmdId < AUDIODRV_CTL_IOCTL_ELEM_INFO || cmdId > AUDIODRV_CTL_IOCTL_VOL_THRESHOLD_READ) {
476         AUDIO_FUNC_LOGE("cmdId Not Supported!");
477         return HDF_FAILURE;
478     }
479 
480     switch (cmdId) {
481         case AUDIODRV_CTL_IOCTL_ELEM_READ:
482             return (AudioCtlRenderGetVolume(handle, cmdId, handleData));
483         case AUDIODRV_CTL_IOCTL_ELEM_WRITE:
484             return (AudioCtlRenderSetVolume(handle, cmdId, handleData));
485         case AUDIODRV_CTL_IOCTL_MUTE_READ:
486             return (AudioCtlRenderGetMuteStu(handle, cmdId, handleData));
487         case AUDIODRV_CTL_IOCTL_MUTE_WRITE:
488             return (AudioCtlRenderSetMuteStu(handle, cmdId, handleData));
489         case AUDIODRV_CTL_IOCTL_CHANNEL_MODE_READ:
490             return (AudioCtlRenderGetChannelMode(handle, cmdId, handleData));
491         case AUDIODRV_CTL_IOCTL_CHANNEL_MODE_WRITE:
492             return (AudioCtlRenderSetChannelMode(handle, cmdId, handleData));
493         case AUDIODRV_CTL_IOCTL_GAIN_WRITE:
494             return (AudioCtlRenderSetGainStu(handle, cmdId, handleData));
495         case AUDIODRV_CTL_IOCTL_GAIN_READ:
496             return (AudioCtlRenderGetGainStu(handle, cmdId, handleData));
497         case AUDIODRV_CTL_IOCTL_SCENESELECT_WRITE:
498             return (AudioCtlRenderSceneSelect(handle, cmdId, handleData));
499         case AUDIODRV_CTL_IOCTL_GAINTHRESHOLD_READ:
500             return (AudioCtlRenderSceneGetGainThreshold(handle, cmdId, handleData));
501         case AUDIODRV_CTL_IOCTL_VOL_THRESHOLD_READ:
502             return (AudioCtlRenderGetVolThreshold(handle, cmdId, handleData));
503         default:
504             AUDIO_FUNC_LOGE("Output Mode not support!");
505             break;
506     }
507 
508     return HDF_FAILURE;
509 }
510 
SetHWParamsSub(snd_pcm_t * handle,snd_pcm_hw_params_t * params,struct AudioPcmHwParams hwParams,snd_pcm_access_t access)511 static int32_t SetHWParamsSub(
512     snd_pcm_t *handle, snd_pcm_hw_params_t *params, struct AudioPcmHwParams hwParams, snd_pcm_access_t access)
513 {
514     int32_t ret;
515     snd_pcm_format_t pcmFormat = SND_PCM_FORMAT_S16_LE;
516 
517     if (handle == NULL || params == NULL) {
518         AUDIO_FUNC_LOGE("Parameter error!");
519         return HDF_FAILURE;
520     }
521 
522     /* set hardware resampling */
523     ret = snd_pcm_hw_params_set_rate_resample(handle, params, g_resample);
524     if (ret < 0) {
525         AUDIO_FUNC_LOGE("Resampling setup failed for playback: %{public}s", snd_strerror(ret));
526         return HDF_FAILURE;
527     }
528     /* set the interleaved read/write format */
529     ret = snd_pcm_hw_params_set_access(handle, params, access);
530     if (ret < 0) {
531         AUDIO_FUNC_LOGE("Access type not available for playback: %{public}s", snd_strerror(ret));
532         return HDF_FAILURE;
533     }
534     ret = CheckParaFormat(hwParams, &pcmFormat);
535     if (ret < 0) {
536         AUDIO_FUNC_LOGE("CheckParaFormat error.");
537         return HDF_FAILURE;
538     }
539     /* set the sample format */
540     ret = snd_pcm_hw_params_set_format(handle, params, pcmFormat);
541     if (ret < 0) {
542         AUDIO_FUNC_LOGE("Sample format not available for playback: %{public}s", snd_strerror(ret));
543         return HDF_FAILURE;
544     }
545     /* set the count of channels */
546     ret = snd_pcm_hw_params_set_channels(handle, params, hwParams.channels);
547     if (ret < 0) {
548         AUDIO_FUNC_LOGE("Channels count (%{public}u) not available for playbacks: %{public}s", hwParams.channels,
549             snd_strerror(ret));
550         return HDF_FAILURE;
551     }
552 
553     return HDF_SUCCESS;
554 }
555 
SetHWRate(snd_pcm_t * handle,snd_pcm_hw_params_t * params,uint32_t * rate)556 static int32_t SetHWRate(snd_pcm_t *handle, snd_pcm_hw_params_t *params, uint32_t *rate)
557 {
558     int32_t ret;
559     uint32_t rRate;
560     int dir = 0; /* dir Value range (-1,0,1) */
561 
562     if (handle == NULL || params == NULL || rate == NULL) {
563         AUDIO_FUNC_LOGE("Parameter error!");
564         return HDF_FAILURE;
565     }
566 
567     /* set the stream rate */
568     rRate = *rate;
569     ret = snd_pcm_hw_params_set_rate_near(handle, params, &rRate, &dir);
570     if (ret < 0) {
571         AUDIO_FUNC_LOGE("Rate %{public}uHz not available for playback: %{public}s.", *rate, snd_strerror(ret));
572         return HDF_FAILURE;
573     }
574 
575     if (rRate != *rate) {
576         ret = snd_pcm_hw_params_set_rate_near(handle, params, &rRate, &dir);
577         if (ret < 0) {
578             AUDIO_FUNC_LOGE("Rate %{public}uHz not available for playback: %{public}s.", *rate, snd_strerror(ret));
579             return HDF_FAILURE;
580         }
581     }
582     /* Update to hardware supported rate */
583     *rate = rRate;
584     g_canPause = snd_pcm_hw_params_can_pause(params);
585 
586     return HDF_SUCCESS;
587 }
SetHWParams(snd_pcm_t * handle,snd_pcm_hw_params_t * params,struct AudioPcmHwParams hwParams,snd_pcm_access_t access)588 static int32_t SetHWParams(
589     snd_pcm_t *handle, snd_pcm_hw_params_t *params, struct AudioPcmHwParams hwParams, snd_pcm_access_t access)
590 {
591     int ret;
592     int dir = 0; /* dir Value range (-1,0,1) */
593     if (handle == NULL || params == NULL) {
594         AUDIO_FUNC_LOGE("Parameter error!");
595         return HDF_FAILURE;
596     }
597     snd_pcm_uframes_t size;
598     ret = snd_pcm_hw_params_any(handle, params); // choose all parameters
599     if (ret < 0) {
600         AUDIO_FUNC_LOGE("No configurations available: %{public}s", snd_strerror(ret));
601         return HDF_FAILURE;
602     }
603     if (SetHWParamsSub(handle, params, hwParams, access) < 0) {
604         AUDIO_FUNC_LOGE("SetHWParamsSub failed!");
605         return HDF_FAILURE;
606     }
607     if (SetHWRate(handle, params, &(hwParams.rate)) < 0) {
608         AUDIO_FUNC_LOGE("SetHWRate failed!");
609         return HDF_FAILURE;
610     }
611     ret = snd_pcm_hw_params_set_buffer_time_near(handle, params, &g_bufferTime, &dir);
612     if (ret < 0) {
613         AUDIO_FUNC_LOGE("Set buffer time %{public}u failed: %{public}s", g_bufferTime, snd_strerror(ret));
614         return HDF_FAILURE;
615     }
616     ret = snd_pcm_hw_params_get_buffer_size(params, &size);
617     if (ret < 0) {
618         AUDIO_FUNC_LOGE("Unable to get buffer size for playback: %{public}s", snd_strerror(ret));
619         return HDF_FAILURE;
620     }
621     g_bufferSize = size;
622     ret = snd_pcm_hw_params_set_period_time_near(handle, params, &g_periodTime, &dir);
623     if (ret < 0) {
624         AUDIO_FUNC_LOGE("Set period time %{public}u failed: %{public}s", g_bufferTime, snd_strerror(ret));
625         return HDF_FAILURE;
626     }
627     ret = snd_pcm_hw_params_get_period_size(params, &size, &dir);
628     if (ret < 0) {
629         AUDIO_FUNC_LOGE("Unable to get period size for playback: %{public}s", snd_strerror(ret));
630         return HDF_FAILURE;
631     }
632     g_periodSize = size;
633     ret = snd_pcm_hw_params(handle, params); // write the parameters to device
634     if (ret < 0) {
635         AUDIO_FUNC_LOGE("Unable to set hw params for playback: %{public}s", snd_strerror(ret));
636         return HDF_FAILURE;
637     }
638     return HDF_SUCCESS;
639 }
640 
SetSWParams(snd_pcm_t * handle,snd_pcm_sw_params_t * swparams)641 static int32_t SetSWParams(snd_pcm_t *handle, snd_pcm_sw_params_t *swparams)
642 {
643     int32_t ret;
644     int32_t val = 1; /* val 0 = disable period event, 1 = enable period event */
645 
646     if (handle == NULL || swparams == NULL) {
647         AUDIO_FUNC_LOGE("Parameter error!");
648         return HDF_FAILURE;
649     }
650 
651     /* get the current swparams */
652     ret = snd_pcm_sw_params_current(handle, swparams);
653     if (ret < 0) {
654         AUDIO_FUNC_LOGE("Unable to determine current swparams for playback: %{public}s", snd_strerror(ret));
655         return HDF_FAILURE;
656     }
657     /* start the transfer when the buffer is almost full: */
658     /* (buffer_size / avail_min) * avail_min */
659     if (g_periodSize == 0) {
660         AUDIO_FUNC_LOGE("g_periodSize=0");
661         return HDF_FAILURE;
662     }
663     ret = snd_pcm_sw_params_set_start_threshold(handle, swparams, (g_bufferSize / g_periodSize) * g_periodSize);
664     if (ret < 0) {
665         AUDIO_FUNC_LOGE("Unable to set start threshold mode for playback: %{public}s", snd_strerror(ret));
666         return HDF_FAILURE;
667     }
668     /* allow the transfer when at least period_size samples can be processed */
669     /* or disable this mechanism when period event is enabled (aka interrupt like style processing) */
670     ret = snd_pcm_sw_params_set_avail_min(handle, swparams, g_periodEvent ? g_bufferSize : g_periodSize);
671     if (ret < 0) {
672         AUDIO_FUNC_LOGE("Unable to set avail min for playback: %{public}s", snd_strerror(ret));
673         return HDF_FAILURE;
674     }
675 
676     /* enable period events when requested */
677     if (g_periodEvent) {
678         ret = snd_pcm_sw_params_set_period_event(handle, swparams, val);
679         if (ret < 0) {
680             AUDIO_FUNC_LOGE("Unable to set period event: %{public}s", snd_strerror(ret));
681             return HDF_FAILURE;
682         }
683     }
684 
685     /* write the parameters to the playback device */
686     ret = snd_pcm_sw_params(handle, swparams);
687     if (ret < 0) {
688         AUDIO_FUNC_LOGE("Unable to set sw params for playback: %{public}s", snd_strerror(ret));
689         return HDF_FAILURE;
690     }
691 
692     return HDF_SUCCESS;
693 }
694 
AudioResetParams(snd_pcm_t * handle,struct AudioPcmHwParams audioHwParams,snd_pcm_access_t access)695 static int32_t AudioResetParams(snd_pcm_t *handle, struct AudioPcmHwParams audioHwParams, snd_pcm_access_t access)
696 {
697     int32_t ret;
698     snd_pcm_hw_params_t *hwParams = NULL;
699     snd_pcm_sw_params_t *swParams = NULL;
700 
701     if (handle == NULL) {
702         AUDIO_FUNC_LOGE("Parameter error!");
703         return HDF_FAILURE;
704     }
705 
706     snd_pcm_hw_params_alloca(&hwParams);
707     snd_pcm_sw_params_alloca(&swParams);
708     ret = SetHWParams(handle, hwParams, audioHwParams, access);
709     if (ret != HDF_SUCCESS) {
710         AUDIO_FUNC_LOGE("Setting of hwparams failed.");
711         return ret;
712     }
713 
714     ret = SetSWParams(handle, swParams);
715     if (ret != HDF_SUCCESS) {
716         AUDIO_FUNC_LOGE("Setting of swparams failed.");
717         return ret;
718     }
719 
720     return HDF_SUCCESS;
721 }
722 
AudioOutputRenderHwParams(const struct DevHandle * handle,int cmdId,const struct AudioHwRenderParam * handleData)723 int32_t AudioOutputRenderHwParams(
724     const struct DevHandle *handle, int cmdId, const struct AudioHwRenderParam *handleData)
725 {
726     int32_t ret;
727     struct AudioCardInfo *cardIns = NULL;
728     snd_pcm_hw_params_t *hwParams = NULL;
729     snd_pcm_sw_params_t *swParams = NULL;
730 
731     (void)cmdId;
732     if (handle == NULL || handleData == NULL) {
733         AUDIO_FUNC_LOGE("Parameter error!");
734         return HDF_FAILURE;
735     }
736 
737     const char *cardName = handleData->renderMode.hwInfo.adapterName;
738     cardIns = GetCardIns(cardName);
739     if (cardIns == NULL) {
740         AUDIO_FUNC_LOGE("cardIns is NULL!");
741         return HDF_FAILURE;
742     }
743 
744     ret = (int32_t)snd_pcm_state(cardIns->renderPcmHandle);
745     if (ret >= SND_PCM_STATE_RUNNING) {
746         AUDIO_FUNC_LOGE("Unable to set parameters during playback!");
747         return HDF_FAILURE;
748     }
749 
750     ret = GetHwParams(cardIns, handleData);
751     if (ret < 0) {
752         AUDIO_FUNC_LOGE("GetHwParams error.");
753         return HDF_FAILURE;
754     }
755 
756     snd_pcm_hw_params_alloca(&hwParams);
757     snd_pcm_sw_params_alloca(&swParams);
758     ret = SetHWParams(cardIns->renderPcmHandle, hwParams, cardIns->hwRenderParams, SND_PCM_ACCESS_RW_INTERLEAVED);
759     if (ret < 0) {
760         AUDIO_FUNC_LOGE("Setting of hwparams failed.");
761         return HDF_FAILURE;
762     }
763 
764     ret = SetSWParams(cardIns->renderPcmHandle, swParams);
765     if (ret < 0) {
766         AUDIO_FUNC_LOGE("Setting of swparams failed.");
767         return HDF_FAILURE;
768     }
769 
770     return HDF_SUCCESS;
771 }
772 
AudioRenderWriteFrameSub(snd_pcm_t * pcm,char * dataBuf,size_t bufSize)773 static int32_t AudioRenderWriteFrameSub(snd_pcm_t *pcm, char *dataBuf, size_t bufSize)
774 {
775     int32_t ret;
776     long frames;
777     int32_t tryNum = AUDIO_ALSALIB_RETYR;
778 
779     if (pcm == NULL || dataBuf == NULL || bufSize == 0) {
780         AUDIO_FUNC_LOGE("Parameter error!");
781         return HDF_FAILURE;
782     }
783 
784     do {
785         /* Write interleaved frames to a PCM. */
786         frames = snd_pcm_writei(pcm, dataBuf, bufSize);
787         if (frames > 0) {
788             return HDF_SUCCESS;
789         }
790 
791         if (frames == -EBADFD) {
792             /* not #SND_PCM_STATE_PREPARED or #SND_PCM_STATE_RUNNING */
793             AUDIO_FUNC_LOGE("render PCM is not in the right state: %{public}s", snd_strerror(frames));
794             ret = snd_pcm_prepare(pcm);
795             if (ret < 0) {
796                 AUDIO_FUNC_LOGE("render snd_pcm_prepare fail: %{public}s", snd_strerror(ret));
797                 return HDF_FAILURE;
798             }
799         } else {
800             /* -ESTRPIPE: a suspend event occurred,
801              * stream is suspended and waiting for an application recovery.
802              * -EPIPE: an underrun occurred.
803              */
804             ret = snd_pcm_recover(pcm, frames, 0); // 0 for open render recover log.
805             if (ret < 0) {
806                 AUDIO_FUNC_LOGE("snd_pcm_writei failed: %{public}s", snd_strerror(ret));
807                 return HDF_FAILURE;
808             }
809             usleep(AUDIO_RENDER_RECOVER_DELAY);
810         }
811         tryNum--;
812     } while (tryNum > 0);
813 
814     return HDF_SUCCESS;
815 }
816 
AudioRenderWriteFrame(snd_pcm_t * pcm,const struct AudioHwRenderParam * handleData)817 static int32_t AudioRenderWriteFrame(snd_pcm_t *pcm, const struct AudioHwRenderParam *handleData)
818 {
819     int32_t ret;
820     size_t sbufFrameSize;
821     snd_pcm_state_t state;
822 
823     if (pcm == NULL || handleData == NULL) {
824         AUDIO_FUNC_LOGE("Parameter error!");
825         return HDF_FAILURE;
826     }
827 
828     /* Check whether the PCM status is normal */
829     state = snd_pcm_state(pcm);
830     if (state == SND_PCM_STATE_SETUP) {
831         ret = snd_pcm_prepare(pcm);
832         if (ret < 0) {
833             AUDIO_FUNC_LOGE("snd_pcm_prepare fail: %{public}s", snd_strerror(ret));
834             return HDF_FAILURE;
835         }
836     }
837 
838     sbufFrameSize = (size_t)handleData->frameRenderMode.bufferFrameSize;
839     ret = AudioRenderWriteFrameSub(pcm, handleData->frameRenderMode.buffer, sbufFrameSize);
840     if (ret != HDF_SUCCESS) {
841         AUDIO_FUNC_LOGE("AudioRenderWriteFrameSub failed!");
842         return HDF_FAILURE;
843     }
844 
845     return HDF_SUCCESS;
846 }
847 
AudioOutputRenderWrite(const struct DevHandle * handle,int cmdId,const struct AudioHwRenderParam * handleData)848 int32_t AudioOutputRenderWrite(const struct DevHandle *handle, int cmdId, const struct AudioHwRenderParam *handleData)
849 {
850     int32_t ret;
851     struct AudioCardInfo *cardIns = NULL;
852 
853     (void)cmdId;
854     if (handle == NULL || handleData == NULL) {
855         AUDIO_FUNC_LOGE("Parameter error!");
856         return HDF_FAILURE;
857     }
858 
859     if (g_canPause == 0) { /* Hardware does not support pause, enable soft solution */
860         if (handleData->renderMode.ctlParam.pause) {
861             AUDIO_FUNC_LOGE("Currently in pause, please check!");
862             return HDF_FAILURE;
863         }
864     }
865 
866     const char *adapterName = handleData->renderMode.hwInfo.adapterName;
867     cardIns = GetCardIns(adapterName);
868     if (cardIns == NULL) {
869         AUDIO_FUNC_LOGE("cardIns is NULL!");
870         return HDF_FAILURE;
871     }
872 
873     if (!cardIns->renderMmapFlag) {
874         ret = AudioResetParams(cardIns->renderPcmHandle, cardIns->hwRenderParams, SND_PCM_ACCESS_RW_INTERLEAVED);
875         if (ret < 0) {
876             AUDIO_FUNC_LOGE("AudioSetParamsMmap failed!");
877             return HDF_FAILURE;
878         }
879         cardIns->renderMmapFlag = true;
880     }
881 
882     ret = AudioRenderWriteFrame(cardIns->renderPcmHandle, handleData);
883     if (ret != HDF_SUCCESS) {
884         AUDIO_FUNC_LOGE("AudioRenderWriteFrame failed!");
885         return HDF_FAILURE;
886     }
887 
888     return HDF_SUCCESS;
889 }
890 
AudioOutputRenderPrepare(const struct DevHandle * handle,int cmdId,const struct AudioHwRenderParam * handleData)891 int32_t AudioOutputRenderPrepare(const struct DevHandle *handle, int cmdId, const struct AudioHwRenderParam *handleData)
892 {
893     int32_t ret;
894     struct AudioCardInfo *sndCardIns = NULL;
895 
896     (void)cmdId;
897     if (handle == NULL || handleData == NULL) {
898         AUDIO_FUNC_LOGE("Parameter error!");
899         return HDF_FAILURE;
900     }
901 
902     const char *sndCardName = handleData->renderMode.hwInfo.adapterName;
903     sndCardIns = GetCardIns(sndCardName);
904     if (sndCardIns == NULL) {
905         AUDIO_FUNC_LOGE("sndCardIns is NULL!");
906         return HDF_FAILURE;
907     }
908 
909     ret = snd_pcm_prepare(sndCardIns->renderPcmHandle);
910     if (ret < 0) {
911         AUDIO_FUNC_LOGE("snd_pcm_prepare fail: %{public}s", snd_strerror(ret));
912         return HDF_FAILURE;
913     }
914 
915     return HDF_SUCCESS;
916 }
917 
InitMixerCtrlVolumeRange(struct AudioCardInfo * cardIns)918 int32_t InitMixerCtrlVolumeRange(struct AudioCardInfo *cardIns)
919 {
920     int32_t ret;
921     long volMin = MIN_VOLUME;
922     long volMax = MIN_VOLUME;
923 
924     if (cardIns == NULL) {
925         AUDIO_FUNC_LOGE("Parameter error!");
926         return HDF_FAILURE;
927     }
928     /** cardIns->ctrlLeftVolume is Mono (Front left alias) */
929     if (cardIns->ctrlLeftVolume == NULL && cardIns->ctrlRightVolume == NULL) {
930         AUDIO_FUNC_LOGE("InitMixerCtrlVolumeRange error.");
931         return HDF_FAILURE;
932     }
933     if (cardIns->ctrlLeftVolume != NULL) {
934         ret = snd_mixer_selem_get_playback_volume_range(cardIns->ctrlLeftVolume, &volMin, &volMax);
935         if (ret < 0) {
936             AUDIO_FUNC_LOGE("Failed to get playback volume range: %{public}s", snd_strerror(ret));
937             return HDF_FAILURE;
938         }
939 
940         ret = snd_mixer_selem_set_playback_volume_range(cardIns->ctrlLeftVolume, MIN_VOLUME, MAX_VOLUME);
941         if (ret < 0) {
942             AUDIO_FUNC_LOGE("Failed to set playback volume range: %{public}s", snd_strerror(ret));
943             return HDF_FAILURE;
944         }
945     }
946 
947     if (cardIns->ctrlRightVolume != NULL) {
948         ret = snd_mixer_selem_get_playback_volume_range(cardIns->ctrlRightVolume, &volMin, &volMax);
949         if (ret < 0) {
950             AUDIO_FUNC_LOGE("Failed to get playback volume range");
951             return HDF_FAILURE;
952         }
953         ret = snd_mixer_selem_set_playback_volume_range(cardIns->ctrlRightVolume, MIN_VOLUME, MAX_VOLUME);
954         if (ret < 0) {
955             AUDIO_FUNC_LOGE("Failed to set playback volume range");
956             return HDF_FAILURE;
957         }
958     }
959 
960     return HDF_SUCCESS;
961 }
962 
InitMixerCtlElement(const char * adapterName,struct AudioCardInfo * cardIns,snd_mixer_t * mixer)963 static int32_t InitMixerCtlElement(const char *adapterName, struct AudioCardInfo *cardIns, snd_mixer_t *mixer)
964 {
965     int32_t ret;
966     snd_mixer_elem_t *pcmElement = NULL;
967 
968     if (adapterName == NULL || cardIns == NULL || mixer == NULL) {
969         AUDIO_FUNC_LOGE("Parameter error!");
970         return HDF_FAILURE;
971     }
972 
973     if (strncmp(adapterName, PRIMARY, strlen(PRIMARY)) == 0) {
974         pcmElement = snd_mixer_first_elem(mixer);
975         if (pcmElement == NULL) {
976             AUDIO_FUNC_LOGE("snd_mixer_first_elem failed.");
977             return HDF_FAILURE;
978         }
979 
980         ret = GetPriMixerCtlElement(cardIns, pcmElement);
981         if (ret < 0) {
982             AUDIO_FUNC_LOGE("Render GetPriMixerCtlElement failed.");
983             return HDF_FAILURE;
984         }
985     } else if (strncmp(adapterName, USB, strlen(USB)) == 0) {
986         cardIns->ctrlLeftVolume = AudioUsbFindElement(mixer);
987     } else {
988         AUDIO_FUNC_LOGE("The selected sound card not supported, please check!");
989         return HDF_FAILURE;
990     }
991 
992     ret = InitMixerCtrlVolumeRange(cardIns);
993     if (ret < 0) {
994         AUDIO_FUNC_LOGE("InitMixerCtrlVolumeRange failed!");
995         return HDF_FAILURE;
996     }
997 
998     ret = AudioMixerSetCtrlMode(cardIns, adapterName, "Digital Playback Path", SND_PLAY_PATH, SND_OUT_CARD_SPK_HP);
999     if (ret < 0) {
1000         AUDIO_FUNC_LOGE("AudioMixerSetCtrlMode failed!");
1001         return HDF_FAILURE;
1002     }
1003 
1004     return HDF_SUCCESS;
1005 }
1006 
1007 /*
1008  * brief: Opens a PCM
1009  * param mode Open mode (see #SND_PCM_NONBLOCK, #SND_PCM_ASYNC)
1010  */
AudioOutputRenderOpen(const struct DevHandle * handle,int cmdId,const struct AudioHwRenderParam * handleData)1011 int32_t AudioOutputRenderOpen(const struct DevHandle *handle, int cmdId, const struct AudioHwRenderParam *handleData)
1012 {
1013     int32_t ret;
1014     struct AudioCardInfo *cardIns = NULL;
1015 
1016     (void)cmdId;
1017     if (handle == NULL || handleData == NULL) {
1018         AUDIO_FUNC_LOGE("The parameter is empty.");
1019         return HDF_FAILURE;
1020     }
1021 
1022     const char *adapterName = handleData->renderMode.hwInfo.adapterName;
1023     cardIns = AudioGetCardInfo(adapterName, SND_PCM_STREAM_PLAYBACK);
1024     if (cardIns == NULL) {
1025         AUDIO_FUNC_LOGE("AudioRenderGetCardIns failed.");
1026         return HDF_FAILURE;
1027     }
1028 
1029     if (cardIns->renderPcmHandle != NULL) {
1030         AUDIO_FUNC_LOGE("Resource busy!!");
1031         return HDF_ERR_DEVICE_BUSY;
1032     }
1033 
1034     ret = snd_pcm_open(&cardIns->renderPcmHandle, cardIns->devName, SND_PCM_STREAM_PLAYBACK, 0);
1035     if (ret < 0) {
1036         AUDIO_FUNC_LOGE("AudioOutputRenderOpen fail: %{public}s!", snd_strerror(ret));
1037         CheckCardStatus(cardIns);
1038         (void)DestroyCardList();
1039         return HDF_FAILURE;
1040     }
1041 
1042     InitSound(&cardIns->mixer, cardIns->ctrlName);
1043     ret = InitMixerCtlElement(adapterName, cardIns, cardIns->mixer);
1044     if (ret < 0) {
1045         AUDIO_FUNC_LOGE("InitMixerCtlElement failed!");
1046         (void)CloseMixerHandle(cardIns->mixer);
1047         CheckCardStatus(cardIns);
1048         (void)DestroyCardList();
1049         return HDF_FAILURE;
1050     }
1051 
1052     return HDF_SUCCESS;
1053 }
1054 
AudioOutputRenderStop(const struct DevHandle * handle,int cmdId,const struct AudioHwRenderParam * handleData)1055 int32_t AudioOutputRenderStop(const struct DevHandle *handle, int cmdId, const struct AudioHwRenderParam *handleData)
1056 {
1057     int32_t ret;
1058     struct AudioCardInfo *cardIns = NULL;
1059 
1060     (void)cmdId;
1061     if (handle == NULL || handleData == NULL) {
1062         AUDIO_FUNC_LOGE("The parameter is empty.");
1063         return HDF_FAILURE;
1064     }
1065 
1066     const char *adapterName = handleData->renderMode.hwInfo.adapterName;
1067     cardIns = GetCardIns(adapterName);
1068     if (cardIns == NULL || cardIns->renderPcmHandle == NULL) {
1069         AUDIO_FUNC_LOGE("cardIns is NULL!");
1070         return HDF_FAILURE;
1071     }
1072     /**For playback, snd_ pcm_ Drain will wait for all pending data frames to be broadcast before turning off PCM */
1073     ret = snd_pcm_drain(cardIns->renderPcmHandle);
1074     if (ret < 0) {
1075         AUDIO_FUNC_LOGE("AudioOutputRenderStop fail!");
1076         return HDF_FAILURE;
1077     }
1078 
1079     return HDF_SUCCESS;
1080 }
1081 
AudioOutputRenderClose(const struct DevHandle * handle,int cmdId,const struct AudioHwRenderParam * handleData)1082 int32_t AudioOutputRenderClose(const struct DevHandle *handle, int cmdId, const struct AudioHwRenderParam *handleData)
1083 {
1084     int32_t ret;
1085     struct AudioCardInfo *alsaCardIns = NULL;
1086 
1087     (void)cmdId;
1088     if (handle == NULL || handleData == NULL) {
1089         AUDIO_FUNC_LOGE("parameter error!!");
1090         return HDF_FAILURE;
1091     }
1092 
1093     const char *adapterName = handleData->renderMode.hwInfo.adapterName;
1094     /* Gets the specified sound card instance */
1095     alsaCardIns = GetCardIns(adapterName);
1096     if (alsaCardIns == NULL) {
1097         AUDIO_FUNC_LOGE("cardInstance is empty pointer!");
1098         return HDF_FAILURE;
1099     }
1100 
1101     if (alsaCardIns->renderPcmHandle != NULL) {
1102         ret = snd_pcm_close(alsaCardIns->renderPcmHandle);
1103         if (ret < 0) {
1104             AUDIO_FUNC_LOGE("snd_pcm_close fail: %{public}s", snd_strerror(ret));
1105         }
1106         alsaCardIns->renderPcmHandle = NULL;
1107     }
1108 
1109     if (alsaCardIns->cardStatus > 0) {
1110         alsaCardIns->cardStatus -= 1;
1111     }
1112     if (alsaCardIns->cardStatus == 0) {
1113         if (alsaCardIns->mixer != NULL) {
1114             ret = snd_mixer_close(alsaCardIns->mixer);
1115             if (ret < 0) {
1116                 AUDIO_FUNC_LOGE("snd_mixer_close fail: %{public}s", snd_strerror(ret));
1117             }
1118             alsaCardIns->mixer = NULL;
1119         }
1120         (void)memset_s(alsaCardIns->cardName, MAX_CARD_NAME_LEN + 1, 0, MAX_CARD_NAME_LEN + 1);
1121         ret = DestroyCardList();
1122         if (ret != HDF_SUCCESS) {
1123             AUDIO_FUNC_LOGE("DestroyCardList failed, reason: %{public}d.", ret);
1124             return ret;
1125         }
1126     }
1127 
1128     return HDF_SUCCESS;
1129 }
1130 
AudioOutputRenderStart(const struct DevHandle * handle,int cmdId,const struct AudioHwRenderParam * handleData)1131 int32_t AudioOutputRenderStart(const struct DevHandle *handle, int cmdId, const struct AudioHwRenderParam *handleData)
1132 {
1133     (void)cmdId;
1134     if (handle == NULL || handleData == NULL) {
1135         AUDIO_FUNC_LOGE("Parameter error!");
1136         return HDF_FAILURE;
1137     }
1138 
1139     return HDF_SUCCESS;
1140 }
1141 
RenderWriteiMmap(const struct AudioHwRenderParam * handleData,struct AudioCardInfo * cardIns)1142 static int32_t RenderWriteiMmap(const struct AudioHwRenderParam *handleData, struct AudioCardInfo *cardIns)
1143 {
1144     int32_t ret;
1145     uint32_t frameSize;
1146     uint32_t totalSize;
1147     uint32_t lastBuffSize;
1148     uint32_t loopTimes;
1149     uint32_t looper = 0;
1150     uint32_t copyLen;
1151     int32_t count = 0;
1152     struct AudioMmapBufferDescripter *mmapBufDesc = NULL;
1153 
1154     if (handleData == NULL || cardIns == NULL) {
1155         AUDIO_FUNC_LOGE("Parameter error!");
1156         return HDF_FAILURE;
1157     }
1158 
1159     frameSize = cardIns->hwRenderParams.channels * cardIns->hwRenderParams.format;
1160     if (frameSize == 0) {
1161         AUDIO_FUNC_LOGE("frame size = 0!");
1162         return HDF_FAILURE;
1163     }
1164     mmapBufDesc = (struct AudioMmapBufferDescripter *)&(handleData->frameRenderMode.mmapBufDesc);
1165     totalSize = (uint32_t)mmapBufDesc->totalBufferFrames * frameSize;
1166     lastBuffSize = ((totalSize % MIN_PERIOD_SIZE) == 0) ? MIN_PERIOD_SIZE : (totalSize % MIN_PERIOD_SIZE);
1167     loopTimes = (lastBuffSize == MIN_PERIOD_SIZE) ? (totalSize / MIN_PERIOD_SIZE) : (totalSize / MIN_PERIOD_SIZE + 1);
1168     while (looper < loopTimes) {
1169         copyLen = (looper < (loopTimes - 1)) ? MIN_PERIOD_SIZE : lastBuffSize;
1170         snd_pcm_uframes_t frames = (snd_pcm_uframes_t)(copyLen / frameSize);
1171         ret = snd_pcm_mmap_writei(
1172             cardIns->renderPcmHandle, (char *)mmapBufDesc->memoryAddress + mmapBufDesc->offset, frames);
1173         if (ret == -EAGAIN) {
1174             count++;
1175             if (count > AUDIO_ALSALIB_MMAP_MAX) {
1176                 AUDIO_FUNC_LOGE("loop > max !");
1177                 return HDF_FAILURE;
1178             }
1179             continue;
1180         }
1181         count = 0;
1182         if (ret < 0) {
1183             AUDIO_FUNC_LOGE("Write error: %{public}s\n", snd_strerror(ret));
1184             return HDF_FAILURE;
1185         }
1186         looper++;
1187         mmapBufDesc->offset += copyLen;
1188         cardIns->renderMmapFrames += (uint64_t)frames;
1189     }
1190 
1191     return HDF_SUCCESS;
1192 }
1193 
AudioOutputRenderReqMmapBuffer(const struct DevHandle * handle,int cmdId,const struct AudioHwRenderParam * handleData)1194 int32_t AudioOutputRenderReqMmapBuffer(
1195     const struct DevHandle *handle, int cmdId, const struct AudioHwRenderParam *handleData)
1196 {
1197     int32_t ret;
1198     struct AudioCardInfo *mmapCardIns = NULL;
1199 
1200     (void)cmdId;
1201     if (handle == NULL || handleData == NULL) {
1202         AUDIO_FUNC_LOGE("Parameter error!");
1203         return HDF_FAILURE;
1204     }
1205 
1206     const char *adapterName = handleData->renderMode.hwInfo.adapterName;
1207     mmapCardIns = GetCardIns(adapterName);
1208     if (mmapCardIns == NULL) {
1209         AUDIO_FUNC_LOGE("cardInstance is NULL!");
1210         return HDF_FAILURE;
1211     }
1212     mmapCardIns->renderMmapFlag = false;
1213 
1214     ret = AudioResetParams(mmapCardIns->renderPcmHandle, mmapCardIns->hwRenderParams, SND_PCM_ACCESS_MMAP_INTERLEAVED);
1215     if (ret < 0) {
1216         AUDIO_FUNC_LOGE("AudioSetParamsMmap failed!");
1217         return HDF_FAILURE;
1218     }
1219 
1220     ret = RenderWriteiMmap(handleData, mmapCardIns);
1221     if (ret < 0) {
1222         AUDIO_FUNC_LOGE("RenderWriteiMmap error!");
1223         return HDF_FAILURE;
1224     }
1225 
1226     return HDF_SUCCESS;
1227 }
1228 
AudioOutputRenderGetMmapPosition(const struct DevHandle * handle,int cmdId,struct AudioHwRenderParam * handleData)1229 int32_t AudioOutputRenderGetMmapPosition(
1230     const struct DevHandle *handle, int cmdId, struct AudioHwRenderParam *handleData)
1231 {
1232     struct AudioCardInfo *alsaMmapCardIns = NULL;
1233 
1234     (void)cmdId;
1235     if (handle == NULL || handleData == NULL) {
1236         AUDIO_FUNC_LOGE("Parameter error!");
1237         return HDF_FAILURE;
1238     }
1239 
1240     /* Get the ALSA sound card instance corresponding to AdapterName */
1241     const char *adapterName = handleData->renderMode.hwInfo.adapterName;
1242     alsaMmapCardIns = GetCardIns(adapterName);
1243     if (alsaMmapCardIns == NULL) {
1244         AUDIO_FUNC_LOGE("Can't find card Instance!");
1245         return HDF_FAILURE;
1246     }
1247     handleData->frameRenderMode.frames = alsaMmapCardIns->renderMmapFrames;
1248 
1249     return HDF_SUCCESS;
1250 }
1251 
AudioInterfaceLibOutputRender(const struct DevHandle * handle,int cmdId,struct AudioHwRenderParam * handleData)1252 int32_t AudioInterfaceLibOutputRender(const struct DevHandle *handle, int cmdId, struct AudioHwRenderParam *handleData)
1253 {
1254     int32_t ret;
1255 
1256     if (handle == NULL || handleData == NULL) {
1257         AUDIO_FUNC_LOGE("Parameter error!");
1258         return HDF_FAILURE;
1259     }
1260 
1261     if (handle->object == NULL) {
1262         AUDIO_FUNC_LOGE("handle's object is null!");
1263         return HDF_FAILURE;
1264     }
1265 
1266     switch (cmdId) {
1267         case AUDIO_DRV_PCM_IOCTL_HW_PARAMS:
1268             ret = AudioOutputRenderHwParams(handle, cmdId, handleData);
1269             break;
1270         case AUDIO_DRV_PCM_IOCTL_WRITE:
1271             ret = AudioOutputRenderWrite(handle, cmdId, handleData);
1272             break;
1273         case AUDIO_DRV_PCM_IOCTRL_STOP:
1274             ret = AudioOutputRenderStop(handle, cmdId, handleData);
1275             break;
1276         case AUDIO_DRV_PCM_IOCTRL_START:
1277             ret = AudioOutputRenderStart(handle, cmdId, handleData);
1278             break;
1279         case AUDIO_DRV_PCM_IOCTL_PREPARE:
1280             ret = AudioOutputRenderPrepare(handle, cmdId, handleData);
1281             break;
1282         case AUDIO_DRV_PCM_IOCTRL_RENDER_CLOSE:
1283             ret = AudioOutputRenderClose(handle, cmdId, handleData);
1284             break;
1285         case AUDIO_DRV_PCM_IOCTRL_RENDER_OPEN:
1286             ret = AudioOutputRenderOpen(handle, cmdId, handleData);
1287             break;
1288         case AUDIODRV_CTL_IOCTL_PAUSE_WRITE:
1289             ret = AudioCtlRenderSetPauseStu(handle, cmdId, handleData);
1290             break;
1291         case AUDIO_DRV_PCM_IOCTL_MMAP_BUFFER:
1292             ret = AudioOutputRenderReqMmapBuffer(handle, cmdId, handleData);
1293             break;
1294         case AUDIO_DRV_PCM_IOCTL_MMAP_POSITION:
1295             ret = (AudioOutputRenderGetMmapPosition(handle, cmdId, handleData));
1296             break;
1297         default:
1298             AUDIO_FUNC_LOGE("Output Mode not support!");
1299             ret = HDF_FAILURE;
1300             break;
1301     }
1302 
1303     return ret;
1304 }
1305 
AudioBindServiceRenderObject(struct DevHandle * handle,const char * name)1306 int32_t AudioBindServiceRenderObject(struct DevHandle *handle, const char *name)
1307 {
1308     int32_t ret;
1309     struct HdfIoService *service = NULL;
1310 
1311     if (handle == NULL || name == NULL) {
1312         AUDIO_FUNC_LOGE("Parameter error!");
1313         return HDF_FAILURE;
1314     }
1315 
1316     char *serviceName = (char *)OsalMemCalloc(NAME_LEN);
1317     if (serviceName == NULL) {
1318         AUDIO_FUNC_LOGE("Failed to OsalMemCalloc memory!");
1319         return HDF_FAILURE;
1320     }
1321 
1322     ret = snprintf_s(serviceName, NAME_LEN - 1, SERVIC_NAME_MAX_LEN + 1, "hdf_audio_%s", name);
1323     if (ret < 0) {
1324         AUDIO_FUNC_LOGE("Render: Failed to snprintf_s");
1325         AudioMemFree((void **)&serviceName);
1326         return HDF_FAILURE;
1327     }
1328 
1329     service = HdfIoServiceBindName(serviceName);
1330     if (service == NULL) {
1331         AUDIO_FUNC_LOGE("Render: Failed to get service!");
1332         AudioMemFree((void **)&serviceName);
1333         return HDF_FAILURE;
1334     }
1335     AudioMemFree((void **)&serviceName);
1336     handle->object = service;
1337 
1338     return HDF_SUCCESS;
1339 }
1340 
1341 /* CreatRender for Bind handle */
AudioBindServiceRender(const char * name)1342 struct DevHandle *AudioBindServiceRender(const char *name)
1343 {
1344     int32_t ret;
1345 
1346     if (name == NULL) {
1347         AUDIO_FUNC_LOGE("service name NULL!");
1348         return NULL;
1349     }
1350 
1351     struct DevHandle *handle = (struct DevHandle *)OsalMemCalloc(sizeof(struct DevHandle));
1352     if (handle == NULL) {
1353         AUDIO_FUNC_LOGE("OsalMemCalloc handle failed!!!");
1354         return NULL;
1355     }
1356 
1357     ret = AudioBindServiceRenderObject(handle, name);
1358     if (ret != HDF_SUCCESS) {
1359         AUDIO_FUNC_LOGE("Bind Service Render Object failed!");
1360         AudioMemFree((void **)&handle);
1361         return NULL;
1362     }
1363 
1364     /* Render: Parsing primary sound card from configuration file */
1365     ret = CardInfoParseFromConfig();
1366     if (ret != HDF_SUCCESS) {
1367         AUDIO_FUNC_LOGE("Render: parse config file failed!");
1368         AudioMemFree((void **)&handle);
1369         return NULL;
1370     }
1371     AUDIO_FUNC_LOGI("BIND SERVICE SUCCESS!");
1372 
1373     return handle;
1374 }
1375 
AudioCloseServiceRender(const struct DevHandle * handle)1376 void AudioCloseServiceRender(const struct DevHandle *handle)
1377 {
1378     if (handle != NULL) {
1379         if (handle->object == NULL) {
1380             AUDIO_FUNC_LOGE("Render handle or handle->object is NULL");
1381         }
1382         AudioMemFree((void **)&handle);
1383     }
1384 }
1385 
AudioInterfaceLibModeRender(const struct DevHandle * handle,struct AudioHwRenderParam * handleData,int cmdId)1386 int32_t AudioInterfaceLibModeRender(const struct DevHandle *handle, struct AudioHwRenderParam *handleData, int cmdId)
1387 {
1388     if (handle == NULL || handleData == NULL) {
1389         AUDIO_FUNC_LOGE("paras is NULL!");
1390         return HDF_FAILURE;
1391     }
1392 
1393     switch (cmdId) {
1394         case AUDIO_DRV_PCM_IOCTL_HW_PARAMS:
1395         case AUDIO_DRV_PCM_IOCTL_WRITE:
1396         case AUDIO_DRV_PCM_IOCTRL_STOP:
1397         case AUDIO_DRV_PCM_IOCTRL_START:
1398         case AUDIO_DRV_PCM_IOCTL_PREPARE:
1399         case AUDIODRV_CTL_IOCTL_PAUSE_WRITE:
1400         case AUDIO_DRV_PCM_IOCTL_MMAP_BUFFER:
1401         case AUDIO_DRV_PCM_IOCTL_MMAP_POSITION:
1402         case AUDIO_DRV_PCM_IOCTRL_RENDER_OPEN:
1403         case AUDIO_DRV_PCM_IOCTRL_RENDER_CLOSE:
1404             return (AudioInterfaceLibOutputRender(handle, cmdId, handleData));
1405         case AUDIODRV_CTL_IOCTL_ELEM_WRITE:
1406         case AUDIODRV_CTL_IOCTL_ELEM_READ:
1407         case AUDIODRV_CTL_IOCTL_MUTE_WRITE:
1408         case AUDIODRV_CTL_IOCTL_MUTE_READ:
1409         case AUDIODRV_CTL_IOCTL_GAIN_WRITE:
1410         case AUDIODRV_CTL_IOCTL_GAIN_READ:
1411         case AUDIODRV_CTL_IOCTL_CHANNEL_MODE_WRITE:
1412         case AUDIODRV_CTL_IOCTL_CHANNEL_MODE_READ:
1413         case AUDIODRV_CTL_IOCTL_SCENESELECT_WRITE:
1414         case AUDIODRV_CTL_IOCTL_GAINTHRESHOLD_READ:
1415         case AUDIODRV_CTL_IOCTL_VOL_THRESHOLD_READ:
1416             return (AudioInterfaceLibCtlRender(handle, cmdId, handleData));
1417         default:
1418             AUDIO_FUNC_LOGE("Mode Error!");
1419             break;
1420     }
1421     return HDF_ERR_NOT_SUPPORT;
1422 }
1423