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