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