Home | History | Annotate | Download | only in musicfx
      1 /*
      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 
     17 package com.android.musicfx;
     18 
     19 import android.content.Context;
     20 import android.content.SharedPreferences;
     21 import android.media.MediaPlayer;
     22 import android.media.audiofx.AudioEffect;
     23 import android.media.audiofx.BassBoost;
     24 import android.media.audiofx.Equalizer;
     25 import android.media.audiofx.PresetReverb;
     26 import android.media.audiofx.Virtualizer;
     27 import android.util.Log;
     28 
     29 import java.util.Arrays;
     30 import java.util.concurrent.ConcurrentHashMap;
     31 
     32 /**
     33  * The Common class defines constants to be used by the control panels.
     34  */
     35 public 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 {
     62         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,
     64         eq_num_bands, eq_level_range, eq_center_freq, eq_band_level, eq_num_presets, eq_preset_name,
     65         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
     68     }
     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
    112     final static boolean GLOBAL_ENABLED_DEFAULT = false;
    113     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 };
    130     private final static short[][] EQUALIZER_PRESET_OPENSL_ES_BAND_LEVEL_DEFAULT = new short[EQUALIZER_NUMBER_PRESETS_DEFAULT][EQUALIZER_NUMBER_BANDS_DEFAULT];
    131 
    132     // EQ effect properties which are invariable over all EQ effects sessions
    133     private static short[] mEQBandLevelRange = EQUALIZER_BAND_LEVEL_RANGE_DEFAULT;
    134     private static short mEQNumBands = EQUALIZER_NUMBER_BANDS_DEFAULT;
    135     private static int[] mEQCenterFreq = EQUALIZER_CENTER_FREQ_DEFAULT;
    136     private static short mEQNumPresets = EQUALIZER_NUMBER_PRESETS_DEFAULT;
    137     private static short[][] mEQPresetOpenSLESBandLevel = EQUALIZER_PRESET_OPENSL_ES_BAND_LEVEL_DEFAULT;
    138     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);
    175             final int vIStrength = prefs.getInt(Key.virt_strength.toString(),
    176                     VIRTUALIZER_STRENGTH_DEFAULT);
    177             editor.putBoolean(Key.virt_enabled.toString(), isVIEnabled);
    178             editor.putInt(Key.virt_strength.toString(), vIStrength);
    179             {
    180                 final MediaPlayer mediaPlayer = new MediaPlayer();
    181                 final int session = mediaPlayer.getAudioSessionId();
    182                 Virtualizer virtualizerEffect = null;
    183                 try {
    184                     virtualizerEffect = new Virtualizer(PRIORITY, session);
    185                     editor.putBoolean(Key.virt_strength_supported.toString(),
    186                             virtualizerEffect.getStrengthSupported());
    187                 } finally {
    188                     if (virtualizerEffect != null) {
    189                         Log.d(TAG, "Releasing dummy Virtualizer effect");
    190                         virtualizerEffect.release();
    191                     }
    192                     mediaPlayer.release();
    193                 }
    194             }
    195 
    196             // BassBoost
    197             final boolean isBBEnabled = prefs.getBoolean(Key.bb_enabled.toString(),
    198                     BASS_BOOST_ENABLED_DEFAULT);
    199             final int bBStrength = prefs.getInt(Key.bb_strength.toString(),
    200                     BASS_BOOST_STRENGTH_DEFAULT);
    201             editor.putBoolean(Key.bb_enabled.toString(), isBBEnabled);
    202             editor.putInt(Key.bb_strength.toString(), bBStrength);
    203 
    204             // Equalizer
    205             synchronized (mEQInitLock) {
    206                 // If EQ is not initialized already create "dummy" audio session created by
    207                 // MediaPlayer and create effect on it to retrieve the invariable EQ properties
    208                 if (!mIsEQInitialized) {
    209                     final MediaPlayer mediaPlayer = new MediaPlayer();
    210                     final int session = mediaPlayer.getAudioSessionId();
    211                     Equalizer equalizerEffect = null;
    212                     try {
    213                         Log.d(TAG, "Creating dummy EQ effect on session " + session);
    214                         equalizerEffect = new Equalizer(PRIORITY, session);
    215 
    216                         mEQBandLevelRange = equalizerEffect.getBandLevelRange();
    217                         mEQNumBands = equalizerEffect.getNumberOfBands();
    218                         mEQCenterFreq = new int[mEQNumBands];
    219                         for (short band = 0; band < mEQNumBands; band++) {
    220                             mEQCenterFreq[band] = equalizerEffect.getCenterFreq(band);
    221                         }
    222                         mEQNumPresets = equalizerEffect.getNumberOfPresets();
    223                         mEQPresetNames = new String[mEQNumPresets];
    224                         mEQPresetOpenSLESBandLevel = new short[mEQNumPresets][mEQNumBands];
    225                         for (short preset = 0; preset < mEQNumPresets; preset++) {
    226                             mEQPresetNames[preset] = equalizerEffect.getPresetName(preset);
    227                             equalizerEffect.usePreset(preset);
    228                             for (short band = 0; band < mEQNumBands; band++) {
    229                                 mEQPresetOpenSLESBandLevel[preset][band] = equalizerEffect
    230                                         .getBandLevel(band);
    231                             }
    232                         }
    233 
    234                         mIsEQInitialized = true;
    235                     } catch (final IllegalStateException e) {
    236                         Log.e(TAG, "Equalizer: " + e);
    237                     } catch (final IllegalArgumentException e) {
    238                         Log.e(TAG, "Equalizer: " + e);
    239                     } catch (final UnsupportedOperationException e) {
    240                         Log.e(TAG, "Equalizer: " + e);
    241                     } catch (final RuntimeException e) {
    242                         Log.e(TAG, "Equalizer: " + e);
    243                     } finally {
    244                         if (equalizerEffect != null) {
    245                             Log.d(TAG, "Releasing dummy EQ effect");
    246                             equalizerEffect.release();
    247                         }
    248                         mediaPlayer.release();
    249 
    250                         // When there was a failure set some good defaults
    251                         if (!mIsEQInitialized) {
    252                             mEQPresetOpenSLESBandLevel = new short[mEQNumPresets][mEQNumBands];
    253                             for (short preset = 0; preset < mEQNumPresets; preset++) {
    254                                 // Init preset names to a dummy name
    255                                 mEQPresetNames[preset] = prefs.getString(
    256                                         Key.eq_preset_name.toString() + preset,
    257                                         EQUALIZER_PRESET_NAME_DEFAULT + preset);
    258                                 if (preset < EQUALIZER_PRESET_OPENSL_ES_BAND_LEVEL_DEFAULT.length) {
    259                                     mEQPresetOpenSLESBandLevel[preset] = Arrays.copyOf(
    260                                             EQUALIZER_PRESET_OPENSL_ES_BAND_LEVEL_DEFAULT[preset],
    261                                             mEQNumBands);
    262                                 }
    263                             }
    264                         }
    265                     }
    266                 }
    267                 editor.putInt(Key.eq_level_range.toString() + 0, mEQBandLevelRange[0]);
    268                 editor.putInt(Key.eq_level_range.toString() + 1, mEQBandLevelRange[1]);
    269                 editor.putInt(Key.eq_num_bands.toString(), mEQNumBands);
    270                 editor.putInt(Key.eq_num_presets.toString(), mEQNumPresets);
    271                 // Resetting the EQ arrays depending on the real # bands with defaults if
    272                 // band < default size else 0 by copying default arrays over new ones
    273                 final short[] eQPresetCIExtremeBandLevel = Arrays.copyOf(
    274                         EQUALIZER_PRESET_CIEXTREME_BAND_LEVEL, mEQNumBands);
    275                 final short[] eQPresetUserBandLevelDefault = Arrays.copyOf(
    276                         EQUALIZER_PRESET_USER_BAND_LEVEL_DEFAULT, mEQNumBands);
    277                 // If no preset prefs set use CI EXTREME (= numPresets)
    278                 final short eQPreset = (short) prefs.getInt(Key.eq_current_preset.toString(),
    279                         mEQNumPresets);
    280                 editor.putInt(Key.eq_current_preset.toString(), eQPreset);
    281                 final short[] bandLevel = new short[mEQNumBands];
    282                 for (short band = 0; band < mEQNumBands; band++) {
    283                     if (controlMode == ControlMode.CONTROL_PREFERENCES) {
    284                         if (eQPreset < mEQNumPresets) {
    285                             // OpenSL ES effect presets
    286                             bandLevel[band] = mEQPresetOpenSLESBandLevel[eQPreset][band];
    287                         } else if (eQPreset == mEQNumPresets) {
    288                             // CI EXTREME
    289                             bandLevel[band] = eQPresetCIExtremeBandLevel[band];
    290                         } else {
    291                             // User
    292                             bandLevel[band] = (short) prefs.getInt(
    293                                     Key.eq_preset_user_band_level.toString() + band,
    294                                     eQPresetUserBandLevelDefault[band]);
    295                         }
    296                         editor.putInt(Key.eq_band_level.toString() + band, bandLevel[band]);
    297                     }
    298                     editor.putInt(Key.eq_center_freq.toString() + band, mEQCenterFreq[band]);
    299                     editor.putInt(Key.eq_preset_ci_extreme_band_level.toString() + band,
    300                             eQPresetCIExtremeBandLevel[band]);
    301                     editor.putInt(Key.eq_preset_user_band_level_default.toString() + band,
    302                             eQPresetUserBandLevelDefault[band]);
    303                 }
    304                 for (short preset = 0; preset < mEQNumPresets; preset++) {
    305                     editor.putString(Key.eq_preset_name.toString() + preset, mEQPresetNames[preset]);
    306                     for (short band = 0; band < mEQNumBands; band++) {
    307                         editor.putInt(Key.eq_preset_opensl_es_band_level.toString() + preset + "_"
    308                                 + band, mEQPresetOpenSLESBandLevel[preset][band]);
    309                     }
    310                 }
    311             }
    312             final boolean isEQEnabled = prefs.getBoolean(Key.eq_enabled.toString(),
    313                     EQUALIZER_ENABLED_DEFAULT);
    314             editor.putBoolean(Key.eq_enabled.toString(), isEQEnabled);
    315 
    316             // Preset reverb
    317             final boolean isEnabledPR = prefs.getBoolean(Key.pr_enabled.toString(),
    318                     PRESET_REVERB_ENABLED_DEFAULT);
    319             final short presetPR = (short) prefs.getInt(Key.pr_current_preset.toString(),
    320                     PRESET_REVERB_CURRENT_PRESET_DEFAULT);
    321             editor.putBoolean(Key.pr_enabled.toString(), isEnabledPR);
    322             editor.putInt(Key.pr_current_preset.toString(), presetPR);
    323 
    324             editor.commit();
    325         } catch (final RuntimeException e) {
    326             Log.e(TAG, "initEffectsPreferences: processingEnabled: " + e);
    327         }
    328     }
    329 
    330     /**
    331      * Gets the effect control mode based on the given audio session in the control panel. Control
    332      * mode defines if the control panel is controlling effects and/or preferences
    333      *
    334      * @param audioSession
    335      *            System wide unique audio session identifier.
    336      * @return effect control mode
    337      */
    338     public static ControlMode getControlMode(final int audioSession) {
    339         if (audioSession == AudioEffect.ERROR_BAD_VALUE) {
    340             return ControlMode.CONTROL_PREFERENCES;
    341         }
    342         return ControlMode.CONTROL_EFFECTS;
    343     }
    344 
    345     /**
    346      * Sets boolean parameter to value for given key
    347      *
    348      * @param context
    349      * @param packageName
    350      * @param audioSession
    351      *            System wide unique audio session identifier.
    352      * @param key
    353      * @param value
    354      */
    355     public static void setParameterBoolean(final Context context, final String packageName,
    356             final int audioSession, final Key key, final boolean value) {
    357         try {
    358             final SharedPreferences prefs = context.getSharedPreferences(packageName,
    359                     Context.MODE_PRIVATE);
    360             final ControlMode controlMode = getControlMode(audioSession);
    361             boolean enabled = value;
    362 
    363             // Global on/off
    364             if (key == Key.global_enabled) {
    365                 boolean processingEnabled = false;
    366                 if (value == true) {
    367                     // enable all with respect to preferences
    368                     if (controlMode == ControlMode.CONTROL_EFFECTS) {
    369                         final Virtualizer virtualizerEffect = getVirtualizerEffect(audioSession);
    370                         if (virtualizerEffect != null) {
    371                             virtualizerEffect.setEnabled(prefs.getBoolean(
    372                                     Key.virt_enabled.toString(), VIRTUALIZER_ENABLED_DEFAULT));
    373                             final int vIStrength = prefs.getInt(Key.virt_strength.toString(),
    374                                     VIRTUALIZER_STRENGTH_DEFAULT);
    375                             setParameterInt(context, packageName,
    376                                     audioSession, Key.virt_strength, vIStrength);
    377                         }
    378                         final BassBoost bassBoostEffect = getBassBoostEffect(audioSession);
    379                         if (bassBoostEffect != null) {
    380                             bassBoostEffect.setEnabled(prefs.getBoolean(Key.bb_enabled.toString(),
    381                                     BASS_BOOST_ENABLED_DEFAULT));
    382                             final int bBStrength = prefs.getInt(Key.bb_strength.toString(),
    383                                     BASS_BOOST_STRENGTH_DEFAULT);
    384                             setParameterInt(context, packageName,
    385                                     audioSession, Key.bb_strength, bBStrength);
    386                         }
    387                         final Equalizer equalizerEffect = getEqualizerEffect(audioSession);
    388                         if (equalizerEffect != null) {
    389                             equalizerEffect.setEnabled(prefs.getBoolean(Key.eq_enabled.toString(),
    390                                     EQUALIZER_ENABLED_DEFAULT));
    391                             final int[] bandLevels = getParameterIntArray(context,
    392                                     packageName, audioSession, Key.eq_band_level);
    393                             final int len = bandLevels.length;
    394                             for (short band = 0; band < len; band++) {
    395                                 final int level = bandLevels[band];
    396                                 setParameterInt(context, packageName,
    397                                         audioSession, Key.eq_band_level, level, band);
    398                             }
    399                         }
    400                         // XXX: Preset Reverb not used for the moment, so commented out the effect
    401                         // creation to not use MIPS
    402                         // final PresetReverb presetReverbEffect =
    403                         // getPresetReverbEffect(audioSession);
    404                         // if (presetReverbEffect != null) {
    405                         // presetReverbEffect.setEnabled(prefs.getBoolean(
    406                         // Key.pr_enabled.toString(), PRESET_REVERB_ENABLED_DEFAULT));
    407                         // }
    408                     }
    409 
    410                     processingEnabled = true;
    411                     Log.v(TAG, "processingEnabled=" + processingEnabled);
    412 
    413                 } else {
    414                     // disable all
    415                     if (controlMode == ControlMode.CONTROL_EFFECTS) {
    416                         final Virtualizer virtualizerEffect = getVirtualizerEffectNoCreate(audioSession);
    417                         if (virtualizerEffect != null) {
    418                             mVirtualizerInstances.remove(audioSession, virtualizerEffect);
    419                             virtualizerEffect.setEnabled(false);
    420                             virtualizerEffect.release();
    421                         }
    422                         final BassBoost bassBoostEffect = getBassBoostEffectNoCreate(audioSession);
    423                         if (bassBoostEffect != null) {
    424                             mBassBoostInstances.remove(audioSession, bassBoostEffect);
    425                             bassBoostEffect.setEnabled(false);
    426                             bassBoostEffect.release();
    427                         }
    428                         final Equalizer equalizerEffect = getEqualizerEffectNoCreate(audioSession);
    429                         if (equalizerEffect != null) {
    430                             mEQInstances.remove(audioSession, equalizerEffect);
    431                             equalizerEffect.setEnabled(false);
    432                             equalizerEffect.release();
    433                         }
    434                         // XXX: Preset Reverb not used for the moment, so commented out the effect
    435                         // creation to not use MIPS
    436                         // final PresetReverb presetReverbEffect =
    437                         // getPresetReverbEffect(audioSession);
    438                         // if (presetReverbEffect != null) {
    439                         // presetReverbEffect.setEnabled(false);
    440                         // }
    441                     }
    442 
    443                     processingEnabled = false;
    444                     Log.v(TAG, "processingEnabled=" + processingEnabled);
    445                 }
    446                 enabled = processingEnabled;
    447             } else if (controlMode == ControlMode.CONTROL_EFFECTS) {
    448                 final boolean isGlobalEnabled = prefs.getBoolean(Key.global_enabled.toString(),
    449                         GLOBAL_ENABLED_DEFAULT);
    450                 if (isGlobalEnabled == true) {
    451                     // Set effect parameters
    452                     switch (key) {
    453 
    454                     case global_enabled:
    455                         // Global, already handled, to get out error free
    456                         break;
    457 
    458                     // Virtualizer
    459                     case virt_enabled:
    460                         final Virtualizer virtualizerEffect = getVirtualizerEffect(audioSession);
    461                         if (virtualizerEffect != null) {
    462                             virtualizerEffect.setEnabled(value);
    463                             enabled = virtualizerEffect.getEnabled();
    464                         }
    465                         break;
    466 
    467                     // BassBoost
    468                     case bb_enabled:
    469                         final BassBoost bassBoostEffect = getBassBoostEffect(audioSession);
    470                         if (bassBoostEffect != null) {
    471                             bassBoostEffect.setEnabled(value);
    472                             enabled = bassBoostEffect.getEnabled();
    473                         }
    474                         break;
    475 
    476                     // Equalizer
    477                     case eq_enabled:
    478                         final Equalizer equalizerEffect = getEqualizerEffect(audioSession);
    479                         if (equalizerEffect != null) {
    480                             equalizerEffect.setEnabled(value);
    481                             enabled = equalizerEffect.getEnabled();
    482                         }
    483                         break;
    484 
    485                     // PresetReverb
    486                     case pr_enabled:
    487                         // XXX: Preset Reverb not used for the moment, so commented out the effect
    488                         // creation to not use MIPS
    489                         // final PresetReverb presetReverbEffect =
    490                         // getPresetReverbEffect(audioSession);
    491                         // if (presetReverbEffect != null) {
    492                         // presetReverbEffect.setEnabled(value);
    493                         // enabled = presetReverbEffect.getEnabled();
    494                         // }
    495                         break;
    496 
    497                     default:
    498                         Log.e(TAG, "Unknown/unsupported key " + key);
    499                         return;
    500                     }
    501                 }
    502 
    503             }
    504 
    505             // Set preferences
    506             final SharedPreferences.Editor editor = prefs.edit();
    507             editor.putBoolean(key.toString(), enabled);
    508             editor.commit();
    509 
    510         } catch (final RuntimeException e) {
    511             Log.e(TAG, "setParameterBoolean: " + key + "; " + value + "; " + e);
    512         }
    513     }
    514 
    515     /**
    516      * Gets boolean parameter for given key
    517      *
    518      * @param context
    519      * @param packageName
    520      * @param audioSession
    521      *            System wide unique audio session identifier.
    522      * @param key
    523      * @return parameter value
    524      */
    525     public static Boolean getParameterBoolean(final Context context, final String packageName,
    526             final int audioSession, final Key key) {
    527         final SharedPreferences prefs = context.getSharedPreferences(packageName,
    528                 Context.MODE_PRIVATE);
    529         boolean value = false;
    530 
    531         try {
    532             value = prefs.getBoolean(key.toString(), value);
    533         } catch (final RuntimeException e) {
    534             Log.e(TAG, "getParameterBoolean: " + key + "; " + value + "; " + e);
    535         }
    536 
    537         return value;
    538 
    539     }
    540 
    541     /**
    542      * Sets int parameter for given key and value arg0, arg1
    543      *
    544      * @param context
    545      * @param packageName
    546      * @param audioSession
    547      *            System wide unique audio session identifier.
    548      * @param key
    549      * @param arg0
    550      * @param arg1
    551      */
    552     public static void setParameterInt(final Context context, final String packageName,
    553             final int audioSession, final Key key, final int arg0, final int arg1) {
    554         String strKey = key.toString();
    555         int value = arg0;
    556 
    557         try {
    558             final SharedPreferences prefs = context.getSharedPreferences(packageName,
    559                     Context.MODE_PRIVATE);
    560             final SharedPreferences.Editor editor = prefs.edit();
    561             final ControlMode controlMode = getControlMode(audioSession);
    562 
    563             // Set effect parameters
    564             if (controlMode == ControlMode.CONTROL_EFFECTS) {
    565 
    566                 switch (key) {
    567 
    568                 // Virtualizer
    569                 case virt_strength: {
    570                     final Virtualizer virtualizerEffect = getVirtualizerEffect(audioSession);
    571                     if (virtualizerEffect != null) {
    572                         virtualizerEffect.setStrength((short) value);
    573                         value = virtualizerEffect.getRoundedStrength();
    574                     }
    575                     break;
    576                 }
    577                     // BassBoost
    578                 case bb_strength: {
    579                     final BassBoost bassBoostEffect = getBassBoostEffect(audioSession);
    580                     if (bassBoostEffect != null) {
    581                         bassBoostEffect.setStrength((short) value);
    582                         value = bassBoostEffect.getRoundedStrength();
    583                     }
    584                     break;
    585                 }
    586                     // Equalizer
    587                 case eq_band_level: {
    588                     if (arg1 == DUMMY_ARGUMENT) {
    589                         throw new IllegalArgumentException("Dummy arg passed.");
    590                     }
    591                     final short band = (short) arg1;
    592                     strKey = strKey + band;
    593                     final Equalizer equalizerEffect = getEqualizerEffect(audioSession);
    594                     if (equalizerEffect != null) {
    595                         equalizerEffect.setBandLevel(band, (short) value);
    596                         value = equalizerEffect.getBandLevel(band);
    597                         // save band level in User preset
    598                         editor.putInt(Key.eq_preset_user_band_level.toString() + band, value);
    599                     }
    600                     break;
    601                 }
    602                 case eq_current_preset: {
    603                     final Equalizer equalizerEffect = getEqualizerEffect(audioSession);
    604                     if (equalizerEffect != null) {
    605                         final short preset = (short) value;
    606                         final int numBands = prefs.getInt(Key.eq_num_bands.toString(),
    607                                 EQUALIZER_NUMBER_BANDS_DEFAULT);
    608                         final int numPresets = prefs.getInt(Key.eq_num_presets.toString(),
    609                                 EQUALIZER_NUMBER_PRESETS_DEFAULT);
    610 
    611                         if (preset < numPresets) {
    612                             // OpenSL ES EQ Effect presets
    613                             equalizerEffect.usePreset(preset);
    614                             value = equalizerEffect.getCurrentPreset();
    615                         } else {
    616                             final short[] eQPresetCIExtremeBandLevelDefault = Arrays.copyOf(
    617                                     EQUALIZER_PRESET_CIEXTREME_BAND_LEVEL, numBands);
    618                             final short[] eQPresetUserBandLevelDefault = Arrays.copyOf(
    619                                     EQUALIZER_PRESET_USER_BAND_LEVEL_DEFAULT, numBands);
    620                             // Set the band levels manually for custom presets
    621                             for (short band = 0; band < numBands; band++) {
    622                                 short bandLevel = 0;
    623                                 if (preset == numPresets) {
    624                                     // CI EXTREME
    625                                     bandLevel = (short) prefs.getInt(
    626                                             Key.eq_preset_ci_extreme_band_level.toString() + band,
    627                                             eQPresetCIExtremeBandLevelDefault[band]);
    628                                 } else {
    629                                     // User
    630                                     bandLevel = (short) prefs.getInt(
    631                                             Key.eq_preset_user_band_level.toString() + band,
    632                                             eQPresetUserBandLevelDefault[band]);
    633                                 }
    634                                 equalizerEffect.setBandLevel(band, bandLevel);
    635                             }
    636                         }
    637 
    638                         // update band levels
    639                         for (short band = 0; band < numBands; band++) {
    640                             final short level = equalizerEffect.getBandLevel(band);
    641                             editor.putInt(Key.eq_band_level.toString() + band, level);
    642                         }
    643                     }
    644                     break;
    645                 }
    646                 case eq_preset_user_band_level:
    647                     // Fall through
    648                 case eq_preset_user_band_level_default:
    649                     // Fall through
    650                 case eq_preset_ci_extreme_band_level: {
    651                     if (arg1 == DUMMY_ARGUMENT) {
    652                         throw new IllegalArgumentException("Dummy arg passed.");
    653                     }
    654                     final short band = (short) arg1;
    655                     strKey = strKey + band;
    656                     break;
    657                 }
    658                 case pr_current_preset:
    659                     // XXX: Preset Reverb not used for the moment, so commented out the effect
    660                     // creation to not use MIPS
    661                     // final PresetReverb presetReverbEffect = getPresetReverbEffect(audioSession);
    662                     // if (presetReverbEffect != null) {
    663                     // presetReverbEffect.setPreset((short) value);
    664                     // value = presetReverbEffect.getPreset();
    665                     // }
    666                     break;
    667                 default:
    668                     Log.e(TAG, "setParameterInt: Unknown/unsupported key " + key);
    669                     return;
    670                 }
    671             } else {
    672                 switch (key) {
    673                 // Virtualizer
    674                 case virt_strength:
    675                     // Do nothing
    676                     break;
    677                 case virt_type:
    678                     // Do nothing
    679                     break;
    680 
    681                 // BassBoost
    682                 case bb_strength:
    683                     // Do nothing
    684                     break;
    685 
    686                 // Equalizer
    687                 case eq_band_level: {
    688                     if (arg1 == DUMMY_ARGUMENT) {
    689                         throw new IllegalArgumentException("Dummy arg passed.");
    690                     }
    691                     final short band = (short) arg1;
    692                     strKey = strKey + band;
    693 
    694                     editor.putInt(Key.eq_preset_user_band_level.toString() + band, value);
    695                     break;
    696                 }
    697                 case eq_current_preset: {
    698                     final short preset = (short) value;
    699                     final int numBands = prefs.getInt(Key.eq_num_bands.toString(),
    700                             EQUALIZER_NUMBER_BANDS_DEFAULT);
    701                     final int numPresets = prefs.getInt(Key.eq_num_presets.toString(),
    702                             EQUALIZER_NUMBER_PRESETS_DEFAULT);
    703 
    704                     final short[][] eQPresetOpenSLESBandLevelDefault = Arrays.copyOf(
    705                             EQUALIZER_PRESET_OPENSL_ES_BAND_LEVEL_DEFAULT, numBands);
    706                     final short[] eQPresetCIExtremeBandLevelDefault = Arrays.copyOf(
    707                             EQUALIZER_PRESET_CIEXTREME_BAND_LEVEL, numBands);
    708                     final short[] eQPresetUserBandLevelDefault = Arrays.copyOf(
    709                             EQUALIZER_PRESET_USER_BAND_LEVEL_DEFAULT, numBands);
    710                     for (short band = 0; band < numBands; band++) {
    711                         short bandLevel = 0;
    712                         if (preset < numPresets) {
    713                             // OpenSL ES EQ Effect presets
    714                             bandLevel = (short) prefs.getInt(
    715                                     Key.eq_preset_opensl_es_band_level.toString() + preset + "_"
    716                                             + band, eQPresetOpenSLESBandLevelDefault[preset][band]);
    717                         } else if (preset == numPresets) {
    718                             // CI EXTREME
    719                             bandLevel = (short) prefs.getInt(
    720                                     Key.eq_preset_ci_extreme_band_level.toString() + band,
    721                                     eQPresetCIExtremeBandLevelDefault[band]);
    722                         } else {
    723                             // User
    724                             bandLevel = (short) prefs.getInt(
    725                                     Key.eq_preset_user_band_level.toString() + band,
    726                                     eQPresetUserBandLevelDefault[band]);
    727                         }
    728                         editor.putInt(Key.eq_band_level.toString() + band, bandLevel);
    729                     }
    730                     break;
    731                 }
    732                 case eq_preset_user_band_level:
    733                     // Fall through
    734                 case eq_preset_user_band_level_default:
    735                     // Fall through
    736                 case eq_preset_ci_extreme_band_level: {
    737                     if (arg1 == DUMMY_ARGUMENT) {
    738                         throw new IllegalArgumentException("Dummy arg passed.");
    739                     }
    740                     final short band = (short) arg1;
    741                     strKey = strKey + band;
    742                     break;
    743                 }
    744                 case pr_current_preset:
    745                     // Do nothing
    746                     break;
    747                 default:
    748                     Log.e(TAG, "setParameterInt: Unknown/unsupported key " + key);
    749                     return;
    750                 }
    751             }
    752 
    753             // Set preferences
    754             editor.putInt(strKey, value);
    755             editor.apply();
    756 
    757         } catch (final RuntimeException e) {
    758             Log.e(TAG, "setParameterInt: " + key + "; " + arg0 + "; " + arg1 + "; " + e);
    759         }
    760 
    761     }
    762 
    763     /**
    764      * Sets int parameter for given key and value arg
    765      *
    766      * @param context
    767      * @param packageName
    768      * @param audioSession
    769      *            System wide unique audio session identifier.
    770      * @param key
    771      * @param arg
    772      */
    773     public static void setParameterInt(final Context context, final String packageName,
    774             final int audioSession, final Key key, final int arg) {
    775         setParameterInt(context, packageName, audioSession, key, arg, DUMMY_ARGUMENT);
    776     }
    777 
    778     /**
    779      * Gets int parameter given key
    780      *
    781      * @param context
    782      * @param packageName
    783      * @param audioSession
    784      *            System wide unique audio session identifier.
    785      * @param key
    786      * @return parameter value
    787      */
    788     public static int getParameterInt(final Context context, final String packageName,
    789             final int audioSession, final String key) {
    790         int value = 0;
    791 
    792         try {
    793             final SharedPreferences prefs = context.getSharedPreferences(packageName,
    794                     Context.MODE_PRIVATE);
    795             value = prefs.getInt(key, value);
    796         } catch (final RuntimeException e) {
    797             Log.e(TAG, "getParameterInt: " + key + "; " + e);
    798         }
    799 
    800         return value;
    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 Key key) {
    815         return getParameterInt(context, packageName, audioSession, key.toString());
    816     }
    817 
    818     /**
    819      * Gets int parameter given key and arg
    820      *
    821      * @param context
    822      * @param packageName
    823      * @param audioSession
    824      *            System wide unique audio session identifier.
    825      * @param audioSession
    826      * @param key
    827      * @param arg
    828      * @return parameter value
    829      */
    830     public static int getParameterInt(final Context context, final String packageName,
    831             final int audioSession, final Key key, final int arg) {
    832         return getParameterInt(context, packageName, audioSession, key.toString() + arg);
    833     }
    834 
    835     /**
    836      * Gets int parameter given key, arg0 and arg1
    837      *
    838      * @param context
    839      * @param packageName
    840      * @param audioSession
    841      *            System wide unique audio session identifier.
    842      * @param audioSession
    843      * @param key
    844      * @param arg0
    845      * @param arg1
    846      * @return parameter value
    847      */
    848     public static int getParameterInt(final Context context, final String packageName,
    849             final int audioSession, final Key key, final int arg0, final int arg1) {
    850         return getParameterInt(context, packageName, audioSession, key.toString() + arg0 + "_"
    851                 + arg1);
    852     }
    853 
    854     /**
    855      * Gets integer array parameter given key. Returns null if not found.
    856      *
    857      * @param context
    858      * @param packageName
    859      * @param audioSession
    860      *            System wide unique audio session identifier.
    861      * @param key
    862      * @return parameter value array
    863      */
    864     public static int[] getParameterIntArray(final Context context, final String packageName,
    865             final int audioSession, final Key key) {
    866         final SharedPreferences prefs = context.getSharedPreferences(packageName,
    867                 Context.MODE_PRIVATE);
    868 
    869         int[] intArray = null;
    870         try {
    871             // Get effect parameters
    872             switch (key) {
    873             case eq_level_range: {
    874                 intArray = new int[2];
    875                 break;
    876             }
    877             case eq_center_freq:
    878                 // Fall through
    879             case eq_band_level:
    880                 // Fall through
    881             case eq_preset_user_band_level:
    882                 // Fall through
    883             case eq_preset_user_band_level_default:
    884                 // Fall through
    885             case eq_preset_ci_extreme_band_level: {
    886                 final int numBands = prefs.getInt(Key.eq_num_bands.toString(), 0);
    887                 intArray = new int[numBands];
    888                 break;
    889             }
    890             default:
    891                 Log.e(TAG, "getParameterIntArray: Unknown/unsupported key " + key);
    892                 return null;
    893             }
    894 
    895             for (int i = 0; i < intArray.length; i++) {
    896                 intArray[i] = prefs.getInt(key.toString() + i, 0);
    897             }
    898 
    899         } catch (final RuntimeException e) {
    900             Log.e(TAG, "getParameterIntArray: " + key + "; " + e);
    901         }
    902 
    903         return intArray;
    904     }
    905 
    906     /**
    907      * Gets string parameter given key. Returns empty string if not found.
    908      *
    909      * @param context
    910      * @param packageName
    911      * @param audioSession
    912      *            System wide unique audio session identifier.
    913      * @param key
    914      * @return parameter value
    915      */
    916     public static String getParameterString(final Context context, final String packageName,
    917             final int audioSession, final String key) {
    918         String value = "";
    919         try {
    920             final SharedPreferences prefs = context.getSharedPreferences(packageName,
    921                     Context.MODE_PRIVATE);
    922 
    923             // Get effect parameters
    924             value = prefs.getString(key, value);
    925 
    926         } catch (final RuntimeException e) {
    927             Log.e(TAG, "getParameterString: " + key + "; " + e);
    928         }
    929 
    930         return value;
    931     }
    932 
    933     /**
    934      * Gets string parameter given key.
    935      *
    936      * @param context
    937      * @param packageName
    938      * @param audioSession
    939      *            System wide unique audio session identifier.
    940      * @param key
    941      * @return parameter value
    942      */
    943     public static String getParameterString(final Context context, final String packageName,
    944             final int audioSession, final Key key) {
    945         return getParameterString(context, packageName, audioSession, key.toString());
    946     }
    947 
    948     /**
    949      * Gets string parameter given key and arg.
    950      *
    951      * @param context
    952      * @param packageName
    953      * @param audioSession
    954      *            System wide unique audio session identifier.
    955      * @param args
    956      * @return parameter value
    957      */
    958     public static String getParameterString(final Context context, final String packageName,
    959             final int audioSession, final Key key, final int arg) {
    960         return getParameterString(context, packageName, audioSession, key.toString() + arg);
    961     }
    962 
    963     /**
    964      * Opens/initializes the effects session for the given audio session with preferences linked to
    965      * the given package name and context.
    966      *
    967      * @param context
    968      * @param packageName
    969      * @param audioSession
    970      *            System wide unique audio session identifier.
    971      */
    972     public static void openSession(final Context context, final String packageName,
    973             final int audioSession) {
    974         Log.v(TAG, "openSession(" + context + ", " + packageName + ", " + audioSession + ")");
    975         final String methodTag = "openSession: ";
    976 
    977         // init preferences
    978         final SharedPreferences prefs = context.getSharedPreferences(packageName,
    979                 Context.MODE_PRIVATE);
    980         final SharedPreferences.Editor editor = prefs.edit();
    981 
    982         final boolean isGlobalEnabled = prefs.getBoolean(Key.global_enabled.toString(),
    983                 GLOBAL_ENABLED_DEFAULT);
    984         editor.putBoolean(Key.global_enabled.toString(), isGlobalEnabled);
    985 
    986         if (!isGlobalEnabled) {
    987             return;
    988         }
    989 
    990         // Manage audioSession information
    991 
    992         // Retrieve AudioSession Id from map
    993         boolean isExistingAudioSession = false;
    994 
    995         try {
    996             final Integer currentAudioSession = mPackageSessions.putIfAbsent(packageName,
    997                     audioSession);
    998             if (currentAudioSession != null) {
    999                 // Compare with passed argument
   1000                 if (currentAudioSession == audioSession) {
   1001                     // FIXME: Normally, we should exit the function here
   1002                     // BUT: we have to take care of the virtualizer because of
   1003                     // a bug in the Android Effects Framework
   1004                     // editor.commit();
   1005                     // return;
   1006                     isExistingAudioSession = true;
   1007                 } else {
   1008                     closeSession(context, packageName, currentAudioSession);
   1009                 }
   1010             }
   1011         } catch (final NullPointerException e) {
   1012             Log.e(TAG, methodTag + e);
   1013             editor.commit();
   1014             return;
   1015         }
   1016 
   1017         // Because the audioSession is new, get effects & settings from shared preferences
   1018 
   1019         // Virtualizer
   1020         // create effect
   1021         final Virtualizer virtualizerEffect = getVirtualizerEffect(audioSession);
   1022         {
   1023             final String errorTag = methodTag + "Virtualizer error: ";
   1024 
   1025             try {
   1026                 // read parameters
   1027                 final boolean isEnabled = prefs.getBoolean(Key.virt_enabled.toString(),
   1028                         VIRTUALIZER_ENABLED_DEFAULT);
   1029                 final int strength = prefs.getInt(Key.virt_strength.toString(),
   1030                         VIRTUALIZER_STRENGTH_DEFAULT);
   1031                 // init settings
   1032                 Virtualizer.Settings settings = new Virtualizer.Settings("Virtualizer;strength="
   1033                         + strength);
   1034 
   1035                 virtualizerEffect.setProperties(settings);
   1036 
   1037                 // set parameters
   1038                 if (isGlobalEnabled == true) {
   1039                     virtualizerEffect.setEnabled(isEnabled);
   1040                 } else {
   1041                     virtualizerEffect.setEnabled(false);
   1042                 }
   1043 
   1044                 // get parameters
   1045                 settings = virtualizerEffect.getProperties();
   1046                 Log.v(TAG, "Parameters: " + settings.toString() + ";enabled=" + isEnabled);
   1047 
   1048                 // update preferences
   1049                 editor.putBoolean(Key.virt_enabled.toString(), isEnabled);
   1050                 editor.putInt(Key.virt_strength.toString(), settings.strength);
   1051             } catch (final RuntimeException e) {
   1052                 Log.e(TAG, errorTag + e);
   1053             }
   1054         }
   1055 
   1056         // In case of an existing audio session
   1057         // Exit after the virtualizer has been re-enabled
   1058 
   1059         if (isExistingAudioSession) {
   1060             editor.apply();
   1061             return;
   1062         }
   1063 
   1064         // BassBoost
   1065         // create effect
   1066         final BassBoost bassBoostEffect = getBassBoostEffect(audioSession);
   1067         {
   1068             final String errorTag = methodTag + "BassBoost error: ";
   1069 
   1070             try {
   1071                 // read parameters
   1072                 final boolean isEnabled = prefs.getBoolean(Key.bb_enabled.toString(),
   1073                         BASS_BOOST_ENABLED_DEFAULT);
   1074                 final int strength = prefs.getInt(Key.bb_strength.toString(),
   1075                         BASS_BOOST_STRENGTH_DEFAULT);
   1076 
   1077                 // init settings
   1078                 BassBoost.Settings settings = new BassBoost.Settings("BassBoost;strength="
   1079                         + strength);
   1080 
   1081                 bassBoostEffect.setProperties(settings);
   1082 
   1083                 // set parameters
   1084                 if (isGlobalEnabled == true) {
   1085                     bassBoostEffect.setEnabled(isEnabled);
   1086                 } else {
   1087                     bassBoostEffect.setEnabled(false);
   1088                 }
   1089 
   1090                 // get parameters
   1091                 settings = bassBoostEffect.getProperties();
   1092                 Log.v(TAG, "Parameters: " + settings.toString() + ";enabled=" + isEnabled);
   1093 
   1094                 // update preferences
   1095                 editor.putBoolean(Key.bb_enabled.toString(), isEnabled);
   1096                 editor.putInt(Key.bb_strength.toString(), settings.strength);
   1097             } catch (final RuntimeException e) {
   1098                 Log.e(TAG, errorTag + e);
   1099             }
   1100         }
   1101 
   1102         // Equalizer
   1103         // create effect
   1104         final Equalizer equalizerEffect = getEqualizerEffect(audioSession);
   1105         {
   1106             final String errorTag = methodTag + "Equalizer error: ";
   1107 
   1108             try {
   1109                 final short eQNumBands;
   1110                 final short[] bandLevel;
   1111                 final int[] eQCenterFreq;
   1112                 final short eQNumPresets;
   1113                 final String[] eQPresetNames;
   1114                 short eQPreset;
   1115                 synchronized (mEQInitLock) {
   1116                     // read parameters
   1117                     mEQBandLevelRange = equalizerEffect.getBandLevelRange();
   1118                     mEQNumBands = equalizerEffect.getNumberOfBands();
   1119                     mEQCenterFreq = new int[mEQNumBands];
   1120                     mEQNumPresets = equalizerEffect.getNumberOfPresets();
   1121                     mEQPresetNames = new String[mEQNumPresets];
   1122 
   1123                     for (short preset = 0; preset < mEQNumPresets; preset++) {
   1124                         mEQPresetNames[preset] = equalizerEffect.getPresetName(preset);
   1125                         editor.putString(Key.eq_preset_name.toString() + preset,
   1126                                 mEQPresetNames[preset]);
   1127                     }
   1128 
   1129                     editor.putInt(Key.eq_level_range.toString() + 0, mEQBandLevelRange[0]);
   1130                     editor.putInt(Key.eq_level_range.toString() + 1, mEQBandLevelRange[1]);
   1131                     editor.putInt(Key.eq_num_bands.toString(), mEQNumBands);
   1132                     editor.putInt(Key.eq_num_presets.toString(), mEQNumPresets);
   1133                     // Resetting the EQ arrays depending on the real # bands with defaults if band <
   1134                     // default size else 0 by copying default arrays over new ones
   1135                     final short[] eQPresetCIExtremeBandLevel = Arrays.copyOf(
   1136                             EQUALIZER_PRESET_CIEXTREME_BAND_LEVEL, mEQNumBands);
   1137                     final short[] eQPresetUserBandLevelDefault = Arrays.copyOf(
   1138                             EQUALIZER_PRESET_USER_BAND_LEVEL_DEFAULT, mEQNumBands);
   1139                     // If no preset prefs set use CI EXTREME (= numPresets)
   1140                     eQPreset = (short) prefs
   1141                             .getInt(Key.eq_current_preset.toString(), mEQNumPresets);
   1142                     if (eQPreset < mEQNumPresets) {
   1143                         // OpenSL ES effect presets
   1144                         equalizerEffect.usePreset(eQPreset);
   1145                         eQPreset = equalizerEffect.getCurrentPreset();
   1146                     } else {
   1147                         for (short band = 0; band < mEQNumBands; band++) {
   1148                             short level = 0;
   1149                             if (eQPreset == mEQNumPresets) {
   1150                                 // CI EXTREME
   1151                                 level = eQPresetCIExtremeBandLevel[band];
   1152                             } else {
   1153                                 // User
   1154                                 level = (short) prefs.getInt(
   1155                                         Key.eq_preset_user_band_level.toString() + band,
   1156                                         eQPresetUserBandLevelDefault[band]);
   1157                             }
   1158                             equalizerEffect.setBandLevel(band, level);
   1159                         }
   1160                     }
   1161                     editor.putInt(Key.eq_current_preset.toString(), eQPreset);
   1162 
   1163                     bandLevel = new short[mEQNumBands];
   1164                     for (short band = 0; band < mEQNumBands; band++) {
   1165                         mEQCenterFreq[band] = equalizerEffect.getCenterFreq(band);
   1166                         bandLevel[band] = equalizerEffect.getBandLevel(band);
   1167 
   1168                         editor.putInt(Key.eq_band_level.toString() + band, bandLevel[band]);
   1169                         editor.putInt(Key.eq_center_freq.toString() + band, mEQCenterFreq[band]);
   1170                         editor.putInt(Key.eq_preset_ci_extreme_band_level.toString() + band,
   1171                                 eQPresetCIExtremeBandLevel[band]);
   1172                         editor.putInt(Key.eq_preset_user_band_level_default.toString() + band,
   1173                                 eQPresetUserBandLevelDefault[band]);
   1174                     }
   1175 
   1176                     eQNumBands = mEQNumBands;
   1177                     eQCenterFreq = mEQCenterFreq;
   1178                     eQNumPresets = mEQNumPresets;
   1179                     eQPresetNames = mEQPresetNames;
   1180                 }
   1181 
   1182                 final boolean isEnabled = prefs.getBoolean(Key.eq_enabled.toString(),
   1183                         EQUALIZER_ENABLED_DEFAULT);
   1184                 editor.putBoolean(Key.eq_enabled.toString(), isEnabled);
   1185                 if (isGlobalEnabled == true) {
   1186                     equalizerEffect.setEnabled(isEnabled);
   1187                 } else {
   1188                     equalizerEffect.setEnabled(false);
   1189                 }
   1190 
   1191                 // dump
   1192                 Log.v(TAG, "Parameters: Equalizer");
   1193                 Log.v(TAG, "bands=" + eQNumBands);
   1194                 String str = "levels=";
   1195                 for (short band = 0; band < eQNumBands; band++) {
   1196                     str = str + bandLevel[band] + "; ";
   1197                 }
   1198                 Log.v(TAG, str);
   1199                 str = "center=";
   1200                 for (short band = 0; band < eQNumBands; band++) {
   1201                     str = str + eQCenterFreq[band] + "; ";
   1202                 }
   1203                 Log.v(TAG, str);
   1204                 str = "presets=";
   1205                 for (short preset = 0; preset < eQNumPresets; preset++) {
   1206                     str = str + eQPresetNames[preset] + "; ";
   1207                 }
   1208                 Log.v(TAG, str);
   1209                 Log.v(TAG, "current=" + eQPreset);
   1210             } catch (final RuntimeException e) {
   1211                 Log.e(TAG, errorTag + e);
   1212             }
   1213         }
   1214 
   1215         // XXX: Preset Reverb not used for the moment, so commented out the effect creation to not
   1216         // use MIPS left in the code for (future) reference.
   1217         // Preset reverb
   1218         // create effect
   1219         // final PresetReverb presetReverbEffect = getPresetReverbEffect(audioSession);
   1220         // {
   1221         // final String errorTag = methodTag + "PresetReverb error: ";
   1222         //
   1223         // try {
   1224         // // read parameters
   1225         // final boolean isEnabled = prefs.getBoolean(Key.pr_enabled.toString(),
   1226         // PRESET_REVERB_ENABLED_DEFAULT);
   1227         // final short preset = (short) prefs.getInt(Key.pr_current_preset.toString(),
   1228         // PRESET_REVERB_CURRENT_PRESET_DEFAULT);
   1229         //
   1230         // // init settings
   1231         // PresetReverb.Settings settings = new PresetReverb.Settings("PresetReverb;preset="
   1232         // + preset);
   1233         //
   1234         // // read/update preferences
   1235         // presetReverbEffect.setProperties(settings);
   1236         //
   1237         // // set parameters
   1238         // if (isGlobalEnabled == true) {
   1239         // presetReverbEffect.setEnabled(isEnabled);
   1240         // } else {
   1241         // presetReverbEffect.setEnabled(false);
   1242         // }
   1243         //
   1244         // // get parameters
   1245         // settings = presetReverbEffect.getProperties();
   1246         // Log.v(TAG, "Parameters: " + settings.toString() + ";enabled=" + isEnabled);
   1247         //
   1248         // // update preferences
   1249         // editor.putBoolean(Key.pr_enabled.toString(), isEnabled);
   1250         // editor.putInt(Key.pr_current_preset.toString(), settings.preset);
   1251         // } catch (final RuntimeException e) {
   1252         // Log.e(TAG, errorTag + e);
   1253         // }
   1254         // }
   1255         editor.commit();
   1256     }
   1257 
   1258     /**
   1259      * Closes the audio session (release effects) for the given session
   1260      *
   1261      * @param context
   1262      * @param packageName
   1263      * @param audioSession
   1264      *            System wide unique audio session identifier.
   1265      */
   1266     public static void closeSession(final Context context, final String packageName,
   1267             final int audioSession) {
   1268         Log.v(TAG, "closeSession(" + context + ", " + packageName + ", " + audioSession + ")");
   1269 
   1270         // PresetReverb
   1271         final PresetReverb presetReverb = mPresetReverbInstances.remove(audioSession);
   1272         if (presetReverb != null) {
   1273             presetReverb.release();
   1274         }
   1275         // Equalizer
   1276         final Equalizer equalizer = mEQInstances.remove(audioSession);
   1277         if (equalizer != null) {
   1278             equalizer.release();
   1279         }
   1280         // BassBoost
   1281         final BassBoost bassBoost = mBassBoostInstances.remove(audioSession);
   1282         if (bassBoost != null) {
   1283             bassBoost.release();
   1284         }
   1285         // Virtualizer
   1286         final Virtualizer virtualizer = mVirtualizerInstances.remove(audioSession);
   1287         if (virtualizer != null) {
   1288             virtualizer.release();
   1289         }
   1290 
   1291         mPackageSessions.remove(packageName);
   1292     }
   1293 
   1294     /**
   1295      * Enables or disables all effects (global enable/disable) for a given context, package name and
   1296      * audio session. It sets/inits the control mode and preferences and then sets the global
   1297      * enabled parameter.
   1298      *
   1299      * @param context
   1300      * @param packageName
   1301      * @param audioSession
   1302      *            System wide unique audio session identifier.
   1303      * @param enabled
   1304      */
   1305     public static void setEnabledAll(final Context context, final String packageName,
   1306             final int audioSession, final boolean enabled) {
   1307         initEffectsPreferences(context, packageName, audioSession);
   1308         setParameterBoolean(context, packageName, audioSession, Key.global_enabled, enabled);
   1309     }
   1310 
   1311     /**
   1312      * Gets the virtualizer effect for the given audio session. If the effect on the session doesn't
   1313      * exist yet, create it and add to collection.
   1314      *
   1315      * @param audioSession
   1316      *            System wide unique audio session identifier.
   1317      * @return virtualizerEffect
   1318      */
   1319     private static Virtualizer getVirtualizerEffectNoCreate(final int audioSession) {
   1320         return mVirtualizerInstances.get(audioSession);
   1321     }
   1322     private static Virtualizer getVirtualizerEffect(final int audioSession) {
   1323         Virtualizer virtualizerEffect = getVirtualizerEffectNoCreate(audioSession);
   1324         if (virtualizerEffect == null) {
   1325             try {
   1326                 final Virtualizer newVirtualizerEffect = new Virtualizer(PRIORITY, audioSession);
   1327                 virtualizerEffect = mVirtualizerInstances.putIfAbsent(audioSession,
   1328                         newVirtualizerEffect);
   1329                 if (virtualizerEffect == null) {
   1330                     // put succeeded, use new value
   1331                     virtualizerEffect = newVirtualizerEffect;
   1332                 }
   1333             } catch (final IllegalArgumentException e) {
   1334                 Log.e(TAG, "Virtualizer: " + e);
   1335             } catch (final UnsupportedOperationException e) {
   1336                 Log.e(TAG, "Virtualizer: " + e);
   1337             } catch (final RuntimeException e) {
   1338                 Log.e(TAG, "Virtualizer: " + e);
   1339             }
   1340         }
   1341         return virtualizerEffect;
   1342     }
   1343 
   1344     /**
   1345      * Gets the bass boost effect for the given audio session. If the effect on the session doesn't
   1346      * exist yet, create it and add to collection.
   1347      *
   1348      * @param audioSession
   1349      *            System wide unique audio session identifier.
   1350      * @return bassBoostEffect
   1351      */
   1352     private static BassBoost getBassBoostEffectNoCreate(final int audioSession) {
   1353         return mBassBoostInstances.get(audioSession);
   1354     }
   1355     private static BassBoost getBassBoostEffect(final int audioSession) {
   1356 
   1357         BassBoost bassBoostEffect = getBassBoostEffectNoCreate(audioSession);
   1358         if (bassBoostEffect == null) {
   1359             try {
   1360                 final BassBoost newBassBoostEffect = new BassBoost(PRIORITY, audioSession);
   1361                 bassBoostEffect = mBassBoostInstances.putIfAbsent(audioSession, newBassBoostEffect);
   1362                 if (bassBoostEffect == null) {
   1363                     // put succeeded, use new value
   1364                     bassBoostEffect = newBassBoostEffect;
   1365                 }
   1366             } catch (final IllegalArgumentException e) {
   1367                 Log.e(TAG, "BassBoost: " + e);
   1368             } catch (final UnsupportedOperationException e) {
   1369                 Log.e(TAG, "BassBoost: " + e);
   1370             } catch (final RuntimeException e) {
   1371                 Log.e(TAG, "BassBoost: " + e);
   1372             }
   1373         }
   1374         return bassBoostEffect;
   1375     }
   1376 
   1377     /**
   1378      * Gets the equalizer effect for the given audio session. If the effect on the session doesn't
   1379      * exist yet, create it and add to collection.
   1380      *
   1381      * @param audioSession
   1382      *            System wide unique audio session identifier.
   1383      * @return equalizerEffect
   1384      */
   1385     private static Equalizer getEqualizerEffectNoCreate(final int audioSession) {
   1386         return mEQInstances.get(audioSession);
   1387     }
   1388     private static Equalizer getEqualizerEffect(final int audioSession) {
   1389         Equalizer equalizerEffect = getEqualizerEffectNoCreate(audioSession);
   1390         if (equalizerEffect == null) {
   1391             try {
   1392                 final Equalizer newEqualizerEffect = new Equalizer(PRIORITY, audioSession);
   1393                 equalizerEffect = mEQInstances.putIfAbsent(audioSession, newEqualizerEffect);
   1394                 if (equalizerEffect == null) {
   1395                     // put succeeded, use new value
   1396                     equalizerEffect = newEqualizerEffect;
   1397                 }
   1398             } catch (final IllegalArgumentException e) {
   1399                 Log.e(TAG, "Equalizer: " + e);
   1400             } catch (final UnsupportedOperationException e) {
   1401                 Log.e(TAG, "Equalizer: " + e);
   1402             } catch (final RuntimeException e) {
   1403                 Log.e(TAG, "Equalizer: " + e);
   1404             }
   1405         }
   1406         return equalizerEffect;
   1407     }
   1408 
   1409     // XXX: Preset Reverb not used for the moment, so commented out the effect creation to not
   1410     // use MIPS
   1411     // /**
   1412     // * Gets the preset reverb effect for the given audio session. If the effect on the session
   1413     // * doesn't exist yet, create it and add to collection.
   1414     // *
   1415     // * @param audioSession
   1416     // * System wide unique audio session identifier.
   1417     // * @return presetReverbEffect
   1418     // */
   1419     // private static PresetReverb getPresetReverbEffect(final int audioSession) {
   1420     // PresetReverb presetReverbEffect = mPresetReverbInstances.get(audioSession);
   1421     // if (presetReverbEffect == null) {
   1422     // try {
   1423     // final PresetReverb newPresetReverbEffect = new PresetReverb(PRIORITY, audioSession);
   1424     // presetReverbEffect = mPresetReverbInstances.putIfAbsent(audioSession,
   1425     // newPresetReverbEffect);
   1426     // if (presetReverbEffect == null) {
   1427     // // put succeeded, use new value
   1428     // presetReverbEffect = newPresetReverbEffect;
   1429     // }
   1430     // } catch (final IllegalArgumentException e) {
   1431     // Log.e(TAG, "PresetReverb: " + e);
   1432     // } catch (final UnsupportedOperationException e) {
   1433     // Log.e(TAG, "PresetReverb: " + e);
   1434     // } catch (final RuntimeException e) {
   1435     // Log.e(TAG, "PresetReverb: " + e);
   1436     // }
   1437     // }
   1438     // return presetReverbEffect;
   1439     // }
   1440 }
   1441