blob: 3db4bc3d028c77560ecf89f59ddea71a30fce5de [file] [log] [blame]
Marco Nelissen66f2cfe2011-06-23 14:05:10 -07001/*
2 * Copyright (C) 2010-2011 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.musicfx;
18
19import android.content.Context;
20import android.content.SharedPreferences;
21import android.media.MediaPlayer;
22import android.media.audiofx.AudioEffect;
23import android.media.audiofx.BassBoost;
24import android.media.audiofx.Equalizer;
25import android.media.audiofx.PresetReverb;
26import android.media.audiofx.Virtualizer;
27import android.util.Log;
28
29import java.util.Arrays;
30import java.util.concurrent.ConcurrentHashMap;
31
32/**
33 * The Common class defines constants to be used by the control panels.
34 */
35public class ControlPanelEffect {
36
37 private final static String TAG = "MusicFXControlPanelEffect";
38
39 /**
40 * Audio session priority
41 */
42 private static final int PRIORITY = 0;
43
44 /**
45 * The control mode specifies if control panel updates effects and preferences or only
46 * preferences.
47 */
48 static enum ControlMode {
49 /**
50 * Control panel updates effects and preferences. Applicable when audio session is delivered
51 * by user.
52 */
53 CONTROL_EFFECTS,
54 /**
55 * Control panel only updates preferences. Applicable when there was no audio or invalid
56 * session provided by user.
57 */
58 CONTROL_PREFERENCES
59 }
60
61 static enum Key {
Marco Nelissenbc778ed2012-10-11 17:37:03 -070062 global_enabled, virt_enabled, virt_strength_supported, virt_strength, virt_type, bb_enabled,
63 bb_strength, te_enabled, te_strength, avl_enabled, lm_enabled, lm_strength, eq_enabled,
Sharad Sangle54c89602013-06-17 23:21:33 +080064 eq_num_bands, eq_level_range, eq_center_freq, eq_band_level, eq_band_level_no_save, eq_num_presets, eq_preset_name,
Marco Nelissenbc778ed2012-10-11 17:37:03 -070065 eq_preset_user_band_level, eq_preset_user_band_level_default,
66 eq_preset_opensl_es_band_level, eq_preset_ci_extreme_band_level, eq_current_preset,
67 pr_enabled, pr_current_preset
Marco Nelissen66f2cfe2011-06-23 14:05:10 -070068 }
69
70 // Effect/audio session Mappings
71 /**
72 * Hashmap initial capacity
73 */
74 private static final int HASHMAP_INITIAL_CAPACITY = 16;
75 /**
76 * Hashmap load factor
77 */
78 private static final float HASHMAP_LOAD_FACTOR = 0.75f;
79 /**
80 * ConcurrentHashMap concurrency level
81 */
82 private static final int HASHMAP_CONCURRENCY_LEVEL = 2;
83
84 /**
85 * Map containing the Virtualizer audio session, effect mappings.
86 */
87 private static final ConcurrentHashMap<Integer, Virtualizer> mVirtualizerInstances = new ConcurrentHashMap<Integer, Virtualizer>(
88 HASHMAP_INITIAL_CAPACITY, HASHMAP_LOAD_FACTOR, HASHMAP_CONCURRENCY_LEVEL);
89 /**
90 * Map containing the BB audio session, effect mappings.
91 */
92 private static final ConcurrentHashMap<Integer, BassBoost> mBassBoostInstances = new ConcurrentHashMap<Integer, BassBoost>(
93 HASHMAP_INITIAL_CAPACITY, HASHMAP_LOAD_FACTOR, HASHMAP_CONCURRENCY_LEVEL);
94 /**
95 * Map containing the EQ audio session, effect mappings.
96 */
97 private static final ConcurrentHashMap<Integer, Equalizer> mEQInstances = new ConcurrentHashMap<Integer, Equalizer>(
98 HASHMAP_INITIAL_CAPACITY, HASHMAP_LOAD_FACTOR, HASHMAP_CONCURRENCY_LEVEL);
99 /**
100 * Map containing the PR audio session, effect mappings.
101 */
102 private static final ConcurrentHashMap<Integer, PresetReverb> mPresetReverbInstances = new ConcurrentHashMap<Integer, PresetReverb>(
103 HASHMAP_INITIAL_CAPACITY, HASHMAP_LOAD_FACTOR, HASHMAP_CONCURRENCY_LEVEL);
104
105 /**
106 * Map containing the package name, audio session mappings.
107 */
108 private static final ConcurrentHashMap<String, Integer> mPackageSessions = new ConcurrentHashMap<String, Integer>(
109 HASHMAP_INITIAL_CAPACITY, HASHMAP_LOAD_FACTOR, HASHMAP_CONCURRENCY_LEVEL);
110
111 // Defaults
Marco Nelissen024018a2011-07-19 14:06:08 -0700112 final static boolean GLOBAL_ENABLED_DEFAULT = false;
Marco Nelissen66f2cfe2011-06-23 14:05:10 -0700113 private final static boolean VIRTUALIZER_ENABLED_DEFAULT = true;
114 private final static int VIRTUALIZER_STRENGTH_DEFAULT = 1000;
115 private final static boolean BASS_BOOST_ENABLED_DEFAULT = true;
116 private final static int BASS_BOOST_STRENGTH_DEFAULT = 667;
117 private final static boolean PRESET_REVERB_ENABLED_DEFAULT = false;
118 private final static int PRESET_REVERB_CURRENT_PRESET_DEFAULT = 0; // None
119
120 // EQ defaults
121 private final static boolean EQUALIZER_ENABLED_DEFAULT = true;
122 private final static String EQUALIZER_PRESET_NAME_DEFAULT = "Preset";
123 private final static short EQUALIZER_NUMBER_BANDS_DEFAULT = 5;
124 private final static short EQUALIZER_NUMBER_PRESETS_DEFAULT = 0;
125 private final static short[] EQUALIZER_BAND_LEVEL_RANGE_DEFAULT = { -1500, 1500 };
126 private final static int[] EQUALIZER_CENTER_FREQ_DEFAULT = { 60000, 230000, 910000, 3600000,
127 14000000 };
128 private final static short[] EQUALIZER_PRESET_CIEXTREME_BAND_LEVEL = { 0, 800, 400, 100, 1000 };
129 private final static short[] EQUALIZER_PRESET_USER_BAND_LEVEL_DEFAULT = { 0, 0, 0, 0, 0 };
Marco Nelissen66f2cfe2011-06-23 14:05:10 -0700130
131 // EQ effect properties which are invariable over all EQ effects sessions
132 private static short[] mEQBandLevelRange = EQUALIZER_BAND_LEVEL_RANGE_DEFAULT;
133 private static short mEQNumBands = EQUALIZER_NUMBER_BANDS_DEFAULT;
134 private static int[] mEQCenterFreq = EQUALIZER_CENTER_FREQ_DEFAULT;
135 private static short mEQNumPresets = EQUALIZER_NUMBER_PRESETS_DEFAULT;
Filipe Gonçalves09156c62016-05-31 13:47:09 +0100136 private static short[][] mEQPresetOpenSLESBandLevel =
137 new short[EQUALIZER_NUMBER_PRESETS_DEFAULT][EQUALIZER_NUMBER_BANDS_DEFAULT];
Marco Nelissen66f2cfe2011-06-23 14:05:10 -0700138 private static String[] mEQPresetNames;
139 private static boolean mIsEQInitialized = false;
140 private final static Object mEQInitLock = new Object();
141
142 /**
143 * Default int argument used in methods to see that the arg is a dummy. Used for method
144 * overloading.
145 */
146 private final static int DUMMY_ARGUMENT = -1;
147
148 /**
149 * Inits effects preferences for the given context and package name in the control panel. If
150 * preferences for the given package name don't exist, they are created and initialized.
151 *
152 * @param context
153 * @param packageName
154 * @param audioSession
155 * System wide unique audio session identifier.
156 */
157 public static void initEffectsPreferences(final Context context, final String packageName,
158 final int audioSession) {
159 final SharedPreferences prefs = context.getSharedPreferences(packageName,
160 Context.MODE_PRIVATE);
161 final SharedPreferences.Editor editor = prefs.edit();
162 final ControlMode controlMode = getControlMode(audioSession);
163
164 // init preferences
165 try {
166 // init global on/off switch
167 final boolean isGlobalEnabled = prefs.getBoolean(Key.global_enabled.toString(),
168 GLOBAL_ENABLED_DEFAULT);
169 editor.putBoolean(Key.global_enabled.toString(), isGlobalEnabled);
170 Log.v(TAG, "isGlobalEnabled = " + isGlobalEnabled);
171
172 // Virtualizer
173 final boolean isVIEnabled = prefs.getBoolean(Key.virt_enabled.toString(),
174 VIRTUALIZER_ENABLED_DEFAULT);
Marco Nelissen20e6c9b2013-05-08 11:53:47 -0700175 final Virtualizer virt = new Virtualizer(0, audioSession);
Marco Nelissen66f2cfe2011-06-23 14:05:10 -0700176 final int vIStrength = prefs.getInt(Key.virt_strength.toString(),
Marco Nelissen20e6c9b2013-05-08 11:53:47 -0700177 virt.getRoundedStrength());
178 virt.release();
Marco Nelissen66f2cfe2011-06-23 14:05:10 -0700179 editor.putBoolean(Key.virt_enabled.toString(), isVIEnabled);
180 editor.putInt(Key.virt_strength.toString(), vIStrength);
Marco Nelissenbc778ed2012-10-11 17:37:03 -0700181 {
182 final MediaPlayer mediaPlayer = new MediaPlayer();
183 final int session = mediaPlayer.getAudioSessionId();
184 Virtualizer virtualizerEffect = null;
185 try {
186 virtualizerEffect = new Virtualizer(PRIORITY, session);
187 editor.putBoolean(Key.virt_strength_supported.toString(),
188 virtualizerEffect.getStrengthSupported());
189 } finally {
190 if (virtualizerEffect != null) {
191 Log.d(TAG, "Releasing dummy Virtualizer effect");
192 virtualizerEffect.release();
193 }
194 mediaPlayer.release();
195 }
196 }
Marco Nelissen19aa9172011-08-15 16:54:22 -0700197
Marco Nelissen66f2cfe2011-06-23 14:05:10 -0700198 // BassBoost
199 final boolean isBBEnabled = prefs.getBoolean(Key.bb_enabled.toString(),
200 BASS_BOOST_ENABLED_DEFAULT);
201 final int bBStrength = prefs.getInt(Key.bb_strength.toString(),
202 BASS_BOOST_STRENGTH_DEFAULT);
203 editor.putBoolean(Key.bb_enabled.toString(), isBBEnabled);
204 editor.putInt(Key.bb_strength.toString(), bBStrength);
Marco Nelissen19aa9172011-08-15 16:54:22 -0700205
Marco Nelissen66f2cfe2011-06-23 14:05:10 -0700206 // Equalizer
207 synchronized (mEQInitLock) {
208 // If EQ is not initialized already create "dummy" audio session created by
209 // MediaPlayer and create effect on it to retrieve the invariable EQ properties
210 if (!mIsEQInitialized) {
211 final MediaPlayer mediaPlayer = new MediaPlayer();
212 final int session = mediaPlayer.getAudioSessionId();
213 Equalizer equalizerEffect = null;
214 try {
Marco Nelissen19aa9172011-08-15 16:54:22 -0700215 Log.d(TAG, "Creating dummy EQ effect on session " + session);
Marco Nelissen66f2cfe2011-06-23 14:05:10 -0700216 equalizerEffect = new Equalizer(PRIORITY, session);
217
218 mEQBandLevelRange = equalizerEffect.getBandLevelRange();
219 mEQNumBands = equalizerEffect.getNumberOfBands();
220 mEQCenterFreq = new int[mEQNumBands];
221 for (short band = 0; band < mEQNumBands; band++) {
222 mEQCenterFreq[band] = equalizerEffect.getCenterFreq(band);
223 }
224 mEQNumPresets = equalizerEffect.getNumberOfPresets();
225 mEQPresetNames = new String[mEQNumPresets];
226 mEQPresetOpenSLESBandLevel = new short[mEQNumPresets][mEQNumBands];
227 for (short preset = 0; preset < mEQNumPresets; preset++) {
228 mEQPresetNames[preset] = equalizerEffect.getPresetName(preset);
229 equalizerEffect.usePreset(preset);
230 for (short band = 0; band < mEQNumBands; band++) {
231 mEQPresetOpenSLESBandLevel[preset][band] = equalizerEffect
232 .getBandLevel(band);
233 }
234 }
235
236 mIsEQInitialized = true;
237 } catch (final IllegalStateException e) {
238 Log.e(TAG, "Equalizer: " + e);
239 } catch (final IllegalArgumentException e) {
240 Log.e(TAG, "Equalizer: " + e);
241 } catch (final UnsupportedOperationException e) {
242 Log.e(TAG, "Equalizer: " + e);
243 } catch (final RuntimeException e) {
244 Log.e(TAG, "Equalizer: " + e);
245 } finally {
246 if (equalizerEffect != null) {
Marco Nelissen19aa9172011-08-15 16:54:22 -0700247 Log.d(TAG, "Releasing dummy EQ effect");
Marco Nelissen66f2cfe2011-06-23 14:05:10 -0700248 equalizerEffect.release();
249 }
250 mediaPlayer.release();
251
252 // When there was a failure set some good defaults
253 if (!mIsEQInitialized) {
Filipe Gonçalves09156c62016-05-31 13:47:09 +0100254 Log.e(TAG, "Error retrieving default EQ values, setting all presets"
255 + " to flat response");
Marco Nelissen66f2cfe2011-06-23 14:05:10 -0700256 mEQPresetOpenSLESBandLevel = new short[mEQNumPresets][mEQNumBands];
257 for (short preset = 0; preset < mEQNumPresets; preset++) {
258 // Init preset names to a dummy name
259 mEQPresetNames[preset] = prefs.getString(
260 Key.eq_preset_name.toString() + preset,
261 EQUALIZER_PRESET_NAME_DEFAULT + preset);
Filipe Gonçalves09156c62016-05-31 13:47:09 +0100262 mEQPresetOpenSLESBandLevel[preset] = Arrays.copyOf(
263 EQUALIZER_PRESET_USER_BAND_LEVEL_DEFAULT, mEQNumBands);
Marco Nelissen66f2cfe2011-06-23 14:05:10 -0700264 }
265 }
266 }
267 }
268 editor.putInt(Key.eq_level_range.toString() + 0, mEQBandLevelRange[0]);
269 editor.putInt(Key.eq_level_range.toString() + 1, mEQBandLevelRange[1]);
270 editor.putInt(Key.eq_num_bands.toString(), mEQNumBands);
271 editor.putInt(Key.eq_num_presets.toString(), mEQNumPresets);
272 // Resetting the EQ arrays depending on the real # bands with defaults if
273 // band < default size else 0 by copying default arrays over new ones
274 final short[] eQPresetCIExtremeBandLevel = Arrays.copyOf(
275 EQUALIZER_PRESET_CIEXTREME_BAND_LEVEL, mEQNumBands);
276 final short[] eQPresetUserBandLevelDefault = Arrays.copyOf(
277 EQUALIZER_PRESET_USER_BAND_LEVEL_DEFAULT, mEQNumBands);
278 // If no preset prefs set use CI EXTREME (= numPresets)
279 final short eQPreset = (short) prefs.getInt(Key.eq_current_preset.toString(),
280 mEQNumPresets);
281 editor.putInt(Key.eq_current_preset.toString(), eQPreset);
282 final short[] bandLevel = new short[mEQNumBands];
283 for (short band = 0; band < mEQNumBands; band++) {
284 if (controlMode == ControlMode.CONTROL_PREFERENCES) {
285 if (eQPreset < mEQNumPresets) {
286 // OpenSL ES effect presets
287 bandLevel[band] = mEQPresetOpenSLESBandLevel[eQPreset][band];
288 } else if (eQPreset == mEQNumPresets) {
289 // CI EXTREME
290 bandLevel[band] = eQPresetCIExtremeBandLevel[band];
291 } else {
292 // User
293 bandLevel[band] = (short) prefs.getInt(
294 Key.eq_preset_user_band_level.toString() + band,
295 eQPresetUserBandLevelDefault[band]);
296 }
297 editor.putInt(Key.eq_band_level.toString() + band, bandLevel[band]);
298 }
299 editor.putInt(Key.eq_center_freq.toString() + band, mEQCenterFreq[band]);
300 editor.putInt(Key.eq_preset_ci_extreme_band_level.toString() + band,
301 eQPresetCIExtremeBandLevel[band]);
302 editor.putInt(Key.eq_preset_user_band_level_default.toString() + band,
303 eQPresetUserBandLevelDefault[band]);
304 }
305 for (short preset = 0; preset < mEQNumPresets; preset++) {
306 editor.putString(Key.eq_preset_name.toString() + preset, mEQPresetNames[preset]);
307 for (short band = 0; band < mEQNumBands; band++) {
308 editor.putInt(Key.eq_preset_opensl_es_band_level.toString() + preset + "_"
309 + band, mEQPresetOpenSLESBandLevel[preset][band]);
310 }
311 }
312 }
313 final boolean isEQEnabled = prefs.getBoolean(Key.eq_enabled.toString(),
314 EQUALIZER_ENABLED_DEFAULT);
315 editor.putBoolean(Key.eq_enabled.toString(), isEQEnabled);
316
317 // Preset reverb
318 final boolean isEnabledPR = prefs.getBoolean(Key.pr_enabled.toString(),
319 PRESET_REVERB_ENABLED_DEFAULT);
320 final short presetPR = (short) prefs.getInt(Key.pr_current_preset.toString(),
321 PRESET_REVERB_CURRENT_PRESET_DEFAULT);
322 editor.putBoolean(Key.pr_enabled.toString(), isEnabledPR);
323 editor.putInt(Key.pr_current_preset.toString(), presetPR);
324
325 editor.commit();
326 } catch (final RuntimeException e) {
327 Log.e(TAG, "initEffectsPreferences: processingEnabled: " + e);
328 }
329 }
330
331 /**
332 * Gets the effect control mode based on the given audio session in the control panel. Control
333 * mode defines if the control panel is controlling effects and/or preferences
334 *
335 * @param audioSession
336 * System wide unique audio session identifier.
337 * @return effect control mode
338 */
339 public static ControlMode getControlMode(final int audioSession) {
340 if (audioSession == AudioEffect.ERROR_BAD_VALUE) {
341 return ControlMode.CONTROL_PREFERENCES;
342 }
343 return ControlMode.CONTROL_EFFECTS;
344 }
345
346 /**
347 * Sets boolean parameter to value for given key
348 *
349 * @param context
350 * @param packageName
351 * @param audioSession
352 * System wide unique audio session identifier.
353 * @param key
354 * @param value
355 */
356 public static void setParameterBoolean(final Context context, final String packageName,
357 final int audioSession, final Key key, final boolean value) {
358 try {
359 final SharedPreferences prefs = context.getSharedPreferences(packageName,
360 Context.MODE_PRIVATE);
361 final ControlMode controlMode = getControlMode(audioSession);
362 boolean enabled = value;
363
364 // Global on/off
365 if (key == Key.global_enabled) {
366 boolean processingEnabled = false;
367 if (value == true) {
368 // enable all with respect to preferences
369 if (controlMode == ControlMode.CONTROL_EFFECTS) {
370 final Virtualizer virtualizerEffect = getVirtualizerEffect(audioSession);
371 if (virtualizerEffect != null) {
372 virtualizerEffect.setEnabled(prefs.getBoolean(
373 Key.virt_enabled.toString(), VIRTUALIZER_ENABLED_DEFAULT));
Marco Nelissen20e6c9b2013-05-08 11:53:47 -0700374 int defaultstrength = virtualizerEffect.getRoundedStrength();
Marco Nelissen19aa9172011-08-15 16:54:22 -0700375 final int vIStrength = prefs.getInt(Key.virt_strength.toString(),
Marco Nelissen20e6c9b2013-05-08 11:53:47 -0700376 defaultstrength);
Marco Nelissen19aa9172011-08-15 16:54:22 -0700377 setParameterInt(context, packageName,
378 audioSession, Key.virt_strength, vIStrength);
Marco Nelissen66f2cfe2011-06-23 14:05:10 -0700379 }
380 final BassBoost bassBoostEffect = getBassBoostEffect(audioSession);
381 if (bassBoostEffect != null) {
382 bassBoostEffect.setEnabled(prefs.getBoolean(Key.bb_enabled.toString(),
383 BASS_BOOST_ENABLED_DEFAULT));
Marco Nelissen19aa9172011-08-15 16:54:22 -0700384 final int bBStrength = prefs.getInt(Key.bb_strength.toString(),
385 BASS_BOOST_STRENGTH_DEFAULT);
386 setParameterInt(context, packageName,
387 audioSession, Key.bb_strength, bBStrength);
Marco Nelissen66f2cfe2011-06-23 14:05:10 -0700388 }
389 final Equalizer equalizerEffect = getEqualizerEffect(audioSession);
390 if (equalizerEffect != null) {
391 equalizerEffect.setEnabled(prefs.getBoolean(Key.eq_enabled.toString(),
392 EQUALIZER_ENABLED_DEFAULT));
Marco Nelissen19aa9172011-08-15 16:54:22 -0700393 final int[] bandLevels = getParameterIntArray(context,
394 packageName, audioSession, Key.eq_band_level);
395 final int len = bandLevels.length;
396 for (short band = 0; band < len; band++) {
397 final int level = bandLevels[band];
398 setParameterInt(context, packageName,
Sharad Sangle54c89602013-06-17 23:21:33 +0800399 audioSession, Key.eq_band_level_no_save, level, band);
Marco Nelissen19aa9172011-08-15 16:54:22 -0700400 }
Marco Nelissen66f2cfe2011-06-23 14:05:10 -0700401 }
402 // XXX: Preset Reverb not used for the moment, so commented out the effect
403 // creation to not use MIPS
404 // final PresetReverb presetReverbEffect =
405 // getPresetReverbEffect(audioSession);
406 // if (presetReverbEffect != null) {
407 // presetReverbEffect.setEnabled(prefs.getBoolean(
408 // Key.pr_enabled.toString(), PRESET_REVERB_ENABLED_DEFAULT));
409 // }
410 }
411
412 processingEnabled = true;
413 Log.v(TAG, "processingEnabled=" + processingEnabled);
414
415 } else {
416 // disable all
417 if (controlMode == ControlMode.CONTROL_EFFECTS) {
Marco Nelissen19aa9172011-08-15 16:54:22 -0700418 final Virtualizer virtualizerEffect = getVirtualizerEffectNoCreate(audioSession);
Marco Nelissen66f2cfe2011-06-23 14:05:10 -0700419 if (virtualizerEffect != null) {
Marco Nelissen19aa9172011-08-15 16:54:22 -0700420 mVirtualizerInstances.remove(audioSession, virtualizerEffect);
Marco Nelissen66f2cfe2011-06-23 14:05:10 -0700421 virtualizerEffect.setEnabled(false);
Marco Nelissen19aa9172011-08-15 16:54:22 -0700422 virtualizerEffect.release();
Marco Nelissen66f2cfe2011-06-23 14:05:10 -0700423 }
Marco Nelissen19aa9172011-08-15 16:54:22 -0700424 final BassBoost bassBoostEffect = getBassBoostEffectNoCreate(audioSession);
Marco Nelissen66f2cfe2011-06-23 14:05:10 -0700425 if (bassBoostEffect != null) {
Marco Nelissen19aa9172011-08-15 16:54:22 -0700426 mBassBoostInstances.remove(audioSession, bassBoostEffect);
Marco Nelissen66f2cfe2011-06-23 14:05:10 -0700427 bassBoostEffect.setEnabled(false);
Marco Nelissen19aa9172011-08-15 16:54:22 -0700428 bassBoostEffect.release();
Marco Nelissen66f2cfe2011-06-23 14:05:10 -0700429 }
Marco Nelissen19aa9172011-08-15 16:54:22 -0700430 final Equalizer equalizerEffect = getEqualizerEffectNoCreate(audioSession);
Marco Nelissen66f2cfe2011-06-23 14:05:10 -0700431 if (equalizerEffect != null) {
Marco Nelissen19aa9172011-08-15 16:54:22 -0700432 mEQInstances.remove(audioSession, equalizerEffect);
Marco Nelissen66f2cfe2011-06-23 14:05:10 -0700433 equalizerEffect.setEnabled(false);
Marco Nelissen19aa9172011-08-15 16:54:22 -0700434 equalizerEffect.release();
Marco Nelissen66f2cfe2011-06-23 14:05:10 -0700435 }
436 // XXX: Preset Reverb not used for the moment, so commented out the effect
437 // creation to not use MIPS
438 // final PresetReverb presetReverbEffect =
439 // getPresetReverbEffect(audioSession);
440 // if (presetReverbEffect != null) {
441 // presetReverbEffect.setEnabled(false);
442 // }
443 }
444
445 processingEnabled = false;
446 Log.v(TAG, "processingEnabled=" + processingEnabled);
447 }
448 enabled = processingEnabled;
449 } else if (controlMode == ControlMode.CONTROL_EFFECTS) {
450 final boolean isGlobalEnabled = prefs.getBoolean(Key.global_enabled.toString(),
451 GLOBAL_ENABLED_DEFAULT);
452 if (isGlobalEnabled == true) {
453 // Set effect parameters
454 switch (key) {
455
456 case global_enabled:
457 // Global, already handled, to get out error free
458 break;
459
460 // Virtualizer
461 case virt_enabled:
462 final Virtualizer virtualizerEffect = getVirtualizerEffect(audioSession);
463 if (virtualizerEffect != null) {
464 virtualizerEffect.setEnabled(value);
465 enabled = virtualizerEffect.getEnabled();
466 }
467 break;
468
469 // BassBoost
470 case bb_enabled:
471 final BassBoost bassBoostEffect = getBassBoostEffect(audioSession);
472 if (bassBoostEffect != null) {
473 bassBoostEffect.setEnabled(value);
474 enabled = bassBoostEffect.getEnabled();
475 }
476 break;
477
478 // Equalizer
479 case eq_enabled:
480 final Equalizer equalizerEffect = getEqualizerEffect(audioSession);
481 if (equalizerEffect != null) {
482 equalizerEffect.setEnabled(value);
483 enabled = equalizerEffect.getEnabled();
484 }
485 break;
486
487 // PresetReverb
488 case pr_enabled:
489 // XXX: Preset Reverb not used for the moment, so commented out the effect
490 // creation to not use MIPS
491 // final PresetReverb presetReverbEffect =
492 // getPresetReverbEffect(audioSession);
493 // if (presetReverbEffect != null) {
494 // presetReverbEffect.setEnabled(value);
495 // enabled = presetReverbEffect.getEnabled();
496 // }
497 break;
498
499 default:
500 Log.e(TAG, "Unknown/unsupported key " + key);
501 return;
502 }
503 }
504
505 }
506
507 // Set preferences
508 final SharedPreferences.Editor editor = prefs.edit();
509 editor.putBoolean(key.toString(), enabled);
510 editor.commit();
511
512 } catch (final RuntimeException e) {
513 Log.e(TAG, "setParameterBoolean: " + key + "; " + value + "; " + e);
514 }
515 }
516
517 /**
518 * Gets boolean parameter for given key
519 *
520 * @param context
521 * @param packageName
522 * @param audioSession
523 * System wide unique audio session identifier.
524 * @param key
525 * @return parameter value
526 */
527 public static Boolean getParameterBoolean(final Context context, final String packageName,
528 final int audioSession, final Key key) {
529 final SharedPreferences prefs = context.getSharedPreferences(packageName,
530 Context.MODE_PRIVATE);
531 boolean value = false;
532
533 try {
534 value = prefs.getBoolean(key.toString(), value);
535 } catch (final RuntimeException e) {
536 Log.e(TAG, "getParameterBoolean: " + key + "; " + value + "; " + e);
537 }
538
539 return value;
540
541 }
542
543 /**
544 * Sets int parameter for given key and value arg0, arg1
545 *
546 * @param context
547 * @param packageName
548 * @param audioSession
549 * System wide unique audio session identifier.
550 * @param key
551 * @param arg0
552 * @param arg1
553 */
554 public static void setParameterInt(final Context context, final String packageName,
555 final int audioSession, final Key key, final int arg0, final int arg1) {
556 String strKey = key.toString();
557 int value = arg0;
558
559 try {
560 final SharedPreferences prefs = context.getSharedPreferences(packageName,
561 Context.MODE_PRIVATE);
562 final SharedPreferences.Editor editor = prefs.edit();
563 final ControlMode controlMode = getControlMode(audioSession);
564
565 // Set effect parameters
566 if (controlMode == ControlMode.CONTROL_EFFECTS) {
567
568 switch (key) {
569
570 // Virtualizer
571 case virt_strength: {
572 final Virtualizer virtualizerEffect = getVirtualizerEffect(audioSession);
573 if (virtualizerEffect != null) {
574 virtualizerEffect.setStrength((short) value);
575 value = virtualizerEffect.getRoundedStrength();
576 }
577 break;
578 }
579 // BassBoost
580 case bb_strength: {
581 final BassBoost bassBoostEffect = getBassBoostEffect(audioSession);
582 if (bassBoostEffect != null) {
583 bassBoostEffect.setStrength((short) value);
584 value = bassBoostEffect.getRoundedStrength();
585 }
586 break;
587 }
588 // Equalizer
589 case eq_band_level: {
590 if (arg1 == DUMMY_ARGUMENT) {
591 throw new IllegalArgumentException("Dummy arg passed.");
592 }
593 final short band = (short) arg1;
594 strKey = strKey + band;
595 final Equalizer equalizerEffect = getEqualizerEffect(audioSession);
596 if (equalizerEffect != null) {
597 equalizerEffect.setBandLevel(band, (short) value);
598 value = equalizerEffect.getBandLevel(band);
599 // save band level in User preset
600 editor.putInt(Key.eq_preset_user_band_level.toString() + band, value);
601 }
602 break;
603 }
Sharad Sangle54c89602013-06-17 23:21:33 +0800604 // Same as eq_band_level except won't save band level in User preset
605 case eq_band_level_no_save: {
606 if (arg1 == DUMMY_ARGUMENT) {
607 throw new IllegalArgumentException("Dummy arg passed.");
608 }
609 final short band = (short) arg1;
610 strKey = Key.eq_band_level.toString() + band;
611 final Equalizer equalizerEffect = getEqualizerEffect(audioSession);
612 if (equalizerEffect != null) {
613 equalizerEffect.setBandLevel(band, (short) value);
614 }
615 break;
616 }
Marco Nelissen66f2cfe2011-06-23 14:05:10 -0700617 case eq_current_preset: {
618 final Equalizer equalizerEffect = getEqualizerEffect(audioSession);
619 if (equalizerEffect != null) {
620 final short preset = (short) value;
621 final int numBands = prefs.getInt(Key.eq_num_bands.toString(),
622 EQUALIZER_NUMBER_BANDS_DEFAULT);
623 final int numPresets = prefs.getInt(Key.eq_num_presets.toString(),
624 EQUALIZER_NUMBER_PRESETS_DEFAULT);
625
626 if (preset < numPresets) {
627 // OpenSL ES EQ Effect presets
628 equalizerEffect.usePreset(preset);
629 value = equalizerEffect.getCurrentPreset();
630 } else {
631 final short[] eQPresetCIExtremeBandLevelDefault = Arrays.copyOf(
632 EQUALIZER_PRESET_CIEXTREME_BAND_LEVEL, numBands);
633 final short[] eQPresetUserBandLevelDefault = Arrays.copyOf(
634 EQUALIZER_PRESET_USER_BAND_LEVEL_DEFAULT, numBands);
635 // Set the band levels manually for custom presets
636 for (short band = 0; band < numBands; band++) {
637 short bandLevel = 0;
638 if (preset == numPresets) {
639 // CI EXTREME
640 bandLevel = (short) prefs.getInt(
641 Key.eq_preset_ci_extreme_band_level.toString() + band,
642 eQPresetCIExtremeBandLevelDefault[band]);
643 } else {
644 // User
645 bandLevel = (short) prefs.getInt(
646 Key.eq_preset_user_band_level.toString() + band,
647 eQPresetUserBandLevelDefault[band]);
648 }
649 equalizerEffect.setBandLevel(band, bandLevel);
650 }
651 }
652
653 // update band levels
654 for (short band = 0; band < numBands; band++) {
655 final short level = equalizerEffect.getBandLevel(band);
656 editor.putInt(Key.eq_band_level.toString() + band, level);
657 }
658 }
659 break;
660 }
661 case eq_preset_user_band_level:
662 // Fall through
663 case eq_preset_user_band_level_default:
664 // Fall through
665 case eq_preset_ci_extreme_band_level: {
666 if (arg1 == DUMMY_ARGUMENT) {
667 throw new IllegalArgumentException("Dummy arg passed.");
668 }
669 final short band = (short) arg1;
670 strKey = strKey + band;
671 break;
672 }
673 case pr_current_preset:
674 // XXX: Preset Reverb not used for the moment, so commented out the effect
675 // creation to not use MIPS
676 // final PresetReverb presetReverbEffect = getPresetReverbEffect(audioSession);
677 // if (presetReverbEffect != null) {
678 // presetReverbEffect.setPreset((short) value);
679 // value = presetReverbEffect.getPreset();
680 // }
681 break;
682 default:
683 Log.e(TAG, "setParameterInt: Unknown/unsupported key " + key);
684 return;
685 }
686 } else {
687 switch (key) {
688 // Virtualizer
689 case virt_strength:
690 // Do nothing
691 break;
692 case virt_type:
693 // Do nothing
694 break;
695
696 // BassBoost
697 case bb_strength:
698 // Do nothing
699 break;
700
701 // Equalizer
702 case eq_band_level: {
703 if (arg1 == DUMMY_ARGUMENT) {
704 throw new IllegalArgumentException("Dummy arg passed.");
705 }
706 final short band = (short) arg1;
707 strKey = strKey + band;
708
709 editor.putInt(Key.eq_preset_user_band_level.toString() + band, value);
710 break;
711 }
Sharad Sangle54c89602013-06-17 23:21:33 +0800712 // Same as eq_band_level except won't save band level in User preset
713 case eq_band_level_no_save: {
714 if (arg1 == DUMMY_ARGUMENT) {
715 throw new IllegalArgumentException("Dummy arg passed.");
716 }
717 final short band = (short) arg1;
718 strKey = Key.eq_band_level.toString() + band;
719 break;
720 }
721
Marco Nelissen66f2cfe2011-06-23 14:05:10 -0700722 case eq_current_preset: {
723 final short preset = (short) value;
724 final int numBands = prefs.getInt(Key.eq_num_bands.toString(),
725 EQUALIZER_NUMBER_BANDS_DEFAULT);
726 final int numPresets = prefs.getInt(Key.eq_num_presets.toString(),
727 EQUALIZER_NUMBER_PRESETS_DEFAULT);
728
729 final short[][] eQPresetOpenSLESBandLevelDefault = Arrays.copyOf(
Filipe Gonçalves09156c62016-05-31 13:47:09 +0100730 mEQPresetOpenSLESBandLevel, numPresets);
Marco Nelissen66f2cfe2011-06-23 14:05:10 -0700731 final short[] eQPresetCIExtremeBandLevelDefault = Arrays.copyOf(
732 EQUALIZER_PRESET_CIEXTREME_BAND_LEVEL, numBands);
733 final short[] eQPresetUserBandLevelDefault = Arrays.copyOf(
734 EQUALIZER_PRESET_USER_BAND_LEVEL_DEFAULT, numBands);
735 for (short band = 0; band < numBands; band++) {
736 short bandLevel = 0;
737 if (preset < numPresets) {
738 // OpenSL ES EQ Effect presets
739 bandLevel = (short) prefs.getInt(
740 Key.eq_preset_opensl_es_band_level.toString() + preset + "_"
741 + band, eQPresetOpenSLESBandLevelDefault[preset][band]);
742 } else if (preset == numPresets) {
743 // CI EXTREME
744 bandLevel = (short) prefs.getInt(
745 Key.eq_preset_ci_extreme_band_level.toString() + band,
746 eQPresetCIExtremeBandLevelDefault[band]);
747 } else {
748 // User
749 bandLevel = (short) prefs.getInt(
750 Key.eq_preset_user_band_level.toString() + band,
751 eQPresetUserBandLevelDefault[band]);
752 }
753 editor.putInt(Key.eq_band_level.toString() + band, bandLevel);
754 }
755 break;
756 }
757 case eq_preset_user_band_level:
758 // Fall through
759 case eq_preset_user_band_level_default:
760 // Fall through
761 case eq_preset_ci_extreme_band_level: {
762 if (arg1 == DUMMY_ARGUMENT) {
763 throw new IllegalArgumentException("Dummy arg passed.");
764 }
765 final short band = (short) arg1;
766 strKey = strKey + band;
767 break;
768 }
769 case pr_current_preset:
770 // Do nothing
771 break;
772 default:
773 Log.e(TAG, "setParameterInt: Unknown/unsupported key " + key);
774 return;
775 }
776 }
777
778 // Set preferences
779 editor.putInt(strKey, value);
Marco Nelissenb6436a62011-12-06 14:48:08 -0800780 editor.apply();
Marco Nelissen66f2cfe2011-06-23 14:05:10 -0700781
782 } catch (final RuntimeException e) {
783 Log.e(TAG, "setParameterInt: " + key + "; " + arg0 + "; " + arg1 + "; " + e);
784 }
785
786 }
787
788 /**
789 * Sets int parameter for given key and value arg
790 *
791 * @param context
792 * @param packageName
793 * @param audioSession
794 * System wide unique audio session identifier.
795 * @param key
796 * @param arg
797 */
798 public static void setParameterInt(final Context context, final String packageName,
799 final int audioSession, final Key key, final int arg) {
800 setParameterInt(context, packageName, audioSession, key, arg, DUMMY_ARGUMENT);
801 }
802
803 /**
804 * Gets int parameter given key
805 *
806 * @param context
807 * @param packageName
808 * @param audioSession
809 * System wide unique audio session identifier.
810 * @param key
811 * @return parameter value
812 */
813 public static int getParameterInt(final Context context, final String packageName,
814 final int audioSession, final String key) {
815 int value = 0;
816
817 try {
818 final SharedPreferences prefs = context.getSharedPreferences(packageName,
819 Context.MODE_PRIVATE);
820 value = prefs.getInt(key, value);
821 } catch (final RuntimeException e) {
822 Log.e(TAG, "getParameterInt: " + key + "; " + e);
823 }
824
825 return value;
826 }
827
828 /**
829 * Gets int parameter given key
830 *
831 * @param context
832 * @param packageName
833 * @param audioSession
834 * System wide unique audio session identifier.
835 * @param key
836 * @return parameter value
837 */
838 public static int getParameterInt(final Context context, final String packageName,
839 final int audioSession, final Key key) {
840 return getParameterInt(context, packageName, audioSession, key.toString());
841 }
842
843 /**
844 * Gets int parameter given key and arg
845 *
846 * @param context
847 * @param packageName
848 * @param audioSession
849 * System wide unique audio session identifier.
850 * @param audioSession
851 * @param key
852 * @param arg
853 * @return parameter value
854 */
855 public static int getParameterInt(final Context context, final String packageName,
856 final int audioSession, final Key key, final int arg) {
857 return getParameterInt(context, packageName, audioSession, key.toString() + arg);
858 }
859
860 /**
861 * Gets int parameter given key, arg0 and arg1
862 *
863 * @param context
864 * @param packageName
865 * @param audioSession
866 * System wide unique audio session identifier.
867 * @param audioSession
868 * @param key
869 * @param arg0
870 * @param arg1
871 * @return parameter value
872 */
873 public static int getParameterInt(final Context context, final String packageName,
874 final int audioSession, final Key key, final int arg0, final int arg1) {
875 return getParameterInt(context, packageName, audioSession, key.toString() + arg0 + "_"
876 + arg1);
877 }
878
879 /**
880 * Gets integer array parameter given key. Returns null if not found.
881 *
882 * @param context
883 * @param packageName
884 * @param audioSession
885 * System wide unique audio session identifier.
886 * @param key
887 * @return parameter value array
888 */
889 public static int[] getParameterIntArray(final Context context, final String packageName,
890 final int audioSession, final Key key) {
891 final SharedPreferences prefs = context.getSharedPreferences(packageName,
892 Context.MODE_PRIVATE);
893
894 int[] intArray = null;
895 try {
896 // Get effect parameters
897 switch (key) {
898 case eq_level_range: {
899 intArray = new int[2];
900 break;
901 }
902 case eq_center_freq:
903 // Fall through
904 case eq_band_level:
905 // Fall through
906 case eq_preset_user_band_level:
907 // Fall through
908 case eq_preset_user_band_level_default:
909 // Fall through
910 case eq_preset_ci_extreme_band_level: {
911 final int numBands = prefs.getInt(Key.eq_num_bands.toString(), 0);
912 intArray = new int[numBands];
913 break;
914 }
915 default:
916 Log.e(TAG, "getParameterIntArray: Unknown/unsupported key " + key);
917 return null;
918 }
919
920 for (int i = 0; i < intArray.length; i++) {
921 intArray[i] = prefs.getInt(key.toString() + i, 0);
922 }
923
924 } catch (final RuntimeException e) {
925 Log.e(TAG, "getParameterIntArray: " + key + "; " + e);
926 }
927
928 return intArray;
929 }
930
931 /**
932 * Gets string parameter given key. Returns empty string if not found.
933 *
934 * @param context
935 * @param packageName
936 * @param audioSession
937 * System wide unique audio session identifier.
938 * @param key
939 * @return parameter value
940 */
941 public static String getParameterString(final Context context, final String packageName,
942 final int audioSession, final String key) {
943 String value = "";
944 try {
945 final SharedPreferences prefs = context.getSharedPreferences(packageName,
946 Context.MODE_PRIVATE);
947
948 // Get effect parameters
949 value = prefs.getString(key, value);
950
951 } catch (final RuntimeException e) {
952 Log.e(TAG, "getParameterString: " + key + "; " + e);
953 }
954
955 return value;
956 }
957
958 /**
959 * Gets string parameter given key.
960 *
961 * @param context
962 * @param packageName
963 * @param audioSession
964 * System wide unique audio session identifier.
965 * @param key
966 * @return parameter value
967 */
968 public static String getParameterString(final Context context, final String packageName,
969 final int audioSession, final Key key) {
970 return getParameterString(context, packageName, audioSession, key.toString());
971 }
972
973 /**
974 * Gets string parameter given key and arg.
975 *
976 * @param context
977 * @param packageName
978 * @param audioSession
979 * System wide unique audio session identifier.
980 * @param args
981 * @return parameter value
982 */
983 public static String getParameterString(final Context context, final String packageName,
984 final int audioSession, final Key key, final int arg) {
985 return getParameterString(context, packageName, audioSession, key.toString() + arg);
986 }
987
988 /**
989 * Opens/initializes the effects session for the given audio session with preferences linked to
990 * the given package name and context.
991 *
992 * @param context
993 * @param packageName
994 * @param audioSession
995 * System wide unique audio session identifier.
996 */
997 public static void openSession(final Context context, final String packageName,
998 final int audioSession) {
999 Log.v(TAG, "openSession(" + context + ", " + packageName + ", " + audioSession + ")");
1000 final String methodTag = "openSession: ";
1001
1002 // init preferences
1003 final SharedPreferences prefs = context.getSharedPreferences(packageName,
1004 Context.MODE_PRIVATE);
1005 final SharedPreferences.Editor editor = prefs.edit();
1006
1007 final boolean isGlobalEnabled = prefs.getBoolean(Key.global_enabled.toString(),
1008 GLOBAL_ENABLED_DEFAULT);
1009 editor.putBoolean(Key.global_enabled.toString(), isGlobalEnabled);
1010
Marco Nelissen19aa9172011-08-15 16:54:22 -07001011 if (!isGlobalEnabled) {
1012 return;
1013 }
1014
Marco Nelissen66f2cfe2011-06-23 14:05:10 -07001015 // Manage audioSession information
1016
1017 // Retrieve AudioSession Id from map
1018 boolean isExistingAudioSession = false;
1019
1020 try {
1021 final Integer currentAudioSession = mPackageSessions.putIfAbsent(packageName,
1022 audioSession);
1023 if (currentAudioSession != null) {
1024 // Compare with passed argument
1025 if (currentAudioSession == audioSession) {
1026 // FIXME: Normally, we should exit the function here
1027 // BUT: we have to take care of the virtualizer because of
1028 // a bug in the Android Effects Framework
1029 // editor.commit();
1030 // return;
1031 isExistingAudioSession = true;
1032 } else {
1033 closeSession(context, packageName, currentAudioSession);
1034 }
1035 }
1036 } catch (final NullPointerException e) {
1037 Log.e(TAG, methodTag + e);
1038 editor.commit();
1039 return;
1040 }
1041
1042 // Because the audioSession is new, get effects & settings from shared preferences
1043
1044 // Virtualizer
1045 // create effect
1046 final Virtualizer virtualizerEffect = getVirtualizerEffect(audioSession);
1047 {
1048 final String errorTag = methodTag + "Virtualizer error: ";
1049
1050 try {
1051 // read parameters
1052 final boolean isEnabled = prefs.getBoolean(Key.virt_enabled.toString(),
1053 VIRTUALIZER_ENABLED_DEFAULT);
Marco Nelissen20e6c9b2013-05-08 11:53:47 -07001054 int defaultstrength = isExistingAudioSession ? VIRTUALIZER_STRENGTH_DEFAULT :
1055 virtualizerEffect.getRoundedStrength();
1056 final int strength = prefs.getInt(Key.virt_strength.toString(), defaultstrength);
Marco Nelissen66f2cfe2011-06-23 14:05:10 -07001057 // init settings
1058 Virtualizer.Settings settings = new Virtualizer.Settings("Virtualizer;strength="
1059 + strength);
1060
1061 virtualizerEffect.setProperties(settings);
1062
1063 // set parameters
1064 if (isGlobalEnabled == true) {
1065 virtualizerEffect.setEnabled(isEnabled);
1066 } else {
1067 virtualizerEffect.setEnabled(false);
1068 }
1069
1070 // get parameters
1071 settings = virtualizerEffect.getProperties();
1072 Log.v(TAG, "Parameters: " + settings.toString() + ";enabled=" + isEnabled);
1073
1074 // update preferences
1075 editor.putBoolean(Key.virt_enabled.toString(), isEnabled);
1076 editor.putInt(Key.virt_strength.toString(), settings.strength);
1077 } catch (final RuntimeException e) {
1078 Log.e(TAG, errorTag + e);
1079 }
1080 }
1081
1082 // In case of an existing audio session
1083 // Exit after the virtualizer has been re-enabled
1084
1085 if (isExistingAudioSession) {
b359fed4c7b2012-05-16 21:14:33 +08001086 editor.apply();
Marco Nelissen66f2cfe2011-06-23 14:05:10 -07001087 return;
1088 }
1089
1090 // BassBoost
1091 // create effect
1092 final BassBoost bassBoostEffect = getBassBoostEffect(audioSession);
1093 {
1094 final String errorTag = methodTag + "BassBoost error: ";
1095
1096 try {
1097 // read parameters
1098 final boolean isEnabled = prefs.getBoolean(Key.bb_enabled.toString(),
1099 BASS_BOOST_ENABLED_DEFAULT);
1100 final int strength = prefs.getInt(Key.bb_strength.toString(),
1101 BASS_BOOST_STRENGTH_DEFAULT);
1102
1103 // init settings
1104 BassBoost.Settings settings = new BassBoost.Settings("BassBoost;strength="
1105 + strength);
1106
1107 bassBoostEffect.setProperties(settings);
1108
1109 // set parameters
1110 if (isGlobalEnabled == true) {
1111 bassBoostEffect.setEnabled(isEnabled);
1112 } else {
1113 bassBoostEffect.setEnabled(false);
1114 }
1115
1116 // get parameters
1117 settings = bassBoostEffect.getProperties();
1118 Log.v(TAG, "Parameters: " + settings.toString() + ";enabled=" + isEnabled);
1119
1120 // update preferences
1121 editor.putBoolean(Key.bb_enabled.toString(), isEnabled);
1122 editor.putInt(Key.bb_strength.toString(), settings.strength);
1123 } catch (final RuntimeException e) {
1124 Log.e(TAG, errorTag + e);
1125 }
1126 }
1127
1128 // Equalizer
1129 // create effect
1130 final Equalizer equalizerEffect = getEqualizerEffect(audioSession);
1131 {
1132 final String errorTag = methodTag + "Equalizer error: ";
1133
1134 try {
1135 final short eQNumBands;
1136 final short[] bandLevel;
1137 final int[] eQCenterFreq;
1138 final short eQNumPresets;
1139 final String[] eQPresetNames;
1140 short eQPreset;
1141 synchronized (mEQInitLock) {
1142 // read parameters
1143 mEQBandLevelRange = equalizerEffect.getBandLevelRange();
1144 mEQNumBands = equalizerEffect.getNumberOfBands();
1145 mEQCenterFreq = new int[mEQNumBands];
1146 mEQNumPresets = equalizerEffect.getNumberOfPresets();
1147 mEQPresetNames = new String[mEQNumPresets];
1148
1149 for (short preset = 0; preset < mEQNumPresets; preset++) {
1150 mEQPresetNames[preset] = equalizerEffect.getPresetName(preset);
1151 editor.putString(Key.eq_preset_name.toString() + preset,
1152 mEQPresetNames[preset]);
1153 }
1154
1155 editor.putInt(Key.eq_level_range.toString() + 0, mEQBandLevelRange[0]);
1156 editor.putInt(Key.eq_level_range.toString() + 1, mEQBandLevelRange[1]);
1157 editor.putInt(Key.eq_num_bands.toString(), mEQNumBands);
1158 editor.putInt(Key.eq_num_presets.toString(), mEQNumPresets);
1159 // Resetting the EQ arrays depending on the real # bands with defaults if band <
1160 // default size else 0 by copying default arrays over new ones
1161 final short[] eQPresetCIExtremeBandLevel = Arrays.copyOf(
1162 EQUALIZER_PRESET_CIEXTREME_BAND_LEVEL, mEQNumBands);
1163 final short[] eQPresetUserBandLevelDefault = Arrays.copyOf(
1164 EQUALIZER_PRESET_USER_BAND_LEVEL_DEFAULT, mEQNumBands);
1165 // If no preset prefs set use CI EXTREME (= numPresets)
1166 eQPreset = (short) prefs
1167 .getInt(Key.eq_current_preset.toString(), mEQNumPresets);
1168 if (eQPreset < mEQNumPresets) {
1169 // OpenSL ES effect presets
1170 equalizerEffect.usePreset(eQPreset);
1171 eQPreset = equalizerEffect.getCurrentPreset();
1172 } else {
1173 for (short band = 0; band < mEQNumBands; band++) {
1174 short level = 0;
1175 if (eQPreset == mEQNumPresets) {
1176 // CI EXTREME
1177 level = eQPresetCIExtremeBandLevel[band];
1178 } else {
1179 // User
1180 level = (short) prefs.getInt(
1181 Key.eq_preset_user_band_level.toString() + band,
1182 eQPresetUserBandLevelDefault[band]);
1183 }
1184 equalizerEffect.setBandLevel(band, level);
1185 }
1186 }
1187 editor.putInt(Key.eq_current_preset.toString(), eQPreset);
1188
1189 bandLevel = new short[mEQNumBands];
1190 for (short band = 0; band < mEQNumBands; band++) {
1191 mEQCenterFreq[band] = equalizerEffect.getCenterFreq(band);
1192 bandLevel[band] = equalizerEffect.getBandLevel(band);
1193
1194 editor.putInt(Key.eq_band_level.toString() + band, bandLevel[band]);
1195 editor.putInt(Key.eq_center_freq.toString() + band, mEQCenterFreq[band]);
1196 editor.putInt(Key.eq_preset_ci_extreme_band_level.toString() + band,
1197 eQPresetCIExtremeBandLevel[band]);
1198 editor.putInt(Key.eq_preset_user_band_level_default.toString() + band,
1199 eQPresetUserBandLevelDefault[band]);
1200 }
1201
1202 eQNumBands = mEQNumBands;
1203 eQCenterFreq = mEQCenterFreq;
1204 eQNumPresets = mEQNumPresets;
1205 eQPresetNames = mEQPresetNames;
1206 }
1207
1208 final boolean isEnabled = prefs.getBoolean(Key.eq_enabled.toString(),
1209 EQUALIZER_ENABLED_DEFAULT);
1210 editor.putBoolean(Key.eq_enabled.toString(), isEnabled);
1211 if (isGlobalEnabled == true) {
1212 equalizerEffect.setEnabled(isEnabled);
1213 } else {
1214 equalizerEffect.setEnabled(false);
1215 }
1216
1217 // dump
1218 Log.v(TAG, "Parameters: Equalizer");
1219 Log.v(TAG, "bands=" + eQNumBands);
1220 String str = "levels=";
1221 for (short band = 0; band < eQNumBands; band++) {
1222 str = str + bandLevel[band] + "; ";
1223 }
1224 Log.v(TAG, str);
1225 str = "center=";
1226 for (short band = 0; band < eQNumBands; band++) {
1227 str = str + eQCenterFreq[band] + "; ";
1228 }
1229 Log.v(TAG, str);
1230 str = "presets=";
1231 for (short preset = 0; preset < eQNumPresets; preset++) {
1232 str = str + eQPresetNames[preset] + "; ";
1233 }
1234 Log.v(TAG, str);
1235 Log.v(TAG, "current=" + eQPreset);
1236 } catch (final RuntimeException e) {
1237 Log.e(TAG, errorTag + e);
1238 }
1239 }
1240
1241 // XXX: Preset Reverb not used for the moment, so commented out the effect creation to not
1242 // use MIPS left in the code for (future) reference.
1243 // Preset reverb
1244 // create effect
1245 // final PresetReverb presetReverbEffect = getPresetReverbEffect(audioSession);
1246 // {
1247 // final String errorTag = methodTag + "PresetReverb error: ";
1248 //
1249 // try {
1250 // // read parameters
1251 // final boolean isEnabled = prefs.getBoolean(Key.pr_enabled.toString(),
1252 // PRESET_REVERB_ENABLED_DEFAULT);
1253 // final short preset = (short) prefs.getInt(Key.pr_current_preset.toString(),
1254 // PRESET_REVERB_CURRENT_PRESET_DEFAULT);
1255 //
1256 // // init settings
1257 // PresetReverb.Settings settings = new PresetReverb.Settings("PresetReverb;preset="
1258 // + preset);
1259 //
1260 // // read/update preferences
1261 // presetReverbEffect.setProperties(settings);
1262 //
1263 // // set parameters
1264 // if (isGlobalEnabled == true) {
1265 // presetReverbEffect.setEnabled(isEnabled);
1266 // } else {
1267 // presetReverbEffect.setEnabled(false);
1268 // }
1269 //
1270 // // get parameters
1271 // settings = presetReverbEffect.getProperties();
1272 // Log.v(TAG, "Parameters: " + settings.toString() + ";enabled=" + isEnabled);
1273 //
1274 // // update preferences
1275 // editor.putBoolean(Key.pr_enabled.toString(), isEnabled);
1276 // editor.putInt(Key.pr_current_preset.toString(), settings.preset);
1277 // } catch (final RuntimeException e) {
1278 // Log.e(TAG, errorTag + e);
1279 // }
1280 // }
1281 editor.commit();
1282 }
1283
1284 /**
1285 * Closes the audio session (release effects) for the given session
1286 *
1287 * @param context
1288 * @param packageName
1289 * @param audioSession
1290 * System wide unique audio session identifier.
1291 */
1292 public static void closeSession(final Context context, final String packageName,
1293 final int audioSession) {
1294 Log.v(TAG, "closeSession(" + context + ", " + packageName + ", " + audioSession + ")");
1295
1296 // PresetReverb
1297 final PresetReverb presetReverb = mPresetReverbInstances.remove(audioSession);
1298 if (presetReverb != null) {
1299 presetReverb.release();
1300 }
1301 // Equalizer
1302 final Equalizer equalizer = mEQInstances.remove(audioSession);
1303 if (equalizer != null) {
1304 equalizer.release();
1305 }
1306 // BassBoost
1307 final BassBoost bassBoost = mBassBoostInstances.remove(audioSession);
1308 if (bassBoost != null) {
1309 bassBoost.release();
1310 }
1311 // Virtualizer
1312 final Virtualizer virtualizer = mVirtualizerInstances.remove(audioSession);
1313 if (virtualizer != null) {
1314 virtualizer.release();
1315 }
1316
1317 mPackageSessions.remove(packageName);
1318 }
1319
1320 /**
1321 * Enables or disables all effects (global enable/disable) for a given context, package name and
1322 * audio session. It sets/inits the control mode and preferences and then sets the global
1323 * enabled parameter.
1324 *
1325 * @param context
1326 * @param packageName
1327 * @param audioSession
1328 * System wide unique audio session identifier.
1329 * @param enabled
1330 */
1331 public static void setEnabledAll(final Context context, final String packageName,
1332 final int audioSession, final boolean enabled) {
1333 initEffectsPreferences(context, packageName, audioSession);
1334 setParameterBoolean(context, packageName, audioSession, Key.global_enabled, enabled);
1335 }
1336
1337 /**
Marco Nelissen66f2cfe2011-06-23 14:05:10 -07001338 * Gets the virtualizer effect for the given audio session. If the effect on the session doesn't
1339 * exist yet, create it and add to collection.
1340 *
1341 * @param audioSession
1342 * System wide unique audio session identifier.
1343 * @return virtualizerEffect
1344 */
Marco Nelissen19aa9172011-08-15 16:54:22 -07001345 private static Virtualizer getVirtualizerEffectNoCreate(final int audioSession) {
1346 return mVirtualizerInstances.get(audioSession);
1347 }
Marco Nelissen66f2cfe2011-06-23 14:05:10 -07001348 private static Virtualizer getVirtualizerEffect(final int audioSession) {
Marco Nelissen19aa9172011-08-15 16:54:22 -07001349 Virtualizer virtualizerEffect = getVirtualizerEffectNoCreate(audioSession);
Marco Nelissen66f2cfe2011-06-23 14:05:10 -07001350 if (virtualizerEffect == null) {
1351 try {
1352 final Virtualizer newVirtualizerEffect = new Virtualizer(PRIORITY, audioSession);
1353 virtualizerEffect = mVirtualizerInstances.putIfAbsent(audioSession,
1354 newVirtualizerEffect);
1355 if (virtualizerEffect == null) {
1356 // put succeeded, use new value
1357 virtualizerEffect = newVirtualizerEffect;
1358 }
1359 } catch (final IllegalArgumentException e) {
1360 Log.e(TAG, "Virtualizer: " + e);
1361 } catch (final UnsupportedOperationException e) {
1362 Log.e(TAG, "Virtualizer: " + e);
1363 } catch (final RuntimeException e) {
1364 Log.e(TAG, "Virtualizer: " + e);
1365 }
1366 }
1367 return virtualizerEffect;
1368 }
1369
1370 /**
1371 * Gets the bass boost effect for the given audio session. If the effect on the session doesn't
1372 * exist yet, create it and add to collection.
1373 *
1374 * @param audioSession
1375 * System wide unique audio session identifier.
1376 * @return bassBoostEffect
1377 */
Marco Nelissen19aa9172011-08-15 16:54:22 -07001378 private static BassBoost getBassBoostEffectNoCreate(final int audioSession) {
1379 return mBassBoostInstances.get(audioSession);
1380 }
Marco Nelissen66f2cfe2011-06-23 14:05:10 -07001381 private static BassBoost getBassBoostEffect(final int audioSession) {
Marco Nelissen19aa9172011-08-15 16:54:22 -07001382
1383 BassBoost bassBoostEffect = getBassBoostEffectNoCreate(audioSession);
Marco Nelissen66f2cfe2011-06-23 14:05:10 -07001384 if (bassBoostEffect == null) {
1385 try {
1386 final BassBoost newBassBoostEffect = new BassBoost(PRIORITY, audioSession);
1387 bassBoostEffect = mBassBoostInstances.putIfAbsent(audioSession, newBassBoostEffect);
1388 if (bassBoostEffect == null) {
1389 // put succeeded, use new value
1390 bassBoostEffect = newBassBoostEffect;
1391 }
1392 } catch (final IllegalArgumentException e) {
1393 Log.e(TAG, "BassBoost: " + e);
1394 } catch (final UnsupportedOperationException e) {
1395 Log.e(TAG, "BassBoost: " + e);
1396 } catch (final RuntimeException e) {
1397 Log.e(TAG, "BassBoost: " + e);
1398 }
1399 }
1400 return bassBoostEffect;
1401 }
1402
1403 /**
1404 * Gets the equalizer effect for the given audio session. If the effect on the session doesn't
1405 * exist yet, create it and add to collection.
1406 *
1407 * @param audioSession
1408 * System wide unique audio session identifier.
1409 * @return equalizerEffect
1410 */
Marco Nelissen19aa9172011-08-15 16:54:22 -07001411 private static Equalizer getEqualizerEffectNoCreate(final int audioSession) {
1412 return mEQInstances.get(audioSession);
1413 }
Marco Nelissen66f2cfe2011-06-23 14:05:10 -07001414 private static Equalizer getEqualizerEffect(final int audioSession) {
Marco Nelissen19aa9172011-08-15 16:54:22 -07001415 Equalizer equalizerEffect = getEqualizerEffectNoCreate(audioSession);
Marco Nelissen66f2cfe2011-06-23 14:05:10 -07001416 if (equalizerEffect == null) {
1417 try {
1418 final Equalizer newEqualizerEffect = new Equalizer(PRIORITY, audioSession);
1419 equalizerEffect = mEQInstances.putIfAbsent(audioSession, newEqualizerEffect);
1420 if (equalizerEffect == null) {
1421 // put succeeded, use new value
1422 equalizerEffect = newEqualizerEffect;
1423 }
1424 } catch (final IllegalArgumentException e) {
1425 Log.e(TAG, "Equalizer: " + e);
1426 } catch (final UnsupportedOperationException e) {
1427 Log.e(TAG, "Equalizer: " + e);
1428 } catch (final RuntimeException e) {
1429 Log.e(TAG, "Equalizer: " + e);
1430 }
1431 }
1432 return equalizerEffect;
1433 }
1434
1435 // XXX: Preset Reverb not used for the moment, so commented out the effect creation to not
1436 // use MIPS
1437 // /**
1438 // * Gets the preset reverb effect for the given audio session. If the effect on the session
1439 // * doesn't exist yet, create it and add to collection.
1440 // *
1441 // * @param audioSession
1442 // * System wide unique audio session identifier.
1443 // * @return presetReverbEffect
1444 // */
1445 // private static PresetReverb getPresetReverbEffect(final int audioSession) {
1446 // PresetReverb presetReverbEffect = mPresetReverbInstances.get(audioSession);
1447 // if (presetReverbEffect == null) {
1448 // try {
1449 // final PresetReverb newPresetReverbEffect = new PresetReverb(PRIORITY, audioSession);
1450 // presetReverbEffect = mPresetReverbInstances.putIfAbsent(audioSession,
1451 // newPresetReverbEffect);
1452 // if (presetReverbEffect == null) {
1453 // // put succeeded, use new value
1454 // presetReverbEffect = newPresetReverbEffect;
1455 // }
1456 // } catch (final IllegalArgumentException e) {
1457 // Log.e(TAG, "PresetReverb: " + e);
1458 // } catch (final UnsupportedOperationException e) {
1459 // Log.e(TAG, "PresetReverb: " + e);
1460 // } catch (final RuntimeException e) {
1461 // Log.e(TAG, "PresetReverb: " + e);
1462 // }
1463 // }
1464 // return presetReverbEffect;
1465 // }
1466}