summaryrefslogtreecommitdiffstats
path: root/src/org/cyanogenmod/audiofx/ControlPanelEffect.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/org/cyanogenmod/audiofx/ControlPanelEffect.java')
-rw-r--r--src/org/cyanogenmod/audiofx/ControlPanelEffect.java1490
1 files changed, 1490 insertions, 0 deletions
diff --git a/src/org/cyanogenmod/audiofx/ControlPanelEffect.java b/src/org/cyanogenmod/audiofx/ControlPanelEffect.java
new file mode 100644
index 0000000..f028105
--- /dev/null
+++ b/src/org/cyanogenmod/audiofx/ControlPanelEffect.java
@@ -0,0 +1,1490 @@
+/*
+ * Copyright (C) 2010-2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.cyanogenmod.audiofx;
+
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.media.MediaPlayer;
+import android.media.audiofx.AudioEffect;
+import android.media.audiofx.BassBoost;
+import android.media.audiofx.Equalizer;
+import android.media.audiofx.PresetReverb;
+import android.media.audiofx.Virtualizer;
+import android.util.Log;
+
+import java.util.Arrays;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * The Common class defines constants to be used by the control panels.
+ */
+public class ControlPanelEffect {
+
+ private final static String TAG = "AudioFXControlPanelEffect";
+
+ /**
+ * Audio session priority
+ */
+ private static final int PRIORITY = 0;
+
+ /**
+ * The control mode specifies if control panel updates effects and preferences or only
+ * preferences.
+ */
+ static enum ControlMode {
+ /**
+ * Control panel updates effects and preferences. Applicable when audio session is delivered
+ * by user.
+ */
+ CONTROL_EFFECTS,
+ /**
+ * Control panel only updates preferences. Applicable when there was no audio or invalid
+ * session provided by user.
+ */
+ CONTROL_PREFERENCES
+ }
+
+ static enum Key {
+ global_enabled, virt_enabled, virt_strength_supported, virt_strength, virt_type, bb_enabled,
+ bb_strength, te_enabled, te_strength, avl_enabled, lm_enabled, lm_strength, eq_enabled,
+ eq_num_bands, eq_level_range, eq_center_freq, eq_band_level, eq_band_level_no_save,
+ eq_num_presets, eq_preset_name, eq_preset_user_band_level,
+ eq_preset_user_band_level_default, eq_preset_opensl_es_band_level,
+ eq_preset_ci_extreme_band_level, eq_current_preset,
+ pr_enabled, pr_current_preset
+ }
+
+ // Effect/audio session Mappings
+ /**
+ * Hashmap initial capacity
+ */
+ private static final int HASHMAP_INITIAL_CAPACITY = 16;
+ /**
+ * Hashmap load factor
+ */
+ private static final float HASHMAP_LOAD_FACTOR = 0.75f;
+ /**
+ * ConcurrentHashMap concurrency level
+ */
+ private static final int HASHMAP_CONCURRENCY_LEVEL = 2;
+
+ /**
+ * Map containing the Virtualizer audio session, effect mappings.
+ */
+ private static final ConcurrentHashMap<Integer, Virtualizer> mVirtualizerInstances = new ConcurrentHashMap<Integer, Virtualizer>(
+ HASHMAP_INITIAL_CAPACITY, HASHMAP_LOAD_FACTOR, HASHMAP_CONCURRENCY_LEVEL);
+ /**
+ * Map containing the BB audio session, effect mappings.
+ */
+ private static final ConcurrentHashMap<Integer, BassBoost> mBassBoostInstances = new ConcurrentHashMap<Integer, BassBoost>(
+ HASHMAP_INITIAL_CAPACITY, HASHMAP_LOAD_FACTOR, HASHMAP_CONCURRENCY_LEVEL);
+ /**
+ * Map containing the EQ audio session, effect mappings.
+ */
+ private static final ConcurrentHashMap<Integer, Equalizer> mEQInstances = new ConcurrentHashMap<Integer, Equalizer>(
+ HASHMAP_INITIAL_CAPACITY, HASHMAP_LOAD_FACTOR, HASHMAP_CONCURRENCY_LEVEL);
+ /**
+ * Map containing the PR audio session, effect mappings.
+ */
+ private static final ConcurrentHashMap<Integer, PresetReverb> mPresetReverbInstances = new ConcurrentHashMap<Integer, PresetReverb>(
+ HASHMAP_INITIAL_CAPACITY, HASHMAP_LOAD_FACTOR, HASHMAP_CONCURRENCY_LEVEL);
+
+ /**
+ * Map containing the package name, audio session mappings.
+ */
+ private static final ConcurrentHashMap<String, Integer> mPackageSessions = new ConcurrentHashMap<String, Integer>(
+ HASHMAP_INITIAL_CAPACITY, HASHMAP_LOAD_FACTOR, HASHMAP_CONCURRENCY_LEVEL);
+
+ // Defaults
+ final static boolean GLOBAL_ENABLED_DEFAULT = false;
+ private final static boolean VIRTUALIZER_ENABLED_DEFAULT = true;
+ private final static int VIRTUALIZER_STRENGTH_DEFAULT = 1000;
+ private final static boolean BASS_BOOST_ENABLED_DEFAULT = true;
+ private final static int BASS_BOOST_STRENGTH_DEFAULT = 667;
+ private final static boolean PRESET_REVERB_ENABLED_DEFAULT = true;
+ private final static int PRESET_REVERB_CURRENT_PRESET_DEFAULT = 0; // None
+ private static int mPrevBassBoostStrength = 0;
+ private static int mPrevVirtStrength = 0;
+
+ // EQ defaults
+ private final static boolean EQUALIZER_ENABLED_DEFAULT = true;
+ private final static String EQUALIZER_PRESET_NAME_DEFAULT = "Preset";
+ private final static short EQUALIZER_NUMBER_BANDS_DEFAULT = 5;
+ private final static short EQUALIZER_NUMBER_PRESETS_DEFAULT = 0;
+ private final static short[] EQUALIZER_BAND_LEVEL_RANGE_DEFAULT = { -1500, 1500 };
+ private final static int[] EQUALIZER_CENTER_FREQ_DEFAULT = { 60000, 230000, 910000, 3600000,
+ 14000000 };
+ private final static short[] EQUALIZER_PRESET_CIEXTREME_BAND_LEVEL = { 0, 800, 400, 100, 1000 };
+ private final static short[] EQUALIZER_PRESET_USER_BAND_LEVEL_DEFAULT = { 0, 0, 0, 0, 0 };
+ private final static short[][] EQUALIZER_PRESET_OPENSL_ES_BAND_LEVEL_DEFAULT = new short[EQUALIZER_NUMBER_PRESETS_DEFAULT][EQUALIZER_NUMBER_BANDS_DEFAULT];
+
+ // EQ effect properties which are invariable over all EQ effects sessions
+ private static short[] mEQBandLevelRange = EQUALIZER_BAND_LEVEL_RANGE_DEFAULT;
+ private static short mEQNumBands = EQUALIZER_NUMBER_BANDS_DEFAULT;
+ private static int[] mEQCenterFreq = EQUALIZER_CENTER_FREQ_DEFAULT;
+ private static short mEQNumPresets = EQUALIZER_NUMBER_PRESETS_DEFAULT;
+ private static short[][] mEQPresetOpenSLESBandLevel = EQUALIZER_PRESET_OPENSL_ES_BAND_LEVEL_DEFAULT;
+ private static String[] mEQPresetNames;
+ private static boolean mIsEQInitialized = false;
+ private final static Object mEQInitLock = new Object();
+
+ /**
+ * Default int argument used in methods to see that the arg is a dummy. Used for method
+ * overloading.
+ */
+ private final static int DUMMY_ARGUMENT = -1;
+
+ /**
+ * Inits effects preferences for the given context and package name in the control panel. If
+ * preferences for the given package name don't exist, they are created and initialized.
+ *
+ * @param context
+ * @param packageName
+ * @param audioSession
+ * System wide unique audio session identifier.
+ */
+ public static void initEffectsPreferences(final Context context, final String packageName,
+ final int audioSession) {
+ final SharedPreferences prefs = context.getSharedPreferences(packageName,
+ Context.MODE_PRIVATE);
+ final SharedPreferences.Editor editor = prefs.edit();
+ final ControlMode controlMode = getControlMode(audioSession);
+
+ // init preferences
+ try {
+ // init global on/off switch
+ final boolean isGlobalEnabled = prefs.getBoolean(Key.global_enabled.toString(),
+ GLOBAL_ENABLED_DEFAULT);
+ editor.putBoolean(Key.global_enabled.toString(), isGlobalEnabled);
+ Log.v(TAG, "isGlobalEnabled = " + isGlobalEnabled);
+
+ // Virtualizer
+ final boolean isVIEnabled = prefs.getBoolean(Key.virt_enabled.toString(),
+ VIRTUALIZER_ENABLED_DEFAULT);
+ final Virtualizer virt = new Virtualizer(0, audioSession);
+ final int vIStrength = prefs.getInt(Key.virt_strength.toString(),
+ virt.getRoundedStrength());
+ virt.release();
+ editor.putBoolean(Key.virt_enabled.toString(), isVIEnabled);
+ editor.putInt(Key.virt_strength.toString(), vIStrength);
+ {
+ final MediaPlayer mediaPlayer = new MediaPlayer();
+ final int session = mediaPlayer.getAudioSessionId();
+ Virtualizer virtualizerEffect = null;
+ try {
+ virtualizerEffect = new Virtualizer(PRIORITY, session);
+ editor.putBoolean(Key.virt_strength_supported.toString(),
+ virtualizerEffect.getStrengthSupported());
+ } finally {
+ if (virtualizerEffect != null) {
+ Log.d(TAG, "Releasing dummy Virtualizer effect");
+ virtualizerEffect.release();
+ }
+ mediaPlayer.release();
+ }
+ }
+
+ // BassBoost
+ final boolean isBBEnabled = prefs.getBoolean(Key.bb_enabled.toString(),
+ BASS_BOOST_ENABLED_DEFAULT);
+ final int bBStrength = prefs.getInt(Key.bb_strength.toString(),
+ BASS_BOOST_STRENGTH_DEFAULT);
+ editor.putBoolean(Key.bb_enabled.toString(), isBBEnabled);
+ editor.putInt(Key.bb_strength.toString(), bBStrength);
+
+ // Equalizer
+ synchronized (mEQInitLock) {
+ // If EQ is not initialized already create "dummy" audio session created by
+ // MediaPlayer and create effect on it to retrieve the invariable EQ properties
+ if (!mIsEQInitialized) {
+ final MediaPlayer mediaPlayer = new MediaPlayer();
+ final int session = mediaPlayer.getAudioSessionId();
+ Equalizer equalizerEffect = null;
+ try {
+ Log.d(TAG, "Creating dummy EQ effect on session " + session);
+ equalizerEffect = new Equalizer(PRIORITY, session);
+
+ mEQBandLevelRange = equalizerEffect.getBandLevelRange();
+ mEQNumBands = equalizerEffect.getNumberOfBands();
+ mEQCenterFreq = new int[mEQNumBands];
+ for (short band = 0; band < mEQNumBands; band++) {
+ mEQCenterFreq[band] = equalizerEffect.getCenterFreq(band);
+ }
+ mEQNumPresets = equalizerEffect.getNumberOfPresets();
+ mEQPresetNames = new String[mEQNumPresets];
+ mEQPresetOpenSLESBandLevel = new short[mEQNumPresets][mEQNumBands];
+ for (short preset = 0; preset < mEQNumPresets; preset++) {
+ mEQPresetNames[preset] = equalizerEffect.getPresetName(preset);
+ equalizerEffect.usePreset(preset);
+ for (short band = 0; band < mEQNumBands; band++) {
+ mEQPresetOpenSLESBandLevel[preset][band] = equalizerEffect
+ .getBandLevel(band);
+ }
+ }
+
+ mIsEQInitialized = true;
+ } catch (final IllegalStateException e) {
+ Log.e(TAG, "Equalizer: " + e);
+ } catch (final IllegalArgumentException e) {
+ Log.e(TAG, "Equalizer: " + e);
+ } catch (final UnsupportedOperationException e) {
+ Log.e(TAG, "Equalizer: " + e);
+ } catch (final RuntimeException e) {
+ Log.e(TAG, "Equalizer: " + e);
+ } finally {
+ if (equalizerEffect != null) {
+ Log.d(TAG, "Releasing dummy EQ effect");
+ equalizerEffect.release();
+ }
+ mediaPlayer.release();
+
+ // When there was a failure set some good defaults
+ if (!mIsEQInitialized) {
+ mEQPresetOpenSLESBandLevel = new short[mEQNumPresets][mEQNumBands];
+ for (short preset = 0; preset < mEQNumPresets; preset++) {
+ // Init preset names to a dummy name
+ mEQPresetNames[preset] = prefs.getString(
+ Key.eq_preset_name.toString() + preset,
+ EQUALIZER_PRESET_NAME_DEFAULT + preset);
+ if (preset < EQUALIZER_PRESET_OPENSL_ES_BAND_LEVEL_DEFAULT.length) {
+ mEQPresetOpenSLESBandLevel[preset] = Arrays.copyOf(
+ EQUALIZER_PRESET_OPENSL_ES_BAND_LEVEL_DEFAULT[preset],
+ mEQNumBands);
+ }
+ }
+ }
+ }
+ }
+ editor.putInt(Key.eq_level_range.toString() + 0, mEQBandLevelRange[0]);
+ editor.putInt(Key.eq_level_range.toString() + 1, mEQBandLevelRange[1]);
+ editor.putInt(Key.eq_num_bands.toString(), mEQNumBands);
+ editor.putInt(Key.eq_num_presets.toString(), mEQNumPresets);
+ // Resetting the EQ arrays depending on the real # bands with defaults if
+ // band < default size else 0 by copying default arrays over new ones
+ final short[] eQPresetCIExtremeBandLevel = Arrays.copyOf(
+ EQUALIZER_PRESET_CIEXTREME_BAND_LEVEL, mEQNumBands);
+ final short[] eQPresetUserBandLevelDefault = Arrays.copyOf(
+ EQUALIZER_PRESET_USER_BAND_LEVEL_DEFAULT, mEQNumBands);
+ // If no preset prefs set use CI EXTREME (= numPresets)
+ final short eQPreset = (short) prefs.getInt(Key.eq_current_preset.toString(),
+ mEQNumPresets);
+ editor.putInt(Key.eq_current_preset.toString(), eQPreset);
+ final short[] bandLevel = new short[mEQNumBands];
+ for (short band = 0; band < mEQNumBands; band++) {
+ if (eQPreset < mEQNumPresets) {
+ // OpenSL ES effect presets
+ bandLevel[band] = mEQPresetOpenSLESBandLevel[eQPreset][band];
+ } else if (eQPreset == mEQNumPresets) {
+ // CI EXTREME
+ bandLevel[band] = eQPresetCIExtremeBandLevel[band];
+ } else {
+ // User
+ bandLevel[band] = (short) prefs.getInt(
+ Key.eq_preset_user_band_level.toString() + band,
+ eQPresetUserBandLevelDefault[band]);
+ }
+ editor.putInt(Key.eq_band_level.toString() + band, bandLevel[band]);
+ editor.putInt(Key.eq_center_freq.toString() + band, mEQCenterFreq[band]);
+ editor.putInt(Key.eq_preset_ci_extreme_band_level.toString() + band,
+ eQPresetCIExtremeBandLevel[band]);
+ editor.putInt(Key.eq_preset_user_band_level_default.toString() + band,
+ eQPresetUserBandLevelDefault[band]);
+ }
+ for (short preset = 0; preset < mEQNumPresets; preset++) {
+ editor.putString(Key.eq_preset_name.toString() + preset, mEQPresetNames[preset]);
+ for (short band = 0; band < mEQNumBands; band++) {
+ editor.putInt(Key.eq_preset_opensl_es_band_level.toString() + preset + "_"
+ + band, mEQPresetOpenSLESBandLevel[preset][band]);
+ }
+ }
+ }
+ final boolean isEQEnabled = prefs.getBoolean(Key.eq_enabled.toString(),
+ EQUALIZER_ENABLED_DEFAULT);
+ editor.putBoolean(Key.eq_enabled.toString(), isEQEnabled);
+
+ // Preset reverb
+ final boolean isEnabledPR = prefs.getBoolean(Key.pr_enabled.toString(),
+ PRESET_REVERB_ENABLED_DEFAULT);
+ final short presetPR = (short) prefs.getInt(Key.pr_current_preset.toString(),
+ PRESET_REVERB_CURRENT_PRESET_DEFAULT);
+ editor.putBoolean(Key.pr_enabled.toString(), isEnabledPR);
+ editor.putInt(Key.pr_current_preset.toString(), presetPR);
+
+ editor.commit();
+ } catch (final RuntimeException e) {
+ Log.e(TAG, "initEffectsPreferences: processingEnabled: " + e);
+ }
+ }
+
+ /**
+ * Gets the effect control mode based on the given audio session in the control panel. Control
+ * mode defines if the control panel is controlling effects and/or preferences
+ *
+ * @param audioSession
+ * System wide unique audio session identifier.
+ * @return effect control mode
+ */
+ public static ControlMode getControlMode(final int audioSession) {
+ if (audioSession == AudioEffect.ERROR_BAD_VALUE) {
+ return ControlMode.CONTROL_PREFERENCES;
+ }
+ return ControlMode.CONTROL_EFFECTS;
+ }
+
+ /**
+ * Sets boolean parameter to value for given key
+ *
+ * @param context
+ * @param packageName
+ * @param audioSession
+ * System wide unique audio session identifier.
+ * @param key
+ * @param value
+ */
+ public static void setParameterBoolean(final Context context, final String packageName,
+ final int audioSession, final Key key, final boolean value) {
+ try {
+ final SharedPreferences prefs = context.getSharedPreferences(packageName,
+ Context.MODE_PRIVATE);
+ final ControlMode controlMode = getControlMode(audioSession);
+ boolean enabled = value;
+
+ // Global on/off
+ if (key == Key.global_enabled) {
+ boolean processingEnabled = false;
+ if (value == true) {
+ // enable all with respect to preferences
+ if (controlMode == ControlMode.CONTROL_EFFECTS) {
+ final Virtualizer virtualizerEffect = getVirtualizerEffect(audioSession);
+ if (virtualizerEffect != null) {
+ virtualizerEffect.setEnabled(true);
+ int defaultstrength = virtualizerEffect.getRoundedStrength();
+ final int vIStrength = prefs.getInt(Key.virt_strength.toString(),
+ defaultstrength);
+ boolean on = prefs.getBoolean(Key.virt_enabled.toString(), VIRTUALIZER_ENABLED_DEFAULT);
+ if (on) {
+ setParameterInt(context, packageName,
+ audioSession, Key.virt_strength, vIStrength);
+ } else {
+ mPrevVirtStrength = vIStrength;
+ virtualizerEffect.setStrength((short) 0);
+ }
+ }
+ final BassBoost bassBoostEffect = getBassBoostEffect(audioSession);
+ if (bassBoostEffect != null) {
+ bassBoostEffect.setEnabled(true);
+ final int bBStrength = prefs.getInt(Key.bb_strength.toString(),
+ BASS_BOOST_STRENGTH_DEFAULT);
+ boolean on = prefs.getBoolean(Key.bb_enabled.toString(), BASS_BOOST_ENABLED_DEFAULT);
+ if (on) {
+ setParameterInt(context, packageName,
+ audioSession, Key.bb_strength, bBStrength);
+ } else {
+ mPrevBassBoostStrength = bBStrength;
+ bassBoostEffect.setStrength((short) 0);
+ }
+ }
+ final Equalizer equalizerEffect = getEqualizerEffect(audioSession);
+ if (equalizerEffect != null) {
+ equalizerEffect.setEnabled(prefs.getBoolean(Key.eq_enabled.toString(),
+ EQUALIZER_ENABLED_DEFAULT));
+ final int[] bandLevels = getParameterIntArray(context,
+ packageName, audioSession, Key.eq_band_level);
+ final int len = bandLevels.length;
+ for (short band = 0; band < len; band++) {
+ final int level = bandLevels[band];
+ setParameterInt(context, packageName,
+ audioSession, Key.eq_band_level_no_save, level, band);
+ }
+ }
+ // XXX: Preset Reverb not used for the moment, so commented out the effect
+ // creation to not use MIPS
+ final PresetReverb presetReverbEffect = getPresetReverbEffect(audioSession);
+ if (presetReverbEffect != null) {
+ presetReverbEffect.setEnabled(prefs.getBoolean(Key.pr_enabled.toString(),
+ PRESET_REVERB_ENABLED_DEFAULT));
+ final short presetPR = (short) prefs.getInt(Key.pr_current_preset.toString(),
+ PRESET_REVERB_CURRENT_PRESET_DEFAULT);
+ setParameterInt(context, packageName,
+ audioSession, Key.pr_current_preset, presetPR);
+ }
+ }
+
+ processingEnabled = true;
+ Log.v(TAG, "processingEnabled=" + processingEnabled);
+
+ } else {
+ // disable all
+ if (controlMode == ControlMode.CONTROL_EFFECTS) {
+ final Virtualizer virtualizerEffect = getVirtualizerEffectNoCreate(audioSession);
+ if (virtualizerEffect != null) {
+ mVirtualizerInstances.remove(audioSession, virtualizerEffect);
+ virtualizerEffect.setEnabled(false);
+ virtualizerEffect.release();
+ }
+ final BassBoost bassBoostEffect = getBassBoostEffectNoCreate(audioSession);
+ if (bassBoostEffect != null) {
+ mBassBoostInstances.remove(audioSession, bassBoostEffect);
+ bassBoostEffect.setEnabled(false);
+ bassBoostEffect.release();
+ }
+ final Equalizer equalizerEffect = getEqualizerEffectNoCreate(audioSession);
+ if (equalizerEffect != null) {
+ mEQInstances.remove(audioSession, equalizerEffect);
+ equalizerEffect.setEnabled(false);
+ equalizerEffect.release();
+ }
+ // XXX: Preset Reverb not used for the moment, so commented out the effect
+ // creation to not use MIPS
+ final PresetReverb presetReverbEffect = getPresetReverbEffect(audioSession);
+ if (presetReverbEffect != null) {
+ mPresetReverbInstances.remove(audioSession, presetReverbEffect);
+ presetReverbEffect.setEnabled(false);
+ presetReverbEffect.release();
+ }
+ }
+
+ processingEnabled = false;
+ Log.v(TAG, "processingEnabled=" + processingEnabled);
+ }
+ enabled = processingEnabled;
+ } else if (controlMode == ControlMode.CONTROL_EFFECTS) {
+ final boolean isGlobalEnabled = prefs.getBoolean(Key.global_enabled.toString(),
+ GLOBAL_ENABLED_DEFAULT);
+ if (isGlobalEnabled == true) {
+ // Set effect parameters
+ switch (key) {
+
+ case global_enabled:
+ // Global, already handled, to get out error free
+ break;
+
+ // Virtualizer
+ case virt_enabled:
+ final Virtualizer virtualizerEffect = getVirtualizerEffect(audioSession);
+ if (virtualizerEffect != null) {
+ if (value) {
+ virtualizerEffect.setStrength((short) mPrevVirtStrength);
+ enabled = true;
+ } else {
+ mPrevVirtStrength = virtualizerEffect.getRoundedStrength();
+ virtualizerEffect.setStrength((short) 0);
+ enabled = false;
+ }
+ }
+ break;
+
+ // BassBoost
+ case bb_enabled:
+ final BassBoost bassBoostEffect = getBassBoostEffect(audioSession);
+ if (bassBoostEffect != null) {
+ if (value) {
+ bassBoostEffect.setStrength((short) mPrevBassBoostStrength);
+ enabled = true;
+ } else {
+ mPrevBassBoostStrength = bassBoostEffect.getRoundedStrength();
+ bassBoostEffect.setStrength((short) 0);
+ enabled = false;
+ }
+ }
+ break;
+
+ // Equalizer
+ case eq_enabled:
+ final Equalizer equalizerEffect = getEqualizerEffect(audioSession);
+ if (equalizerEffect != null) {
+ equalizerEffect.setEnabled(value);
+ enabled = equalizerEffect.getEnabled();
+ }
+ break;
+
+ // PresetReverb
+ case pr_enabled:
+ // XXX: Preset Reverb not used for the moment, so commented out the effect
+ // creation to not use MIPS
+ final PresetReverb presetReverbEffect = getPresetReverbEffect(audioSession);
+ if (presetReverbEffect != null) {
+ presetReverbEffect.setEnabled(value);
+ enabled = presetReverbEffect.getEnabled();
+ }
+ break;
+
+ default:
+ Log.e(TAG, "Unknown/unsupported key " + key);
+ return;
+ }
+ }
+
+ }
+
+ // Set preferences
+ final SharedPreferences.Editor editor = prefs.edit();
+ editor.putBoolean(key.toString(), enabled);
+ editor.commit();
+
+ } catch (final RuntimeException e) {
+ Log.e(TAG, "setParameterBoolean: " + key + "; " + value + "; " + e);
+ }
+ }
+
+ /**
+ * Gets boolean parameter for given key
+ *
+ * @param context
+ * @param packageName
+ * @param audioSession
+ * System wide unique audio session identifier.
+ * @param key
+ * @return parameter value
+ */
+ public static Boolean getParameterBoolean(final Context context, final String packageName,
+ final int audioSession, final Key key) {
+ final SharedPreferences prefs = context.getSharedPreferences(packageName,
+ Context.MODE_PRIVATE);
+ boolean value = false;
+
+ try {
+ value = prefs.getBoolean(key.toString(), value);
+ } catch (final RuntimeException e) {
+ Log.e(TAG, "getParameterBoolean: " + key + "; " + value + "; " + e);
+ }
+
+ return value;
+
+ }
+
+ /**
+ * Sets int parameter for given key and value arg0, arg1
+ *
+ * @param context
+ * @param packageName
+ * @param audioSession
+ * System wide unique audio session identifier.
+ * @param key
+ * @param arg0
+ * @param arg1
+ */
+ public static void setParameterInt(final Context context, final String packageName,
+ final int audioSession, final Key key, final int arg0, final int arg1) {
+ String strKey = key.toString();
+ int value = arg0;
+
+ try {
+ final SharedPreferences prefs = context.getSharedPreferences(packageName,
+ Context.MODE_PRIVATE);
+ final SharedPreferences.Editor editor = prefs.edit();
+ final ControlMode controlMode = getControlMode(audioSession);
+
+ // Set effect parameters
+ if (controlMode == ControlMode.CONTROL_EFFECTS) {
+
+ switch (key) {
+
+ // Virtualizer
+ case virt_strength: {
+ final Virtualizer virtualizerEffect = getVirtualizerEffect(audioSession);
+ boolean on = prefs.getBoolean(Key.virt_enabled.toString(), VIRTUALIZER_ENABLED_DEFAULT);
+ if ((virtualizerEffect != null) && on) {
+ virtualizerEffect.setStrength((short) value);
+ value = virtualizerEffect.getRoundedStrength();
+ }
+ break;
+ }
+ // BassBoost
+ case bb_strength: {
+ final BassBoost bassBoostEffect = getBassBoostEffect(audioSession);
+ boolean on = prefs.getBoolean(Key.bb_enabled.toString(), BASS_BOOST_ENABLED_DEFAULT);
+ if ((bassBoostEffect != null) && on) {
+ bassBoostEffect.setStrength((short) value);
+ value = bassBoostEffect.getRoundedStrength();
+ }
+ break;
+ }
+ // Equalizer
+ case eq_band_level: {
+ if (arg1 == DUMMY_ARGUMENT) {
+ throw new IllegalArgumentException("Dummy arg passed.");
+ }
+ final short band = (short) arg1;
+ strKey = strKey + band;
+ final Equalizer equalizerEffect = getEqualizerEffect(audioSession);
+ if (equalizerEffect != null) {
+ equalizerEffect.setBandLevel(band, (short) value);
+ value = equalizerEffect.getBandLevel(band);
+ // save band level in User preset
+ editor.putInt(Key.eq_preset_user_band_level.toString() + band, value);
+ }
+ break;
+ }
+ // Same as eq_band_level except won't save band level in User preset
+ case eq_band_level_no_save: {
+ if (arg1 == DUMMY_ARGUMENT) {
+ throw new IllegalArgumentException("Dummy arg passed.");
+ }
+ final short band = (short) arg1;
+ strKey = Key.eq_band_level.toString() + band;
+ final Equalizer equalizerEffect = getEqualizerEffect(audioSession);
+ if (equalizerEffect != null) {
+ equalizerEffect.setBandLevel(band, (short) value);
+ }
+ break;
+ }
+ case eq_current_preset: {
+ final Equalizer equalizerEffect = getEqualizerEffect(audioSession);
+ if (equalizerEffect != null) {
+ final short preset = (short) value;
+ final int numBands = prefs.getInt(Key.eq_num_bands.toString(),
+ EQUALIZER_NUMBER_BANDS_DEFAULT);
+ final int numPresets = prefs.getInt(Key.eq_num_presets.toString(),
+ EQUALIZER_NUMBER_PRESETS_DEFAULT);
+
+ if (preset < numPresets) {
+ // OpenSL ES EQ Effect presets
+ equalizerEffect.usePreset(preset);
+ value = equalizerEffect.getCurrentPreset();
+ } else {
+ final short[] eQPresetCIExtremeBandLevelDefault = Arrays.copyOf(
+ EQUALIZER_PRESET_CIEXTREME_BAND_LEVEL, numBands);
+ final short[] eQPresetUserBandLevelDefault = Arrays.copyOf(
+ EQUALIZER_PRESET_USER_BAND_LEVEL_DEFAULT, numBands);
+ // Set the band levels manually for custom presets
+ for (short band = 0; band < numBands; band++) {
+ short bandLevel = 0;
+ if (preset == numPresets) {
+ // CI EXTREME
+ bandLevel = (short) prefs.getInt(
+ Key.eq_preset_ci_extreme_band_level.toString() + band,
+ eQPresetCIExtremeBandLevelDefault[band]);
+ } else {
+ // User
+ bandLevel = (short) prefs.getInt(
+ Key.eq_preset_user_band_level.toString() + band,
+ eQPresetUserBandLevelDefault[band]);
+ }
+ equalizerEffect.setBandLevel(band, bandLevel);
+ }
+ }
+
+ // update band levels
+ for (short band = 0; band < numBands; band++) {
+ final short level = equalizerEffect.getBandLevel(band);
+ editor.putInt(Key.eq_band_level.toString() + band, level);
+ }
+ }
+ break;
+ }
+ case eq_preset_user_band_level:
+ // Fall through
+ case eq_preset_user_band_level_default:
+ // Fall through
+ case eq_preset_ci_extreme_band_level: {
+ if (arg1 == DUMMY_ARGUMENT) {
+ throw new IllegalArgumentException("Dummy arg passed.");
+ }
+ final short band = (short) arg1;
+ strKey = strKey + band;
+ break;
+ }
+ case pr_current_preset:
+ // XXX: Preset Reverb not used for the moment, so commented out the effect
+ // creation to not use MIPS
+ final PresetReverb presetReverbEffect = getPresetReverbEffect(audioSession);
+ if (presetReverbEffect != null) {
+ presetReverbEffect.setPreset((short) value);
+ value = presetReverbEffect.getPreset();
+ }
+ break;
+ default:
+ Log.e(TAG, "setParameterInt: Unknown/unsupported key " + key);
+ return;
+ }
+ } else {
+ switch (key) {
+ // Virtualizer
+ case virt_strength:
+ // Do nothing
+ break;
+ case virt_type:
+ // Do nothing
+ break;
+
+ // BassBoost
+ case bb_strength:
+ // Do nothing
+ break;
+
+ // Equalizer
+ case eq_band_level: {
+ if (arg1 == DUMMY_ARGUMENT) {
+ throw new IllegalArgumentException("Dummy arg passed.");
+ }
+ final short band = (short) arg1;
+ strKey = strKey + band;
+
+ editor.putInt(Key.eq_preset_user_band_level.toString() + band, value);
+ break;
+ }
+ case eq_band_level_no_save: {
+ if (arg1 == DUMMY_ARGUMENT) {
+ throw new IllegalArgumentException("Dummy arg passed.");
+ }
+ final short band = (short) arg1;
+ strKey = Key.eq_band_level.toString() + band;
+ break;
+ }
+ case eq_current_preset: {
+ final short preset = (short) value;
+ final int numBands = prefs.getInt(Key.eq_num_bands.toString(),
+ EQUALIZER_NUMBER_BANDS_DEFAULT);
+ final int numPresets = prefs.getInt(Key.eq_num_presets.toString(),
+ EQUALIZER_NUMBER_PRESETS_DEFAULT);
+
+ final short[][] eQPresetOpenSLESBandLevelDefault = Arrays.copyOf(
+ EQUALIZER_PRESET_OPENSL_ES_BAND_LEVEL_DEFAULT, numBands);
+ final short[] eQPresetCIExtremeBandLevelDefault = Arrays.copyOf(
+ EQUALIZER_PRESET_CIEXTREME_BAND_LEVEL, numBands);
+ final short[] eQPresetUserBandLevelDefault = Arrays.copyOf(
+ EQUALIZER_PRESET_USER_BAND_LEVEL_DEFAULT, numBands);
+ for (short band = 0; band < numBands; band++) {
+ short bandLevel = 0;
+ if (preset < numPresets) {
+ // OpenSL ES EQ Effect presets
+ bandLevel = (short) prefs.getInt(
+ Key.eq_preset_opensl_es_band_level.toString() + preset + "_"
+ + band, eQPresetOpenSLESBandLevelDefault[preset][band]);
+ } else if (preset == numPresets) {
+ // CI EXTREME
+ bandLevel = (short) prefs.getInt(
+ Key.eq_preset_ci_extreme_band_level.toString() + band,
+ eQPresetCIExtremeBandLevelDefault[band]);
+ } else {
+ // User
+ bandLevel = (short) prefs.getInt(
+ Key.eq_preset_user_band_level.toString() + band,
+ eQPresetUserBandLevelDefault[band]);
+ }
+ editor.putInt(Key.eq_band_level.toString() + band, bandLevel);
+ }
+ break;
+ }
+ case eq_preset_user_band_level:
+ // Fall through
+ case eq_preset_user_band_level_default:
+ // Fall through
+ case eq_preset_ci_extreme_band_level: {
+ if (arg1 == DUMMY_ARGUMENT) {
+ throw new IllegalArgumentException("Dummy arg passed.");
+ }
+ final short band = (short) arg1;
+ strKey = strKey + band;
+ break;
+ }
+ case pr_current_preset:
+ // Do nothing
+ break;
+ default:
+ Log.e(TAG, "setParameterInt: Unknown/unsupported key " + key);
+ return;
+ }
+ }
+
+ // Set preferences
+ editor.putInt(strKey, value);
+ editor.apply();
+
+ } catch (final RuntimeException e) {
+ Log.e(TAG, "setParameterInt: " + key + "; " + arg0 + "; " + arg1 + "; " + e);
+ }
+
+ }
+
+ /**
+ * Sets int parameter for given key and value arg
+ *
+ * @param context
+ * @param packageName
+ * @param audioSession
+ * System wide unique audio session identifier.
+ * @param key
+ * @param arg
+ */
+ public static void setParameterInt(final Context context, final String packageName,
+ final int audioSession, final Key key, final int arg) {
+ setParameterInt(context, packageName, audioSession, key, arg, DUMMY_ARGUMENT);
+ }
+
+ /**
+ * Gets int parameter given key
+ *
+ * @param context
+ * @param packageName
+ * @param audioSession
+ * System wide unique audio session identifier.
+ * @param key
+ * @return parameter value
+ */
+ public static int getParameterInt(final Context context, final String packageName,
+ final int audioSession, final String key) {
+ int value = 0;
+
+ try {
+ final SharedPreferences prefs = context.getSharedPreferences(packageName,
+ Context.MODE_PRIVATE);
+ value = prefs.getInt(key, value);
+ } catch (final RuntimeException e) {
+ Log.e(TAG, "getParameterInt: " + key + "; " + e);
+ }
+
+ return value;
+ }
+
+ /**
+ * Gets int parameter given key
+ *
+ * @param context
+ * @param packageName
+ * @param audioSession
+ * System wide unique audio session identifier.
+ * @param key
+ * @return parameter value
+ */
+ public static int getParameterInt(final Context context, final String packageName,
+ final int audioSession, final Key key) {
+ return getParameterInt(context, packageName, audioSession, key.toString());
+ }
+
+ /**
+ * Gets int parameter given key and arg
+ *
+ * @param context
+ * @param packageName
+ * @param audioSession
+ * System wide unique audio session identifier.
+ * @param audioSession
+ * @param key
+ * @param arg
+ * @return parameter value
+ */
+ public static int getParameterInt(final Context context, final String packageName,
+ final int audioSession, final Key key, final int arg) {
+ return getParameterInt(context, packageName, audioSession, key.toString() + arg);
+ }
+
+ /**
+ * Gets int parameter given key, arg0 and arg1
+ *
+ * @param context
+ * @param packageName
+ * @param audioSession
+ * System wide unique audio session identifier.
+ * @param audioSession
+ * @param key
+ * @param arg0
+ * @param arg1
+ * @return parameter value
+ */
+ public static int getParameterInt(final Context context, final String packageName,
+ final int audioSession, final Key key, final int arg0, final int arg1) {
+ return getParameterInt(context, packageName, audioSession, key.toString() + arg0 + "_"
+ + arg1);
+ }
+
+ /**
+ * Gets integer array parameter given key. Returns null if not found.
+ *
+ * @param context
+ * @param packageName
+ * @param audioSession
+ * System wide unique audio session identifier.
+ * @param key
+ * @return parameter value array
+ */
+ public static int[] getParameterIntArray(final Context context, final String packageName,
+ final int audioSession, final Key key) {
+ final SharedPreferences prefs = context.getSharedPreferences(packageName,
+ Context.MODE_PRIVATE);
+
+ int[] intArray = null;
+ try {
+ // Get effect parameters
+ switch (key) {
+ case eq_level_range: {
+ intArray = new int[2];
+ break;
+ }
+ case eq_center_freq:
+ // Fall through
+ case eq_band_level:
+ // Fall through
+ case eq_preset_user_band_level:
+ // Fall through
+ case eq_preset_user_band_level_default:
+ // Fall through
+ case eq_preset_ci_extreme_band_level: {
+ final int numBands = prefs.getInt(Key.eq_num_bands.toString(), 0);
+ intArray = new int[numBands];
+ break;
+ }
+ default:
+ Log.e(TAG, "getParameterIntArray: Unknown/unsupported key " + key);
+ return null;
+ }
+
+ for (int i = 0; i < intArray.length; i++) {
+ intArray[i] = prefs.getInt(key.toString() + i, 0);
+ }
+
+ } catch (final RuntimeException e) {
+ Log.e(TAG, "getParameterIntArray: " + key + "; " + e);
+ }
+
+ return intArray;
+ }
+
+ /**
+ * Gets string parameter given key. Returns empty string if not found.
+ *
+ * @param context
+ * @param packageName
+ * @param audioSession
+ * System wide unique audio session identifier.
+ * @param key
+ * @return parameter value
+ */
+ public static String getParameterString(final Context context, final String packageName,
+ final int audioSession, final String key) {
+ String value = "";
+ try {
+ final SharedPreferences prefs = context.getSharedPreferences(packageName,
+ Context.MODE_PRIVATE);
+
+ // Get effect parameters
+ value = prefs.getString(key, value);
+
+ } catch (final RuntimeException e) {
+ Log.e(TAG, "getParameterString: " + key + "; " + e);
+ }
+
+ return value;
+ }
+
+ /**
+ * Gets string parameter given key.
+ *
+ * @param context
+ * @param packageName
+ * @param audioSession
+ * System wide unique audio session identifier.
+ * @param key
+ * @return parameter value
+ */
+ public static String getParameterString(final Context context, final String packageName,
+ final int audioSession, final Key key) {
+ return getParameterString(context, packageName, audioSession, key.toString());
+ }
+
+ /**
+ * Gets string parameter given key and arg.
+ *
+ * @param context
+ * @param packageName
+ * @param audioSession
+ * System wide unique audio session identifier.
+ * @param args
+ * @return parameter value
+ */
+ public static String getParameterString(final Context context, final String packageName,
+ final int audioSession, final Key key, final int arg) {
+ return getParameterString(context, packageName, audioSession, key.toString() + arg);
+ }
+
+ /**
+ * Opens/initializes the effects session for the given audio session with preferences linked to
+ * the given package name and context.
+ *
+ * @param context
+ * @param packageName
+ * @param audioSession
+ * System wide unique audio session identifier.
+ */
+ public static void openSession(final Context context, final String packageName,
+ final int audioSession) {
+ Log.v(TAG, "openSession(" + context + ", " + packageName + ", " + audioSession + ")");
+ final String methodTag = "openSession: ";
+
+ // init preferences
+ final SharedPreferences prefs = context.getSharedPreferences(packageName,
+ Context.MODE_PRIVATE);
+ final SharedPreferences.Editor editor = prefs.edit();
+
+ final boolean isGlobalEnabled = prefs.getBoolean(Key.global_enabled.toString(),
+ GLOBAL_ENABLED_DEFAULT);
+ editor.putBoolean(Key.global_enabled.toString(), isGlobalEnabled);
+
+ if (!isGlobalEnabled) {
+ return;
+ }
+
+ // Manage audioSession information
+
+ // Retrieve AudioSession Id from map
+ boolean isExistingAudioSession = false;
+
+ try {
+ final Integer currentAudioSession = mPackageSessions.putIfAbsent(packageName,
+ audioSession);
+ if (currentAudioSession != null) {
+ // Compare with passed argument
+ if (currentAudioSession == audioSession) {
+ // FIXME: Normally, we should exit the function here
+ // BUT: we have to take care of the virtualizer because of
+ // a bug in the Android Effects Framework
+ // editor.commit();
+ // return;
+ isExistingAudioSession = true;
+ } else {
+ closeSession(context, packageName, currentAudioSession);
+ }
+ }
+ } catch (final NullPointerException e) {
+ Log.e(TAG, methodTag + e);
+ editor.commit();
+ return;
+ }
+
+ // Because the audioSession is new, get effects & settings from shared preferences
+
+ // Virtualizer
+ // create effect
+ final Virtualizer virtualizerEffect = getVirtualizerEffect(audioSession);
+ {
+ final String errorTag = methodTag + "Virtualizer error: ";
+
+ try {
+ // read parameters
+ final boolean isEnabled = prefs.getBoolean(Key.virt_enabled.toString(),
+ VIRTUALIZER_ENABLED_DEFAULT);
+ int defaultstrength = isExistingAudioSession ? VIRTUALIZER_STRENGTH_DEFAULT :
+ virtualizerEffect.getRoundedStrength();
+ final int strength = prefs.getInt(Key.virt_strength.toString(), defaultstrength);
+ // init settings
+ Virtualizer.Settings settings = new Virtualizer.Settings("Virtualizer;strength="
+ + strength);
+
+ virtualizerEffect.setProperties(settings);
+
+ // set parameters
+ if (isGlobalEnabled == true) {
+ virtualizerEffect.setEnabled(isEnabled);
+ } else {
+ virtualizerEffect.setEnabled(false);
+ }
+
+ // get parameters
+ settings = virtualizerEffect.getProperties();
+ Log.v(TAG, "Parameters: " + settings.toString() + ";enabled=" + isEnabled);
+
+ // update preferences
+ editor.putBoolean(Key.virt_enabled.toString(), isEnabled);
+ editor.putInt(Key.virt_strength.toString(), settings.strength);
+ } catch (final RuntimeException e) {
+ Log.e(TAG, errorTag + e);
+ }
+ }
+
+ // In case of an existing audio session
+ // Exit after the virtualizer has been re-enabled
+
+ if (isExistingAudioSession) {
+ editor.apply();
+ return;
+ }
+
+ // BassBoost
+ // create effect
+ final BassBoost bassBoostEffect = getBassBoostEffect(audioSession);
+ {
+ final String errorTag = methodTag + "BassBoost error: ";
+
+ try {
+ // read parameters
+ final boolean isEnabled = prefs.getBoolean(Key.bb_enabled.toString(),
+ BASS_BOOST_ENABLED_DEFAULT);
+ final int strength = prefs.getInt(Key.bb_strength.toString(),
+ BASS_BOOST_STRENGTH_DEFAULT);
+
+ // init settings
+ BassBoost.Settings settings = new BassBoost.Settings("BassBoost;strength="
+ + strength);
+
+ bassBoostEffect.setProperties(settings);
+
+ // set parameters
+ if (isGlobalEnabled == true) {
+ bassBoostEffect.setEnabled(isEnabled);
+ } else {
+ bassBoostEffect.setEnabled(false);
+ }
+
+ // get parameters
+ settings = bassBoostEffect.getProperties();
+ Log.v(TAG, "Parameters: " + settings.toString() + ";enabled=" + isEnabled);
+
+ // update preferences
+ editor.putBoolean(Key.bb_enabled.toString(), isEnabled);
+ editor.putInt(Key.bb_strength.toString(), settings.strength);
+ } catch (final RuntimeException e) {
+ Log.e(TAG, errorTag + e);
+ }
+ }
+
+ // Equalizer
+ // create effect
+ final Equalizer equalizerEffect = getEqualizerEffect(audioSession);
+ {
+ final String errorTag = methodTag + "Equalizer error: ";
+
+ try {
+ final short eQNumBands;
+ final short[] bandLevel;
+ final int[] eQCenterFreq;
+ final short eQNumPresets;
+ final String[] eQPresetNames;
+ short eQPreset;
+ synchronized (mEQInitLock) {
+ // read parameters
+ mEQBandLevelRange = equalizerEffect.getBandLevelRange();
+ mEQNumBands = equalizerEffect.getNumberOfBands();
+ mEQCenterFreq = new int[mEQNumBands];
+ mEQNumPresets = equalizerEffect.getNumberOfPresets();
+ mEQPresetNames = new String[mEQNumPresets];
+
+ for (short preset = 0; preset < mEQNumPresets; preset++) {
+ mEQPresetNames[preset] = equalizerEffect.getPresetName(preset);
+ editor.putString(Key.eq_preset_name.toString() + preset,
+ mEQPresetNames[preset]);
+ }
+
+ editor.putInt(Key.eq_level_range.toString() + 0, mEQBandLevelRange[0]);
+ editor.putInt(Key.eq_level_range.toString() + 1, mEQBandLevelRange[1]);
+ editor.putInt(Key.eq_num_bands.toString(), mEQNumBands);
+ editor.putInt(Key.eq_num_presets.toString(), mEQNumPresets);
+ // Resetting the EQ arrays depending on the real # bands with defaults if band <
+ // default size else 0 by copying default arrays over new ones
+ final short[] eQPresetCIExtremeBandLevel = Arrays.copyOf(
+ EQUALIZER_PRESET_CIEXTREME_BAND_LEVEL, mEQNumBands);
+ final short[] eQPresetUserBandLevelDefault = Arrays.copyOf(
+ EQUALIZER_PRESET_USER_BAND_LEVEL_DEFAULT, mEQNumBands);
+ // If no preset prefs set use CI EXTREME (= numPresets)
+ eQPreset = (short) prefs
+ .getInt(Key.eq_current_preset.toString(), mEQNumPresets);
+ if (eQPreset < mEQNumPresets) {
+ // OpenSL ES effect presets
+ equalizerEffect.usePreset(eQPreset);
+ eQPreset = equalizerEffect.getCurrentPreset();
+ } else {
+ for (short band = 0; band < mEQNumBands; band++) {
+ short level = 0;
+ if (eQPreset == mEQNumPresets) {
+ // CI EXTREME
+ level = eQPresetCIExtremeBandLevel[band];
+ } else {
+ // User
+ level = (short) prefs.getInt(
+ Key.eq_preset_user_band_level.toString() + band,
+ eQPresetUserBandLevelDefault[band]);
+ }
+ equalizerEffect.setBandLevel(band, level);
+ }
+ }
+ editor.putInt(Key.eq_current_preset.toString(), eQPreset);
+
+ bandLevel = new short[mEQNumBands];
+ for (short band = 0; band < mEQNumBands; band++) {
+ mEQCenterFreq[band] = equalizerEffect.getCenterFreq(band);
+ bandLevel[band] = equalizerEffect.getBandLevel(band);
+
+ editor.putInt(Key.eq_band_level.toString() + band, bandLevel[band]);
+ editor.putInt(Key.eq_center_freq.toString() + band, mEQCenterFreq[band]);
+ editor.putInt(Key.eq_preset_ci_extreme_band_level.toString() + band,
+ eQPresetCIExtremeBandLevel[band]);
+ editor.putInt(Key.eq_preset_user_band_level_default.toString() + band,
+ eQPresetUserBandLevelDefault[band]);
+ }
+
+ eQNumBands = mEQNumBands;
+ eQCenterFreq = mEQCenterFreq;
+ eQNumPresets = mEQNumPresets;
+ eQPresetNames = mEQPresetNames;
+ }
+
+ final boolean isEnabled = prefs.getBoolean(Key.eq_enabled.toString(),
+ EQUALIZER_ENABLED_DEFAULT);
+ editor.putBoolean(Key.eq_enabled.toString(), isEnabled);
+ if (isGlobalEnabled == true) {
+ equalizerEffect.setEnabled(isEnabled);
+ } else {
+ equalizerEffect.setEnabled(false);
+ }
+
+ // dump
+ Log.v(TAG, "Parameters: Equalizer");
+ Log.v(TAG, "bands=" + eQNumBands);
+ String str = "levels=";
+ for (short band = 0; band < eQNumBands; band++) {
+ str = str + bandLevel[band] + "; ";
+ }
+ Log.v(TAG, str);
+ str = "center=";
+ for (short band = 0; band < eQNumBands; band++) {
+ str = str + eQCenterFreq[band] + "; ";
+ }
+ Log.v(TAG, str);
+ str = "presets=";
+ for (short preset = 0; preset < eQNumPresets; preset++) {
+ str = str + eQPresetNames[preset] + "; ";
+ }
+ Log.v(TAG, str);
+ Log.v(TAG, "current=" + eQPreset);
+ } catch (final RuntimeException e) {
+ Log.e(TAG, errorTag + e);
+ }
+ }
+
+ // XXX: Preset Reverb not used for the moment, so commented out the effect creation to not
+ // use MIPS left in the code for (future) reference.
+ // Preset reverb
+ // create effect
+ final PresetReverb presetReverbEffect = getPresetReverbEffect(audioSession);
+ {
+ final String errorTag = methodTag + "PresetReverb error: ";
+
+ try {
+ // read parameters
+ final boolean isEnabled = prefs.getBoolean(Key.pr_enabled.toString(), PRESET_REVERB_ENABLED_DEFAULT);
+ final short preset = (short) prefs.getInt(Key.pr_current_preset.toString(), PRESET_REVERB_CURRENT_PRESET_DEFAULT);
+
+ // init settings
+ PresetReverb.Settings settings = new PresetReverb.Settings("PresetReverb;preset=" + preset);
+
+ // read/update preferences
+ presetReverbEffect.setProperties(settings);
+
+ // set parameters
+ if (isGlobalEnabled == true) {
+ presetReverbEffect.setEnabled(isEnabled);
+ } else {
+ presetReverbEffect.setEnabled(false);
+ }
+
+ // get parameters
+ settings = presetReverbEffect.getProperties();
+ Log.v(TAG, "Parameters: " + settings.toString() + ";enabled=" + isEnabled);
+
+ // update preferences
+ editor.putBoolean(Key.pr_enabled.toString(), isEnabled);
+ editor.putInt(Key.pr_current_preset.toString(), settings.preset);
+ } catch (final RuntimeException e) {
+ Log.e(TAG, errorTag + e);
+ }
+ }
+ editor.commit();
+ }
+
+ /**
+ * Closes the audio session (release effects) for the given session
+ *
+ * @param context
+ * @param packageName
+ * @param audioSession
+ * System wide unique audio session identifier.
+ */
+ public static void closeSession(final Context context, final String packageName,
+ final int audioSession) {
+ Log.v(TAG, "closeSession(" + context + ", " + packageName + ", " + audioSession + ")");
+
+ // PresetReverb
+ final PresetReverb presetReverb = mPresetReverbInstances.remove(audioSession);
+ if (presetReverb != null) {
+ presetReverb.release();
+ }
+ // Equalizer
+ final Equalizer equalizer = mEQInstances.remove(audioSession);
+ if (equalizer != null) {
+ equalizer.release();
+ }
+ // BassBoost
+ final BassBoost bassBoost = mBassBoostInstances.remove(audioSession);
+ if (bassBoost != null) {
+ bassBoost.release();
+ }
+ // Virtualizer
+ final Virtualizer virtualizer = mVirtualizerInstances.remove(audioSession);
+ if (virtualizer != null) {
+ virtualizer.release();
+ }
+
+ mPackageSessions.remove(packageName);
+ }
+
+ /**
+ * Enables or disables all effects (global enable/disable) for a given context, package name and
+ * audio session. It sets/inits the control mode and preferences and then sets the global
+ * enabled parameter.
+ *
+ * @param context
+ * @param packageName
+ * @param audioSession
+ * System wide unique audio session identifier.
+ * @param enabled
+ */
+ public static void setEnabledAll(final Context context, final String packageName,
+ final int audioSession, final boolean enabled) {
+ initEffectsPreferences(context, packageName, audioSession);
+ setParameterBoolean(context, packageName, audioSession, Key.global_enabled, enabled);
+ }
+
+ /**
+ * Gets the virtualizer effect for the given audio session. If the effect on the session doesn't
+ * exist yet, create it and add to collection.
+ *
+ * @param audioSession
+ * System wide unique audio session identifier.
+ * @return virtualizerEffect
+ */
+ private static Virtualizer getVirtualizerEffectNoCreate(final int audioSession) {
+ return mVirtualizerInstances.get(audioSession);
+ }
+ private static Virtualizer getVirtualizerEffect(final int audioSession) {
+ Virtualizer virtualizerEffect = getVirtualizerEffectNoCreate(audioSession);
+ if (virtualizerEffect == null) {
+ try {
+ final Virtualizer newVirtualizerEffect = new Virtualizer(PRIORITY, audioSession);
+ virtualizerEffect = mVirtualizerInstances.putIfAbsent(audioSession,
+ newVirtualizerEffect);
+ if (virtualizerEffect == null) {
+ // put succeeded, use new value
+ virtualizerEffect = newVirtualizerEffect;
+ }
+ } catch (final IllegalArgumentException e) {
+ Log.e(TAG, "Virtualizer: " + e);
+ } catch (final UnsupportedOperationException e) {
+ Log.e(TAG, "Virtualizer: " + e);
+ } catch (final RuntimeException e) {
+ Log.e(TAG, "Virtualizer: " + e);
+ }
+ }
+ return virtualizerEffect;
+ }
+
+ /**
+ * Gets the bass boost effect for the given audio session. If the effect on the session doesn't
+ * exist yet, create it and add to collection.
+ *
+ * @param audioSession
+ * System wide unique audio session identifier.
+ * @return bassBoostEffect
+ */
+ private static BassBoost getBassBoostEffectNoCreate(final int audioSession) {
+ return mBassBoostInstances.get(audioSession);
+ }
+ private static BassBoost getBassBoostEffect(final int audioSession) {
+
+ BassBoost bassBoostEffect = getBassBoostEffectNoCreate(audioSession);
+ if (bassBoostEffect == null) {
+ try {
+ final BassBoost newBassBoostEffect = new BassBoost(PRIORITY, audioSession);
+ bassBoostEffect = mBassBoostInstances.putIfAbsent(audioSession, newBassBoostEffect);
+ if (bassBoostEffect == null) {
+ // put succeeded, use new value
+ bassBoostEffect = newBassBoostEffect;
+ }
+ } catch (final IllegalArgumentException e) {
+ Log.e(TAG, "BassBoost: " + e);
+ } catch (final UnsupportedOperationException e) {
+ Log.e(TAG, "BassBoost: " + e);
+ } catch (final RuntimeException e) {
+ Log.e(TAG, "BassBoost: " + e);
+ }
+ }
+ return bassBoostEffect;
+ }
+
+ /**
+ * Gets the equalizer effect for the given audio session. If the effect on the session doesn't
+ * exist yet, create it and add to collection.
+ *
+ * @param audioSession
+ * System wide unique audio session identifier.
+ * @return equalizerEffect
+ */
+ private static Equalizer getEqualizerEffectNoCreate(final int audioSession) {
+ return mEQInstances.get(audioSession);
+ }
+ private static Equalizer getEqualizerEffect(final int audioSession) {
+ Equalizer equalizerEffect = getEqualizerEffectNoCreate(audioSession);
+ if (equalizerEffect == null) {
+ try {
+ final Equalizer newEqualizerEffect = new Equalizer(PRIORITY, audioSession);
+ equalizerEffect = mEQInstances.putIfAbsent(audioSession, newEqualizerEffect);
+ if (equalizerEffect == null) {
+ // put succeeded, use new value
+ equalizerEffect = newEqualizerEffect;
+ }
+ } catch (final IllegalArgumentException e) {
+ Log.e(TAG, "Equalizer: " + e);
+ } catch (final UnsupportedOperationException e) {
+ Log.e(TAG, "Equalizer: " + e);
+ } catch (final RuntimeException e) {
+ Log.e(TAG, "Equalizer: " + e);
+ }
+ }
+ return equalizerEffect;
+ }
+
+ // XXX: Preset Reverb not used for the moment, so commented out the effect creation to not
+ // use MIPS
+ /**
+ * Gets the preset reverb effect for the given audio session. If the effect on the session
+ * doesn't exist yet, create it and add to collection.
+ *
+ * @param audioSession
+ * System wide unique audio session identifier.
+ * @return presetReverbEffect
+ */
+ private static PresetReverb getPresetReverbEffect(final int audioSession) {
+ PresetReverb presetReverbEffect = mPresetReverbInstances.get(audioSession);
+ if (presetReverbEffect == null) {
+ try {
+ final PresetReverb newPresetReverbEffect = new PresetReverb(PRIORITY, audioSession);
+ presetReverbEffect = mPresetReverbInstances.putIfAbsent(audioSession,
+ newPresetReverbEffect);
+ if (presetReverbEffect == null) {
+ // put succeeded, use new value
+ presetReverbEffect = newPresetReverbEffect;
+ }
+ } catch (final IllegalArgumentException e) {
+ Log.e(TAG, "PresetReverb: " + e);
+ } catch (final UnsupportedOperationException e) {
+ Log.e(TAG, "PresetReverb: " + e);
+ } catch (final RuntimeException e) {
+ Log.e(TAG, "PresetReverb: " + e);
+ }
+ }
+ return presetReverbEffect;
+ }
+}