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