IEqualizer.cpp revision faf90312d2156acbf27c62e114fd180708aa7654
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#define MAX_EQ_PRESETS 3
223a413f1863daa026ed2b9fc9eac01e1341116cdbGlenn Kasten
23faf90312d2156acbf27c62e114fd180708aa7654Glenn Kasten#if !defined(ANDROID)
243a413f1863daa026ed2b9fc9eac01e1341116cdbGlenn Kastenstatic const struct EqualizerBand EqualizerBands[MAX_EQ_BANDS] = {
250b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    {1000, 1500, 2000},
260b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    {2000, 3000, 4000},
270b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    {4000, 5500, 7000},
280b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    {7000, 8000, 9000}
290b167267bda99b68346045ccab14e810121d5de4Glenn Kasten};
300b167267bda99b68346045ccab14e810121d5de4Glenn Kasten
313a413f1863daa026ed2b9fc9eac01e1341116cdbGlenn Kastenstatic const struct EqualizerPreset {
323a413f1863daa026ed2b9fc9eac01e1341116cdbGlenn Kasten    const char *mName;
333a413f1863daa026ed2b9fc9eac01e1341116cdbGlenn Kasten    SLmillibel mLevels[MAX_EQ_BANDS];
343a413f1863daa026ed2b9fc9eac01e1341116cdbGlenn Kasten} EqualizerPresets[MAX_EQ_PRESETS] = {
353a413f1863daa026ed2b9fc9eac01e1341116cdbGlenn Kasten    {"Default", {0, 0, 0, 0}},
363a413f1863daa026ed2b9fc9eac01e1341116cdbGlenn Kasten    {"Bass", {500, 200, 100, 0}},
373a413f1863daa026ed2b9fc9eac01e1341116cdbGlenn Kasten    {"Treble", {0, 100, 200, 500}}
380b167267bda99b68346045ccab14e810121d5de4Glenn Kasten};
394be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi#endif
400b167267bda99b68346045ccab14e810121d5de4Glenn Kasten
41ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
42faf90312d2156acbf27c62e114fd180708aa7654Glenn Kasten#if defined(ANDROID)
43cfe5b1c6f0b65499d9aed2cf4b2a7e805fb02758Jean-Michel Trivi/**
44cfe5b1c6f0b65499d9aed2cf4b2a7e805fb02758Jean-Michel Trivi * returns true if this interface is not associated with an initialized Equalizer effect
45cfe5b1c6f0b65499d9aed2cf4b2a7e805fb02758Jean-Michel Trivi */
46cfe5b1c6f0b65499d9aed2cf4b2a7e805fb02758Jean-Michel Trivistatic inline bool NO_EQ(IEqualizer* v) {
47cfe5b1c6f0b65499d9aed2cf4b2a7e805fb02758Jean-Michel Trivi    return (v->mEqEffect == 0);
48cfe5b1c6f0b65499d9aed2cf4b2a7e805fb02758Jean-Michel Trivi}
49768edbc2a8e7f197548cf1141689dd237d19c455Glenn Kasten#endif
50cfe5b1c6f0b65499d9aed2cf4b2a7e805fb02758Jean-Michel Trivi
51cfe5b1c6f0b65499d9aed2cf4b2a7e805fb02758Jean-Michel Trivi
52a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kastenstatic SLresult IEqualizer_SetEnabled(SLEqualizerItf self, SLboolean enabled)
53a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten{
54ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    SL_ENTER_INTERFACE
55ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
56a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten    IEqualizer *this = (IEqualizer *) self;
574be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi    interface_lock_exclusive(this);
58cfe5b1c6f0b65499d9aed2cf4b2a7e805fb02758Jean-Michel Trivi    this->mEnabled = (SLboolean) enabled;
59faf90312d2156acbf27c62e114fd180708aa7654Glenn Kasten#if !defined(ANDROID)
60ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    result = SL_RESULT_SUCCESS;
614be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi#else
62cfe5b1c6f0b65499d9aed2cf4b2a7e805fb02758Jean-Michel Trivi    if (NO_EQ(this)) {
63cfe5b1c6f0b65499d9aed2cf4b2a7e805fb02758Jean-Michel Trivi        result = SL_RESULT_CONTROL_LOST;
644be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi    } else {
65cfe5b1c6f0b65499d9aed2cf4b2a7e805fb02758Jean-Michel Trivi        android::status_t status =
66cfe5b1c6f0b65499d9aed2cf4b2a7e805fb02758Jean-Michel Trivi                this->mEqEffect->setEnabled((bool) this->mEnabled);
67cfe5b1c6f0b65499d9aed2cf4b2a7e805fb02758Jean-Michel Trivi        result = android_fx_statusToResult(status);
684be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi    }
694be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi#endif
704be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi    interface_unlock_exclusive(this);
71ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
72ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    SL_LEAVE_INTERFACE
73a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten}
74a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten
75ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
76a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kastenstatic SLresult IEqualizer_IsEnabled(SLEqualizerItf self, SLboolean *pEnabled)
77a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten{
78ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    SL_ENTER_INTERFACE
79ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
80cfe5b1c6f0b65499d9aed2cf4b2a7e805fb02758Jean-Michel Trivi      if (NULL == pEnabled) {
81cfe5b1c6f0b65499d9aed2cf4b2a7e805fb02758Jean-Michel Trivi          result = SL_RESULT_PARAMETER_INVALID;
82cfe5b1c6f0b65499d9aed2cf4b2a7e805fb02758Jean-Michel Trivi      } else {
83cfe5b1c6f0b65499d9aed2cf4b2a7e805fb02758Jean-Michel Trivi          IEqualizer *this = (IEqualizer *) self;
84cfe5b1c6f0b65499d9aed2cf4b2a7e805fb02758Jean-Michel Trivi          interface_lock_exclusive(this);
85cfe5b1c6f0b65499d9aed2cf4b2a7e805fb02758Jean-Michel Trivi          SLboolean enabled = this->mEnabled;
86faf90312d2156acbf27c62e114fd180708aa7654Glenn Kasten #if !defined(ANDROID)
87cfe5b1c6f0b65499d9aed2cf4b2a7e805fb02758Jean-Michel Trivi          *pEnabled = enabled;
88cfe5b1c6f0b65499d9aed2cf4b2a7e805fb02758Jean-Michel Trivi          result = SL_RESULT_SUCCESS;
89a3080daa505f91df51a808c85ddb37c48745bf7cGlenn Kasten #else
90cfe5b1c6f0b65499d9aed2cf4b2a7e805fb02758Jean-Michel Trivi          if (NO_EQ(this)) {
91cfe5b1c6f0b65499d9aed2cf4b2a7e805fb02758Jean-Michel Trivi              result = SL_RESULT_CONTROL_LOST;
92cfe5b1c6f0b65499d9aed2cf4b2a7e805fb02758Jean-Michel Trivi          } else {
93cfe5b1c6f0b65499d9aed2cf4b2a7e805fb02758Jean-Michel Trivi              *pEnabled = (SLboolean) this->mEqEffect->getEnabled();
94cfe5b1c6f0b65499d9aed2cf4b2a7e805fb02758Jean-Michel Trivi              result = SL_RESULT_SUCCESS;
95cfe5b1c6f0b65499d9aed2cf4b2a7e805fb02758Jean-Michel Trivi          }
96a3080daa505f91df51a808c85ddb37c48745bf7cGlenn Kasten #endif
97cfe5b1c6f0b65499d9aed2cf4b2a7e805fb02758Jean-Michel Trivi          interface_unlock_exclusive(this);
98cfe5b1c6f0b65499d9aed2cf4b2a7e805fb02758Jean-Michel Trivi      }
99cfe5b1c6f0b65499d9aed2cf4b2a7e805fb02758Jean-Michel Trivi
100cfe5b1c6f0b65499d9aed2cf4b2a7e805fb02758Jean-Michel Trivi      SL_LEAVE_INTERFACE
101a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten}
102a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten
103ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
1043a413f1863daa026ed2b9fc9eac01e1341116cdbGlenn Kastenstatic SLresult IEqualizer_GetNumberOfBands(SLEqualizerItf self, SLuint16 *pNumBands)
105a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten{
106ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    SL_ENTER_INTERFACE
107ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
108ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    if (NULL == pNumBands) {
109ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        result = SL_RESULT_PARAMETER_INVALID;
110ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    } else {
111ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        IEqualizer *this = (IEqualizer *) self;
112ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        // Note: no lock, but OK because it is const
113ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        *pNumBands = this->mNumBands;
114ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        result = SL_RESULT_SUCCESS;
115ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    }
116ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
117ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    SL_LEAVE_INTERFACE
118a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten}
119a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten
120ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
121e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kastenstatic SLresult IEqualizer_GetBandLevelRange(SLEqualizerItf self, SLmillibel *pMin,
122e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kasten    SLmillibel *pMax)
123a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten{
124ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    SL_ENTER_INTERFACE
125ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
126ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    if (NULL == pMin && NULL == pMax) {
127ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        result = SL_RESULT_PARAMETER_INVALID;
128ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    } else {
129ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        IEqualizer *this = (IEqualizer *) self;
130ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        // Note: no lock, but OK because it is const
131ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        if (NULL != pMin)
132ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten            *pMin = this->mBandLevelRangeMin;
133ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        if (NULL != pMax)
134ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten            *pMax = this->mBandLevelRangeMax;
135ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        result = SL_RESULT_SUCCESS;
136ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    }
137ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
138ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    SL_LEAVE_INTERFACE
139a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten}
140a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten
141ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
1423a413f1863daa026ed2b9fc9eac01e1341116cdbGlenn Kastenstatic SLresult IEqualizer_SetBandLevel(SLEqualizerItf self, SLuint16 band, SLmillibel level)
143a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten{
144ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    SL_ENTER_INTERFACE
145ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
146a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten    IEqualizer *this = (IEqualizer *) self;
147ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    if (!(this->mBandLevelRangeMin <= level && level <= this->mBandLevelRangeMax) ||
1484be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi            (band >= this->mNumBands)) {
149ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        result = SL_RESULT_PARAMETER_INVALID;
150ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    } else {
151ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        interface_lock_exclusive(this);
152faf90312d2156acbf27c62e114fd180708aa7654Glenn Kasten#if !defined(ANDROID)
153ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        this->mLevels[band] = level;
154ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        this->mPreset = SL_EQUALIZER_UNDEFINED;
155ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        result = SL_RESULT_SUCCESS;
1564be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi#else
157cfe5b1c6f0b65499d9aed2cf4b2a7e805fb02758Jean-Michel Trivi        if (NO_EQ(this)) {
1587e01bc6208fb5b4a2a0019d67bf74373f8ee9428Jean-Michel Trivi            result = SL_RESULT_CONTROL_LOST;
1597e01bc6208fb5b4a2a0019d67bf74373f8ee9428Jean-Michel Trivi        } else {
1609cd3c9e7a2395647b92c32f33c06cf9fd546b22fJean-Michel Trivi            android::status_t status =
1614be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi                android_eq_setParam(this->mEqEffect, EQ_PARAM_BAND_LEVEL, band, &level);
1629cd3c9e7a2395647b92c32f33c06cf9fd546b22fJean-Michel Trivi            result = android_fx_statusToResult(status);
1639cd3c9e7a2395647b92c32f33c06cf9fd546b22fJean-Michel Trivi        }
1644be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi#endif
1654be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi        interface_unlock_exclusive(this);
166ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    }
167ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
168ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    SL_LEAVE_INTERFACE
169a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten}
170a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten
171ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
172d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kastenstatic SLresult IEqualizer_GetBandLevel(SLEqualizerItf self, SLuint16 band, SLmillibel *pLevel)
173a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten{
174ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    SL_ENTER_INTERFACE
175ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
176ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    if (NULL == pLevel) {
177ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        result = SL_RESULT_PARAMETER_INVALID;
178ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    } else {
179ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        IEqualizer *this = (IEqualizer *) self;
180ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        // const, no lock needed
181ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        if (band >= this->mNumBands) {
182ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten            result = SL_RESULT_PARAMETER_INVALID;
183ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        } else {
1849cd3c9e7a2395647b92c32f33c06cf9fd546b22fJean-Michel Trivi            SLmillibel level = 0;
1854be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi            interface_lock_shared(this);
186faf90312d2156acbf27c62e114fd180708aa7654Glenn Kasten#if !defined(ANDROID)
1874be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi            level = this->mLevels[band];
188ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten            result = SL_RESULT_SUCCESS;
1894be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi#else
190cfe5b1c6f0b65499d9aed2cf4b2a7e805fb02758Jean-Michel Trivi            if (NO_EQ(this)) {
1917e01bc6208fb5b4a2a0019d67bf74373f8ee9428Jean-Michel Trivi                result = SL_RESULT_CONTROL_LOST;
1927e01bc6208fb5b4a2a0019d67bf74373f8ee9428Jean-Michel Trivi            } else {
1939cd3c9e7a2395647b92c32f33c06cf9fd546b22fJean-Michel Trivi                android::status_t status =
1944be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi                    android_eq_getParam(this->mEqEffect, EQ_PARAM_BAND_LEVEL, band, &level);
1959cd3c9e7a2395647b92c32f33c06cf9fd546b22fJean-Michel Trivi                result = android_fx_statusToResult(status);
1969cd3c9e7a2395647b92c32f33c06cf9fd546b22fJean-Michel Trivi            }
1974be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi#endif
1984be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi            interface_unlock_shared(this);
1994be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi            *pLevel = level;
200ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        }
201ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    }
202ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
203ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    SL_LEAVE_INTERFACE
204a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten}
205a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten
206ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
2073a413f1863daa026ed2b9fc9eac01e1341116cdbGlenn Kastenstatic SLresult IEqualizer_GetCenterFreq(SLEqualizerItf self, SLuint16 band, SLmilliHertz *pCenter)
208a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten{
209ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    SL_ENTER_INTERFACE
210ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
211ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    if (NULL == pCenter) {
212ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        result = SL_RESULT_PARAMETER_INVALID;
213ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    } else {
214ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        IEqualizer *this = (IEqualizer *) self;
215ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        if (band >= this->mNumBands) {
216ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten            result = SL_RESULT_PARAMETER_INVALID;
217ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        } else {
218faf90312d2156acbf27c62e114fd180708aa7654Glenn Kasten#if !defined(ANDROID)
219ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten            // Note: no lock, but OK because it is const
220ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten            *pCenter = this->mBands[band].mCenter;
221ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten            result = SL_RESULT_SUCCESS;
2224be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi#else
2239cd3c9e7a2395647b92c32f33c06cf9fd546b22fJean-Michel Trivi            SLmilliHertz center = 0;
2244be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi            interface_lock_shared(this);
225cfe5b1c6f0b65499d9aed2cf4b2a7e805fb02758Jean-Michel Trivi            if (NO_EQ(this)) {
2267e01bc6208fb5b4a2a0019d67bf74373f8ee9428Jean-Michel Trivi                result = SL_RESULT_CONTROL_LOST;
2277e01bc6208fb5b4a2a0019d67bf74373f8ee9428Jean-Michel Trivi            } else {
2289cd3c9e7a2395647b92c32f33c06cf9fd546b22fJean-Michel Trivi                android::status_t status =
2294be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi                    android_eq_getParam(this->mEqEffect, EQ_PARAM_CENTER_FREQ, band, &center);
2309cd3c9e7a2395647b92c32f33c06cf9fd546b22fJean-Michel Trivi                result = android_fx_statusToResult(status);
2319cd3c9e7a2395647b92c32f33c06cf9fd546b22fJean-Michel Trivi            }
2324be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi            interface_unlock_shared(this);
2334be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi            *pCenter = center;
2344be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi#endif
235ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        }
236ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    }
237ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
238ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    SL_LEAVE_INTERFACE
239a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten}
240a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten
241ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
242a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kastenstatic SLresult IEqualizer_GetBandFreqRange(SLEqualizerItf self, SLuint16 band,
243a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten    SLmilliHertz *pMin, SLmilliHertz *pMax)
244a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten{
245ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    SL_ENTER_INTERFACE
246ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
247ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    if (NULL == pMin && NULL == pMax) {
248ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        result = SL_RESULT_PARAMETER_INVALID;
249ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    } else {
250ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        IEqualizer *this = (IEqualizer *) self;
251ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        if (band >= this->mNumBands) {
252ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten            result = SL_RESULT_PARAMETER_INVALID;
253ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        } else {
254faf90312d2156acbf27c62e114fd180708aa7654Glenn Kasten#if !defined(ANDROID)
255ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten            // Note: no lock, but OK because it is const
256ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten            if (NULL != pMin)
257ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten                *pMin = this->mBands[band].mMin;
258ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten            if (NULL != pMax)
259ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten                *pMax = this->mBands[band].mMax;
260ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten            result = SL_RESULT_SUCCESS;
2614be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi#else
2629cd3c9e7a2395647b92c32f33c06cf9fd546b22fJean-Michel Trivi            SLmilliHertz range[2] = {0, 0}; // SLmilliHertz is SLuint32
2634be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi            interface_lock_shared(this);
264cfe5b1c6f0b65499d9aed2cf4b2a7e805fb02758Jean-Michel Trivi            if (NO_EQ(this)) {
2657e01bc6208fb5b4a2a0019d67bf74373f8ee9428Jean-Michel Trivi                result = SL_RESULT_CONTROL_LOST;
2667e01bc6208fb5b4a2a0019d67bf74373f8ee9428Jean-Michel Trivi            } else {
2679cd3c9e7a2395647b92c32f33c06cf9fd546b22fJean-Michel Trivi                android::status_t status =
2684be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi                    android_eq_getParam(this->mEqEffect, EQ_PARAM_BAND_FREQ_RANGE, band, range);
2699cd3c9e7a2395647b92c32f33c06cf9fd546b22fJean-Michel Trivi                result = android_fx_statusToResult(status);
2709cd3c9e7a2395647b92c32f33c06cf9fd546b22fJean-Michel Trivi            }
2714be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi            interface_unlock_shared(this);
2724be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi            if (NULL != pMin) {
2734be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi                *pMin = range[0];
2744be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi            }
2754be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi            if (NULL != pMax) {
2764be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi                *pMax = range[1];
2774be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi            }
2784be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi#endif
279ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        }
280ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    }
281ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
282ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    SL_LEAVE_INTERFACE
283a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten}
284a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten
285ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
2863a413f1863daa026ed2b9fc9eac01e1341116cdbGlenn Kastenstatic SLresult IEqualizer_GetBand(SLEqualizerItf self, SLmilliHertz frequency, SLuint16 *pBand)
287a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten{
288ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    SL_ENTER_INTERFACE
289ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
290ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    if (NULL == pBand) {
291ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        result = SL_RESULT_PARAMETER_INVALID;
292ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    } else {
293ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        IEqualizer *this = (IEqualizer *) self;
294faf90312d2156acbf27c62e114fd180708aa7654Glenn Kasten#if !defined(ANDROID)
295ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        // search for band whose center frequency has the closest ratio to 1.0
296ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        // assumes bands are unsorted (a pessimistic assumption)
297ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        // assumes bands can overlap (a pessimistic assumption)
298ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        // assumes a small number of bands, so no need for a fancier algorithm
299ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        const struct EqualizerBand *band;
300ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        float floatFreq = (float) frequency;
301ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        float bestRatio = 0.0;
302ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        SLuint16 bestBand = SL_EQUALIZER_UNDEFINED;
303ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        for (band = this->mBands; band < &this->mBands[this->mNumBands]; ++band) {
304ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten            if (!(band->mMin <= frequency && frequency <= band->mMax))
305ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten                continue;
306ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten            assert(band->mMin <= band->mCenter && band->mCenter <= band->mMax);
307ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten            assert(band->mCenter != 0);
308ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten            float ratio = frequency <= band->mCenter ?
309ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten                floatFreq / band->mCenter : band->mCenter / floatFreq;
310ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten            if (ratio > bestRatio) {
311ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten                bestRatio = ratio;
312ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten                bestBand = band - this->mBands;
313ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten            }
314a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten        }
3157c3fe21525e62f24acc9d391f9d396ce2d7e57acGlenn Kasten        *pBand = bestBand;
316ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        result = SL_RESULT_SUCCESS;
3174be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi#else
3189cd3c9e7a2395647b92c32f33c06cf9fd546b22fJean-Michel Trivi        uint16_t band = 0;
3194be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi        interface_lock_shared(this);
320cfe5b1c6f0b65499d9aed2cf4b2a7e805fb02758Jean-Michel Trivi        if (NO_EQ(this)) {
3217e01bc6208fb5b4a2a0019d67bf74373f8ee9428Jean-Michel Trivi            result = SL_RESULT_CONTROL_LOST;
3227e01bc6208fb5b4a2a0019d67bf74373f8ee9428Jean-Michel Trivi        } else {
3239cd3c9e7a2395647b92c32f33c06cf9fd546b22fJean-Michel Trivi            android::status_t status =
3249cd3c9e7a2395647b92c32f33c06cf9fd546b22fJean-Michel Trivi                android_eq_getParam(this->mEqEffect, EQ_PARAM_GET_BAND, frequency, &band);
3259cd3c9e7a2395647b92c32f33c06cf9fd546b22fJean-Michel Trivi            result = android_fx_statusToResult(status);
3269cd3c9e7a2395647b92c32f33c06cf9fd546b22fJean-Michel Trivi        }
3274be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi        interface_unlock_shared(this);
3284be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi        *pBand = (SLuint16)band;
3294be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi#endif
330a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten    }
331ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
332ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    SL_LEAVE_INTERFACE
333a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten}
334a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten
335ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
336d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kastenstatic SLresult IEqualizer_GetCurrentPreset(SLEqualizerItf self, SLuint16 *pPreset)
337a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten{
338ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    SL_ENTER_INTERFACE
339ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
340ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    if (NULL == pPreset) {
341ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        result = SL_RESULT_PARAMETER_INVALID;
342ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    } else {
343ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        IEqualizer *this = (IEqualizer *) self;
344ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        interface_lock_shared(this);
345faf90312d2156acbf27c62e114fd180708aa7654Glenn Kasten#if !defined(ANDROID)
346ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        SLuint16 preset = this->mPreset;
347ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        interface_unlock_shared(this);
348ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        *pPreset = preset;
349ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        result = SL_RESULT_SUCCESS;
3504be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi#else
3519cd3c9e7a2395647b92c32f33c06cf9fd546b22fJean-Michel Trivi        uint16_t preset = 0;
352cfe5b1c6f0b65499d9aed2cf4b2a7e805fb02758Jean-Michel Trivi        if (NO_EQ(this)) {
3537e01bc6208fb5b4a2a0019d67bf74373f8ee9428Jean-Michel Trivi            result = SL_RESULT_CONTROL_LOST;
3547e01bc6208fb5b4a2a0019d67bf74373f8ee9428Jean-Michel Trivi        } else {
3559cd3c9e7a2395647b92c32f33c06cf9fd546b22fJean-Michel Trivi            android::status_t status =
3569cd3c9e7a2395647b92c32f33c06cf9fd546b22fJean-Michel Trivi                    android_eq_getParam(this->mEqEffect, EQ_PARAM_CUR_PRESET, 0, &preset);
3579cd3c9e7a2395647b92c32f33c06cf9fd546b22fJean-Michel Trivi            result = android_fx_statusToResult(status);
3589cd3c9e7a2395647b92c32f33c06cf9fd546b22fJean-Michel Trivi        }
3594be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi        interface_unlock_shared(this);
3609cd3c9e7a2395647b92c32f33c06cf9fd546b22fJean-Michel Trivi
3614be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi        if (preset < 0) {
3624be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi            *pPreset = SL_EQUALIZER_UNDEFINED;
3634be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi        } else {
3644be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi            *pPreset = (SLuint16) preset;
3654be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi        }
3664be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi#endif
3674be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi
368ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    }
369ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
370ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    SL_LEAVE_INTERFACE
371a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten}
372a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten
373ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
374a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kastenstatic SLresult IEqualizer_UsePreset(SLEqualizerItf self, SLuint16 index)
375a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten{
376ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    SL_ENTER_INTERFACE
377a7b79e766ec6d95e9236168c27461c2ebaef4659Glenn Kasten    SL_LOGV("Equalizer::UsePreset index=%u", index);
378ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
379a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten    IEqualizer *this = (IEqualizer *) self;
380ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    if (index >= this->mNumPresets) {
381ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        result = SL_RESULT_PARAMETER_INVALID;
382ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    } else {
383ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        interface_lock_exclusive(this);
384faf90312d2156acbf27c62e114fd180708aa7654Glenn Kasten#if !defined(ANDROID)
385ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        SLuint16 band;
386ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        for (band = 0; band < this->mNumBands; ++band)
387ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten            this->mLevels[band] = EqualizerPresets[index].mLevels[band];
388ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        this->mPreset = index;
389ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        interface_unlock_exclusive(this);
390ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        result = SL_RESULT_SUCCESS;
3914be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi#else
392cfe5b1c6f0b65499d9aed2cf4b2a7e805fb02758Jean-Michel Trivi        if (NO_EQ(this)) {
3937e01bc6208fb5b4a2a0019d67bf74373f8ee9428Jean-Michel Trivi            result = SL_RESULT_CONTROL_LOST;
3947e01bc6208fb5b4a2a0019d67bf74373f8ee9428Jean-Michel Trivi        } else {
3959cd3c9e7a2395647b92c32f33c06cf9fd546b22fJean-Michel Trivi            android::status_t status =
396b3b757daa7d162b6f66590d917c1f84f3ba73c70Eric Laurent                android_eq_setParam(this->mEqEffect, EQ_PARAM_CUR_PRESET, 0, &index);
3979cd3c9e7a2395647b92c32f33c06cf9fd546b22fJean-Michel Trivi            result = android_fx_statusToResult(status);
3989cd3c9e7a2395647b92c32f33c06cf9fd546b22fJean-Michel Trivi        }
3994be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi        interface_unlock_shared(this);
4004be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi#endif
401ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    }
402ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
403ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    SL_LEAVE_INTERFACE
404a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten}
405a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten
406ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
407d2a7f0d6883a6d3835642e7b282f05ed1c54fe63Glenn Kastenstatic SLresult IEqualizer_GetNumberOfPresets(SLEqualizerItf self, SLuint16 *pNumPresets)
408a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten{
409ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    SL_ENTER_INTERFACE
410ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
411ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    if (NULL == pNumPresets) {
412ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        result = SL_RESULT_PARAMETER_INVALID;
413ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    } else {
414ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        IEqualizer *this = (IEqualizer *) self;
415ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        // Note: no lock, but OK because it is const
416ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        *pNumPresets = this->mNumPresets;
4177e01bc6208fb5b4a2a0019d67bf74373f8ee9428Jean-Michel Trivi
418ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        result = SL_RESULT_SUCCESS;
419ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    }
420ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
421ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    SL_LEAVE_INTERFACE
422a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten}
423a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten
424ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
425e5bf0d2c9531a7064eb3ddcafaf93ac1b0974037Glenn Kastenstatic SLresult IEqualizer_GetPresetName(SLEqualizerItf self, SLuint16 index, const SLchar **ppName)
426a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten{
427ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    SL_ENTER_INTERFACE
428ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
429ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    if (NULL == ppName) {
430ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        result = SL_RESULT_PARAMETER_INVALID;
431ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    } else {
432ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        IEqualizer *this = (IEqualizer *) self;
433faf90312d2156acbf27c62e114fd180708aa7654Glenn Kasten#if !defined(ANDROID)
434ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        if (index >= this->mNumPresets) {
435ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten            result = SL_RESULT_PARAMETER_INVALID;
436ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        } else {
437ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten            *ppName = (SLchar *) this->mPresets[index].mName;
438ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten            result = SL_RESULT_SUCCESS;
439ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten        }
4404be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi#else
4417e01bc6208fb5b4a2a0019d67bf74373f8ee9428Jean-Michel Trivi        if (index >= this->mNumPresets) {
4424be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi            result = SL_RESULT_PARAMETER_INVALID;
4434be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi        } else {
4447e01bc6208fb5b4a2a0019d67bf74373f8ee9428Jean-Michel Trivi            // FIXME query preset name rather than retrieve it from the engine.
4457e01bc6208fb5b4a2a0019d67bf74373f8ee9428Jean-Michel Trivi            //       In SL ES 1.0.1, the strings must exist for the lifetime of the engine.
4467e01bc6208fb5b4a2a0019d67bf74373f8ee9428Jean-Michel Trivi            //       Starting in 1.1, this will change and we don't need to hold onto the strings
4477e01bc6208fb5b4a2a0019d67bf74373f8ee9428Jean-Michel Trivi            //       for so long as they will copied into application space.
4484be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi            *ppName = (SLchar *) this->mThis->mEngine->mEqPresetNames[index];
4494be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi            result = SL_RESULT_SUCCESS;
4504be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi        }
4514be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi#endif
452ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    }
453ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
454ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten    SL_LEAVE_INTERFACE
455a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten}
456a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten
457ed46c29d6a09112dbbf584c82953f63289596fd6Glenn Kasten
458a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kastenstatic const struct SLEqualizerItf_ IEqualizer_Itf = {
459a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten    IEqualizer_SetEnabled,
460a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten    IEqualizer_IsEnabled,
461a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten    IEqualizer_GetNumberOfBands,
462a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten    IEqualizer_GetBandLevelRange,
463a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten    IEqualizer_SetBandLevel,
464a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten    IEqualizer_GetBandLevel,
465a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten    IEqualizer_GetCenterFreq,
466a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten    IEqualizer_GetBandFreqRange,
467a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten    IEqualizer_GetBand,
468a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten    IEqualizer_GetCurrentPreset,
469a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten    IEqualizer_UsePreset,
470a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten    IEqualizer_GetNumberOfPresets,
471a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten    IEqualizer_GetPresetName
472a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten};
473a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten
474a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kastenvoid IEqualizer_init(void *self)
475a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten{
476a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten    IEqualizer *this = (IEqualizer *) self;
477a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten    this->mItf = &IEqualizer_Itf;
478a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten    this->mEnabled = SL_BOOLEAN_FALSE;
4793a413f1863daa026ed2b9fc9eac01e1341116cdbGlenn Kasten    this->mPreset = SL_EQUALIZER_UNDEFINED;
480a9a70a4451545034c9263dd55b181f2912534c37Glenn Kasten#if 0 < MAX_EQ_BANDS
4810b167267bda99b68346045ccab14e810121d5de4Glenn Kasten    unsigned band;
4823a413f1863daa026ed2b9fc9eac01e1341116cdbGlenn Kasten    for (band = 0; band < MAX_EQ_BANDS; ++band)
4830b167267bda99b68346045ccab14e810121d5de4Glenn Kasten        this->mLevels[band] = 0;
4844b65ef9efdf5aba01bea89d8cdd64f500560a28dGlenn Kasten#endif
4853a413f1863daa026ed2b9fc9eac01e1341116cdbGlenn Kasten    // const fields
4864be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi    this->mNumPresets = 0;
4874be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi    this->mNumBands = 0;
488faf90312d2156acbf27c62e114fd180708aa7654Glenn Kasten#if !defined(ANDROID)
4893a413f1863daa026ed2b9fc9eac01e1341116cdbGlenn Kasten    this->mBands = EqualizerBands;
4903a413f1863daa026ed2b9fc9eac01e1341116cdbGlenn Kasten    this->mPresets = EqualizerPresets;
4914be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi#endif
4924be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi    this->mBandLevelRangeMin = 0;
4934be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi    this->mBandLevelRangeMax = 0;
494faf90312d2156acbf27c62e114fd180708aa7654Glenn Kasten#if defined(ANDROID)
495a9a70a4451545034c9263dd55b181f2912534c37Glenn Kasten    memset(&this->mEqDescriptor, 0, sizeof(effect_descriptor_t));
496a9a70a4451545034c9263dd55b181f2912534c37Glenn Kasten    // placement new (explicit constructor)
497a9a70a4451545034c9263dd55b181f2912534c37Glenn Kasten    (void) new (&this->mEqEffect) android::sp<android::AudioEffect>();
498a9a70a4451545034c9263dd55b181f2912534c37Glenn Kasten#endif
499a9a70a4451545034c9263dd55b181f2912534c37Glenn Kasten}
5004be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi
501a9a70a4451545034c9263dd55b181f2912534c37Glenn Kastenvoid IEqualizer_deinit(void *self)
502a9a70a4451545034c9263dd55b181f2912534c37Glenn Kasten{
503faf90312d2156acbf27c62e114fd180708aa7654Glenn Kasten#if defined(ANDROID)
504a9a70a4451545034c9263dd55b181f2912534c37Glenn Kasten    IEqualizer *this = (IEqualizer *) self;
505a9a70a4451545034c9263dd55b181f2912534c37Glenn Kasten    // explicit destructor
506a9a70a4451545034c9263dd55b181f2912534c37Glenn Kasten    this->mEqEffect.~sp();
507a9a70a4451545034c9263dd55b181f2912534c37Glenn Kasten#endif
508a9a70a4451545034c9263dd55b181f2912534c37Glenn Kasten}
5094be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi
510a9a70a4451545034c9263dd55b181f2912534c37Glenn Kastenbool IEqualizer_Expose(void *self)
511a9a70a4451545034c9263dd55b181f2912534c37Glenn Kasten{
512faf90312d2156acbf27c62e114fd180708aa7654Glenn Kasten#if defined(ANDROID)
513a9a70a4451545034c9263dd55b181f2912534c37Glenn Kasten    IEqualizer *this = (IEqualizer *) self;
514f5fce95f98037ea4ab341b416c82444af595313dJean-Michel Trivi    if (!android_fx_initEffectDescriptor(SL_IID_EQUALIZER, &this->mEqDescriptor)) {
515a9a70a4451545034c9263dd55b181f2912534c37Glenn Kasten        SL_LOGE("Equalizer initialization failed");
516f5fce95f98037ea4ab341b416c82444af595313dJean-Michel Trivi        this->mNumPresets = 0;
517f5fce95f98037ea4ab341b416c82444af595313dJean-Michel Trivi        this->mNumBands = 0;
518f5fce95f98037ea4ab341b416c82444af595313dJean-Michel Trivi        this->mBandLevelRangeMin = 0;
519f5fce95f98037ea4ab341b416c82444af595313dJean-Michel Trivi        this->mBandLevelRangeMax = 0;
520a9a70a4451545034c9263dd55b181f2912534c37Glenn Kasten        return false;
521f5fce95f98037ea4ab341b416c82444af595313dJean-Michel Trivi    }
5224be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi#endif
523a9a70a4451545034c9263dd55b181f2912534c37Glenn Kasten    return true;
524a6d984c32855a239f7f79a3d3b7f2ddfb8cb9697Glenn Kasten}
525