1 /*
2  * Copyright (c) 2024 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_snd_render.h"
17 #include "common.h"
18 
19 #define HDF_LOG_TAG HDF_AUDIO_HAL_RENDER
20 
21 typedef struct RenderData {
22     struct AlsaMixerCtlElement ctrlLeftVolume;
23     struct AlsaMixerCtlElement ctrlRightVolume;
24     long tempVolume;
25 } RenderData;
26 
RenderInitImpl(struct AlsaRender *renderIns)27 static int32_t RenderInitImpl(struct AlsaRender *renderIns)
28 {
29     CHECK_NULL_PTR_RETURN_DEFAULT(renderIns);
30     if (renderIns->priData != NULL) {
31         return HDF_SUCCESS;
32     }
33 
34     RenderData *priData = (RenderData *)OsalMemCalloc(sizeof(RenderData));
35     if (priData == NULL) {
36         AUDIO_FUNC_LOGE("Failed to allocate memory!");
37         return HDF_FAILURE;
38     }
39 
40     SndElementItemInit(&priData->ctrlLeftVolume);
41     SndElementItemInit(&priData->ctrlRightVolume);
42     priData->ctrlLeftVolume.numid = SND_NUMID_DACL_PLAYBACK_VOL;
43     priData->ctrlLeftVolume.name = SND_ELEM_DACL_PLAYBACK_VOL;
44     priData->ctrlRightVolume.numid = SND_NUMID_DACR_PLAYBACK_VOL;
45     priData->ctrlRightVolume.name = SND_ELEM_DACR_PLAYBACK_VOL;
46     RenderSetPriData(renderIns, (RenderPriData)priData);
47 
48     return HDF_SUCCESS;
49 }
50 
RenderSelectSceneImpl(struct AlsaRender *renderIns, enum AudioPortPin descPins, const struct PathDeviceInfo *deviceInfo)51 static int32_t RenderSelectSceneImpl(struct AlsaRender *renderIns, enum AudioPortPin descPins,
52     const struct PathDeviceInfo *deviceInfo)
53 {
54     CHECK_NULL_PTR_RETURN_DEFAULT(renderIns);
55     renderIns->descPins = descPins;
56     return HDF_SUCCESS;
57 }
58 
RenderGetVolThresholdImpl(struct AlsaRender *renderIns, long *volMin, long *volMax)59 static int32_t RenderGetVolThresholdImpl(struct AlsaRender *renderIns, long *volMin, long *volMax)
60 {
61     CHECK_NULL_PTR_RETURN_DEFAULT(renderIns);
62     CHECK_NULL_PTR_RETURN_DEFAULT(volMin);
63     CHECK_NULL_PTR_RETURN_DEFAULT(volMax);
64     int32_t ret = HDF_SUCCESS;
65     long volMinTmp = 0;
66     long volMaxTmp = 0;
67     struct AlsaSoundCard *cardIns = (struct AlsaSoundCard *)renderIns;
68     RenderData *priData = RenderGetPriData(renderIns);
69     CHECK_NULL_PTR_RETURN_DEFAULT(cardIns);
70     CHECK_NULL_PTR_RETURN_DEFAULT(priData);
71 
72     ret = SndElementReadRange(cardIns, &priData->ctrlLeftVolume, &volMinTmp, &volMaxTmp);
73     if (ret != HDF_SUCCESS) {
74         AUDIO_FUNC_LOGE("SndElementReadRange fail!");
75         return HDF_FAILURE;
76     }
77     *volMin = volMinTmp;
78     *volMax = volMaxTmp;
79 
80     return HDF_SUCCESS;
81 }
82 
RenderGetVolumeImpl(struct AlsaRender *renderIns, long *volume)83 static int32_t RenderGetVolumeImpl(struct AlsaRender *renderIns, long *volume)
84 {
85     CHECK_NULL_PTR_RETURN_DEFAULT(renderIns);
86     CHECK_NULL_PTR_RETURN_DEFAULT(volume);
87     int32_t ret = HDF_SUCCESS;
88     long volLeft = 0;
89     long volRight = 0;
90     struct AlsaSoundCard *cardIns = (struct AlsaSoundCard *)renderIns;
91     RenderData *priData = RenderGetPriData(renderIns);
92     CHECK_NULL_PTR_RETURN_DEFAULT(cardIns);
93     CHECK_NULL_PTR_RETURN_DEFAULT(priData);
94 
95     ret = SndElementReadInt(cardIns, &priData->ctrlLeftVolume, &volLeft);
96     if (ret != HDF_SUCCESS) {
97         AUDIO_FUNC_LOGE("Read left volume fail!");
98         return HDF_FAILURE;
99     }
100     ret = SndElementReadInt(cardIns, &priData->ctrlRightVolume, &volRight);
101     if (ret != HDF_SUCCESS) {
102         AUDIO_FUNC_LOGE("Read right volume fail!");
103         return HDF_FAILURE;
104     }
105     *volume = (volLeft + volRight) >> 1;
106 
107     return HDF_SUCCESS;
108 }
109 
RenderSetVolumeImpl(struct AlsaRender *renderIns, long volume)110 static int32_t RenderSetVolumeImpl(struct AlsaRender *renderIns, long volume)
111 {
112     CHECK_NULL_PTR_RETURN_DEFAULT(renderIns);
113     int32_t ret = HDF_SUCCESS;
114     struct AlsaSoundCard *cardIns = (struct AlsaSoundCard *)renderIns;
115     RenderData *priData = RenderGetPriData(renderIns);
116     CHECK_NULL_PTR_RETURN_DEFAULT(cardIns);
117     CHECK_NULL_PTR_RETURN_DEFAULT(priData);
118 
119     ret = SndElementWriteInt(cardIns, &priData->ctrlLeftVolume, volume);
120     if (ret != HDF_SUCCESS) {
121         AUDIO_FUNC_LOGE("Write left volume fail!");
122         return HDF_FAILURE;
123     }
124     ret = SndElementWriteInt(cardIns, &priData->ctrlRightVolume, volume);
125     if (ret != HDF_SUCCESS) {
126         AUDIO_FUNC_LOGE("Write right volume fail!");
127         return HDF_FAILURE;
128     }
129 
130     return HDF_SUCCESS;
131 }
132 
RenderGetMuteImpl(struct AlsaRender *renderIns)133 static bool RenderGetMuteImpl(struct AlsaRender *renderIns)
134 {
135     CHECK_NULL_PTR_RETURN_DEFAULT(renderIns);
136     return renderIns->muteState;
137 }
138 
RenderSetMuteImpl(struct AlsaRender *renderIns, bool muteFlag)139 static int32_t RenderSetMuteImpl(struct AlsaRender *renderIns, bool muteFlag)
140 {
141     CHECK_NULL_PTR_RETURN_DEFAULT(renderIns);
142     int32_t ret = HDF_SUCCESS;
143     long vol = 0;
144     long setVol = 0;
145     RenderData *priData = RenderGetPriData(renderIns);
146     CHECK_NULL_PTR_RETURN_DEFAULT(renderIns);
147     CHECK_NULL_PTR_RETURN_DEFAULT(priData);
148 
149     ret = renderIns->GetVolume(renderIns, &vol);
150     if (ret != HDF_SUCCESS) {
151         AUDIO_FUNC_LOGE("GetVolume failed!");
152         return HDF_FAILURE;
153     }
154 
155     if (muteFlag) {
156         priData->tempVolume = vol;
157         setVol = 0;
158     } else {
159         setVol = priData->tempVolume;
160     }
161 
162     renderIns->SetVolume(renderIns, setVol);
163     if (ret != HDF_SUCCESS) {
164         AUDIO_FUNC_LOGE("SetVolume failed!");
165         return HDF_FAILURE;
166     }
167     renderIns->muteState = muteFlag;
168 
169     return HDF_SUCCESS;
170 }
171 
RenderStartImpl(struct AlsaRender *renderIns)172 static int32_t RenderStartImpl(struct AlsaRender *renderIns)
173 {
174     return HDF_SUCCESS;
175 }
176 
RenderStopImpl(struct AlsaRender *renderIns)177 static int32_t RenderStopImpl(struct AlsaRender *renderIns)
178 {
179     CHECK_NULL_PTR_RETURN_DEFAULT(renderIns);
180     snd_pcm_drain(renderIns->soundCard.pcmHandle);
181     return HDF_SUCCESS;
182 }
183 
RenderGetGainThresholdImpl(struct AlsaRender *renderIns, float *gainMin, float *gainMax)184 static int32_t RenderGetGainThresholdImpl(struct AlsaRender *renderIns, float *gainMin, float *gainMax)
185 {
186     AUDIO_FUNC_LOGI("emulator not support gain operation");
187     return HDF_SUCCESS;
188 }
189 
RenderGetGainImpl(struct AlsaRender *renderIns, float *volume)190 static int32_t RenderGetGainImpl(struct AlsaRender *renderIns, float *volume)
191 {
192     AUDIO_FUNC_LOGI("emulator not support gain operation");
193     return HDF_SUCCESS;
194 }
195 
RenderSetGainImpl(struct AlsaRender *renderIns, float volume)196 static int32_t RenderSetGainImpl(struct AlsaRender *renderIns, float volume)
197 {
198     AUDIO_FUNC_LOGI("emulator not support gain operation");
199     return HDF_SUCCESS;
200 }
201 
RenderGetChannelModeImpl(struct AlsaRender *renderIns, enum AudioChannelMode *mode)202 static int32_t RenderGetChannelModeImpl(struct AlsaRender *renderIns, enum AudioChannelMode *mode)
203 {
204     return HDF_SUCCESS;
205 }
206 
RenderSetChannelModeImpl(struct AlsaRender *renderIns, enum AudioChannelMode mode)207 static int32_t RenderSetChannelModeImpl(struct AlsaRender *renderIns, enum AudioChannelMode mode)
208 {
209     return HDF_SUCCESS;
210 }
211 
RenderOverrideFunc(struct AlsaRender *renderIns)212 int32_t RenderOverrideFunc(struct AlsaRender *renderIns)
213 {
214     CHECK_NULL_PTR_RETURN_DEFAULT(renderIns);
215     struct AlsaSoundCard *cardIns = (struct AlsaSoundCard *)renderIns;
216 
217     if (cardIns->cardType == SND_CARD_PRIMARY) {
218         renderIns->Init = RenderInitImpl;
219         renderIns->SelectScene = RenderSelectSceneImpl;
220         renderIns->Start = RenderStartImpl;
221         renderIns->Stop = RenderStopImpl;
222         renderIns->GetVolThreshold = RenderGetVolThresholdImpl;
223         renderIns->GetVolume = RenderGetVolumeImpl;
224         renderIns->SetVolume = RenderSetVolumeImpl;
225         renderIns->GetGainThreshold = RenderGetGainThresholdImpl;
226         renderIns->GetGain = RenderGetGainImpl;
227         renderIns->SetGain = RenderSetGainImpl;
228         renderIns->GetMute = RenderGetMuteImpl;
229         renderIns->SetMute = RenderSetMuteImpl;
230         renderIns->GetChannelMode = RenderGetChannelModeImpl;
231         renderIns->SetChannelMode = RenderSetChannelModeImpl;
232     }
233 
234     return HDF_SUCCESS;
235 }
236