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 /* Record implementation */ 18 19 #include "sles_allinclusive.h" 20 21 22 static SLresult IRecord_SetRecordState(SLRecordItf self, SLuint32 state) 23 { 24 SL_ENTER_INTERFACE 25 26 switch (state) { 27 case SL_RECORDSTATE_STOPPED: 28 case SL_RECORDSTATE_PAUSED: 29 case SL_RECORDSTATE_RECORDING: 30 { 31 IRecord *this = (IRecord *) self; 32 interface_lock_poke(this); 33 this->mState = state; 34 #ifdef ANDROID 35 android_audioRecorder_setRecordState(InterfaceToCAudioRecorder(this), state); 36 #endif 37 interface_unlock_poke(this); 38 result = SL_RESULT_SUCCESS; 39 } 40 break; 41 default: 42 result = SL_RESULT_PARAMETER_INVALID; 43 break; 44 } 45 46 SL_LEAVE_INTERFACE 47 } 48 49 50 static SLresult IRecord_GetRecordState(SLRecordItf self, SLuint32 *pState) 51 { 52 SL_ENTER_INTERFACE 53 54 IRecord *this = (IRecord *) self; 55 if (NULL == pState) { 56 result = SL_RESULT_PARAMETER_INVALID; 57 } else { 58 interface_lock_peek(this); 59 SLuint32 state = this->mState; 60 interface_unlock_peek(this); 61 *pState = state; 62 result = SL_RESULT_SUCCESS; 63 } 64 65 SL_LEAVE_INTERFACE 66 } 67 68 69 static SLresult IRecord_SetDurationLimit(SLRecordItf self, SLmillisecond msec) 70 { 71 SL_ENTER_INTERFACE 72 73 IRecord *this = (IRecord *) self; 74 interface_lock_exclusive(this); 75 if (this->mDurationLimit != msec) { 76 this->mDurationLimit = msec; 77 interface_unlock_exclusive_attributes(this, ATTR_TRANSPORT); 78 } else { 79 interface_unlock_exclusive(this); 80 } 81 result = SL_RESULT_SUCCESS; 82 83 SL_LEAVE_INTERFACE 84 } 85 86 87 static SLresult IRecord_GetPosition(SLRecordItf self, SLmillisecond *pMsec) 88 { 89 SL_ENTER_INTERFACE 90 91 if (NULL == pMsec) { 92 result = SL_RESULT_PARAMETER_INVALID; 93 } else { 94 IRecord *this = (IRecord *) self; 95 SLmillisecond position; 96 interface_lock_shared(this); 97 #ifdef ANDROID 98 // Android does not use the mPosition field for audio recorders 99 if (SL_OBJECTID_AUDIORECORDER == InterfaceToObjectID(this)) { 100 android_audioRecorder_getPosition(InterfaceToCAudioRecorder(this), &position); 101 } else { 102 position = this->mPosition; 103 } 104 #else 105 position = this->mPosition; 106 #endif 107 interface_unlock_shared(this); 108 *pMsec = position; 109 result = SL_RESULT_SUCCESS; 110 } 111 112 SL_LEAVE_INTERFACE 113 } 114 115 116 static SLresult IRecord_RegisterCallback(SLRecordItf self, slRecordCallback callback, 117 void *pContext) 118 { 119 SL_ENTER_INTERFACE 120 121 IRecord *this = (IRecord *) self; 122 interface_lock_exclusive(this); 123 this->mCallback = callback; 124 this->mContext = pContext; 125 interface_unlock_exclusive(this); 126 result = SL_RESULT_SUCCESS; 127 128 SL_LEAVE_INTERFACE 129 } 130 131 132 static SLresult IRecord_SetCallbackEventsMask(SLRecordItf self, SLuint32 eventFlags) 133 { 134 SL_ENTER_INTERFACE 135 136 if (eventFlags & ~( 137 SL_RECORDEVENT_HEADATLIMIT | 138 SL_RECORDEVENT_HEADATMARKER | 139 SL_RECORDEVENT_HEADATNEWPOS | 140 SL_RECORDEVENT_HEADMOVING | 141 SL_RECORDEVENT_HEADSTALLED | 142 SL_RECORDEVENT_BUFFER_FULL)) { 143 result = SL_RESULT_PARAMETER_INVALID; 144 } else { 145 IRecord *this = (IRecord *) self; 146 interface_lock_exclusive(this); 147 if (this->mCallbackEventsMask != eventFlags) { 148 this->mCallbackEventsMask = eventFlags; 149 interface_unlock_exclusive_attributes(this, ATTR_TRANSPORT); 150 } else { 151 interface_unlock_exclusive(this); 152 } 153 result = SL_RESULT_SUCCESS; 154 } 155 156 SL_LEAVE_INTERFACE 157 } 158 159 160 static SLresult IRecord_GetCallbackEventsMask(SLRecordItf self, SLuint32 *pEventFlags) 161 { 162 SL_ENTER_INTERFACE 163 164 if (NULL == pEventFlags) { 165 result = SL_RESULT_PARAMETER_INVALID; 166 } else { 167 IRecord *this = (IRecord *) self; 168 interface_lock_peek(this); 169 SLuint32 callbackEventsMask = this->mCallbackEventsMask; 170 interface_unlock_peek(this); 171 *pEventFlags = callbackEventsMask; 172 result = SL_RESULT_SUCCESS; 173 } 174 175 SL_LEAVE_INTERFACE 176 } 177 178 179 static SLresult IRecord_SetMarkerPosition(SLRecordItf self, SLmillisecond mSec) 180 { 181 SL_ENTER_INTERFACE 182 183 IRecord *this = (IRecord *) self; 184 interface_lock_exclusive(this); 185 if (this->mMarkerPosition != mSec) { 186 this->mMarkerPosition = mSec; 187 interface_unlock_exclusive_attributes(this, ATTR_TRANSPORT); 188 } else { 189 interface_unlock_exclusive(this); 190 } 191 result = SL_RESULT_SUCCESS; 192 193 SL_LEAVE_INTERFACE 194 } 195 196 197 static SLresult IRecord_ClearMarkerPosition(SLRecordItf self) 198 { 199 SL_ENTER_INTERFACE 200 201 IRecord *this = (IRecord *) self; 202 interface_lock_exclusive(this); 203 if (this->mMarkerPosition != 0) { 204 this->mMarkerPosition = 0; 205 interface_unlock_exclusive_attributes(this, ATTR_TRANSPORT); 206 } else { 207 interface_unlock_exclusive(this); 208 } 209 result = SL_RESULT_SUCCESS; 210 211 SL_LEAVE_INTERFACE 212 } 213 214 215 static SLresult IRecord_GetMarkerPosition(SLRecordItf self, SLmillisecond *pMsec) 216 { 217 SL_ENTER_INTERFACE 218 219 if (NULL == pMsec) { 220 result = SL_RESULT_PARAMETER_INVALID; 221 } else { 222 IRecord *this = (IRecord *) self; 223 interface_lock_peek(this); 224 SLmillisecond markerPosition = this->mMarkerPosition; 225 interface_unlock_peek(this); 226 *pMsec = markerPosition; 227 result = SL_RESULT_SUCCESS; 228 } 229 230 SL_LEAVE_INTERFACE 231 } 232 233 234 static SLresult IRecord_SetPositionUpdatePeriod(SLRecordItf self, SLmillisecond mSec) 235 { 236 SL_ENTER_INTERFACE 237 238 if (0 == mSec) { 239 result = SL_RESULT_PARAMETER_INVALID; 240 } else { 241 IRecord *this = (IRecord *) self; 242 interface_lock_exclusive(this); 243 if (this->mPositionUpdatePeriod != mSec) { 244 this->mPositionUpdatePeriod = mSec; 245 interface_unlock_exclusive_attributes(this, ATTR_TRANSPORT); 246 } else { 247 interface_unlock_exclusive(this); 248 } 249 result = SL_RESULT_SUCCESS; 250 } 251 252 SL_LEAVE_INTERFACE 253 } 254 255 256 static SLresult IRecord_GetPositionUpdatePeriod(SLRecordItf self, SLmillisecond *pMsec) 257 { 258 SL_ENTER_INTERFACE 259 260 if (NULL == pMsec) { 261 result = SL_RESULT_PARAMETER_INVALID; 262 } else { 263 IRecord *this = (IRecord *) self; 264 interface_lock_peek(this); 265 SLmillisecond positionUpdatePeriod = this->mPositionUpdatePeriod; 266 interface_unlock_peek(this); 267 *pMsec = positionUpdatePeriod; 268 result = SL_RESULT_SUCCESS; 269 } 270 271 SL_LEAVE_INTERFACE 272 } 273 274 275 static const struct SLRecordItf_ IRecord_Itf = { 276 IRecord_SetRecordState, 277 IRecord_GetRecordState, 278 IRecord_SetDurationLimit, 279 IRecord_GetPosition, 280 IRecord_RegisterCallback, 281 IRecord_SetCallbackEventsMask, 282 IRecord_GetCallbackEventsMask, 283 IRecord_SetMarkerPosition, 284 IRecord_ClearMarkerPosition, 285 IRecord_GetMarkerPosition, 286 IRecord_SetPositionUpdatePeriod, 287 IRecord_GetPositionUpdatePeriod 288 }; 289 290 void IRecord_init(void *self) 291 { 292 IRecord *this = (IRecord *) self; 293 this->mItf = &IRecord_Itf; 294 this->mState = SL_RECORDSTATE_STOPPED; 295 this->mDurationLimit = 0; 296 this->mPosition = 0; 297 this->mCallback = NULL; 298 this->mContext = NULL; 299 this->mCallbackEventsMask = 0; 300 this->mMarkerPosition = 0; 301 this->mPositionUpdatePeriod = 1000; 302 } 303