Home | History | Annotate | Download | only in libopensles
      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