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