IPlaybackRate.c revision 262059f71a68edc5e510427c63f5f1623d3672a8
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/* PlaybackRate implementation */
18
19#include "sles_allinclusive.h"
20
21
22static SLresult IPlaybackRate_SetRate(SLPlaybackRateItf self, SLpermille rate)
23{
24    SL_ENTER_INTERFACE
25
26    IPlaybackRate *this = (IPlaybackRate *) self;
27    // const, so no lock needed
28    if (!(this->mMinRate <= rate && rate <= this->mMaxRate)) {
29        result = SL_RESULT_PARAMETER_INVALID;
30    } else {
31        interface_lock_exclusive(this);
32        this->mRate = rate;
33        interface_unlock_exclusive(this);
34#ifdef ANDROID
35        CAudioPlayer *ap = (SL_OBJECTID_AUDIOPLAYER == InterfaceToObjectID(this)) ?
36                (CAudioPlayer *) this->mThis : NULL;
37        if (NULL != ap) {
38            result = android_audioPlayer_setPlayRate(ap, rate, true);
39        } else {
40            result = SL_RESULT_PARAMETER_INVALID;
41        }
42#else
43        result = SL_RESULT_SUCCESS;
44#endif
45    }
46
47    SL_LEAVE_INTERFACE
48}
49
50
51static SLresult IPlaybackRate_GetRate(SLPlaybackRateItf self, SLpermille *pRate)
52{
53    SL_ENTER_INTERFACE
54
55    if (NULL == pRate) {
56        result = SL_RESULT_PARAMETER_INVALID;
57    } else {
58        IPlaybackRate *this = (IPlaybackRate *) self;
59        interface_lock_peek(this);
60        SLpermille rate = this->mRate;
61        interface_unlock_peek(this);
62        *pRate = rate;
63        result = SL_RESULT_SUCCESS;
64    }
65
66    SL_LEAVE_INTERFACE
67}
68
69
70static SLresult IPlaybackRate_SetPropertyConstraints(SLPlaybackRateItf self, SLuint32 constraints)
71{
72    SL_ENTER_INTERFACE
73
74    IPlaybackRate *this = (IPlaybackRate *) self;
75    this->mProperties = constraints;
76#ifdef ANDROID
77    // verify property support before storing
78    CAudioPlayer *ap = (SL_OBJECTID_AUDIOPLAYER == InterfaceToObjectID(this)) ?
79            (CAudioPlayer *) this->mThis : NULL;
80    if (NULL != ap) {
81        result = android_audioPlayer_setPlaybackRateBehavior(ap, constraints);
82    } else {
83        result = SL_RESULT_PARAMETER_INVALID;
84    }
85
86#else
87    result = SL_RESULT_SUCCESS;
88#endif
89    interface_lock_poke(this);
90    if (result == SL_RESULT_SUCCESS) {
91        this->mProperties = constraints;
92    }
93    interface_unlock_poke(this);
94
95    SL_LEAVE_INTERFACE
96}
97
98
99static SLresult IPlaybackRate_GetProperties(SLPlaybackRateItf self, SLuint32 *pProperties)
100{
101    SL_ENTER_INTERFACE
102
103    if (NULL == pProperties) {
104        result = SL_RESULT_PARAMETER_INVALID;
105    } else {
106        IPlaybackRate *this = (IPlaybackRate *) self;
107        interface_lock_peek(this);
108        SLuint32 properties = this->mProperties;
109        interface_unlock_peek(this);
110        *pProperties = properties;
111        result = SL_RESULT_SUCCESS;
112    }
113
114    SL_LEAVE_INTERFACE
115}
116
117
118static SLresult IPlaybackRate_GetCapabilitiesOfRate(SLPlaybackRateItf self,
119    SLpermille rate, SLuint32 *pCapabilities)
120{
121    SL_ENTER_INTERFACE
122
123    if (NULL == pCapabilities) {
124        result = SL_RESULT_PARAMETER_INVALID;
125    } else {
126        IPlaybackRate *this = (IPlaybackRate *) self;
127        // const, so no lock needed
128        if (!(this->mMinRate <= rate && rate <= this->mMaxRate)) {
129            result = SL_RESULT_PARAMETER_INVALID;
130        } else {
131            SLuint32 capabilities = 0;
132#ifdef ANDROID
133            CAudioPlayer *ap = (SL_OBJECTID_AUDIOPLAYER == InterfaceToObjectID(this)) ?
134                    (CAudioPlayer *) this->mThis : NULL;
135            if (NULL != ap) {
136                android_audioPlayer_getCapabilitiesOfRate(ap, &capabilities);
137            }
138#else
139            capabilities = this->mCapabilities;
140#endif
141            *pCapabilities = capabilities;
142            result = SL_RESULT_SUCCESS;
143        }
144    }
145
146    SL_LEAVE_INTERFACE
147}
148
149
150static SLresult IPlaybackRate_GetRateRange(SLPlaybackRateItf self, SLuint8 index,
151    SLpermille *pMinRate, SLpermille *pMaxRate, SLpermille *pStepSize, SLuint32 *pCapabilities)
152{
153    SL_ENTER_INTERFACE
154
155    // only one range
156    if (NULL == pMinRate || NULL == pMaxRate || NULL == pStepSize || NULL == pCapabilities ||
157        (0 < index)) {
158        result = SL_RESULT_PARAMETER_INVALID;
159    } else {
160        IPlaybackRate *this = (IPlaybackRate *) self;
161        interface_lock_shared(this);
162        SLpermille minRate = this->mMinRate;
163        SLpermille maxRate = this->mMaxRate;
164        SLpermille stepSize = this->mStepSize;
165        SLuint32 capabilities = this->mCapabilities;
166        interface_unlock_shared(this);
167        *pMinRate = minRate;
168        *pMaxRate = maxRate;
169        *pStepSize = stepSize;
170        *pCapabilities = capabilities;
171        result = SL_RESULT_SUCCESS;
172    }
173
174    SL_LEAVE_INTERFACE
175}
176
177
178static const struct SLPlaybackRateItf_ IPlaybackRate_Itf = {
179    IPlaybackRate_SetRate,
180    IPlaybackRate_GetRate,
181    IPlaybackRate_SetPropertyConstraints,
182    IPlaybackRate_GetProperties,
183    IPlaybackRate_GetCapabilitiesOfRate,
184    IPlaybackRate_GetRateRange
185};
186
187void IPlaybackRate_init(void *self)
188{
189    IPlaybackRate *this = (IPlaybackRate *) self;
190    this->mItf = &IPlaybackRate_Itf;
191    this->mProperties = SL_RATEPROP_NOPITCHCORAUDIO;
192    this->mRate = 1000;
193    // const
194    this->mMinRate = 500;
195    this->mMaxRate = 2000;
196    this->mStepSize = 0;
197#ifdef ANDROID
198    // for an AudioPlayer, mCapabilities will be initialized in sles_to_android_audioPlayerCreate
199#endif
200    // The generic implementation sets no capabilities because the generic
201    // implementation alone doesn't support any.
202    this->mCapabilities = 0;
203    // SL_RATEPROP_SILENTAUDIO | SL_RATEPROP_STAGGEREDAUDIO | SL_RATEPROP_NOPITCHCORAUDIO |
204    // SL_RATEPROP_PITCHCORAUDIO
205}
206