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