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