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