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