IEqualizer.cpp revision a3080daa505f91df51a808c85ddb37c48745bf7c
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
45768edbc2a8e7f197548cf1141689dd237d19c455Glenn Kasten#if defined(ANDROID) && !defined(USE_BACKPORT)
46cfe5b1c6f0b65499d9aed2cf4b2a7e805fb02758Jean-Michel Trivi/**
47cfe5b1c6f0b65499d9aed2cf4b2a7e805fb02758Jean-Michel Trivi * returns true if this interface is not associated with an initialized Equalizer effect
48cfe5b1c6f0b65499d9aed2cf4b2a7e805fb02758Jean-Michel Trivi */
49cfe5b1c6f0b65499d9aed2cf4b2a7e805fb02758Jean-Michel Trivistatic inline bool NO_EQ(IEqualizer* v) {
50cfe5b1c6f0b65499d9aed2cf4b2a7e805fb02758Jean-Michel Trivi    return (v->mEqEffect == 0);
51cfe5b1c6f0b65499d9aed2cf4b2a7e805fb02758Jean-Michel Trivi}
52768edbc2a8e7f197548cf1141689dd237d19c455Glenn Kasten#endif
53cfe5b1c6f0b65499d9aed2cf4b2a7e805fb02758Jean-Michel Trivi
54cfe5b1c6f0b65499d9aed2cf4b2a7e805fb02758Jean-Michel Trivi
55a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kastenstatic SLresult IEqualizer_SetEnabled(SLEqualizerItf self, SLboolean enabled)
56a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten{
57ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    SL_ENTER_INTERFACE
58ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
59a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten    IEqualizer *this = (IEqualizer *) self;
604be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi    interface_lock_exclusive(this);
61cfe5b1c6f0b65499d9aed2cf4b2a7e805fb02758Jean-Michel Trivi    this->mEnabled = (SLboolean) enabled;
6214e903028c4abfc1b2fbfab6560e3b864086f895Glenn Kasten#if !defined(ANDROID) || defined(USE_BACKPORT)
63ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    result = SL_RESULT_SUCCESS;
644be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi#else
65cfe5b1c6f0b65499d9aed2cf4b2a7e805fb02758Jean-Michel Trivi    if (NO_EQ(this)) {
66cfe5b1c6f0b65499d9aed2cf4b2a7e805fb02758Jean-Michel Trivi        result = SL_RESULT_CONTROL_LOST;
674be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi    } else {
68cfe5b1c6f0b65499d9aed2cf4b2a7e805fb02758Jean-Michel Trivi        android::status_t status =
69cfe5b1c6f0b65499d9aed2cf4b2a7e805fb02758Jean-Michel Trivi                this->mEqEffect->setEnabled((bool) this->mEnabled);
70cfe5b1c6f0b65499d9aed2cf4b2a7e805fb02758Jean-Michel Trivi        result = android_fx_statusToResult(status);
714be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi    }
724be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi#endif
734be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi    interface_unlock_exclusive(this);
74ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
75ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    SL_LEAVE_INTERFACE
76a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten}
77a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten
78ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
79a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kastenstatic SLresult IEqualizer_IsEnabled(SLEqualizerItf self, SLboolean *pEnabled)
80a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten{
81ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    SL_ENTER_INTERFACE
82ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
83cfe5b1c6f0b65499d9aed2cf4b2a7e805fb02758Jean-Michel Trivi      if (NULL == pEnabled) {
84cfe5b1c6f0b65499d9aed2cf4b2a7e805fb02758Jean-Michel Trivi          result = SL_RESULT_PARAMETER_INVALID;
85cfe5b1c6f0b65499d9aed2cf4b2a7e805fb02758Jean-Michel Trivi      } else {
86cfe5b1c6f0b65499d9aed2cf4b2a7e805fb02758Jean-Michel Trivi          IEqualizer *this = (IEqualizer *) self;
87cfe5b1c6f0b65499d9aed2cf4b2a7e805fb02758Jean-Michel Trivi          interface_lock_exclusive(this);
88cfe5b1c6f0b65499d9aed2cf4b2a7e805fb02758Jean-Michel Trivi          SLboolean enabled = this->mEnabled;
89a3080daa505f91df51a808c85ddb37c48745bf7cGlenn Kasten #if !defined(ANDROID) || defined(USE_BACKPORT)
90cfe5b1c6f0b65499d9aed2cf4b2a7e805fb02758Jean-Michel Trivi          *pEnabled = enabled;
91cfe5b1c6f0b65499d9aed2cf4b2a7e805fb02758Jean-Michel Trivi          result = SL_RESULT_SUCCESS;
92a3080daa505f91df51a808c85ddb37c48745bf7cGlenn Kasten #else
93cfe5b1c6f0b65499d9aed2cf4b2a7e805fb02758Jean-Michel Trivi          if (NO_EQ(this)) {
94cfe5b1c6f0b65499d9aed2cf4b2a7e805fb02758Jean-Michel Trivi              result = SL_RESULT_CONTROL_LOST;
95cfe5b1c6f0b65499d9aed2cf4b2a7e805fb02758Jean-Michel Trivi          } else {
96cfe5b1c6f0b65499d9aed2cf4b2a7e805fb02758Jean-Michel Trivi              *pEnabled = (SLboolean) this->mEqEffect->getEnabled();
97cfe5b1c6f0b65499d9aed2cf4b2a7e805fb02758Jean-Michel Trivi              result = SL_RESULT_SUCCESS;
98cfe5b1c6f0b65499d9aed2cf4b2a7e805fb02758Jean-Michel Trivi          }
99a3080daa505f91df51a808c85ddb37c48745bf7cGlenn Kasten #endif
100cfe5b1c6f0b65499d9aed2cf4b2a7e805fb02758Jean-Michel Trivi          interface_unlock_exclusive(this);
101cfe5b1c6f0b65499d9aed2cf4b2a7e805fb02758Jean-Michel Trivi      }
102cfe5b1c6f0b65499d9aed2cf4b2a7e805fb02758Jean-Michel Trivi
103cfe5b1c6f0b65499d9aed2cf4b2a7e805fb02758Jean-Michel Trivi      SL_LEAVE_INTERFACE
104a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten}
105a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten
106ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
1073a413f1863daa026ed2b9fc9eac01e1341116cdbGlenn Kastenstatic SLresult IEqualizer_GetNumberOfBands(SLEqualizerItf self, SLuint16 *pNumBands)
108a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten{
109ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    SL_ENTER_INTERFACE
110ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
111ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    if (NULL == pNumBands) {
112ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        result = SL_RESULT_PARAMETER_INVALID;
113ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    } else {
114ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        IEqualizer *this = (IEqualizer *) self;
115ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        // Note: no lock, but OK because it is const
116ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        *pNumBands = this->mNumBands;
117ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        result = SL_RESULT_SUCCESS;
118ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    }
119ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
120ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    SL_LEAVE_INTERFACE
121a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten}
122a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten
123ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
124e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kastenstatic SLresult IEqualizer_GetBandLevelRange(SLEqualizerItf self, SLmillibel *pMin,
125e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten    SLmillibel *pMax)
126a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten{
127ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    SL_ENTER_INTERFACE
128ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
129ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    if (NULL == pMin && NULL == pMax) {
130ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        result = SL_RESULT_PARAMETER_INVALID;
131ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    } else {
132ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        IEqualizer *this = (IEqualizer *) self;
133ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        // Note: no lock, but OK because it is const
134ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        if (NULL != pMin)
135ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten            *pMin = this->mBandLevelRangeMin;
136ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        if (NULL != pMax)
137ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten            *pMax = this->mBandLevelRangeMax;
138ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        result = SL_RESULT_SUCCESS;
139ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    }
140ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
141ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    SL_LEAVE_INTERFACE
142a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten}
143a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten
144ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
1453a413f1863daa026ed2b9fc9eac01e1341116cdbGlenn Kastenstatic SLresult IEqualizer_SetBandLevel(SLEqualizerItf self, SLuint16 band, SLmillibel level)
146a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten{
147ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    SL_ENTER_INTERFACE
148ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
149a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten    IEqualizer *this = (IEqualizer *) self;
150ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    if (!(this->mBandLevelRangeMin <= level && level <= this->mBandLevelRangeMax) ||
1514be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi            (band >= this->mNumBands)) {
152ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        result = SL_RESULT_PARAMETER_INVALID;
153ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    } else {
154ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        interface_lock_exclusive(this);
15514e903028c4abfc1b2fbfab6560e3b864086f895Glenn Kasten#if !defined(ANDROID) || defined(USE_BACKPORT)
156ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        this->mLevels[band] = level;
157ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        this->mPreset = SL_EQUALIZER_UNDEFINED;
158ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        result = SL_RESULT_SUCCESS;
1594be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi#else
160cfe5b1c6f0b65499d9aed2cf4b2a7e805fb02758Jean-Michel Trivi        if (NO_EQ(this)) {
1617e01bc6208fb5b4a2a0019d67bf74373f8ee9428Jean-Michel Trivi            result = SL_RESULT_CONTROL_LOST;
1627e01bc6208fb5b4a2a0019d67bf74373f8ee9428Jean-Michel Trivi        } else {
1639cd3c9e7a2395647b92c32f33c06cf9fd546b22fJean-Michel Trivi            android::status_t status =
1644be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi                android_eq_setParam(this->mEqEffect, EQ_PARAM_BAND_LEVEL, band, &level);
1659cd3c9e7a2395647b92c32f33c06cf9fd546b22fJean-Michel Trivi            result = android_fx_statusToResult(status);
1669cd3c9e7a2395647b92c32f33c06cf9fd546b22fJean-Michel Trivi        }
1674be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi#endif
1684be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi        interface_unlock_exclusive(this);
169ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    }
170ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
171ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    SL_LEAVE_INTERFACE
172a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten}
173a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten
174ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
175d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kastenstatic SLresult IEqualizer_GetBandLevel(SLEqualizerItf self, SLuint16 band, SLmillibel *pLevel)
176a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten{
177ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    SL_ENTER_INTERFACE
178ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
179ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    if (NULL == pLevel) {
180ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        result = SL_RESULT_PARAMETER_INVALID;
181ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    } else {
182ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        IEqualizer *this = (IEqualizer *) self;
183ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        // const, no lock needed
184ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        if (band >= this->mNumBands) {
185ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten            result = SL_RESULT_PARAMETER_INVALID;
186ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        } else {
1879cd3c9e7a2395647b92c32f33c06cf9fd546b22fJean-Michel Trivi            SLmillibel level = 0;
1884be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi            interface_lock_shared(this);
18914e903028c4abfc1b2fbfab6560e3b864086f895Glenn Kasten#if !defined(ANDROID) || defined(USE_BACKPORT)
1904be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi            level = this->mLevels[band];
191ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten            result = SL_RESULT_SUCCESS;
1924be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi#else
193cfe5b1c6f0b65499d9aed2cf4b2a7e805fb02758Jean-Michel Trivi            if (NO_EQ(this)) {
1947e01bc6208fb5b4a2a0019d67bf74373f8ee9428Jean-Michel Trivi                result = SL_RESULT_CONTROL_LOST;
1957e01bc6208fb5b4a2a0019d67bf74373f8ee9428Jean-Michel Trivi            } else {
1969cd3c9e7a2395647b92c32f33c06cf9fd546b22fJean-Michel Trivi                android::status_t status =
1974be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi                    android_eq_getParam(this->mEqEffect, EQ_PARAM_BAND_LEVEL, band, &level);
1989cd3c9e7a2395647b92c32f33c06cf9fd546b22fJean-Michel Trivi                result = android_fx_statusToResult(status);
1999cd3c9e7a2395647b92c32f33c06cf9fd546b22fJean-Michel Trivi            }
2004be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi#endif
2014be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi            interface_unlock_shared(this);
2024be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi            *pLevel = level;
203ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        }
204ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    }
205ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
206ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    SL_LEAVE_INTERFACE
207a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten}
208a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten
209ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
2103a413f1863daa026ed2b9fc9eac01e1341116cdbGlenn Kastenstatic SLresult IEqualizer_GetCenterFreq(SLEqualizerItf self, SLuint16 band, SLmilliHertz *pCenter)
211a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten{
212ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    SL_ENTER_INTERFACE
213ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
214ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    if (NULL == pCenter) {
215ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        result = SL_RESULT_PARAMETER_INVALID;
216ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    } else {
217ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        IEqualizer *this = (IEqualizer *) self;
218ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        if (band >= this->mNumBands) {
219ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten            result = SL_RESULT_PARAMETER_INVALID;
220ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        } else {
22114e903028c4abfc1b2fbfab6560e3b864086f895Glenn Kasten#if !defined(ANDROID) || defined(USE_BACKPORT)
222ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten            // Note: no lock, but OK because it is const
223ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten            *pCenter = this->mBands[band].mCenter;
224ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten            result = SL_RESULT_SUCCESS;
2254be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi#else
2269cd3c9e7a2395647b92c32f33c06cf9fd546b22fJean-Michel Trivi            SLmilliHertz center = 0;
2274be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi            interface_lock_shared(this);
228cfe5b1c6f0b65499d9aed2cf4b2a7e805fb02758Jean-Michel Trivi            if (NO_EQ(this)) {
2297e01bc6208fb5b4a2a0019d67bf74373f8ee9428Jean-Michel Trivi                result = SL_RESULT_CONTROL_LOST;
2307e01bc6208fb5b4a2a0019d67bf74373f8ee9428Jean-Michel Trivi            } else {
2319cd3c9e7a2395647b92c32f33c06cf9fd546b22fJean-Michel Trivi                android::status_t status =
2324be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi                    android_eq_getParam(this->mEqEffect, EQ_PARAM_CENTER_FREQ, band, &center);
2339cd3c9e7a2395647b92c32f33c06cf9fd546b22fJean-Michel Trivi                result = android_fx_statusToResult(status);
2349cd3c9e7a2395647b92c32f33c06cf9fd546b22fJean-Michel Trivi            }
2354be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi            interface_unlock_shared(this);
2364be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi            *pCenter = center;
2374be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi#endif
238ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        }
239ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    }
240ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
241ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    SL_LEAVE_INTERFACE
242a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten}
243a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten
244ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
245a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kastenstatic SLresult IEqualizer_GetBandFreqRange(SLEqualizerItf self, SLuint16 band,
246a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten    SLmilliHertz *pMin, SLmilliHertz *pMax)
247a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten{
248ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    SL_ENTER_INTERFACE
249ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
250ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    if (NULL == pMin && NULL == pMax) {
251ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        result = SL_RESULT_PARAMETER_INVALID;
252ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    } else {
253ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        IEqualizer *this = (IEqualizer *) self;
254ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        if (band >= this->mNumBands) {
255ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten            result = SL_RESULT_PARAMETER_INVALID;
256ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        } else {
25714e903028c4abfc1b2fbfab6560e3b864086f895Glenn Kasten#if !defined(ANDROID) || defined(USE_BACKPORT)
258ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten            // Note: no lock, but OK because it is const
259ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten            if (NULL != pMin)
260ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten                *pMin = this->mBands[band].mMin;
261ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten            if (NULL != pMax)
262ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten                *pMax = this->mBands[band].mMax;
263ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten            result = SL_RESULT_SUCCESS;
2644be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi#else
2659cd3c9e7a2395647b92c32f33c06cf9fd546b22fJean-Michel Trivi            SLmilliHertz range[2] = {0, 0}; // SLmilliHertz is SLuint32
2664be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi            interface_lock_shared(this);
267cfe5b1c6f0b65499d9aed2cf4b2a7e805fb02758Jean-Michel Trivi            if (NO_EQ(this)) {
2687e01bc6208fb5b4a2a0019d67bf74373f8ee9428Jean-Michel Trivi                result = SL_RESULT_CONTROL_LOST;
2697e01bc6208fb5b4a2a0019d67bf74373f8ee9428Jean-Michel Trivi            } else {
2709cd3c9e7a2395647b92c32f33c06cf9fd546b22fJean-Michel Trivi                android::status_t status =
2714be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi                    android_eq_getParam(this->mEqEffect, EQ_PARAM_BAND_FREQ_RANGE, band, range);
2729cd3c9e7a2395647b92c32f33c06cf9fd546b22fJean-Michel Trivi                result = android_fx_statusToResult(status);
2739cd3c9e7a2395647b92c32f33c06cf9fd546b22fJean-Michel Trivi            }
2744be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi            interface_unlock_shared(this);
2754be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi            if (NULL != pMin) {
2764be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi                *pMin = range[0];
2774be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi            }
2784be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi            if (NULL != pMax) {
2794be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi                *pMax = range[1];
2804be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi            }
2814be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi#endif
282ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        }
283ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    }
284ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
285ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    SL_LEAVE_INTERFACE
286a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten}
287a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten
288ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
2893a413f1863daa026ed2b9fc9eac01e1341116cdbGlenn Kastenstatic SLresult IEqualizer_GetBand(SLEqualizerItf self, SLmilliHertz frequency, SLuint16 *pBand)
290a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten{
291ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    SL_ENTER_INTERFACE
292ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
293ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    if (NULL == pBand) {
294ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        result = SL_RESULT_PARAMETER_INVALID;
295ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    } else {
296ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        IEqualizer *this = (IEqualizer *) self;
29714e903028c4abfc1b2fbfab6560e3b864086f895Glenn Kasten#if !defined(ANDROID) || defined(USE_BACKPORT)
298ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        // search for band whose center frequency has the closest ratio to 1.0
299ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        // assumes bands are unsorted (a pessimistic assumption)
300ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        // assumes bands can overlap (a pessimistic assumption)
301ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        // assumes a small number of bands, so no need for a fancier algorithm
302ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        const struct EqualizerBand *band;
303ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        float floatFreq = (float) frequency;
304ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        float bestRatio = 0.0;
305ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        SLuint16 bestBand = SL_EQUALIZER_UNDEFINED;
306ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        for (band = this->mBands; band < &this->mBands[this->mNumBands]; ++band) {
307ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten            if (!(band->mMin <= frequency && frequency <= band->mMax))
308ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten                continue;
309ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten            assert(band->mMin <= band->mCenter && band->mCenter <= band->mMax);
310ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten            assert(band->mCenter != 0);
311ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten            float ratio = frequency <= band->mCenter ?
312ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten                floatFreq / band->mCenter : band->mCenter / floatFreq;
313ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten            if (ratio > bestRatio) {
314ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten                bestRatio = ratio;
315ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten                bestBand = band - this->mBands;
316ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten            }
317a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten        }
3187c3fe21525e62f24acc9d391f9d396ce2d7e57acGlenn Kasten        *pBand = bestBand;
319ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        result = SL_RESULT_SUCCESS;
3204be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi#else
3219cd3c9e7a2395647b92c32f33c06cf9fd546b22fJean-Michel Trivi        uint16_t band = 0;
3224be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi        interface_lock_shared(this);
323cfe5b1c6f0b65499d9aed2cf4b2a7e805fb02758Jean-Michel Trivi        if (NO_EQ(this)) {
3247e01bc6208fb5b4a2a0019d67bf74373f8ee9428Jean-Michel Trivi            result = SL_RESULT_CONTROL_LOST;
3257e01bc6208fb5b4a2a0019d67bf74373f8ee9428Jean-Michel Trivi        } else {
3269cd3c9e7a2395647b92c32f33c06cf9fd546b22fJean-Michel Trivi            android::status_t status =
3279cd3c9e7a2395647b92c32f33c06cf9fd546b22fJean-Michel Trivi                android_eq_getParam(this->mEqEffect, EQ_PARAM_GET_BAND, frequency, &band);
3289cd3c9e7a2395647b92c32f33c06cf9fd546b22fJean-Michel Trivi            result = android_fx_statusToResult(status);
3299cd3c9e7a2395647b92c32f33c06cf9fd546b22fJean-Michel Trivi        }
3304be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi        interface_unlock_shared(this);
3314be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi        *pBand = (SLuint16)band;
3324be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi#endif
333a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten    }
334ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
335ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    SL_LEAVE_INTERFACE
336a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten}
337a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten
338ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
339d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kastenstatic SLresult IEqualizer_GetCurrentPreset(SLEqualizerItf self, SLuint16 *pPreset)
340a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten{
341ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    SL_ENTER_INTERFACE
342ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
343ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    if (NULL == pPreset) {
344ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        result = SL_RESULT_PARAMETER_INVALID;
345ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    } else {
346ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        IEqualizer *this = (IEqualizer *) self;
347ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        interface_lock_shared(this);
34814e903028c4abfc1b2fbfab6560e3b864086f895Glenn Kasten#if !defined(ANDROID) || defined(USE_BACKPORT)
349ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        SLuint16 preset = this->mPreset;
350ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        interface_unlock_shared(this);
351ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        *pPreset = preset;
352ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        result = SL_RESULT_SUCCESS;
3534be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi#else
3549cd3c9e7a2395647b92c32f33c06cf9fd546b22fJean-Michel Trivi        uint16_t preset = 0;
355cfe5b1c6f0b65499d9aed2cf4b2a7e805fb02758Jean-Michel Trivi        if (NO_EQ(this)) {
3567e01bc6208fb5b4a2a0019d67bf74373f8ee9428Jean-Michel Trivi            result = SL_RESULT_CONTROL_LOST;
3577e01bc6208fb5b4a2a0019d67bf74373f8ee9428Jean-Michel Trivi        } else {
3589cd3c9e7a2395647b92c32f33c06cf9fd546b22fJean-Michel Trivi            android::status_t status =
3599cd3c9e7a2395647b92c32f33c06cf9fd546b22fJean-Michel Trivi                    android_eq_getParam(this->mEqEffect, EQ_PARAM_CUR_PRESET, 0, &preset);
3609cd3c9e7a2395647b92c32f33c06cf9fd546b22fJean-Michel Trivi            result = android_fx_statusToResult(status);
3619cd3c9e7a2395647b92c32f33c06cf9fd546b22fJean-Michel Trivi        }
3624be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi        interface_unlock_shared(this);
3639cd3c9e7a2395647b92c32f33c06cf9fd546b22fJean-Michel Trivi
3644be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi        if (preset < 0) {
3654be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi            *pPreset = SL_EQUALIZER_UNDEFINED;
3664be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi        } else {
3674be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi            *pPreset = (SLuint16) preset;
3684be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi        }
3694be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi#endif
3704be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi
371ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    }
372ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
373ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    SL_LEAVE_INTERFACE
374a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten}
375a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten
376ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
377a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kastenstatic SLresult IEqualizer_UsePreset(SLEqualizerItf self, SLuint16 index)
378a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten{
379ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    SL_ENTER_INTERFACE
380a7b79e766ec6d95e9236168c27461c2ebaef4659Glenn Kasten    SL_LOGV("Equalizer::UsePreset index=%u", index);
381ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
382a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten    IEqualizer *this = (IEqualizer *) self;
383ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    if (index >= this->mNumPresets) {
384ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        result = SL_RESULT_PARAMETER_INVALID;
385ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    } else {
386ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        interface_lock_exclusive(this);
38714e903028c4abfc1b2fbfab6560e3b864086f895Glenn Kasten#if !defined(ANDROID) || defined(USE_BACKPORT)
388ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        SLuint16 band;
389ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        for (band = 0; band < this->mNumBands; ++band)
390ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten            this->mLevels[band] = EqualizerPresets[index].mLevels[band];
391ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        this->mPreset = index;
392ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        interface_unlock_exclusive(this);
393ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        result = SL_RESULT_SUCCESS;
3944be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi#else
395cfe5b1c6f0b65499d9aed2cf4b2a7e805fb02758Jean-Michel Trivi        if (NO_EQ(this)) {
3967e01bc6208fb5b4a2a0019d67bf74373f8ee9428Jean-Michel Trivi            result = SL_RESULT_CONTROL_LOST;
3977e01bc6208fb5b4a2a0019d67bf74373f8ee9428Jean-Michel Trivi        } else {
3989cd3c9e7a2395647b92c32f33c06cf9fd546b22fJean-Michel Trivi            android::status_t status =
399b3b757daa7d162b6f66590d917c1f84f3ba73c70Eric Laurent                android_eq_setParam(this->mEqEffect, EQ_PARAM_CUR_PRESET, 0, &index);
4009cd3c9e7a2395647b92c32f33c06cf9fd546b22fJean-Michel Trivi            result = android_fx_statusToResult(status);
4019cd3c9e7a2395647b92c32f33c06cf9fd546b22fJean-Michel Trivi        }
4024be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi        interface_unlock_shared(this);
4034be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi#endif
404ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    }
405ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
406ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    SL_LEAVE_INTERFACE
407a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten}
408a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten
409ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
410d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kastenstatic SLresult IEqualizer_GetNumberOfPresets(SLEqualizerItf self, SLuint16 *pNumPresets)
411a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten{
412ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    SL_ENTER_INTERFACE
413ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
414ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    if (NULL == pNumPresets) {
415ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        result = SL_RESULT_PARAMETER_INVALID;
416ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    } else {
417ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        IEqualizer *this = (IEqualizer *) self;
418ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        // Note: no lock, but OK because it is const
419ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        *pNumPresets = this->mNumPresets;
4207e01bc6208fb5b4a2a0019d67bf74373f8ee9428Jean-Michel Trivi
421ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        result = SL_RESULT_SUCCESS;
422ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    }
423ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
424ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    SL_LEAVE_INTERFACE
425a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten}
426a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten
427ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
428e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kastenstatic SLresult IEqualizer_GetPresetName(SLEqualizerItf self, SLuint16 index, const SLchar **ppName)
429a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten{
430ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    SL_ENTER_INTERFACE
431ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
432ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    if (NULL == ppName) {
433ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        result = SL_RESULT_PARAMETER_INVALID;
434ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    } else {
435ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        IEqualizer *this = (IEqualizer *) self;
43614e903028c4abfc1b2fbfab6560e3b864086f895Glenn Kasten#if !defined(ANDROID) || defined(USE_BACKPORT)
437ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        if (index >= this->mNumPresets) {
438ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten            result = SL_RESULT_PARAMETER_INVALID;
439ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        } else {
440ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten            *ppName = (SLchar *) this->mPresets[index].mName;
441ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten            result = SL_RESULT_SUCCESS;
442ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        }
4434be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi#else
4447e01bc6208fb5b4a2a0019d67bf74373f8ee9428Jean-Michel Trivi        if (index >= this->mNumPresets) {
4454be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi            result = SL_RESULT_PARAMETER_INVALID;
4464be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi        } else {
4477e01bc6208fb5b4a2a0019d67bf74373f8ee9428Jean-Michel Trivi            // FIXME query preset name rather than retrieve it from the engine.
4487e01bc6208fb5b4a2a0019d67bf74373f8ee9428Jean-Michel Trivi            //       In SL ES 1.0.1, the strings must exist for the lifetime of the engine.
4497e01bc6208fb5b4a2a0019d67bf74373f8ee9428Jean-Michel Trivi            //       Starting in 1.1, this will change and we don't need to hold onto the strings
4507e01bc6208fb5b4a2a0019d67bf74373f8ee9428Jean-Michel Trivi            //       for so long as they will copied into application space.
4514be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi            *ppName = (SLchar *) this->mThis->mEngine->mEqPresetNames[index];
4524be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi            result = SL_RESULT_SUCCESS;
4534be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi        }
4544be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi#endif
455ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    }
456ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
457ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    SL_LEAVE_INTERFACE
458a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten}
459a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten
460ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
461a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kastenstatic const struct SLEqualizerItf_ IEqualizer_Itf = {
462a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten    IEqualizer_SetEnabled,
463a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten    IEqualizer_IsEnabled,
464a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten    IEqualizer_GetNumberOfBands,
465a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten    IEqualizer_GetBandLevelRange,
466a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten    IEqualizer_SetBandLevel,
467a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten    IEqualizer_GetBandLevel,
468a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten    IEqualizer_GetCenterFreq,
469a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten    IEqualizer_GetBandFreqRange,
470a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten    IEqualizer_GetBand,
471a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten    IEqualizer_GetCurrentPreset,
472a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten    IEqualizer_UsePreset,
473a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten    IEqualizer_GetNumberOfPresets,
474a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten    IEqualizer_GetPresetName
475a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten};
476a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten
477a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kastenvoid IEqualizer_init(void *self)
478a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten{
479a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten    IEqualizer *this = (IEqualizer *) self;
480a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten    this->mItf = &IEqualizer_Itf;
481a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten    this->mEnabled = SL_BOOLEAN_FALSE;
4823a413f1863daa026ed2b9fc9eac01e1341116cdbGlenn Kasten    this->mPreset = SL_EQUALIZER_UNDEFINED;
4834b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten#if (0 < MAX_EQ_BANDS)
4840b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    unsigned band;
4853a413f1863daa026ed2b9fc9eac01e1341116cdbGlenn Kasten    for (band = 0; band < MAX_EQ_BANDS; ++band)
4860b167267bda99b68346045ccab14e810121d5de4Glenn Kasten        this->mLevels[band] = 0;
4874b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten#endif
4883a413f1863daa026ed2b9fc9eac01e1341116cdbGlenn Kasten    // const fields
4894be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi    this->mNumPresets = 0;
4904be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi    this->mNumBands = 0;
49114e903028c4abfc1b2fbfab6560e3b864086f895Glenn Kasten#if !defined(ANDROID) || defined(USE_BACKPORT)
4923a413f1863daa026ed2b9fc9eac01e1341116cdbGlenn Kasten    this->mBands = EqualizerBands;
4933a413f1863daa026ed2b9fc9eac01e1341116cdbGlenn Kasten    this->mPresets = EqualizerPresets;
4944be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi#endif
4954be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi    this->mBandLevelRangeMin = 0;
4964be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi    this->mBandLevelRangeMax = 0;
4974be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi
49814e903028c4abfc1b2fbfab6560e3b864086f895Glenn Kasten#if defined(ANDROID) && !defined(USE_BACKPORT)
4994be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi
500f5fce95f98037ea4ab341b416c82444af595313dJean-Michel Trivi    if (!android_fx_initEffectDescriptor(SL_IID_EQUALIZER, &this->mEqDescriptor)) {
501f5fce95f98037ea4ab341b416c82444af595313dJean-Michel Trivi        // EQ init failed
502f5fce95f98037ea4ab341b416c82444af595313dJean-Michel Trivi        this->mNumPresets = 0;
503f5fce95f98037ea4ab341b416c82444af595313dJean-Michel Trivi        this->mNumBands = 0;
504f5fce95f98037ea4ab341b416c82444af595313dJean-Michel Trivi        this->mBandLevelRangeMin = 0;
505f5fce95f98037ea4ab341b416c82444af595313dJean-Michel Trivi        this->mBandLevelRangeMax = 0;
506f5fce95f98037ea4ab341b416c82444af595313dJean-Michel Trivi    }
5074be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi#endif
508a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten}
509