18d6344f9Sopenharmony_ci/* 28d6344f9Sopenharmony_ci * Copyright (c) 2022 Huawei Device Co., Ltd. 38d6344f9Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 48d6344f9Sopenharmony_ci * you may not use this file except in compliance with the License. 58d6344f9Sopenharmony_ci * You may obtain a copy of the License at 68d6344f9Sopenharmony_ci * 78d6344f9Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 88d6344f9Sopenharmony_ci * 98d6344f9Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 108d6344f9Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 118d6344f9Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 128d6344f9Sopenharmony_ci * See the License for the specific language governing permissions and 138d6344f9Sopenharmony_ci * limitations under the License. 148d6344f9Sopenharmony_ci */ 158d6344f9Sopenharmony_ci 168d6344f9Sopenharmony_ci#include "alsa_snd_render.h" 178d6344f9Sopenharmony_ci#include "common.h" 188d6344f9Sopenharmony_ci 198d6344f9Sopenharmony_ci#define HDF_LOG_TAG HDF_AUDIO_HAL_RENDER 208d6344f9Sopenharmony_ci 218d6344f9Sopenharmony_citypedef struct _RENDER_DATA_ { 228d6344f9Sopenharmony_ci struct AlsaMixerCtlElement ctrlLeftVolume; 238d6344f9Sopenharmony_ci struct AlsaMixerCtlElement ctrlRightVolume; 248d6344f9Sopenharmony_ci long tempVolume; 258d6344f9Sopenharmony_ci}RenderData; 268d6344f9Sopenharmony_ci 278d6344f9Sopenharmony_cistatic int32_t RenderInitImpl(struct AlsaRender *renderIns) 288d6344f9Sopenharmony_ci{ 298d6344f9Sopenharmony_ci if (renderIns->priData != NULL) { 308d6344f9Sopenharmony_ci return HDF_SUCCESS; 318d6344f9Sopenharmony_ci } 328d6344f9Sopenharmony_ci CHECK_NULL_PTR_RETURN_DEFAULT(renderIns); 338d6344f9Sopenharmony_ci 348d6344f9Sopenharmony_ci RenderData *priData = (RenderData *)OsalMemCalloc(sizeof(RenderData)); 358d6344f9Sopenharmony_ci if (priData == NULL) { 368d6344f9Sopenharmony_ci AUDIO_FUNC_LOGE("Failed to allocate memory!"); 378d6344f9Sopenharmony_ci return HDF_FAILURE; 388d6344f9Sopenharmony_ci } 398d6344f9Sopenharmony_ci 408d6344f9Sopenharmony_ci SndElementItemInit(&priData->ctrlLeftVolume); 418d6344f9Sopenharmony_ci SndElementItemInit(&priData->ctrlRightVolume); 428d6344f9Sopenharmony_ci priData->ctrlLeftVolume.numid = SND_NUMID_DACL_PLAYBACK_VOL; 438d6344f9Sopenharmony_ci priData->ctrlLeftVolume.name = SND_ELEM_DACL_PLAYBACK_VOL; 448d6344f9Sopenharmony_ci priData->ctrlRightVolume.numid = SND_NUMID_DACR_PLAYBACK_VOL; 458d6344f9Sopenharmony_ci priData->ctrlRightVolume.name = SND_ELEM_DACR_PLAYBACK_VOL; 468d6344f9Sopenharmony_ci RenderSetPriData(renderIns, (RenderPriData)priData); 478d6344f9Sopenharmony_ci 488d6344f9Sopenharmony_ci return HDF_SUCCESS; 498d6344f9Sopenharmony_ci} 508d6344f9Sopenharmony_ci 518d6344f9Sopenharmony_cistatic int32_t RenderSelectSceneImpl(struct AlsaRender *renderIns, enum AudioPortPin descPins, 528d6344f9Sopenharmony_ci const struct PathDeviceInfo *deviceInfo) 538d6344f9Sopenharmony_ci{ 548d6344f9Sopenharmony_ci renderIns->descPins = descPins; 558d6344f9Sopenharmony_ci return HDF_SUCCESS; 568d6344f9Sopenharmony_ci} 578d6344f9Sopenharmony_ci 588d6344f9Sopenharmony_cistatic int32_t RenderGetVolThresholdImpl(struct AlsaRender *renderIns, long *volMin, long *volMax) 598d6344f9Sopenharmony_ci{ 608d6344f9Sopenharmony_ci int32_t ret; 618d6344f9Sopenharmony_ci long _volMin = 0; 628d6344f9Sopenharmony_ci long _volMax = 0; 638d6344f9Sopenharmony_ci struct AlsaSoundCard *cardIns = (struct AlsaSoundCard *)renderIns; 648d6344f9Sopenharmony_ci RenderData *priData = RenderGetPriData(renderIns); 658d6344f9Sopenharmony_ci CHECK_NULL_PTR_RETURN_DEFAULT(cardIns); 668d6344f9Sopenharmony_ci CHECK_NULL_PTR_RETURN_DEFAULT(priData); 678d6344f9Sopenharmony_ci 688d6344f9Sopenharmony_ci ret = SndElementReadRange(cardIns, &priData->ctrlLeftVolume, &_volMin, &_volMax); 698d6344f9Sopenharmony_ci if (ret != HDF_SUCCESS) { 708d6344f9Sopenharmony_ci AUDIO_FUNC_LOGE("SndElementReadRange fail!"); 718d6344f9Sopenharmony_ci return HDF_FAILURE; 728d6344f9Sopenharmony_ci } 738d6344f9Sopenharmony_ci *volMin = _volMin; 748d6344f9Sopenharmony_ci *volMax = _volMax; 758d6344f9Sopenharmony_ci 768d6344f9Sopenharmony_ci return HDF_SUCCESS; 778d6344f9Sopenharmony_ci} 788d6344f9Sopenharmony_ci 798d6344f9Sopenharmony_cistatic int32_t RenderGetVolumeImpl(struct AlsaRender *renderIns, long *volume) 808d6344f9Sopenharmony_ci{ 818d6344f9Sopenharmony_ci int32_t ret; 828d6344f9Sopenharmony_ci long volLeft = 0; 838d6344f9Sopenharmony_ci long volRight = 0; 848d6344f9Sopenharmony_ci struct AlsaSoundCard *cardIns = (struct AlsaSoundCard *)renderIns; 858d6344f9Sopenharmony_ci RenderData *priData = RenderGetPriData(renderIns); 868d6344f9Sopenharmony_ci CHECK_NULL_PTR_RETURN_DEFAULT(cardIns); 878d6344f9Sopenharmony_ci CHECK_NULL_PTR_RETURN_DEFAULT(priData); 888d6344f9Sopenharmony_ci 898d6344f9Sopenharmony_ci ret = SndElementReadInt(cardIns, &priData->ctrlLeftVolume, &volLeft); 908d6344f9Sopenharmony_ci if (ret != HDF_SUCCESS) { 918d6344f9Sopenharmony_ci AUDIO_FUNC_LOGE("Read left volume fail!"); 928d6344f9Sopenharmony_ci return HDF_FAILURE; 938d6344f9Sopenharmony_ci } 948d6344f9Sopenharmony_ci ret = SndElementReadInt(cardIns, &priData->ctrlRightVolume, &volRight); 958d6344f9Sopenharmony_ci if (ret != HDF_SUCCESS) { 968d6344f9Sopenharmony_ci AUDIO_FUNC_LOGE("Read right volume fail!"); 978d6344f9Sopenharmony_ci return HDF_FAILURE; 988d6344f9Sopenharmony_ci } 998d6344f9Sopenharmony_ci *volume = (volLeft + volRight) >> 1; 1008d6344f9Sopenharmony_ci 1018d6344f9Sopenharmony_ci return HDF_SUCCESS; 1028d6344f9Sopenharmony_ci} 1038d6344f9Sopenharmony_ci 1048d6344f9Sopenharmony_cistatic int32_t RenderSetVolumeImpl(struct AlsaRender *renderIns, long volume) 1058d6344f9Sopenharmony_ci{ 1068d6344f9Sopenharmony_ci int32_t ret; 1078d6344f9Sopenharmony_ci struct AlsaSoundCard *cardIns = (struct AlsaSoundCard *)renderIns; 1088d6344f9Sopenharmony_ci RenderData *priData = RenderGetPriData(renderIns); 1098d6344f9Sopenharmony_ci CHECK_NULL_PTR_RETURN_DEFAULT(cardIns); 1108d6344f9Sopenharmony_ci CHECK_NULL_PTR_RETURN_DEFAULT(priData); 1118d6344f9Sopenharmony_ci 1128d6344f9Sopenharmony_ci ret = SndElementWriteInt(cardIns, &priData->ctrlLeftVolume, volume); 1138d6344f9Sopenharmony_ci if (ret != HDF_SUCCESS) { 1148d6344f9Sopenharmony_ci AUDIO_FUNC_LOGE("Write left volume fail!"); 1158d6344f9Sopenharmony_ci return HDF_FAILURE; 1168d6344f9Sopenharmony_ci } 1178d6344f9Sopenharmony_ci ret = SndElementWriteInt(cardIns, &priData->ctrlRightVolume, volume); 1188d6344f9Sopenharmony_ci if (ret != HDF_SUCCESS) { 1198d6344f9Sopenharmony_ci AUDIO_FUNC_LOGE("Write right volume fail!"); 1208d6344f9Sopenharmony_ci return HDF_FAILURE; 1218d6344f9Sopenharmony_ci } 1228d6344f9Sopenharmony_ci 1238d6344f9Sopenharmony_ci return HDF_SUCCESS; 1248d6344f9Sopenharmony_ci} 1258d6344f9Sopenharmony_ci 1268d6344f9Sopenharmony_cistatic bool RenderGetMuteImpl(struct AlsaRender *renderIns) 1278d6344f9Sopenharmony_ci{ 1288d6344f9Sopenharmony_ci return renderIns->muteState; 1298d6344f9Sopenharmony_ci} 1308d6344f9Sopenharmony_ci 1318d6344f9Sopenharmony_cistatic int32_t RenderSetMuteImpl(struct AlsaRender *renderIns, bool muteFlag) 1328d6344f9Sopenharmony_ci{ 1338d6344f9Sopenharmony_ci int32_t ret; 1348d6344f9Sopenharmony_ci long vol, setVol; 1358d6344f9Sopenharmony_ci RenderData *priData = RenderGetPriData(renderIns); 1368d6344f9Sopenharmony_ci CHECK_NULL_PTR_RETURN_DEFAULT(renderIns); 1378d6344f9Sopenharmony_ci CHECK_NULL_PTR_RETURN_DEFAULT(priData); 1388d6344f9Sopenharmony_ci 1398d6344f9Sopenharmony_ci ret = renderIns->GetVolume(renderIns, &vol); 1408d6344f9Sopenharmony_ci if (ret != HDF_SUCCESS) { 1418d6344f9Sopenharmony_ci AUDIO_FUNC_LOGE("GetVolume failed!"); 1428d6344f9Sopenharmony_ci return HDF_FAILURE; 1438d6344f9Sopenharmony_ci } 1448d6344f9Sopenharmony_ci 1458d6344f9Sopenharmony_ci if (muteFlag) { 1468d6344f9Sopenharmony_ci priData->tempVolume = vol; 1478d6344f9Sopenharmony_ci setVol = 0; 1488d6344f9Sopenharmony_ci } else { 1498d6344f9Sopenharmony_ci setVol = priData->tempVolume; 1508d6344f9Sopenharmony_ci } 1518d6344f9Sopenharmony_ci 1528d6344f9Sopenharmony_ci renderIns->SetVolume(renderIns, setVol); 1538d6344f9Sopenharmony_ci if (ret != HDF_SUCCESS) { 1548d6344f9Sopenharmony_ci AUDIO_FUNC_LOGE("SetVolume failed!"); 1558d6344f9Sopenharmony_ci return HDF_FAILURE; 1568d6344f9Sopenharmony_ci } 1578d6344f9Sopenharmony_ci renderIns->muteState = muteFlag; 1588d6344f9Sopenharmony_ci 1598d6344f9Sopenharmony_ci return HDF_SUCCESS; 1608d6344f9Sopenharmony_ci} 1618d6344f9Sopenharmony_ci 1628d6344f9Sopenharmony_cistatic int32_t RenderStartImpl(struct AlsaRender *renderIns) 1638d6344f9Sopenharmony_ci{ 1648d6344f9Sopenharmony_ci int32_t ret; 1658d6344f9Sopenharmony_ci struct AlsaMixerCtlElement elem; 1668d6344f9Sopenharmony_ci struct AlsaSoundCard *cardIns = (struct AlsaSoundCard *)renderIns; 1678d6344f9Sopenharmony_ci 1688d6344f9Sopenharmony_ci SndElementItemInit(&elem); 1698d6344f9Sopenharmony_ci elem.numid = SND_NUMID_PLAYBACK_PATH; 1708d6344f9Sopenharmony_ci elem.name = SND_ELEM_PLAYBACK_PATH; 1718d6344f9Sopenharmony_ci switch (renderIns->descPins) { 1728d6344f9Sopenharmony_ci case PIN_OUT_SPEAKER: 1738d6344f9Sopenharmony_ci elem.value = SND_OUT_CARD_SPK_HP; 1748d6344f9Sopenharmony_ci break; 1758d6344f9Sopenharmony_ci case PIN_OUT_HEADSET: 1768d6344f9Sopenharmony_ci elem.value = SND_OUT_CARD_HP; 1778d6344f9Sopenharmony_ci break; 1788d6344f9Sopenharmony_ci default: 1798d6344f9Sopenharmony_ci elem.value = SND_OUT_CARD_SPK_HP; 1808d6344f9Sopenharmony_ci } 1818d6344f9Sopenharmony_ci 1828d6344f9Sopenharmony_ci ret = SndElementWrite(cardIns, &elem); 1838d6344f9Sopenharmony_ci if (ret != HDF_SUCCESS) { 1848d6344f9Sopenharmony_ci AUDIO_FUNC_LOGE("write render fail!"); 1858d6344f9Sopenharmony_ci return HDF_FAILURE; 1868d6344f9Sopenharmony_ci } 1878d6344f9Sopenharmony_ci 1888d6344f9Sopenharmony_ci return HDF_SUCCESS; 1898d6344f9Sopenharmony_ci} 1908d6344f9Sopenharmony_ci 1918d6344f9Sopenharmony_cistatic int32_t RenderStopImpl(struct AlsaRender *renderIns) 1928d6344f9Sopenharmony_ci{ 1938d6344f9Sopenharmony_ci CHECK_NULL_PTR_RETURN_DEFAULT(renderIns); 1948d6344f9Sopenharmony_ci int32_t ret; 1958d6344f9Sopenharmony_ci struct AlsaMixerCtlElement elem; 1968d6344f9Sopenharmony_ci struct AlsaSoundCard *cardIns = (struct AlsaSoundCard *)renderIns; 1978d6344f9Sopenharmony_ci CHECK_NULL_PTR_RETURN_DEFAULT(cardIns); 1988d6344f9Sopenharmony_ci CHECK_NULL_PTR_RETURN_DEFAULT(&renderIns->soundCard); 1998d6344f9Sopenharmony_ci 2008d6344f9Sopenharmony_ci SndElementItemInit(&elem); 2018d6344f9Sopenharmony_ci elem.numid = SND_NUMID_PLAYBACK_PATH; 2028d6344f9Sopenharmony_ci elem.name = SND_ELEM_PLAYBACK_PATH; 2038d6344f9Sopenharmony_ci elem.value = SND_OUT_CARD_OFF; 2048d6344f9Sopenharmony_ci ret = SndElementWrite(cardIns, &elem); 2058d6344f9Sopenharmony_ci if (ret != HDF_SUCCESS) { 2068d6344f9Sopenharmony_ci AUDIO_FUNC_LOGE("write render fail!"); 2078d6344f9Sopenharmony_ci return HDF_FAILURE; 2088d6344f9Sopenharmony_ci } 2098d6344f9Sopenharmony_ci 2108d6344f9Sopenharmony_ci CHECK_NULL_PTR_RETURN_DEFAULT(renderIns->soundCard.pcmHandle); 2118d6344f9Sopenharmony_ci 2128d6344f9Sopenharmony_ci snd_pcm_drain(renderIns->soundCard.pcmHandle); 2138d6344f9Sopenharmony_ci return HDF_SUCCESS; 2148d6344f9Sopenharmony_ci} 2158d6344f9Sopenharmony_ci 2168d6344f9Sopenharmony_cistatic int32_t RenderGetGainThresholdImpl(struct AlsaRender *renderIns, float *gainMin, float *gainMax) 2178d6344f9Sopenharmony_ci{ 2188d6344f9Sopenharmony_ci AUDIO_FUNC_LOGI("Not support gain operation"); 2198d6344f9Sopenharmony_ci return HDF_SUCCESS; 2208d6344f9Sopenharmony_ci} 2218d6344f9Sopenharmony_ci 2228d6344f9Sopenharmony_cistatic int32_t RenderGetGainImpl(struct AlsaRender *renderIns, float *volume) 2238d6344f9Sopenharmony_ci{ 2248d6344f9Sopenharmony_ci AUDIO_FUNC_LOGI("Not support gain operation"); 2258d6344f9Sopenharmony_ci return HDF_SUCCESS; 2268d6344f9Sopenharmony_ci} 2278d6344f9Sopenharmony_ci 2288d6344f9Sopenharmony_cistatic int32_t RenderSetGainImpl(struct AlsaRender *renderIns, float volume) 2298d6344f9Sopenharmony_ci{ 2308d6344f9Sopenharmony_ci AUDIO_FUNC_LOGI("Not support gain operation"); 2318d6344f9Sopenharmony_ci return HDF_SUCCESS; 2328d6344f9Sopenharmony_ci} 2338d6344f9Sopenharmony_ci 2348d6344f9Sopenharmony_cistatic int32_t RenderGetChannelModeImpl(struct AlsaRender *renderIns, enum AudioChannelMode *mode) 2358d6344f9Sopenharmony_ci{ 2368d6344f9Sopenharmony_ci return HDF_SUCCESS; 2378d6344f9Sopenharmony_ci} 2388d6344f9Sopenharmony_ci 2398d6344f9Sopenharmony_cistatic int32_t RenderSetChannelModeImpl(struct AlsaRender *renderIns, enum AudioChannelMode mode) 2408d6344f9Sopenharmony_ci{ 2418d6344f9Sopenharmony_ci return HDF_SUCCESS; 2428d6344f9Sopenharmony_ci} 2438d6344f9Sopenharmony_ci 2448d6344f9Sopenharmony_ciint32_t RenderOverrideFunc(struct AlsaRender *renderIns) 2458d6344f9Sopenharmony_ci{ 2468d6344f9Sopenharmony_ci struct AlsaSoundCard *cardIns = (struct AlsaSoundCard *)renderIns; 2478d6344f9Sopenharmony_ci 2488d6344f9Sopenharmony_ci if (cardIns->cardType == SND_CARD_PRIMARY) { 2498d6344f9Sopenharmony_ci renderIns->Init = RenderInitImpl; 2508d6344f9Sopenharmony_ci renderIns->SelectScene = RenderSelectSceneImpl; 2518d6344f9Sopenharmony_ci renderIns->Start = RenderStartImpl; 2528d6344f9Sopenharmony_ci renderIns->Stop = RenderStopImpl; 2538d6344f9Sopenharmony_ci renderIns->GetVolThreshold = RenderGetVolThresholdImpl; 2548d6344f9Sopenharmony_ci renderIns->GetVolume = RenderGetVolumeImpl; 2558d6344f9Sopenharmony_ci renderIns->SetVolume = RenderSetVolumeImpl; 2568d6344f9Sopenharmony_ci renderIns->GetGainThreshold = RenderGetGainThresholdImpl; 2578d6344f9Sopenharmony_ci renderIns->GetGain = RenderGetGainImpl; 2588d6344f9Sopenharmony_ci renderIns->SetGain = RenderSetGainImpl; 2598d6344f9Sopenharmony_ci renderIns->GetMute = RenderGetMuteImpl; 2608d6344f9Sopenharmony_ci renderIns->SetMute = RenderSetMuteImpl; 2618d6344f9Sopenharmony_ci renderIns->GetChannelMode = RenderGetChannelModeImpl; 2628d6344f9Sopenharmony_ci renderIns->SetChannelMode = RenderSetChannelModeImpl; 2638d6344f9Sopenharmony_ci } 2648d6344f9Sopenharmony_ci 2658d6344f9Sopenharmony_ci return HDF_SUCCESS; 2668d6344f9Sopenharmony_ci} 267