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 /* 3DSource implementation */ 18 19 #include "sles_allinclusive.h" 20 21 22 static SLresult I3DSource_SetHeadRelative(SL3DSourceItf self, SLboolean headRelative) 23 { 24 SL_ENTER_INTERFACE 25 26 I3DSource *thiz = (I3DSource *) self; 27 interface_lock_poke(thiz); 28 thiz->mHeadRelative = SL_BOOLEAN_FALSE != headRelative; // normalize 29 interface_unlock_poke(thiz); 30 result = SL_RESULT_SUCCESS; 31 32 SL_LEAVE_INTERFACE 33 } 34 35 36 static SLresult I3DSource_GetHeadRelative(SL3DSourceItf self, SLboolean *pHeadRelative) 37 { 38 SL_ENTER_INTERFACE 39 40 if (NULL == pHeadRelative) { 41 result = SL_RESULT_PARAMETER_INVALID; 42 } else { 43 I3DSource *thiz = (I3DSource *) self; 44 interface_lock_peek(thiz); 45 SLboolean headRelative = thiz->mHeadRelative; 46 interface_unlock_peek(thiz); 47 *pHeadRelative = headRelative; 48 result = SL_RESULT_SUCCESS; 49 } 50 51 SL_LEAVE_INTERFACE 52 } 53 54 55 static SLresult I3DSource_SetRolloffDistances(SL3DSourceItf self, 56 SLmillimeter minDistance, SLmillimeter maxDistance) 57 { 58 SL_ENTER_INTERFACE 59 60 if (!((0 < minDistance) && (minDistance <= SL_MILLIMETER_MAX) && 61 (minDistance <= maxDistance) && (maxDistance <= SL_MILLIMETER_MAX))) { 62 result = SL_RESULT_PARAMETER_INVALID; 63 } else { 64 I3DSource *thiz = (I3DSource *) self; 65 interface_lock_exclusive(thiz); 66 thiz->mMinDistance = minDistance; 67 thiz->mMaxDistance = maxDistance; 68 interface_unlock_exclusive(thiz); 69 result = SL_RESULT_SUCCESS; 70 } 71 72 SL_LEAVE_INTERFACE 73 } 74 75 76 static SLresult I3DSource_GetRolloffDistances(SL3DSourceItf self, 77 SLmillimeter *pMinDistance, SLmillimeter *pMaxDistance) 78 { 79 SL_ENTER_INTERFACE 80 81 if (NULL == pMinDistance || NULL == pMaxDistance) { 82 result = SL_RESULT_PARAMETER_INVALID; 83 } else { 84 I3DSource *thiz = (I3DSource *) self; interface_lock_shared(thiz); 85 SLmillimeter minDistance = thiz->mMinDistance; 86 SLmillimeter maxDistance = thiz->mMaxDistance; 87 interface_unlock_shared(thiz); 88 *pMinDistance = minDistance; 89 *pMaxDistance = maxDistance; 90 result = SL_RESULT_SUCCESS; 91 } 92 93 SL_LEAVE_INTERFACE 94 } 95 96 97 static SLresult I3DSource_SetRolloffMaxDistanceMute(SL3DSourceItf self, SLboolean mute) 98 { 99 SL_ENTER_INTERFACE 100 101 I3DSource *thiz = (I3DSource *) self; 102 interface_lock_poke(thiz); 103 thiz->mRolloffMaxDistanceMute = SL_BOOLEAN_FALSE != mute; // normalize 104 interface_unlock_poke(thiz); 105 result = SL_RESULT_SUCCESS; 106 107 SL_LEAVE_INTERFACE 108 } 109 110 111 static SLresult I3DSource_GetRolloffMaxDistanceMute(SL3DSourceItf self, SLboolean *pMute) 112 { 113 SL_ENTER_INTERFACE 114 115 if (NULL == pMute) { 116 result = SL_RESULT_PARAMETER_INVALID; 117 } else { 118 I3DSource *thiz = (I3DSource *) self; 119 interface_lock_peek(thiz); 120 SLboolean mute = thiz->mRolloffMaxDistanceMute; 121 interface_unlock_peek(thiz); 122 *pMute = mute; 123 result = SL_RESULT_SUCCESS; 124 } 125 126 SL_LEAVE_INTERFACE 127 } 128 129 130 static SLresult I3DSource_SetRolloffFactor(SL3DSourceItf self, SLpermille rolloffFactor) 131 { 132 SL_ENTER_INTERFACE 133 134 if (!((0 <= rolloffFactor) && (rolloffFactor <= 10000))) { 135 result = SL_RESULT_PARAMETER_INVALID; 136 } else { 137 I3DSource *thiz = (I3DSource *) self; 138 interface_lock_poke(thiz); 139 thiz->mRolloffFactor = rolloffFactor; 140 interface_unlock_poke(thiz); 141 result = SL_RESULT_SUCCESS; 142 } 143 144 SL_LEAVE_INTERFACE 145 } 146 147 148 static SLresult I3DSource_GetRolloffFactor(SL3DSourceItf self, SLpermille *pRolloffFactor) 149 { 150 SL_ENTER_INTERFACE 151 152 I3DSource *thiz = (I3DSource *) self; 153 interface_lock_peek(thiz); 154 SLpermille rolloffFactor = thiz->mRolloffFactor; 155 interface_unlock_peek(thiz); 156 *pRolloffFactor = rolloffFactor; 157 result = SL_RESULT_SUCCESS; 158 159 SL_LEAVE_INTERFACE 160 } 161 162 163 static SLresult I3DSource_SetRoomRolloffFactor(SL3DSourceItf self, SLpermille roomRolloffFactor) 164 { 165 SL_ENTER_INTERFACE 166 167 if (!((0 <= roomRolloffFactor) && (roomRolloffFactor <= 10000))) { 168 result = SL_RESULT_PARAMETER_INVALID; 169 } else { 170 I3DSource *thiz = (I3DSource *) self; 171 interface_lock_poke(thiz); 172 thiz->mRoomRolloffFactor = roomRolloffFactor; 173 interface_unlock_poke(thiz); 174 result = SL_RESULT_SUCCESS; 175 } 176 177 SL_LEAVE_INTERFACE 178 } 179 180 181 static SLresult I3DSource_GetRoomRolloffFactor(SL3DSourceItf self, SLpermille *pRoomRolloffFactor) 182 { 183 SL_ENTER_INTERFACE 184 185 I3DSource *thiz = (I3DSource *) self; 186 interface_lock_peek(thiz); 187 SLpermille roomRolloffFactor = thiz->mRoomRolloffFactor; 188 interface_unlock_peek(thiz); 189 *pRoomRolloffFactor = roomRolloffFactor; 190 result = SL_RESULT_SUCCESS; 191 192 SL_LEAVE_INTERFACE 193 } 194 195 196 static SLresult I3DSource_SetRolloffModel(SL3DSourceItf self, SLuint8 model) 197 { 198 SL_ENTER_INTERFACE 199 200 switch (model) { 201 case SL_ROLLOFFMODEL_LINEAR: 202 case SL_ROLLOFFMODEL_EXPONENTIAL: 203 { 204 I3DSource *thiz = (I3DSource *) self; 205 interface_lock_poke(thiz); 206 thiz->mDistanceModel = model; 207 interface_unlock_poke(thiz); 208 result = SL_RESULT_SUCCESS; 209 } 210 break; 211 default: 212 result = SL_RESULT_PARAMETER_INVALID; 213 break; 214 } 215 216 SL_LEAVE_INTERFACE 217 } 218 219 220 static SLresult I3DSource_GetRolloffModel(SL3DSourceItf self, SLuint8 *pModel) 221 { 222 SL_ENTER_INTERFACE 223 224 I3DSource *thiz = (I3DSource *) self; 225 interface_lock_peek(thiz); 226 SLuint8 model = thiz->mDistanceModel; 227 interface_unlock_peek(thiz); 228 *pModel = model; 229 result = SL_RESULT_SUCCESS; 230 231 SL_LEAVE_INTERFACE 232 } 233 234 235 static SLresult I3DSource_SetCone(SL3DSourceItf self, SLmillidegree innerAngle, 236 SLmillidegree outerAngle, SLmillibel outerLevel) 237 { 238 SL_ENTER_INTERFACE 239 240 if (!((0 <= innerAngle) && (innerAngle <= 360000) && 241 (0 <= outerAngle) && (outerAngle <= 360000) && 242 (SL_MILLIBEL_MIN <= outerLevel) && (outerLevel <= 0))) { 243 result = SL_RESULT_PARAMETER_INVALID; 244 } else { 245 I3DSource *thiz = (I3DSource *) self; 246 interface_lock_exclusive(thiz); 247 thiz->mConeInnerAngle = innerAngle; 248 thiz->mConeOuterAngle = outerAngle; 249 thiz->mConeOuterLevel = outerLevel; 250 interface_unlock_exclusive(thiz); 251 result = SL_RESULT_SUCCESS; 252 } 253 254 SL_LEAVE_INTERFACE 255 } 256 257 258 static SLresult I3DSource_GetCone(SL3DSourceItf self, SLmillidegree *pInnerAngle, 259 SLmillidegree *pOuterAngle, SLmillibel *pOuterLevel) 260 { 261 SL_ENTER_INTERFACE 262 263 if (NULL == pInnerAngle || NULL == pOuterAngle || NULL == pOuterLevel) { 264 result = SL_RESULT_PARAMETER_INVALID; 265 } else { 266 I3DSource *thiz = (I3DSource *) self; 267 interface_lock_shared(thiz); 268 SLmillidegree innerAngle = thiz->mConeInnerAngle; 269 SLmillidegree outerAngle = thiz->mConeOuterAngle; 270 SLmillibel outerLevel = thiz->mConeOuterLevel; 271 interface_unlock_shared(thiz); 272 *pInnerAngle = innerAngle; 273 *pOuterAngle = outerAngle; 274 *pOuterLevel = outerLevel; 275 result = SL_RESULT_SUCCESS; 276 } 277 278 SL_LEAVE_INTERFACE 279 } 280 281 282 static const struct SL3DSourceItf_ I3DSource_Itf = { 283 I3DSource_SetHeadRelative, 284 I3DSource_GetHeadRelative, 285 I3DSource_SetRolloffDistances, 286 I3DSource_GetRolloffDistances, 287 I3DSource_SetRolloffMaxDistanceMute, 288 I3DSource_GetRolloffMaxDistanceMute, 289 I3DSource_SetRolloffFactor, 290 I3DSource_GetRolloffFactor, 291 I3DSource_SetRoomRolloffFactor, 292 I3DSource_GetRoomRolloffFactor, 293 I3DSource_SetRolloffModel, 294 I3DSource_GetRolloffModel, 295 I3DSource_SetCone, 296 I3DSource_GetCone 297 }; 298 299 void I3DSource_init(void *self) 300 { 301 I3DSource *thiz = (I3DSource *) self; 302 thiz->mItf = &I3DSource_Itf; 303 thiz->mHeadRelative = SL_BOOLEAN_FALSE; 304 thiz->mRolloffMaxDistanceMute = SL_BOOLEAN_FALSE; 305 thiz->mMaxDistance = SL_MILLIMETER_MAX; 306 thiz->mMinDistance = 1000; 307 thiz->mConeInnerAngle = 360000; 308 thiz->mConeOuterAngle = 360000; 309 thiz->mConeOuterLevel = 0; 310 thiz->mRolloffFactor = 1000; 311 thiz->mRoomRolloffFactor = 0; 312 thiz->mDistanceModel = SL_ROLLOFFMODEL_EXPONENTIAL; 313 } 314