123b3f68cab75e480ac93d656a6e4f60b979de6d2Glenn Kasten/*
223b3f68cab75e480ac93d656a6e4f60b979de6d2Glenn Kasten * Copyright (C) 2010 The Android Open Source Project
323b3f68cab75e480ac93d656a6e4f60b979de6d2Glenn Kasten *
423b3f68cab75e480ac93d656a6e4f60b979de6d2Glenn Kasten * Licensed under the Apache License, Version 2.0 (the "License");
523b3f68cab75e480ac93d656a6e4f60b979de6d2Glenn Kasten * you may not use this file except in compliance with the License.
623b3f68cab75e480ac93d656a6e4f60b979de6d2Glenn Kasten * You may obtain a copy of the License at
723b3f68cab75e480ac93d656a6e4f60b979de6d2Glenn Kasten *
823b3f68cab75e480ac93d656a6e4f60b979de6d2Glenn Kasten *      http://www.apache.org/licenses/LICENSE-2.0
923b3f68cab75e480ac93d656a6e4f60b979de6d2Glenn Kasten *
1023b3f68cab75e480ac93d656a6e4f60b979de6d2Glenn Kasten * Unless required by applicable law or agreed to in writing, software
1123b3f68cab75e480ac93d656a6e4f60b979de6d2Glenn Kasten * distributed under the License is distributed on an "AS IS" BASIS,
1223b3f68cab75e480ac93d656a6e4f60b979de6d2Glenn Kasten * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1323b3f68cab75e480ac93d656a6e4f60b979de6d2Glenn Kasten * See the License for the specific language governing permissions and
1423b3f68cab75e480ac93d656a6e4f60b979de6d2Glenn Kasten * limitations under the License.
1523b3f68cab75e480ac93d656a6e4f60b979de6d2Glenn Kasten */
1623b3f68cab75e480ac93d656a6e4f60b979de6d2Glenn Kasten
1723b3f68cab75e480ac93d656a6e4f60b979de6d2Glenn Kasten/* PlaybackRate implementation */
1823b3f68cab75e480ac93d656a6e4f60b979de6d2Glenn Kasten
1923b3f68cab75e480ac93d656a6e4f60b979de6d2Glenn Kasten#include "sles_allinclusive.h"
2023b3f68cab75e480ac93d656a6e4f60b979de6d2Glenn Kasten
21f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten
2223b3f68cab75e480ac93d656a6e4f60b979de6d2Glenn Kastenstatic SLresult IPlaybackRate_SetRate(SLPlaybackRateItf self, SLpermille rate)
2323b3f68cab75e480ac93d656a6e4f60b979de6d2Glenn Kasten{
24f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten    SL_ENTER_INTERFACE
25f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten
2650bccde01980ae803b8656e8b08ecacb65540f50Glenn Kasten    IPlaybackRate *thiz = (IPlaybackRate *) self;
27437f9ab9914ea61112aa496a047162a0d22194cdGlenn Kasten    // const, so no lock needed
2850bccde01980ae803b8656e8b08ecacb65540f50Glenn Kasten    if (!(thiz->mMinRate <= rate && rate <= thiz->mMaxRate)) {
29f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten        result = SL_RESULT_PARAMETER_INVALID;
30f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten    } else {
3150bccde01980ae803b8656e8b08ecacb65540f50Glenn Kasten        interface_lock_exclusive(thiz);
329db8335361c67c4ed877f68218835df96ce43a4bJean-Michel Trivi#ifdef ANDROID
3350bccde01980ae803b8656e8b08ecacb65540f50Glenn Kasten        CAudioPlayer *ap = (SL_OBJECTID_AUDIOPLAYER == InterfaceToObjectID(thiz)) ?
3450bccde01980ae803b8656e8b08ecacb65540f50Glenn Kasten                (CAudioPlayer *) thiz->mThis : NULL;
3567537364adc48cd6fa56e36d4201428b5d9dedafJean-Michel Trivi        if (NULL != ap) {
3631b842fa58d602d38cdf2937efc4b47603bbb71eGlenn Kasten            result = android_audioPlayer_setPlaybackRateAndConstraints(ap, rate, thiz->mProperties);
3767537364adc48cd6fa56e36d4201428b5d9dedafJean-Michel Trivi        } else {
3831b842fa58d602d38cdf2937efc4b47603bbb71eGlenn Kasten            result = SL_RESULT_FEATURE_UNSUPPORTED;
3967537364adc48cd6fa56e36d4201428b5d9dedafJean-Michel Trivi        }
40f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten#else
41f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten        result = SL_RESULT_SUCCESS;
420793e68d3c69c490de12633f757d7816fcde5392Jean-Michel Trivi#endif
4331b842fa58d602d38cdf2937efc4b47603bbb71eGlenn Kasten        if (SL_RESULT_SUCCESS == result) {
4431b842fa58d602d38cdf2937efc4b47603bbb71eGlenn Kasten            thiz->mRate = rate;
4531b842fa58d602d38cdf2937efc4b47603bbb71eGlenn Kasten        }
4631b842fa58d602d38cdf2937efc4b47603bbb71eGlenn Kasten        interface_unlock_exclusive(thiz);
47f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten    }
48f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten
49f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten    SL_LEAVE_INTERFACE
5023b3f68cab75e480ac93d656a6e4f60b979de6d2Glenn Kasten}
5123b3f68cab75e480ac93d656a6e4f60b979de6d2Glenn Kasten
52f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten
5323b3f68cab75e480ac93d656a6e4f60b979de6d2Glenn Kastenstatic SLresult IPlaybackRate_GetRate(SLPlaybackRateItf self, SLpermille *pRate)
5423b3f68cab75e480ac93d656a6e4f60b979de6d2Glenn Kasten{
55f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten    SL_ENTER_INTERFACE
56f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten
570793e68d3c69c490de12633f757d7816fcde5392Jean-Michel Trivi    if (NULL == pRate) {
58f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten        result = SL_RESULT_PARAMETER_INVALID;
59f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten    } else {
6050bccde01980ae803b8656e8b08ecacb65540f50Glenn Kasten        IPlaybackRate *thiz = (IPlaybackRate *) self;
6131b842fa58d602d38cdf2937efc4b47603bbb71eGlenn Kasten        interface_lock_shared(thiz);
6250bccde01980ae803b8656e8b08ecacb65540f50Glenn Kasten        SLpermille rate = thiz->mRate;
6331b842fa58d602d38cdf2937efc4b47603bbb71eGlenn Kasten        interface_unlock_shared(thiz);
64f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten        *pRate = rate;
65f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten        result = SL_RESULT_SUCCESS;
660793e68d3c69c490de12633f757d7816fcde5392Jean-Michel Trivi    }
67f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten
68f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten    SL_LEAVE_INTERFACE
6923b3f68cab75e480ac93d656a6e4f60b979de6d2Glenn Kasten}
7023b3f68cab75e480ac93d656a6e4f60b979de6d2Glenn Kasten
71f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten
72437f9ab9914ea61112aa496a047162a0d22194cdGlenn Kastenstatic SLresult IPlaybackRate_SetPropertyConstraints(SLPlaybackRateItf self, SLuint32 constraints)
7323b3f68cab75e480ac93d656a6e4f60b979de6d2Glenn Kasten{
74f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten    SL_ENTER_INTERFACE
75f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten
7650bccde01980ae803b8656e8b08ecacb65540f50Glenn Kasten    IPlaybackRate *thiz = (IPlaybackRate *) self;
7731b842fa58d602d38cdf2937efc4b47603bbb71eGlenn Kasten    if (constraints & ~(SL_RATEPROP_SILENTAUDIO | SL_RATEPROP_STAGGEREDAUDIO |
7831b842fa58d602d38cdf2937efc4b47603bbb71eGlenn Kasten            SL_RATEPROP_NOPITCHCORAUDIO | SL_RATEPROP_PITCHCORAUDIO)) {
7967537364adc48cd6fa56e36d4201428b5d9dedafJean-Michel Trivi        result = SL_RESULT_PARAMETER_INVALID;
8031b842fa58d602d38cdf2937efc4b47603bbb71eGlenn Kasten    // const, so no lock needed
8131b842fa58d602d38cdf2937efc4b47603bbb71eGlenn Kasten    } else if (!(thiz->mCapabilities & constraints)) {
8231b842fa58d602d38cdf2937efc4b47603bbb71eGlenn Kasten        result = SL_RESULT_FEATURE_UNSUPPORTED;
8331b842fa58d602d38cdf2937efc4b47603bbb71eGlenn Kasten    } else {
8431b842fa58d602d38cdf2937efc4b47603bbb71eGlenn Kasten        interface_lock_exclusive(thiz);
8531b842fa58d602d38cdf2937efc4b47603bbb71eGlenn Kasten#ifdef ANDROID
8631b842fa58d602d38cdf2937efc4b47603bbb71eGlenn Kasten        // verify property support before storing
8731b842fa58d602d38cdf2937efc4b47603bbb71eGlenn Kasten        CAudioPlayer *ap = (SL_OBJECTID_AUDIOPLAYER == InterfaceToObjectID(thiz)) ?
8831b842fa58d602d38cdf2937efc4b47603bbb71eGlenn Kasten                (CAudioPlayer *) thiz->mThis : NULL;
8931b842fa58d602d38cdf2937efc4b47603bbb71eGlenn Kasten        if (NULL != ap) {
9031b842fa58d602d38cdf2937efc4b47603bbb71eGlenn Kasten            result = android_audioPlayer_setPlaybackRateAndConstraints(ap, thiz->mRate,
9131b842fa58d602d38cdf2937efc4b47603bbb71eGlenn Kasten                    constraints);
9231b842fa58d602d38cdf2937efc4b47603bbb71eGlenn Kasten        } else {
9331b842fa58d602d38cdf2937efc4b47603bbb71eGlenn Kasten            result = SL_RESULT_FEATURE_UNSUPPORTED;
9431b842fa58d602d38cdf2937efc4b47603bbb71eGlenn Kasten        }
95f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten#else
9631b842fa58d602d38cdf2937efc4b47603bbb71eGlenn Kasten        result = SL_RESULT_SUCCESS;
970793e68d3c69c490de12633f757d7816fcde5392Jean-Michel Trivi#endif
9831b842fa58d602d38cdf2937efc4b47603bbb71eGlenn Kasten        if (result == SL_RESULT_SUCCESS) {
9931b842fa58d602d38cdf2937efc4b47603bbb71eGlenn Kasten            thiz->mProperties = constraints;
10031b842fa58d602d38cdf2937efc4b47603bbb71eGlenn Kasten        }
10131b842fa58d602d38cdf2937efc4b47603bbb71eGlenn Kasten        interface_unlock_exclusive(thiz);
1020793e68d3c69c490de12633f757d7816fcde5392Jean-Michel Trivi    }
103f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten
104f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten    SL_LEAVE_INTERFACE
10523b3f68cab75e480ac93d656a6e4f60b979de6d2Glenn Kasten}
10623b3f68cab75e480ac93d656a6e4f60b979de6d2Glenn Kasten
107f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten
108437f9ab9914ea61112aa496a047162a0d22194cdGlenn Kastenstatic SLresult IPlaybackRate_GetProperties(SLPlaybackRateItf self, SLuint32 *pProperties)
10923b3f68cab75e480ac93d656a6e4f60b979de6d2Glenn Kasten{
110f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten    SL_ENTER_INTERFACE
111f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten
1120793e68d3c69c490de12633f757d7816fcde5392Jean-Michel Trivi    if (NULL == pProperties) {
113f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten        result = SL_RESULT_PARAMETER_INVALID;
114f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten    } else {
11550bccde01980ae803b8656e8b08ecacb65540f50Glenn Kasten        IPlaybackRate *thiz = (IPlaybackRate *) self;
11631b842fa58d602d38cdf2937efc4b47603bbb71eGlenn Kasten        interface_lock_shared(thiz);
11750bccde01980ae803b8656e8b08ecacb65540f50Glenn Kasten        SLuint32 properties = thiz->mProperties;
11831b842fa58d602d38cdf2937efc4b47603bbb71eGlenn Kasten        interface_unlock_shared(thiz);
119f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten        *pProperties = properties;
120f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten        result = SL_RESULT_SUCCESS;
1210793e68d3c69c490de12633f757d7816fcde5392Jean-Michel Trivi    }
122f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten
123f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten    SL_LEAVE_INTERFACE
12423b3f68cab75e480ac93d656a6e4f60b979de6d2Glenn Kasten}
12523b3f68cab75e480ac93d656a6e4f60b979de6d2Glenn Kasten
126f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten
12723b3f68cab75e480ac93d656a6e4f60b979de6d2Glenn Kastenstatic SLresult IPlaybackRate_GetCapabilitiesOfRate(SLPlaybackRateItf self,
12823b3f68cab75e480ac93d656a6e4f60b979de6d2Glenn Kasten    SLpermille rate, SLuint32 *pCapabilities)
12923b3f68cab75e480ac93d656a6e4f60b979de6d2Glenn Kasten{
130f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten    SL_ENTER_INTERFACE
131f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten
1320793e68d3c69c490de12633f757d7816fcde5392Jean-Michel Trivi    if (NULL == pCapabilities) {
133f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten        result = SL_RESULT_PARAMETER_INVALID;
134f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten    } else {
13550bccde01980ae803b8656e8b08ecacb65540f50Glenn Kasten        IPlaybackRate *thiz = (IPlaybackRate *) self;
13631b842fa58d602d38cdf2937efc4b47603bbb71eGlenn Kasten        SLuint32 capabilities;
137f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten        // const, so no lock needed
13850bccde01980ae803b8656e8b08ecacb65540f50Glenn Kasten        if (!(thiz->mMinRate <= rate && rate <= thiz->mMaxRate)) {
13931b842fa58d602d38cdf2937efc4b47603bbb71eGlenn Kasten            capabilities = 0;
140f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten            result = SL_RESULT_PARAMETER_INVALID;
141f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten        } else {
14250bccde01980ae803b8656e8b08ecacb65540f50Glenn Kasten            capabilities = thiz->mCapabilities;
143f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten            result = SL_RESULT_SUCCESS;
144f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten        }
14531b842fa58d602d38cdf2937efc4b47603bbb71eGlenn Kasten        *pCapabilities = capabilities;
146f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten    }
147f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten
148f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten    SL_LEAVE_INTERFACE
14923b3f68cab75e480ac93d656a6e4f60b979de6d2Glenn Kasten}
15023b3f68cab75e480ac93d656a6e4f60b979de6d2Glenn Kasten
151f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten
15223b3f68cab75e480ac93d656a6e4f60b979de6d2Glenn Kastenstatic SLresult IPlaybackRate_GetRateRange(SLPlaybackRateItf self, SLuint8 index,
153437f9ab9914ea61112aa496a047162a0d22194cdGlenn Kasten    SLpermille *pMinRate, SLpermille *pMaxRate, SLpermille *pStepSize, SLuint32 *pCapabilities)
15423b3f68cab75e480ac93d656a6e4f60b979de6d2Glenn Kasten{
155f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten    SL_ENTER_INTERFACE
156f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten
157437f9ab9914ea61112aa496a047162a0d22194cdGlenn Kasten    // only one range
158f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten    if (NULL == pMinRate || NULL == pMaxRate || NULL == pStepSize || NULL == pCapabilities ||
159f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten        (0 < index)) {
160f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten        result = SL_RESULT_PARAMETER_INVALID;
161f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten    } else {
16250bccde01980ae803b8656e8b08ecacb65540f50Glenn Kasten        IPlaybackRate *thiz = (IPlaybackRate *) self;
16331b842fa58d602d38cdf2937efc4b47603bbb71eGlenn Kasten        // const, so no lock needed
16450bccde01980ae803b8656e8b08ecacb65540f50Glenn Kasten        SLpermille minRate = thiz->mMinRate;
16550bccde01980ae803b8656e8b08ecacb65540f50Glenn Kasten        SLpermille maxRate = thiz->mMaxRate;
16650bccde01980ae803b8656e8b08ecacb65540f50Glenn Kasten        SLpermille stepSize = thiz->mStepSize;
16750bccde01980ae803b8656e8b08ecacb65540f50Glenn Kasten        SLuint32 capabilities = thiz->mCapabilities;
168f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten        *pMinRate = minRate;
169f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten        *pMaxRate = maxRate;
170f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten        *pStepSize = stepSize;
171f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten        *pCapabilities = capabilities;
172f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten        result = SL_RESULT_SUCCESS;
173f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten    }
174f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten
175f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten    SL_LEAVE_INTERFACE
17623b3f68cab75e480ac93d656a6e4f60b979de6d2Glenn Kasten}
17723b3f68cab75e480ac93d656a6e4f60b979de6d2Glenn Kasten
178f156301680273e71e56e898f98798f5b5b2431f6Glenn Kasten
17923b3f68cab75e480ac93d656a6e4f60b979de6d2Glenn Kastenstatic const struct SLPlaybackRateItf_ IPlaybackRate_Itf = {
18023b3f68cab75e480ac93d656a6e4f60b979de6d2Glenn Kasten    IPlaybackRate_SetRate,
18123b3f68cab75e480ac93d656a6e4f60b979de6d2Glenn Kasten    IPlaybackRate_GetRate,
18223b3f68cab75e480ac93d656a6e4f60b979de6d2Glenn Kasten    IPlaybackRate_SetPropertyConstraints,
18323b3f68cab75e480ac93d656a6e4f60b979de6d2Glenn Kasten    IPlaybackRate_GetProperties,
18423b3f68cab75e480ac93d656a6e4f60b979de6d2Glenn Kasten    IPlaybackRate_GetCapabilitiesOfRate,
18523b3f68cab75e480ac93d656a6e4f60b979de6d2Glenn Kasten    IPlaybackRate_GetRateRange
18623b3f68cab75e480ac93d656a6e4f60b979de6d2Glenn Kasten};
18723b3f68cab75e480ac93d656a6e4f60b979de6d2Glenn Kasten
18823b3f68cab75e480ac93d656a6e4f60b979de6d2Glenn Kastenvoid IPlaybackRate_init(void *self)
18923b3f68cab75e480ac93d656a6e4f60b979de6d2Glenn Kasten{
19050bccde01980ae803b8656e8b08ecacb65540f50Glenn Kasten    IPlaybackRate *thiz = (IPlaybackRate *) self;
19150bccde01980ae803b8656e8b08ecacb65540f50Glenn Kasten    thiz->mItf = &IPlaybackRate_Itf;
19250bccde01980ae803b8656e8b08ecacb65540f50Glenn Kasten    thiz->mProperties = SL_RATEPROP_NOPITCHCORAUDIO;
19350bccde01980ae803b8656e8b08ecacb65540f50Glenn Kasten    thiz->mRate = 1000;
19431b842fa58d602d38cdf2937efc4b47603bbb71eGlenn Kasten    // const after initialization; these are default values which may be overwritten
19531b842fa58d602d38cdf2937efc4b47603bbb71eGlenn Kasten    // during object creation but will not be modified after that
19631b842fa58d602d38cdf2937efc4b47603bbb71eGlenn Kasten    // (e.g. for an Android AudioPlayer, see sles_to_android_audioPlayerCreate)
19731b842fa58d602d38cdf2937efc4b47603bbb71eGlenn Kasten    thiz->mMinRate = 1000;
19831b842fa58d602d38cdf2937efc4b47603bbb71eGlenn Kasten    thiz->mMaxRate = 1000;
19950bccde01980ae803b8656e8b08ecacb65540f50Glenn Kasten    thiz->mStepSize = 0;
20031b842fa58d602d38cdf2937efc4b47603bbb71eGlenn Kasten    thiz->mCapabilities = SL_RATEPROP_NOPITCHCORAUDIO;
20123b3f68cab75e480ac93d656a6e4f60b979de6d2Glenn Kasten}
202