• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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     int32_t ret;
194     struct AlsaMixerCtlElement elem;
195     struct AlsaSoundCard *cardIns = (struct AlsaSoundCard *)renderIns;
196 
197     SndElementItemInit(&elem);
198     elem.numid = SND_NUMID_PLAYBACK_PATH;
199     elem.name = SND_ELEM_PLAYBACK_PATH;
200     elem.value = SND_OUT_CARD_OFF;
201     ret = SndElementWrite(cardIns, &elem);
202     if (ret != HDF_SUCCESS) {
203         AUDIO_FUNC_LOGE("write render fail!");
204         return HDF_FAILURE;
205     }
206 
207     snd_pcm_drain(renderIns->soundCard.pcmHandle);
208     return HDF_SUCCESS;
209 }
210 
RenderGetGainThresholdImpl(struct AlsaRender * renderIns,float * gainMin,float * gainMax)211 static int32_t RenderGetGainThresholdImpl(struct AlsaRender *renderIns, float *gainMin, float *gainMax)
212 {
213     AUDIO_FUNC_LOGI("Not support gain operation");
214     return HDF_SUCCESS;
215 }
216 
RenderGetGainImpl(struct AlsaRender * renderIns,float * volume)217 static int32_t RenderGetGainImpl(struct AlsaRender *renderIns, float *volume)
218 {
219     AUDIO_FUNC_LOGI("Not support gain operation");
220     return HDF_SUCCESS;
221 }
222 
RenderSetGainImpl(struct AlsaRender * renderIns,float volume)223 static int32_t RenderSetGainImpl(struct AlsaRender *renderIns, float volume)
224 {
225     AUDIO_FUNC_LOGI("Not support gain operation");
226     return HDF_SUCCESS;
227 }
228 
RenderGetChannelModeImpl(struct AlsaRender * renderIns,enum AudioChannelMode * mode)229 static int32_t RenderGetChannelModeImpl(struct AlsaRender *renderIns, enum AudioChannelMode *mode)
230 {
231     return HDF_SUCCESS;
232 }
233 
RenderSetChannelModeImpl(struct AlsaRender * renderIns,enum AudioChannelMode mode)234 static int32_t RenderSetChannelModeImpl(struct AlsaRender *renderIns, enum AudioChannelMode mode)
235 {
236     return HDF_SUCCESS;
237 }
238 
RenderOverrideFunc(struct AlsaRender * renderIns)239 int32_t RenderOverrideFunc(struct AlsaRender *renderIns)
240 {
241     struct AlsaSoundCard *cardIns = (struct AlsaSoundCard *)renderIns;
242 
243     if (cardIns->cardType == SND_CARD_PRIMARY) {
244         renderIns->Init = RenderInitImpl;
245         renderIns->SelectScene = RenderSelectSceneImpl;
246         renderIns->Start = RenderStartImpl;
247         renderIns->Stop = RenderStopImpl;
248         renderIns->GetVolThreshold = RenderGetVolThresholdImpl;
249         renderIns->GetVolume = RenderGetVolumeImpl;
250         renderIns->SetVolume = RenderSetVolumeImpl;
251         renderIns->GetGainThreshold = RenderGetGainThresholdImpl;
252         renderIns->GetGain = RenderGetGainImpl;
253         renderIns->SetGain = RenderSetGainImpl;
254         renderIns->GetMute = RenderGetMuteImpl;
255         renderIns->SetMute = RenderSetMuteImpl;
256         renderIns->GetChannelMode = RenderGetChannelModeImpl;
257         renderIns->SetChannelMode = RenderSetChannelModeImpl;
258     }
259 
260     return HDF_SUCCESS;
261 }
262