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