1 /*
2  * Copyright (C) 2010 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 /* Volume implementation */
18 
19 #include "sles_allinclusive.h"
20 
21 
IVolume_SetVolumeLevel(SLVolumeItf self,SLmillibel level_)22 static SLresult IVolume_SetVolumeLevel(SLVolumeItf self, SLmillibel level_)
23 {
24     SL_ENTER_INTERFACE
25 
26     int level = level_;
27     if (!((SL_MILLIBEL_MIN <= level) && (level <= PLATFORM_MILLIBEL_MAX_VOLUME))) {
28         result = SL_RESULT_PARAMETER_INVALID;
29     } else {
30         IVolume *thiz = (IVolume *) self;
31         interface_lock_exclusive(thiz);
32         SLmillibel oldLevel = thiz->mLevel;
33         if (oldLevel != level) {
34             thiz->mLevel = level;
35             interface_unlock_exclusive_attributes(thiz, ATTR_GAIN);
36         } else {
37             interface_unlock_exclusive(thiz);
38         }
39         result = SL_RESULT_SUCCESS;
40     }
41 
42     SL_LEAVE_INTERFACE
43 }
44 
45 
IVolume_GetVolumeLevel(SLVolumeItf self,SLmillibel * pLevel)46 static SLresult IVolume_GetVolumeLevel(SLVolumeItf self, SLmillibel *pLevel)
47 {
48     SL_ENTER_INTERFACE
49 
50     if (NULL == pLevel) {
51         result = SL_RESULT_PARAMETER_INVALID;
52     } else {
53         IVolume *thiz = (IVolume *) self;
54         interface_lock_shared(thiz);
55         SLmillibel level = thiz->mLevel;
56         interface_unlock_shared(thiz);
57         *pLevel = level;
58         result = SL_RESULT_SUCCESS;
59     }
60 
61     SL_LEAVE_INTERFACE
62 }
63 
64 
IVolume_GetMaxVolumeLevel(SLVolumeItf self,SLmillibel * pMaxLevel)65 static SLresult IVolume_GetMaxVolumeLevel(SLVolumeItf self, SLmillibel *pMaxLevel)
66 {
67     SL_ENTER_INTERFACE
68 
69     if (NULL == pMaxLevel) {
70         result = SL_RESULT_PARAMETER_INVALID;
71     } else {
72         *pMaxLevel = PLATFORM_MILLIBEL_MAX_VOLUME;
73         result = SL_RESULT_SUCCESS;
74     }
75 
76     SL_LEAVE_INTERFACE
77 }
78 
79 
IVolume_SetMute(SLVolumeItf self,SLboolean mute)80 static SLresult IVolume_SetMute(SLVolumeItf self, SLboolean mute)
81 {
82     SL_ENTER_INTERFACE
83 
84     IVolume *thiz = (IVolume *) self;
85     mute = SL_BOOLEAN_FALSE != mute; // normalize
86     interface_lock_exclusive(thiz);
87     SLboolean oldMute = thiz->mMute;
88     if (oldMute != mute) {
89         thiz->mMute = (SLuint8) mute;
90         interface_unlock_exclusive_attributes(thiz, ATTR_GAIN);
91     } else {
92         interface_unlock_exclusive(thiz);
93     }
94     result = SL_RESULT_SUCCESS;
95 
96     SL_LEAVE_INTERFACE
97 }
98 
99 
IVolume_GetMute(SLVolumeItf self,SLboolean * pMute)100 static SLresult IVolume_GetMute(SLVolumeItf self, SLboolean *pMute)
101 {
102     SL_ENTER_INTERFACE
103 
104     if (NULL == pMute) {
105         result = SL_RESULT_PARAMETER_INVALID;
106     } else {
107         IVolume *thiz = (IVolume *) self;
108         interface_lock_shared(thiz);
109         SLboolean mute = thiz->mMute;
110         interface_unlock_shared(thiz);
111         *pMute = mute;
112         result = SL_RESULT_SUCCESS;
113     }
114 
115     SL_LEAVE_INTERFACE
116 }
117 
118 
IVolume_EnableStereoPosition(SLVolumeItf self,SLboolean enable)119 static SLresult IVolume_EnableStereoPosition(SLVolumeItf self, SLboolean enable)
120 {
121     SL_ENTER_INTERFACE
122 
123     IVolume *thiz = (IVolume *) self;
124     enable = SL_BOOLEAN_FALSE != enable; // normalize
125     interface_lock_exclusive(thiz);
126     SLboolean oldEnable = thiz->mEnableStereoPosition;
127     if (oldEnable != enable) {
128         thiz->mEnableStereoPosition = (SLuint8) enable;
129         interface_unlock_exclusive_attributes(thiz, ATTR_GAIN);
130     } else {
131         interface_unlock_exclusive(thiz);
132     }
133     result = SL_RESULT_SUCCESS;
134 
135     SL_LEAVE_INTERFACE
136 }
137 
138 
IVolume_IsEnabledStereoPosition(SLVolumeItf self,SLboolean * pEnable)139 static SLresult IVolume_IsEnabledStereoPosition(SLVolumeItf self, SLboolean *pEnable)
140 {
141     SL_ENTER_INTERFACE
142 
143     if (NULL == pEnable) {
144         result = SL_RESULT_PARAMETER_INVALID;
145     } else {
146         IVolume *thiz = (IVolume *) self;
147         interface_lock_shared(thiz);
148         SLboolean enable = thiz->mEnableStereoPosition;
149         interface_unlock_shared(thiz);
150         *pEnable = enable;
151         result = SL_RESULT_SUCCESS;
152     }
153 
154     SL_LEAVE_INTERFACE
155 }
156 
157 
IVolume_SetStereoPosition(SLVolumeItf self,SLpermille stereoPosition)158 static SLresult IVolume_SetStereoPosition(SLVolumeItf self, SLpermille stereoPosition)
159 {
160     SL_ENTER_INTERFACE
161 
162     if (!((-1000 <= stereoPosition) && (1000 >= stereoPosition))) {
163         result = SL_RESULT_PARAMETER_INVALID;
164     } else {
165         IVolume *thiz = (IVolume *) self;
166         interface_lock_exclusive(thiz);
167         SLpermille oldStereoPosition = thiz->mStereoPosition;
168         if (oldStereoPosition != stereoPosition) {
169             thiz->mStereoPosition = stereoPosition;
170             interface_unlock_exclusive_attributes(thiz, ATTR_GAIN);
171         } else {
172             interface_unlock_exclusive(thiz);
173         }
174         result = SL_RESULT_SUCCESS;
175     }
176 
177     SL_LEAVE_INTERFACE
178 }
179 
180 
IVolume_GetStereoPosition(SLVolumeItf self,SLpermille * pStereoPosition)181 static SLresult IVolume_GetStereoPosition(SLVolumeItf self, SLpermille *pStereoPosition)
182 {
183     SL_ENTER_INTERFACE
184 
185     if (NULL == pStereoPosition) {
186         result = SL_RESULT_PARAMETER_INVALID;
187     } else {
188         IVolume *thiz = (IVolume *) self;
189         interface_lock_shared(thiz);
190         SLpermille stereoPosition = thiz->mStereoPosition;
191         interface_unlock_shared(thiz);
192         *pStereoPosition = stereoPosition;
193         result = SL_RESULT_SUCCESS;
194     }
195 
196     SL_LEAVE_INTERFACE
197 }
198 
199 
200 static const struct SLVolumeItf_ IVolume_Itf = {
201     IVolume_SetVolumeLevel,
202     IVolume_GetVolumeLevel,
203     IVolume_GetMaxVolumeLevel,
204     IVolume_SetMute,
205     IVolume_GetMute,
206     IVolume_EnableStereoPosition,
207     IVolume_IsEnabledStereoPosition,
208     IVolume_SetStereoPosition,
209     IVolume_GetStereoPosition
210 };
211 
IVolume_init(void * self)212 void IVolume_init(void *self)
213 {
214     IVolume *thiz = (IVolume *) self;
215     thiz->mItf = &IVolume_Itf;
216     thiz->mLevel = 0;
217     thiz->mMute = SL_BOOLEAN_FALSE;
218     thiz->mEnableStereoPosition = SL_BOOLEAN_FALSE;
219     thiz->mStereoPosition = 0;
220 }
221