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 /* MuteSolo implementation */
18 
19 #include "sles_allinclusive.h"
20 
21 
IMuteSolo_SetChannelMute(SLMuteSoloItf self,SLuint8 chan,SLboolean mute)22 static SLresult IMuteSolo_SetChannelMute(SLMuteSoloItf self, SLuint8 chan, SLboolean mute)
23 {
24     SL_ENTER_INTERFACE
25 
26     IMuteSolo *thiz = (IMuteSolo *) self;
27     IObject *thisObject = thiz->mThis;
28     if (SL_OBJECTID_AUDIOPLAYER != IObjectToObjectID(thisObject)) {
29         result = SL_RESULT_FEATURE_UNSUPPORTED;
30     } else {
31         CAudioPlayer *ap = (CAudioPlayer *) thisObject;
32         interface_lock_exclusive(thiz);
33         SLuint8 numChannels = ap->mNumChannels;
34         if (1 >= numChannels) {
35             interface_unlock_exclusive(thiz);
36             result = SL_RESULT_FEATURE_UNSUPPORTED;
37         } else if (numChannels <= chan) {
38             interface_unlock_exclusive(thiz);
39             result = SL_RESULT_PARAMETER_INVALID;
40         } else {
41             SLuint8 mask = 1 << chan;
42             SLuint8 oldMuteMask = ap->mMuteMask;
43             if (mute) {
44                 ap->mMuteMask |= mask;
45             } else {
46                 ap->mMuteMask &= ~mask;
47             }
48             interface_unlock_exclusive_attributes(thiz, oldMuteMask != ap->mMuteMask ? ATTR_GAIN :
49                 ATTR_NONE);
50             result = SL_RESULT_SUCCESS;
51         }
52     }
53 
54     SL_LEAVE_INTERFACE
55 }
56 
57 
IMuteSolo_GetChannelMute(SLMuteSoloItf self,SLuint8 chan,SLboolean * pMute)58 static SLresult IMuteSolo_GetChannelMute(SLMuteSoloItf self, SLuint8 chan, SLboolean *pMute)
59 {
60     SL_ENTER_INTERFACE
61 
62     if (NULL == pMute) {
63         result = SL_RESULT_PARAMETER_INVALID;
64     } else {
65         IMuteSolo *thiz = (IMuteSolo *) self;
66         IObject *thisObject = thiz->mThis;
67         if (SL_OBJECTID_AUDIOPLAYER != IObjectToObjectID(thisObject)) {
68             result = SL_RESULT_FEATURE_UNSUPPORTED;
69         } else {
70             CAudioPlayer *ap = (CAudioPlayer *) thisObject;
71             SLboolean mute;
72             interface_lock_shared(thiz);
73             SLuint8 numChannels = ap->mNumChannels;
74             if (1 >= numChannels) {
75                 mute = SL_BOOLEAN_FALSE;
76                 result = SL_RESULT_FEATURE_UNSUPPORTED;
77             } else if (numChannels <= chan) {
78                 mute = SL_BOOLEAN_FALSE;
79                 result = SL_RESULT_PARAMETER_INVALID;
80             } else {
81                 SLuint8 mask = ap->mMuteMask;
82                 mute = (SLboolean) ((mask >> chan) & 1);
83                 result = SL_RESULT_SUCCESS;
84             }
85             interface_unlock_shared(thiz);
86             *pMute = mute;
87         }
88     }
89 
90     SL_LEAVE_INTERFACE
91 }
92 
93 
IMuteSolo_SetChannelSolo(SLMuteSoloItf self,SLuint8 chan,SLboolean solo)94 static SLresult IMuteSolo_SetChannelSolo(SLMuteSoloItf self, SLuint8 chan, SLboolean solo)
95 {
96     SL_ENTER_INTERFACE
97 
98     IMuteSolo *thiz = (IMuteSolo *) self;
99     IObject *thisObject = thiz->mThis;
100     if (SL_OBJECTID_AUDIOPLAYER != IObjectToObjectID(thisObject)) {
101         result = SL_RESULT_FEATURE_UNSUPPORTED;
102     } else {
103         CAudioPlayer *ap = (CAudioPlayer *) thisObject;
104         interface_lock_exclusive(thiz);
105         SLuint8 numChannels = ap->mNumChannels;
106         if (1 >= numChannels) {
107             interface_unlock_exclusive(thiz);
108             result = SL_RESULT_FEATURE_UNSUPPORTED;
109         } else if (numChannels <= chan) {
110             interface_unlock_exclusive(thiz);
111             result = SL_RESULT_PARAMETER_INVALID;
112         } else {
113             SLuint8 mask = 1 << chan;
114             SLuint8 oldSoloMask = ap->mSoloMask;
115             if (solo) {
116                 ap->mSoloMask |= mask;
117             } else {
118                 ap->mSoloMask &= ~mask;
119             }
120             interface_unlock_exclusive_attributes(thiz, oldSoloMask != ap->mSoloMask ? ATTR_GAIN :
121                 ATTR_NONE);
122             result = SL_RESULT_SUCCESS;
123         }
124     }
125 
126     SL_LEAVE_INTERFACE
127 }
128 
129 
IMuteSolo_GetChannelSolo(SLMuteSoloItf self,SLuint8 chan,SLboolean * pSolo)130 static SLresult IMuteSolo_GetChannelSolo(SLMuteSoloItf self, SLuint8 chan, SLboolean *pSolo)
131 {
132     SL_ENTER_INTERFACE
133 
134     if (NULL == pSolo) {
135         result = SL_RESULT_PARAMETER_INVALID;
136     } else {
137         IMuteSolo *thiz = (IMuteSolo *) self;
138         IObject *thisObject = thiz->mThis;
139         if (SL_OBJECTID_AUDIOPLAYER != IObjectToObjectID(thisObject)) {
140             result = SL_RESULT_FEATURE_UNSUPPORTED;
141         } else {
142             CAudioPlayer *ap = (CAudioPlayer *) thisObject;
143             SLboolean solo;
144             interface_lock_shared(thiz);
145             SLuint8 numChannels = ap->mNumChannels;
146             if (1 >= numChannels) {
147                 solo = SL_BOOLEAN_FALSE;
148                 result = SL_RESULT_FEATURE_UNSUPPORTED;
149             } else if (numChannels <= chan) {
150                 solo = SL_BOOLEAN_FALSE;
151                 result = SL_RESULT_PARAMETER_INVALID;
152             } else {
153                 SLuint8 mask = ap->mSoloMask;
154                 solo = (SLboolean) ((mask >> chan) & 1);
155                 result = SL_RESULT_SUCCESS;
156             }
157             interface_unlock_shared(thiz);
158             *pSolo = solo;
159         }
160     }
161 
162     SL_LEAVE_INTERFACE
163 }
164 
165 
IMuteSolo_GetNumChannels(SLMuteSoloItf self,SLuint8 * pNumChannels)166 static SLresult IMuteSolo_GetNumChannels(SLMuteSoloItf self, SLuint8 *pNumChannels)
167 {
168     SL_ENTER_INTERFACE
169 
170     if (NULL == pNumChannels) {
171         result = SL_RESULT_PARAMETER_INVALID;
172     } else {
173         IMuteSolo *thiz = (IMuteSolo *) self;
174         IObject *thisObject = thiz->mThis;
175         if (SL_OBJECTID_AUDIOPLAYER != IObjectToObjectID(thisObject)) {
176             result = SL_RESULT_FEATURE_UNSUPPORTED;
177         } else {
178             CAudioPlayer *ap = (CAudioPlayer *) thisObject;
179             object_lock_shared(thisObject);
180             SLuint8 numChannels = ap->mNumChannels;
181             object_unlock_shared(thisObject);
182             *pNumChannels = numChannels;
183             // spec errata says to return 0 (== UNKNOWN_NUMCHANNELS) if channel count is unknown
184             result = SL_RESULT_SUCCESS;
185         }
186     }
187 
188     SL_LEAVE_INTERFACE
189 }
190 
191 
192 static const struct SLMuteSoloItf_ IMuteSolo_Itf = {
193     IMuteSolo_SetChannelMute,
194     IMuteSolo_GetChannelMute,
195     IMuteSolo_SetChannelSolo,
196     IMuteSolo_GetChannelSolo,
197     IMuteSolo_GetNumChannels
198 };
199 
IMuteSolo_init(void * self)200 void IMuteSolo_init(void *self)
201 {
202     IMuteSolo *thiz = (IMuteSolo *) self;
203     thiz->mItf = &IMuteSolo_Itf;
204 }
205