IEqualizer.cpp revision 7c3fe21525e62f24acc9d391f9d396ce2d7e57ac
1a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten/*
2a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten * Copyright (C) 2010 The Android Open Source Project
3a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten *
4a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten * Licensed under the Apache License, Version 2.0 (the "License");
5a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten * you may not use this file except in compliance with the License.
6a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten * You may obtain a copy of the License at
7a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten *
8a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten *      http://www.apache.org/licenses/LICENSE-2.0
9a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten *
10a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten * Unless required by applicable law or agreed to in writing, software
11a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten * distributed under the License is distributed on an "AS IS" BASIS,
12a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten * See the License for the specific language governing permissions and
14a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten * limitations under the License.
15a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten */
16a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten
17a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten/* Equalizer implementation */
18a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten
19a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten#include "sles_allinclusive.h"
20a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten
213a413f1863daa026ed2b9fc9eac01e1341116cdbGlenn Kasten// FIXME move to platform-specific configuration
220b167267bda99b68346045ccab14e810121d5de4Glenn Kasten
233a413f1863daa026ed2b9fc9eac01e1341116cdbGlenn Kasten#define MAX_EQ_PRESETS 3
243a413f1863daa026ed2b9fc9eac01e1341116cdbGlenn Kasten
2514e903028c4abfc1b2fbfab6560e3b864086f895Glenn Kasten#if !defined(ANDROID) || defined(USE_BACKPORT)
264be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi// FIXME needs to be defined in a platform-dependent manner
273a413f1863daa026ed2b9fc9eac01e1341116cdbGlenn Kastenstatic const struct EqualizerBand EqualizerBands[MAX_EQ_BANDS] = {
280b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    {1000, 1500, 2000},
290b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    {2000, 3000, 4000},
300b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    {4000, 5500, 7000},
310b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    {7000, 8000, 9000}
320b167267bda99b68346045ccab14e810121d5de4Glenn Kasten};
330b167267bda99b68346045ccab14e810121d5de4Glenn Kasten
343a413f1863daa026ed2b9fc9eac01e1341116cdbGlenn Kastenstatic const struct EqualizerPreset {
353a413f1863daa026ed2b9fc9eac01e1341116cdbGlenn Kasten    const char *mName;
363a413f1863daa026ed2b9fc9eac01e1341116cdbGlenn Kasten    SLmillibel mLevels[MAX_EQ_BANDS];
373a413f1863daa026ed2b9fc9eac01e1341116cdbGlenn Kasten} EqualizerPresets[MAX_EQ_PRESETS] = {
383a413f1863daa026ed2b9fc9eac01e1341116cdbGlenn Kasten    {"Default", {0, 0, 0, 0}},
393a413f1863daa026ed2b9fc9eac01e1341116cdbGlenn Kasten    {"Bass", {500, 200, 100, 0}},
403a413f1863daa026ed2b9fc9eac01e1341116cdbGlenn Kasten    {"Treble", {0, 100, 200, 500}}
410b167267bda99b68346045ccab14e810121d5de4Glenn Kasten};
424be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi#endif
430b167267bda99b68346045ccab14e810121d5de4Glenn Kasten
44ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
45a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kastenstatic SLresult IEqualizer_SetEnabled(SLEqualizerItf self, SLboolean enabled)
46a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten{
47ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    SL_ENTER_INTERFACE
48ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
49a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten    IEqualizer *this = (IEqualizer *) self;
504be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi    interface_lock_exclusive(this);
51d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kasten    this->mEnabled = SL_BOOLEAN_FALSE != enabled; // normalize
5214e903028c4abfc1b2fbfab6560e3b864086f895Glenn Kasten#if !defined(ANDROID) || defined(USE_BACKPORT)
53ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    result = SL_RESULT_SUCCESS;
544be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi#else
554be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi    bool fxEnabled = this->mEqEffect->getEnabled();
564be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi    // the audio effect framework will return an error if you set the same "enabled" state as
574be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi    // the one the effect is currently in, so we only act on state changes
589cd3c9e7a2395647b92c32f33c06cf9fd546b22fJean-Michel Trivi    // FIXME this has been fixed, update this function and IsEnabled to behave like the BassBoost
599cd3c9e7a2395647b92c32f33c06cf9fd546b22fJean-Michel Trivi    //       implementation
604be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi    if (fxEnabled != (enabled == SL_BOOLEAN_TRUE)) {
614be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi        // state change
624be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi        android::status_t status = this->mEqEffect->setEnabled(this->mEnabled == SL_BOOLEAN_TRUE);
634be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi        result = android_fx_statusToResult(status);
644be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi    } else {
654be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi        result = SL_RESULT_SUCCESS;
664be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi    }
674be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi#endif
684be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi    interface_unlock_exclusive(this);
69ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
70ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    SL_LEAVE_INTERFACE
71a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten}
72a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten
73ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
74a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kastenstatic SLresult IEqualizer_IsEnabled(SLEqualizerItf self, SLboolean *pEnabled)
75a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten{
76ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    SL_ENTER_INTERFACE
77ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
78ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    if (NULL == pEnabled) {
79ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        result = SL_RESULT_PARAMETER_INVALID;
80ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    } else {
81ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        IEqualizer *this = (IEqualizer *) self;
824be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi        interface_lock_shared(this);
83ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        SLboolean enabled = this->mEnabled;
844be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi        interface_unlock_shared(this);
8514e903028c4abfc1b2fbfab6560e3b864086f895Glenn Kasten#if !defined(ANDROID) || defined(USE_BACKPORT)
86ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        *pEnabled = enabled;
87ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        result = SL_RESULT_SUCCESS;
884be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi#else
894be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi        bool fxEnabled = this->mEqEffect->getEnabled();
904be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi        *pEnabled = fxEnabled ? SL_BOOLEAN_TRUE : SL_BOOLEAN_FALSE;
914be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi        result = SL_RESULT_SUCCESS;
924be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi#endif
93ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    }
94ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
95ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    SL_LEAVE_INTERFACE
96a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten}
97a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten
98ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
993a413f1863daa026ed2b9fc9eac01e1341116cdbGlenn Kastenstatic SLresult IEqualizer_GetNumberOfBands(SLEqualizerItf self, SLuint16 *pNumBands)
100a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten{
101ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    SL_ENTER_INTERFACE
102ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
103ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    if (NULL == pNumBands) {
104ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        result = SL_RESULT_PARAMETER_INVALID;
105ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    } else {
106ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        IEqualizer *this = (IEqualizer *) self;
107ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        // Note: no lock, but OK because it is const
108ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        *pNumBands = this->mNumBands;
109ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        result = SL_RESULT_SUCCESS;
110ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    }
111ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
112ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    SL_LEAVE_INTERFACE
113a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten}
114a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten
115ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
116e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kastenstatic SLresult IEqualizer_GetBandLevelRange(SLEqualizerItf self, SLmillibel *pMin,
117e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten    SLmillibel *pMax)
118a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten{
119ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    SL_ENTER_INTERFACE
120ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
121ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    if (NULL == pMin && NULL == pMax) {
122ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        result = SL_RESULT_PARAMETER_INVALID;
123ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    } else {
124ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        IEqualizer *this = (IEqualizer *) self;
125ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        // Note: no lock, but OK because it is const
126ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        if (NULL != pMin)
127ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten            *pMin = this->mBandLevelRangeMin;
128ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        if (NULL != pMax)
129ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten            *pMax = this->mBandLevelRangeMax;
130ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        result = SL_RESULT_SUCCESS;
131ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    }
132ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
133ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    SL_LEAVE_INTERFACE
134a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten}
135a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten
136ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
1373a413f1863daa026ed2b9fc9eac01e1341116cdbGlenn Kastenstatic SLresult IEqualizer_SetBandLevel(SLEqualizerItf self, SLuint16 band, SLmillibel level)
138a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten{
139ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    SL_ENTER_INTERFACE
140ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
141a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten    IEqualizer *this = (IEqualizer *) self;
142ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    if (!(this->mBandLevelRangeMin <= level && level <= this->mBandLevelRangeMax) ||
1434be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi            (band >= this->mNumBands)) {
144ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        result = SL_RESULT_PARAMETER_INVALID;
145ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    } else {
146ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        interface_lock_exclusive(this);
14714e903028c4abfc1b2fbfab6560e3b864086f895Glenn Kasten#if !defined(ANDROID) || defined(USE_BACKPORT)
148ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        this->mLevels[band] = level;
149ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        this->mPreset = SL_EQUALIZER_UNDEFINED;
150ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        result = SL_RESULT_SUCCESS;
1514be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi#else
1529cd3c9e7a2395647b92c32f33c06cf9fd546b22fJean-Michel Trivi        if (this->mEqEffect != 0) {
1539cd3c9e7a2395647b92c32f33c06cf9fd546b22fJean-Michel Trivi            android::status_t status =
1544be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi                android_eq_setParam(this->mEqEffect, EQ_PARAM_BAND_LEVEL, band, &level);
1559cd3c9e7a2395647b92c32f33c06cf9fd546b22fJean-Michel Trivi            result = android_fx_statusToResult(status);
1569cd3c9e7a2395647b92c32f33c06cf9fd546b22fJean-Michel Trivi        } else {
1579cd3c9e7a2395647b92c32f33c06cf9fd546b22fJean-Michel Trivi            result = SL_RESULT_CONTROL_LOST;
1589cd3c9e7a2395647b92c32f33c06cf9fd546b22fJean-Michel Trivi        }
1594be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi#endif
1604be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi        interface_unlock_exclusive(this);
161ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    }
162ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
163ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    SL_LEAVE_INTERFACE
164a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten}
165a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten
166ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
167d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kastenstatic SLresult IEqualizer_GetBandLevel(SLEqualizerItf self, SLuint16 band, SLmillibel *pLevel)
168a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten{
169ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    SL_ENTER_INTERFACE
170ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
171ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    if (NULL == pLevel) {
172ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        result = SL_RESULT_PARAMETER_INVALID;
173ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    } else {
174ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        IEqualizer *this = (IEqualizer *) self;
175ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        // const, no lock needed
176ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        if (band >= this->mNumBands) {
177ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten            result = SL_RESULT_PARAMETER_INVALID;
178ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        } else {
1799cd3c9e7a2395647b92c32f33c06cf9fd546b22fJean-Michel Trivi            SLmillibel level = 0;
1804be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi            interface_lock_shared(this);
18114e903028c4abfc1b2fbfab6560e3b864086f895Glenn Kasten#if !defined(ANDROID) || defined(USE_BACKPORT)
1824be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi            level = this->mLevels[band];
183ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten            result = SL_RESULT_SUCCESS;
1844be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi#else
1859cd3c9e7a2395647b92c32f33c06cf9fd546b22fJean-Michel Trivi            if (this->mEqEffect != 0) {
1869cd3c9e7a2395647b92c32f33c06cf9fd546b22fJean-Michel Trivi                android::status_t status =
1874be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi                    android_eq_getParam(this->mEqEffect, EQ_PARAM_BAND_LEVEL, band, &level);
1889cd3c9e7a2395647b92c32f33c06cf9fd546b22fJean-Michel Trivi                result = android_fx_statusToResult(status);
1899cd3c9e7a2395647b92c32f33c06cf9fd546b22fJean-Michel Trivi            } else {
1909cd3c9e7a2395647b92c32f33c06cf9fd546b22fJean-Michel Trivi                result = SL_RESULT_CONTROL_LOST;
1919cd3c9e7a2395647b92c32f33c06cf9fd546b22fJean-Michel Trivi            }
1924be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi#endif
1934be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi            interface_unlock_shared(this);
1944be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi            *pLevel = level;
195ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        }
196ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    }
197ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
198ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    SL_LEAVE_INTERFACE
199a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten}
200a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten
201ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
2023a413f1863daa026ed2b9fc9eac01e1341116cdbGlenn Kastenstatic SLresult IEqualizer_GetCenterFreq(SLEqualizerItf self, SLuint16 band, SLmilliHertz *pCenter)
203a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten{
204ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    SL_ENTER_INTERFACE
205ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
206ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    if (NULL == pCenter) {
207ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        result = SL_RESULT_PARAMETER_INVALID;
208ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    } else {
209ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        IEqualizer *this = (IEqualizer *) self;
210ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        if (band >= this->mNumBands) {
211ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten            result = SL_RESULT_PARAMETER_INVALID;
212ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        } else {
21314e903028c4abfc1b2fbfab6560e3b864086f895Glenn Kasten#if !defined(ANDROID) || defined(USE_BACKPORT)
214ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten            // Note: no lock, but OK because it is const
215ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten            *pCenter = this->mBands[band].mCenter;
216ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten            result = SL_RESULT_SUCCESS;
2174be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi#else
2189cd3c9e7a2395647b92c32f33c06cf9fd546b22fJean-Michel Trivi            SLmilliHertz center = 0;
2194be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi            interface_lock_shared(this);
2209cd3c9e7a2395647b92c32f33c06cf9fd546b22fJean-Michel Trivi            if (this->mEqEffect != 0) {
2219cd3c9e7a2395647b92c32f33c06cf9fd546b22fJean-Michel Trivi                android::status_t status =
2224be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi                    android_eq_getParam(this->mEqEffect, EQ_PARAM_CENTER_FREQ, band, &center);
2239cd3c9e7a2395647b92c32f33c06cf9fd546b22fJean-Michel Trivi                result = android_fx_statusToResult(status);
2249cd3c9e7a2395647b92c32f33c06cf9fd546b22fJean-Michel Trivi            } else {
2259cd3c9e7a2395647b92c32f33c06cf9fd546b22fJean-Michel Trivi                result = SL_RESULT_CONTROL_LOST;
2269cd3c9e7a2395647b92c32f33c06cf9fd546b22fJean-Michel Trivi            }
2274be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi            interface_unlock_shared(this);
2284be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi            *pCenter = center;
2294be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi#endif
230ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        }
231ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    }
232ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
233ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    SL_LEAVE_INTERFACE
234a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten}
235a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten
236ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
237a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kastenstatic SLresult IEqualizer_GetBandFreqRange(SLEqualizerItf self, SLuint16 band,
238a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten    SLmilliHertz *pMin, SLmilliHertz *pMax)
239a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten{
240ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    SL_ENTER_INTERFACE
241ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
242ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    if (NULL == pMin && NULL == pMax) {
243ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        result = SL_RESULT_PARAMETER_INVALID;
244ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    } else {
245ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        IEqualizer *this = (IEqualizer *) self;
246ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        if (band >= this->mNumBands) {
247ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten            result = SL_RESULT_PARAMETER_INVALID;
248ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        } else {
24914e903028c4abfc1b2fbfab6560e3b864086f895Glenn Kasten#if !defined(ANDROID) || defined(USE_BACKPORT)
250ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten            // Note: no lock, but OK because it is const
251ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten            if (NULL != pMin)
252ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten                *pMin = this->mBands[band].mMin;
253ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten            if (NULL != pMax)
254ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten                *pMax = this->mBands[band].mMax;
255ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten            result = SL_RESULT_SUCCESS;
2564be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi#else
2579cd3c9e7a2395647b92c32f33c06cf9fd546b22fJean-Michel Trivi            SLmilliHertz range[2] = {0, 0}; // SLmilliHertz is SLuint32
2584be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi            interface_lock_shared(this);
2599cd3c9e7a2395647b92c32f33c06cf9fd546b22fJean-Michel Trivi            if (this->mEqEffect != 0) {
2609cd3c9e7a2395647b92c32f33c06cf9fd546b22fJean-Michel Trivi                android::status_t status =
2614be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi                    android_eq_getParam(this->mEqEffect, EQ_PARAM_BAND_FREQ_RANGE, band, range);
2629cd3c9e7a2395647b92c32f33c06cf9fd546b22fJean-Michel Trivi                result = android_fx_statusToResult(status);
2639cd3c9e7a2395647b92c32f33c06cf9fd546b22fJean-Michel Trivi            } else {
2649cd3c9e7a2395647b92c32f33c06cf9fd546b22fJean-Michel Trivi                result = SL_RESULT_CONTROL_LOST;
2659cd3c9e7a2395647b92c32f33c06cf9fd546b22fJean-Michel Trivi            }
2664be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi            interface_unlock_shared(this);
2674be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi            if (NULL != pMin) {
2684be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi                *pMin = range[0];
2694be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi            }
2704be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi            if (NULL != pMax) {
2714be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi                *pMax = range[1];
2724be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi            }
2734be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi#endif
274ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        }
275ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    }
276ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
277ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    SL_LEAVE_INTERFACE
278a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten}
279a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten
280ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
2813a413f1863daa026ed2b9fc9eac01e1341116cdbGlenn Kastenstatic SLresult IEqualizer_GetBand(SLEqualizerItf self, SLmilliHertz frequency, SLuint16 *pBand)
282a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten{
283ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    SL_ENTER_INTERFACE
284ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
285ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    if (NULL == pBand) {
286ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        result = SL_RESULT_PARAMETER_INVALID;
287ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    } else {
288ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        IEqualizer *this = (IEqualizer *) self;
28914e903028c4abfc1b2fbfab6560e3b864086f895Glenn Kasten#if !defined(ANDROID) || defined(USE_BACKPORT)
290ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        // search for band whose center frequency has the closest ratio to 1.0
291ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        // assumes bands are unsorted (a pessimistic assumption)
292ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        // assumes bands can overlap (a pessimistic assumption)
293ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        // assumes a small number of bands, so no need for a fancier algorithm
294ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        const struct EqualizerBand *band;
295ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        float floatFreq = (float) frequency;
296ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        float bestRatio = 0.0;
297ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        SLuint16 bestBand = SL_EQUALIZER_UNDEFINED;
298ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        for (band = this->mBands; band < &this->mBands[this->mNumBands]; ++band) {
299ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten            if (!(band->mMin <= frequency && frequency <= band->mMax))
300ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten                continue;
301ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten            assert(band->mMin <= band->mCenter && band->mCenter <= band->mMax);
302ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten            assert(band->mCenter != 0);
303ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten            float ratio = frequency <= band->mCenter ?
304ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten                floatFreq / band->mCenter : band->mCenter / floatFreq;
305ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten            if (ratio > bestRatio) {
306ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten                bestRatio = ratio;
307ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten                bestBand = band - this->mBands;
308ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten            }
309a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten        }
3107c3fe21525e62f24acc9d391f9d396ce2d7e57acGlenn Kasten        *pBand = bestBand;
311ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        result = SL_RESULT_SUCCESS;
3124be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi#else
3139cd3c9e7a2395647b92c32f33c06cf9fd546b22fJean-Michel Trivi        uint16_t band = 0;
3144be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi        interface_lock_shared(this);
3159cd3c9e7a2395647b92c32f33c06cf9fd546b22fJean-Michel Trivi        if (this->mEqEffect != 0) {
3169cd3c9e7a2395647b92c32f33c06cf9fd546b22fJean-Michel Trivi            android::status_t status =
3179cd3c9e7a2395647b92c32f33c06cf9fd546b22fJean-Michel Trivi                android_eq_getParam(this->mEqEffect, EQ_PARAM_GET_BAND, frequency, &band);
3189cd3c9e7a2395647b92c32f33c06cf9fd546b22fJean-Michel Trivi            result = android_fx_statusToResult(status);
3199cd3c9e7a2395647b92c32f33c06cf9fd546b22fJean-Michel Trivi        } else {
3209cd3c9e7a2395647b92c32f33c06cf9fd546b22fJean-Michel Trivi            result = SL_RESULT_CONTROL_LOST;
3219cd3c9e7a2395647b92c32f33c06cf9fd546b22fJean-Michel Trivi        }
3224be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi        interface_unlock_shared(this);
3234be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi        *pBand = (SLuint16)band;
3244be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi#endif
325a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten    }
326ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
327ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    SL_LEAVE_INTERFACE
328a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten}
329a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten
330ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
331d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kastenstatic SLresult IEqualizer_GetCurrentPreset(SLEqualizerItf self, SLuint16 *pPreset)
332a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten{
333ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    SL_ENTER_INTERFACE
334ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
335ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    if (NULL == pPreset) {
336ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        result = SL_RESULT_PARAMETER_INVALID;
337ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    } else {
338ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        IEqualizer *this = (IEqualizer *) self;
339ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        interface_lock_shared(this);
34014e903028c4abfc1b2fbfab6560e3b864086f895Glenn Kasten#if !defined(ANDROID) || defined(USE_BACKPORT)
341ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        SLuint16 preset = this->mPreset;
342ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        interface_unlock_shared(this);
343ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        *pPreset = preset;
344ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        result = SL_RESULT_SUCCESS;
3454be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi#else
3469cd3c9e7a2395647b92c32f33c06cf9fd546b22fJean-Michel Trivi        uint16_t preset = 0;
3479cd3c9e7a2395647b92c32f33c06cf9fd546b22fJean-Michel Trivi        if (this->mEqEffect != 0) {
3489cd3c9e7a2395647b92c32f33c06cf9fd546b22fJean-Michel Trivi            android::status_t status =
3499cd3c9e7a2395647b92c32f33c06cf9fd546b22fJean-Michel Trivi                    android_eq_getParam(this->mEqEffect, EQ_PARAM_CUR_PRESET, 0, &preset);
3509cd3c9e7a2395647b92c32f33c06cf9fd546b22fJean-Michel Trivi            result = android_fx_statusToResult(status);
3519cd3c9e7a2395647b92c32f33c06cf9fd546b22fJean-Michel Trivi        } else {
3529cd3c9e7a2395647b92c32f33c06cf9fd546b22fJean-Michel Trivi            result = SL_RESULT_CONTROL_LOST;
3539cd3c9e7a2395647b92c32f33c06cf9fd546b22fJean-Michel Trivi        }
3544be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi        interface_unlock_shared(this);
3559cd3c9e7a2395647b92c32f33c06cf9fd546b22fJean-Michel Trivi
3564be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi        if (preset < 0) {
3574be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi            *pPreset = SL_EQUALIZER_UNDEFINED;
3584be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi        } else {
3594be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi            *pPreset = (SLuint16) preset;
3604be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi        }
3614be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi#endif
3624be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi
363ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    }
364ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
365ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    SL_LEAVE_INTERFACE
366a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten}
367a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten
368ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
369a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kastenstatic SLresult IEqualizer_UsePreset(SLEqualizerItf self, SLuint16 index)
370a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten{
371ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    SL_ENTER_INTERFACE
372ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
373a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten    IEqualizer *this = (IEqualizer *) self;
374ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    if (index >= this->mNumPresets) {
375ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        result = SL_RESULT_PARAMETER_INVALID;
376ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    } else {
377ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        interface_lock_exclusive(this);
37814e903028c4abfc1b2fbfab6560e3b864086f895Glenn Kasten#if !defined(ANDROID) || defined(USE_BACKPORT)
379ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        SLuint16 band;
380ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        for (band = 0; band < this->mNumBands; ++band)
381ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten            this->mLevels[band] = EqualizerPresets[index].mLevels[band];
382ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        this->mPreset = index;
383ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        interface_unlock_exclusive(this);
384ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        result = SL_RESULT_SUCCESS;
3854be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi#else
3869cd3c9e7a2395647b92c32f33c06cf9fd546b22fJean-Michel Trivi        if (this->mEqEffect != 0) {
3879cd3c9e7a2395647b92c32f33c06cf9fd546b22fJean-Michel Trivi            android::status_t status =
388b3b757daa7d162b6f66590d917c1f84f3ba73c70Eric Laurent                android_eq_setParam(this->mEqEffect, EQ_PARAM_CUR_PRESET, 0, &index);
3899cd3c9e7a2395647b92c32f33c06cf9fd546b22fJean-Michel Trivi            result = android_fx_statusToResult(status);
3909cd3c9e7a2395647b92c32f33c06cf9fd546b22fJean-Michel Trivi        } else {
3919cd3c9e7a2395647b92c32f33c06cf9fd546b22fJean-Michel Trivi            result = SL_RESULT_CONTROL_LOST;
3929cd3c9e7a2395647b92c32f33c06cf9fd546b22fJean-Michel Trivi        }
3934be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi        interface_unlock_shared(this);
3944be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi#endif
395ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    }
396ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
397ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    SL_LEAVE_INTERFACE
398a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten}
399a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten
400ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
401d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kastenstatic SLresult IEqualizer_GetNumberOfPresets(SLEqualizerItf self, SLuint16 *pNumPresets)
402a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten{
403ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    SL_ENTER_INTERFACE
404ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
405ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    if (NULL == pNumPresets) {
406ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        result = SL_RESULT_PARAMETER_INVALID;
407ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    } else {
408ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        IEqualizer *this = (IEqualizer *) self;
409ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        // Note: no lock, but OK because it is const
41014e903028c4abfc1b2fbfab6560e3b864086f895Glenn Kasten#if !defined(ANDROID) || defined(USE_BACKPORT)
411ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        *pNumPresets = this->mNumPresets;
4124be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi#else
4134be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi        *pNumPresets = this->mThis->mEngine->mEqNumPresets;
4144be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi#endif
415ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        result = SL_RESULT_SUCCESS;
416ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    }
417ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
418ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    SL_LEAVE_INTERFACE
419a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten}
420a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten
421ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
422e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kastenstatic SLresult IEqualizer_GetPresetName(SLEqualizerItf self, SLuint16 index, const SLchar **ppName)
423a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten{
424ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    SL_ENTER_INTERFACE
425ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
426ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    if (NULL == ppName) {
427ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        result = SL_RESULT_PARAMETER_INVALID;
428ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    } else {
429ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        IEqualizer *this = (IEqualizer *) self;
43014e903028c4abfc1b2fbfab6560e3b864086f895Glenn Kasten#if !defined(ANDROID) || defined(USE_BACKPORT)
431ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        if (index >= this->mNumPresets) {
432ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten            result = SL_RESULT_PARAMETER_INVALID;
433ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        } else {
434ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten            *ppName = (SLchar *) this->mPresets[index].mName;
435ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten            result = SL_RESULT_SUCCESS;
436ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        }
4374be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi#else
4384be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi        if (index >= this->mThis->mEngine->mEqNumPresets) {
4394be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi            result = SL_RESULT_PARAMETER_INVALID;
4404be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi        } else {
4414be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi            *ppName = (SLchar *) this->mThis->mEngine->mEqPresetNames[index];
4424be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi            result = SL_RESULT_SUCCESS;
4434be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi        }
4444be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi#endif
445ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    }
446ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
447ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    SL_LEAVE_INTERFACE
448a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten}
449a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten
450ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
451a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kastenstatic const struct SLEqualizerItf_ IEqualizer_Itf = {
452a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten    IEqualizer_SetEnabled,
453a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten    IEqualizer_IsEnabled,
454a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten    IEqualizer_GetNumberOfBands,
455a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten    IEqualizer_GetBandLevelRange,
456a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten    IEqualizer_SetBandLevel,
457a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten    IEqualizer_GetBandLevel,
458a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten    IEqualizer_GetCenterFreq,
459a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten    IEqualizer_GetBandFreqRange,
460a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten    IEqualizer_GetBand,
461a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten    IEqualizer_GetCurrentPreset,
462a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten    IEqualizer_UsePreset,
463a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten    IEqualizer_GetNumberOfPresets,
464a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten    IEqualizer_GetPresetName
465a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten};
466a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten
467a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kastenvoid IEqualizer_init(void *self)
468a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten{
469a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten    IEqualizer *this = (IEqualizer *) self;
470a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten    this->mItf = &IEqualizer_Itf;
471a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten    this->mEnabled = SL_BOOLEAN_FALSE;
4723a413f1863daa026ed2b9fc9eac01e1341116cdbGlenn Kasten    this->mPreset = SL_EQUALIZER_UNDEFINED;
4734b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten#if (0 < MAX_EQ_BANDS)
4740b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    unsigned band;
4753a413f1863daa026ed2b9fc9eac01e1341116cdbGlenn Kasten    for (band = 0; band < MAX_EQ_BANDS; ++band)
4760b167267bda99b68346045ccab14e810121d5de4Glenn Kasten        this->mLevels[band] = 0;
4774b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten#endif
4783a413f1863daa026ed2b9fc9eac01e1341116cdbGlenn Kasten    // const fields
4794be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi    this->mNumPresets = 0;
4804be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi    this->mNumBands = 0;
48114e903028c4abfc1b2fbfab6560e3b864086f895Glenn Kasten#if !defined(ANDROID) || defined(USE_BACKPORT)
4823a413f1863daa026ed2b9fc9eac01e1341116cdbGlenn Kasten    this->mBands = EqualizerBands;
4833a413f1863daa026ed2b9fc9eac01e1341116cdbGlenn Kasten    this->mPresets = EqualizerPresets;
4844be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi#endif
4854be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi    this->mBandLevelRangeMin = 0;
4864be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi    this->mBandLevelRangeMax = 0;
4874be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi
48814e903028c4abfc1b2fbfab6560e3b864086f895Glenn Kasten#if defined(ANDROID) && !defined(USE_BACKPORT)
4894be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi
490f5fce95f98037ea4ab341b416c82444af595313dJean-Michel Trivi    if (!android_fx_initEffectDescriptor(SL_IID_EQUALIZER, &this->mEqDescriptor)) {
491f5fce95f98037ea4ab341b416c82444af595313dJean-Michel Trivi        // EQ init failed
492f5fce95f98037ea4ab341b416c82444af595313dJean-Michel Trivi        this->mNumPresets = 0;
493f5fce95f98037ea4ab341b416c82444af595313dJean-Michel Trivi        this->mNumBands = 0;
494f5fce95f98037ea4ab341b416c82444af595313dJean-Michel Trivi        this->mBandLevelRangeMin = 0;
495f5fce95f98037ea4ab341b416c82444af595313dJean-Michel Trivi        this->mBandLevelRangeMax = 0;
496f5fce95f98037ea4ab341b416c82444af595313dJean-Michel Trivi    }
4974be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi#endif
498a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten}
499