Home | History | Annotate | Download | only in itf
      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 *thiz = (IRecord *) self;
     32         interface_lock_exclusive(thiz);
     33         thiz->mState = state;
     34 #ifdef ANDROID
     35         android_audioRecorder_setRecordState(InterfaceToCAudioRecorder(thiz), state);
     36 #endif
     37         interface_unlock_exclusive(thiz);
     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 *thiz = (IRecord *) self;
     55     if (NULL == pState) {
     56         result = SL_RESULT_PARAMETER_INVALID;
     57     } else {
     58         interface_lock_shared(thiz);
     59         SLuint32 state = thiz->mState;
     60         interface_unlock_shared(thiz);
     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 *thiz = (IRecord *) self;
     74     interface_lock_exclusive(thiz);
     75     if (thiz->mDurationLimit != msec) {
     76         thiz->mDurationLimit = msec;
     77         interface_unlock_exclusive_attributes(thiz, ATTR_TRANSPORT);
     78     } else {
     79         interface_unlock_exclusive(thiz);
     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 *thiz = (IRecord *) self;
     95         SLmillisecond position;
     96         interface_lock_shared(thiz);
     97 #ifdef ANDROID
     98         // Android does not use the mPosition field for audio recorders
     99         if (SL_OBJECTID_AUDIORECORDER == InterfaceToObjectID(thiz)) {
    100             android_audioRecorder_getPosition(InterfaceToCAudioRecorder(thiz), &position);
    101         } else {
    102             position = thiz->mPosition;
    103         }
    104 #else
    105         position = thiz->mPosition;
    106 #endif
    107         interface_unlock_shared(thiz);
    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 *thiz = (IRecord *) self;
    122     interface_lock_exclusive(thiz);
    123     thiz->mCallback = callback;
    124     thiz->mContext = pContext;
    125     interface_unlock_exclusive(thiz);
    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 *thiz = (IRecord *) self;
    146         interface_lock_exclusive(thiz);
    147         if (thiz->mCallbackEventsMask != eventFlags) {
    148             thiz->mCallbackEventsMask = eventFlags;
    149             interface_unlock_exclusive_attributes(thiz, ATTR_TRANSPORT);
    150         } else {
    151             interface_unlock_exclusive(thiz);
    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 *thiz = (IRecord *) self;
    168         interface_lock_shared(thiz);
    169         SLuint32 callbackEventsMask = thiz->mCallbackEventsMask;
    170         interface_unlock_shared(thiz);
    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     if (SL_TIME_UNKNOWN == mSec) {
    184         result = SL_RESULT_PARAMETER_INVALID;
    185     } else {
    186         IRecord *thiz = (IRecord *) self;
    187         bool significant = false;
    188         interface_lock_exclusive(thiz);
    189         if (thiz->mMarkerPosition != mSec) {
    190             thiz->mMarkerPosition = mSec;
    191             if (thiz->mCallbackEventsMask & SL_PLAYEVENT_HEADATMARKER) {
    192                 significant = true;
    193             }
    194         }
    195         if (significant) {
    196             interface_unlock_exclusive_attributes(thiz, ATTR_TRANSPORT);
    197         } else {
    198             interface_unlock_exclusive(thiz);
    199         }
    200         result = SL_RESULT_SUCCESS;
    201     }
    202 
    203     SL_LEAVE_INTERFACE
    204 }
    205 
    206 
    207 static SLresult IRecord_ClearMarkerPosition(SLRecordItf self)
    208 {
    209     SL_ENTER_INTERFACE
    210 
    211     IRecord *thiz = (IRecord *) self;
    212     bool significant = false;
    213     interface_lock_exclusive(thiz);
    214     // clearing the marker position is equivalent to setting the marker to SL_TIME_UNKNOWN
    215     if (thiz->mMarkerPosition != SL_TIME_UNKNOWN) {
    216         thiz->mMarkerPosition = SL_TIME_UNKNOWN;
    217         if (thiz->mCallbackEventsMask & SL_PLAYEVENT_HEADATMARKER) {
    218             significant = true;
    219         }
    220     }
    221     if (significant) {
    222         interface_unlock_exclusive_attributes(thiz, ATTR_TRANSPORT);
    223     } else {
    224         interface_unlock_exclusive(thiz);
    225     }
    226     result = SL_RESULT_SUCCESS;
    227 
    228     SL_LEAVE_INTERFACE
    229 }
    230 
    231 
    232 static SLresult IRecord_GetMarkerPosition(SLRecordItf self, SLmillisecond *pMsec)
    233 {
    234     SL_ENTER_INTERFACE
    235 
    236     if (NULL == pMsec) {
    237         result = SL_RESULT_PARAMETER_INVALID;
    238     } else {
    239         IRecord *thiz = (IRecord *) self;
    240         interface_lock_shared(thiz);
    241         SLmillisecond markerPosition = thiz->mMarkerPosition;
    242         interface_unlock_shared(thiz);
    243         *pMsec = markerPosition;
    244         if (SL_TIME_UNKNOWN == markerPosition) {
    245             result = SL_RESULT_PRECONDITIONS_VIOLATED;
    246         } else {
    247             result = SL_RESULT_SUCCESS;
    248         }
    249     }
    250 
    251     SL_LEAVE_INTERFACE
    252 }
    253 
    254 
    255 static SLresult IRecord_SetPositionUpdatePeriod(SLRecordItf self, SLmillisecond mSec)
    256 {
    257     SL_ENTER_INTERFACE
    258 
    259     if (0 == mSec) {
    260         result = SL_RESULT_PARAMETER_INVALID;
    261     } else {
    262         IRecord *thiz = (IRecord *) self;
    263         interface_lock_exclusive(thiz);
    264         if (thiz->mPositionUpdatePeriod != mSec) {
    265             thiz->mPositionUpdatePeriod = mSec;
    266             interface_unlock_exclusive_attributes(thiz, ATTR_TRANSPORT);
    267         } else {
    268             interface_unlock_exclusive(thiz);
    269         }
    270         result = SL_RESULT_SUCCESS;
    271     }
    272 
    273     SL_LEAVE_INTERFACE
    274 }
    275 
    276 
    277 static SLresult IRecord_GetPositionUpdatePeriod(SLRecordItf self, SLmillisecond *pMsec)
    278 {
    279     SL_ENTER_INTERFACE
    280 
    281     if (NULL == pMsec) {
    282         result = SL_RESULT_PARAMETER_INVALID;
    283     } else {
    284         IRecord *thiz = (IRecord *) self;
    285         interface_lock_shared(thiz);
    286         SLmillisecond positionUpdatePeriod = thiz->mPositionUpdatePeriod;
    287         interface_unlock_shared(thiz);
    288         *pMsec = positionUpdatePeriod;
    289         result = SL_RESULT_SUCCESS;
    290     }
    291 
    292     SL_LEAVE_INTERFACE
    293 }
    294 
    295 
    296 static const struct SLRecordItf_ IRecord_Itf = {
    297     IRecord_SetRecordState,
    298     IRecord_GetRecordState,
    299     IRecord_SetDurationLimit,
    300     IRecord_GetPosition,
    301     IRecord_RegisterCallback,
    302     IRecord_SetCallbackEventsMask,
    303     IRecord_GetCallbackEventsMask,
    304     IRecord_SetMarkerPosition,
    305     IRecord_ClearMarkerPosition,
    306     IRecord_GetMarkerPosition,
    307     IRecord_SetPositionUpdatePeriod,
    308     IRecord_GetPositionUpdatePeriod
    309 };
    310 
    311 void IRecord_init(void *self)
    312 {
    313     IRecord *thiz = (IRecord *) self;
    314     thiz->mItf = &IRecord_Itf;
    315     thiz->mState = SL_RECORDSTATE_STOPPED;
    316     thiz->mDurationLimit = 0;
    317     thiz->mPosition = (SLmillisecond) 0;
    318     thiz->mCallback = NULL;
    319     thiz->mContext = NULL;
    320     thiz->mCallbackEventsMask = 0;
    321     thiz->mMarkerPosition = SL_TIME_UNKNOWN;
    322     thiz->mPositionUpdatePeriod = 1000; // per spec
    323 }
    324