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_snd_render.h"
17 #include "common.h"
18
19 #define HDF_LOG_TAG HDF_AUDIO_HAL_RENDER
20
21 typedef struct _RENDER_DATA_ {
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 if (renderIns->priData != NULL) {
30 return HDF_SUCCESS;
31 }
32 CHECK_NULL_PTR_RETURN_DEFAULT(renderIns);
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 renderIns->descPins = descPins;
55 return HDF_SUCCESS;
56 }
57
RenderGetVolThresholdImpl(struct AlsaRender *renderIns, long *volMin, long *volMax)58 static int32_t RenderGetVolThresholdImpl(struct AlsaRender *renderIns, long *volMin, long *volMax)
59 {
60 int32_t ret;
61 long _volMin = 0;
62 long _volMax = 0;
63 struct AlsaSoundCard *cardIns = (struct AlsaSoundCard *)renderIns;
64 RenderData *priData = RenderGetPriData(renderIns);
65 CHECK_NULL_PTR_RETURN_DEFAULT(cardIns);
66 CHECK_NULL_PTR_RETURN_DEFAULT(priData);
67
68 ret = SndElementReadRange(cardIns, &priData->ctrlLeftVolume, &_volMin, &_volMax);
69 if (ret != HDF_SUCCESS) {
70 AUDIO_FUNC_LOGE("SndElementReadRange fail!");
71 return HDF_FAILURE;
72 }
73 *volMin = _volMin;
74 *volMax = _volMax;
75
76 return HDF_SUCCESS;
77 }
78
RenderGetVolumeImpl(struct AlsaRender *renderIns, long *volume)79 static int32_t RenderGetVolumeImpl(struct AlsaRender *renderIns, long *volume)
80 {
81 int32_t ret;
82 long volLeft = 0;
83 long volRight = 0;
84 struct AlsaSoundCard *cardIns = (struct AlsaSoundCard *)renderIns;
85 RenderData *priData = RenderGetPriData(renderIns);
86 CHECK_NULL_PTR_RETURN_DEFAULT(cardIns);
87 CHECK_NULL_PTR_RETURN_DEFAULT(priData);
88
89 ret = SndElementReadInt(cardIns, &priData->ctrlLeftVolume, &volLeft);
90 if (ret != HDF_SUCCESS) {
91 AUDIO_FUNC_LOGE("Read left volume fail!");
92 return HDF_FAILURE;
93 }
94 ret = SndElementReadInt(cardIns, &priData->ctrlRightVolume, &volRight);
95 if (ret != HDF_SUCCESS) {
96 AUDIO_FUNC_LOGE("Read right volume fail!");
97 return HDF_FAILURE;
98 }
99 *volume = (volLeft + volRight) >> 1;
100
101 return HDF_SUCCESS;
102 }
103
RenderSetVolumeImpl(struct AlsaRender *renderIns, long volume)104 static int32_t RenderSetVolumeImpl(struct AlsaRender *renderIns, long volume)
105 {
106 int32_t ret;
107 struct AlsaSoundCard *cardIns = (struct AlsaSoundCard *)renderIns;
108 RenderData *priData = RenderGetPriData(renderIns);
109 CHECK_NULL_PTR_RETURN_DEFAULT(cardIns);
110 CHECK_NULL_PTR_RETURN_DEFAULT(priData);
111
112 ret = SndElementWriteInt(cardIns, &priData->ctrlLeftVolume, volume);
113 if (ret != HDF_SUCCESS) {
114 AUDIO_FUNC_LOGE("Write left volume fail!");
115 return HDF_FAILURE;
116 }
117 ret = SndElementWriteInt(cardIns, &priData->ctrlRightVolume, volume);
118 if (ret != HDF_SUCCESS) {
119 AUDIO_FUNC_LOGE("Write right volume fail!");
120 return HDF_FAILURE;
121 }
122
123 return HDF_SUCCESS;
124 }
125
RenderGetMuteImpl(struct AlsaRender *renderIns)126 static bool RenderGetMuteImpl(struct AlsaRender *renderIns)
127 {
128 return renderIns->muteState;
129 }
130
RenderSetMuteImpl(struct AlsaRender *renderIns, bool muteFlag)131 static int32_t RenderSetMuteImpl(struct AlsaRender *renderIns, bool muteFlag)
132 {
133 int32_t ret;
134 long vol, setVol;
135 RenderData *priData = RenderGetPriData(renderIns);
136 CHECK_NULL_PTR_RETURN_DEFAULT(renderIns);
137 CHECK_NULL_PTR_RETURN_DEFAULT(priData);
138
139 ret = renderIns->GetVolume(renderIns, &vol);
140 if (ret != HDF_SUCCESS) {
141 AUDIO_FUNC_LOGE("GetVolume failed!");
142 return HDF_FAILURE;
143 }
144
145 if (muteFlag) {
146 priData->tempVolume = vol;
147 setVol = 0;
148 } else {
149 setVol = priData->tempVolume;
150 }
151
152 renderIns->SetVolume(renderIns, setVol);
153 if (ret != HDF_SUCCESS) {
154 AUDIO_FUNC_LOGE("SetVolume failed!");
155 return HDF_FAILURE;
156 }
157 renderIns->muteState = muteFlag;
158
159 return HDF_SUCCESS;
160 }
161
RenderStartImpl(struct AlsaRender *renderIns)162 static int32_t RenderStartImpl(struct AlsaRender *renderIns)
163 {
164 int32_t ret;
165 struct AlsaMixerCtlElement elem;
166 struct AlsaSoundCard *cardIns = (struct AlsaSoundCard *)renderIns;
167
168 SndElementItemInit(&elem);
169 elem.numid = SND_NUMID_PLAYBACK_PATH;
170 elem.name = SND_ELEM_PLAYBACK_PATH;
171 switch (renderIns->descPins) {
172 case PIN_OUT_SPEAKER:
173 elem.value = SND_OUT_CARD_SPK_HP;
174 break;
175 case PIN_OUT_HEADSET:
176 elem.value = SND_OUT_CARD_HP;
177 break;
178 default:
179 elem.value = SND_OUT_CARD_SPK_HP;
180 }
181
182 ret = SndElementWrite(cardIns, &elem);
183 if (ret != HDF_SUCCESS) {
184 AUDIO_FUNC_LOGE("write render fail!");
185 return HDF_FAILURE;
186 }
187
188 return HDF_SUCCESS;
189 }
190
RenderStopImpl(struct AlsaRender *renderIns)191 static int32_t RenderStopImpl(struct AlsaRender *renderIns)
192 {
193 CHECK_NULL_PTR_RETURN_DEFAULT(renderIns);
194 int32_t ret;
195 struct AlsaMixerCtlElement elem;
196 struct AlsaSoundCard *cardIns = (struct AlsaSoundCard *)renderIns;
197 CHECK_NULL_PTR_RETURN_DEFAULT(cardIns);
198 CHECK_NULL_PTR_RETURN_DEFAULT(&renderIns->soundCard);
199
200 SndElementItemInit(&elem);
201 elem.numid = SND_NUMID_PLAYBACK_PATH;
202 elem.name = SND_ELEM_PLAYBACK_PATH;
203 elem.value = SND_OUT_CARD_OFF;
204 ret = SndElementWrite(cardIns, &elem);
205 if (ret != HDF_SUCCESS) {
206 AUDIO_FUNC_LOGE("write render fail!");
207 return HDF_FAILURE;
208 }
209
210 CHECK_NULL_PTR_RETURN_DEFAULT(renderIns->soundCard.pcmHandle);
211
212 snd_pcm_drain(renderIns->soundCard.pcmHandle);
213 return HDF_SUCCESS;
214 }
215
RenderGetGainThresholdImpl(struct AlsaRender *renderIns, float *gainMin, float *gainMax)216 static int32_t RenderGetGainThresholdImpl(struct AlsaRender *renderIns, float *gainMin, float *gainMax)
217 {
218 AUDIO_FUNC_LOGI("Not support gain operation");
219 return HDF_SUCCESS;
220 }
221
RenderGetGainImpl(struct AlsaRender *renderIns, float *volume)222 static int32_t RenderGetGainImpl(struct AlsaRender *renderIns, float *volume)
223 {
224 AUDIO_FUNC_LOGI("Not support gain operation");
225 return HDF_SUCCESS;
226 }
227
RenderSetGainImpl(struct AlsaRender *renderIns, float volume)228 static int32_t RenderSetGainImpl(struct AlsaRender *renderIns, float volume)
229 {
230 AUDIO_FUNC_LOGI("Not support gain operation");
231 return HDF_SUCCESS;
232 }
233
RenderGetChannelModeImpl(struct AlsaRender *renderIns, enum AudioChannelMode *mode)234 static int32_t RenderGetChannelModeImpl(struct AlsaRender *renderIns, enum AudioChannelMode *mode)
235 {
236 return HDF_SUCCESS;
237 }
238
RenderSetChannelModeImpl(struct AlsaRender *renderIns, enum AudioChannelMode mode)239 static int32_t RenderSetChannelModeImpl(struct AlsaRender *renderIns, enum AudioChannelMode mode)
240 {
241 return HDF_SUCCESS;
242 }
243
RenderOverrideFunc(struct AlsaRender *renderIns)244 int32_t RenderOverrideFunc(struct AlsaRender *renderIns)
245 {
246 struct AlsaSoundCard *cardIns = (struct AlsaSoundCard *)renderIns;
247
248 if (cardIns->cardType == SND_CARD_PRIMARY) {
249 renderIns->Init = RenderInitImpl;
250 renderIns->SelectScene = RenderSelectSceneImpl;
251 renderIns->Start = RenderStartImpl;
252 renderIns->Stop = RenderStopImpl;
253 renderIns->GetVolThreshold = RenderGetVolThresholdImpl;
254 renderIns->GetVolume = RenderGetVolumeImpl;
255 renderIns->SetVolume = RenderSetVolumeImpl;
256 renderIns->GetGainThreshold = RenderGetGainThresholdImpl;
257 renderIns->GetGain = RenderGetGainImpl;
258 renderIns->SetGain = RenderSetGainImpl;
259 renderIns->GetMute = RenderGetMuteImpl;
260 renderIns->SetMute = RenderSetMuteImpl;
261 renderIns->GetChannelMode = RenderGetChannelModeImpl;
262 renderIns->SetChannelMode = RenderSetChannelModeImpl;
263 }
264
265 return HDF_SUCCESS;
266 }
267