1 /* 2 * Copyright (C) 2010 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 android.media.cts; 18 19 import android.media.audiofx.AudioEffect; 20 import android.media.AudioFormat; 21 import android.media.AudioManager; 22 import android.media.audiofx.Equalizer; 23 import android.os.Looper; 24 import android.test.AndroidTestCase; 25 import android.util.Log; 26 27 public class EqualizerTest extends PostProcTestBase { 28 29 private String TAG = "EqualizerTest"; 30 private final static int MIN_NUMBER_OF_BANDS = 2; 31 private final static int MAX_LEVEL_RANGE_LOW = 0; // 0dB 32 private final static int MIN_LEVEL_RANGE_HIGH = 0; // 0dB 33 private final static int TEST_FREQUENCY_MILLIHERTZ = 1000000; // 1kHz 34 private final static int MIN_NUMBER_OF_PRESETS = 0; 35 private final static float TOLERANCE = 100; // +/-1dB 36 private final static int MAX_LOOPER_WAIT_COUNT = 10; 37 38 private Equalizer mEqualizer = null; 39 private Equalizer mEqualizer2 = null; 40 private ListenerThread mEffectListenerLooper = null; 41 42 //----------------------------------------------------------------- 43 // EQUALIZER TESTS: 44 //---------------------------------- 45 46 //----------------------------------------------------------------- 47 // 0 - constructor 48 //---------------------------------- 49 50 //Test case 0.0: test constructor and release 51 public void test0_0ConstructorAndRelease() throws Exception { 52 Equalizer eq = null; 53 try { 54 eq = new Equalizer(0, getSessionId()); 55 try { 56 assertTrue("invalid effect ID", (eq.getId() != 0)); 57 } catch (IllegalStateException e) { 58 fail("Equalizer not initialized"); 59 } 60 } catch (IllegalArgumentException e) { 61 fail("Equalizer not found"); 62 } catch (UnsupportedOperationException e) { 63 fail("Effect library not loaded"); 64 } finally { 65 if (eq != null) { 66 eq.release(); 67 } 68 } 69 } 70 71 72 //----------------------------------------------------------------- 73 // 1 - get/set parameters 74 //---------------------------------- 75 76 //Test case 1.0: test setBandLevel() and getBandLevel() 77 public void test1_0BandLevel() throws Exception { 78 getEqualizer(getSessionId()); 79 try { 80 short numBands = mEqualizer.getNumberOfBands(); 81 assertTrue("not enough bands", numBands >= MIN_NUMBER_OF_BANDS); 82 83 short[] levelRange = mEqualizer.getBandLevelRange(); 84 assertTrue("min level too high", levelRange[0] <= MAX_LEVEL_RANGE_LOW); 85 assertTrue("max level too low", levelRange[1] >= MIN_LEVEL_RANGE_HIGH); 86 87 mEqualizer.setBandLevel((short)0, levelRange[1]); 88 short level = mEqualizer.getBandLevel((short)0); 89 // allow +/- TOLERANCE margin on actual level compared to requested level 90 assertTrue("setBandLevel failed", 91 (level >= (levelRange[1] - TOLERANCE)) && 92 (level <= (levelRange[1] + TOLERANCE))); 93 94 } catch (IllegalArgumentException e) { 95 fail("Bad parameter value"); 96 } catch (UnsupportedOperationException e) { 97 fail("get parameter() rejected"); 98 } catch (IllegalStateException e) { 99 fail("get parameter() called in wrong state"); 100 } finally { 101 releaseEqualizer(); 102 } 103 } 104 105 //Test case 1.1: test band frequency 106 public void test1_1BandFrequency() throws Exception { 107 getEqualizer(getSessionId()); 108 try { 109 short band = mEqualizer.getBand(TEST_FREQUENCY_MILLIHERTZ); 110 assertTrue("getBand failed", band >= 0); 111 int[] freqRange = mEqualizer.getBandFreqRange(band); 112 assertTrue("getBandFreqRange failed", 113 (freqRange[0] <= TEST_FREQUENCY_MILLIHERTZ) && 114 (freqRange[1] >= TEST_FREQUENCY_MILLIHERTZ)); 115 int freq = mEqualizer.getCenterFreq(band); 116 assertTrue("getCenterFreq failed", 117 (freqRange[0] <= freq) && (freqRange[1] >= freq)); 118 119 } catch (IllegalArgumentException e) { 120 fail("Bad parameter value"); 121 } catch (UnsupportedOperationException e) { 122 fail("get parameter() rejected"); 123 } catch (IllegalStateException e) { 124 fail("get parameter() called in wrong state"); 125 } finally { 126 releaseEqualizer(); 127 } 128 } 129 130 //Test case 1.2: test presets 131 public void test1_2Presets() throws Exception { 132 getEqualizer(getSessionId()); 133 try { 134 short numPresets = mEqualizer.getNumberOfPresets(); 135 assertTrue("getNumberOfPresets failed", numPresets >= MIN_NUMBER_OF_PRESETS); 136 if (numPresets > 0) { 137 mEqualizer.usePreset((short)(numPresets - 1)); 138 short preset = mEqualizer.getCurrentPreset(); 139 assertEquals("usePreset failed", preset, (short)(numPresets - 1)); 140 String name = mEqualizer.getPresetName(preset); 141 assertNotNull("getPresetName failed", name); 142 } 143 144 } catch (IllegalArgumentException e) { 145 fail("Bad parameter value"); 146 } catch (UnsupportedOperationException e) { 147 fail("get parameter() rejected"); 148 } catch (IllegalStateException e) { 149 fail("get parameter() called in wrong state"); 150 } finally { 151 releaseEqualizer(); 152 } 153 } 154 155 //Test case 1.3: test properties 156 public void test1_3Properties() throws Exception { 157 getEqualizer(getSessionId()); 158 try { 159 Equalizer.Settings settings = mEqualizer.getProperties(); 160 assertTrue("no enough bands", settings.numBands >= MIN_NUMBER_OF_BANDS); 161 short newLevel = 0; 162 if (settings.bandLevels[0] == 0) { 163 newLevel = -600; 164 } 165 String str = settings.toString(); 166 settings = new Equalizer.Settings(str); 167 settings.curPreset = (short)-1; 168 settings.bandLevels[0] = newLevel; 169 mEqualizer.setProperties(settings); 170 settings = mEqualizer.getProperties(); 171 assertTrue("setProperties failed", 172 (settings.bandLevels[0] >= (newLevel - TOLERANCE)) && 173 (settings.bandLevels[0] <= (newLevel + TOLERANCE))); 174 175 } catch (IllegalArgumentException e) { 176 fail("Bad parameter value"); 177 } catch (UnsupportedOperationException e) { 178 fail("get parameter() rejected"); 179 } catch (IllegalStateException e) { 180 fail("get parameter() called in wrong state"); 181 } finally { 182 releaseEqualizer(); 183 } 184 } 185 186 //Test case 1.4: test setBandLevel() throws exception after release 187 public void test1_4SetBandLevelAfterRelease() throws Exception { 188 getEqualizer(getSessionId()); 189 mEqualizer.release(); 190 try { 191 mEqualizer.setBandLevel((short)0, (short)0); 192 } catch (IllegalStateException e) { 193 // test passed 194 } finally { 195 releaseEqualizer(); 196 } 197 } 198 199 //----------------------------------------------------------------- 200 // 2 - Effect enable/disable 201 //---------------------------------- 202 203 //Test case 2.0: test setEnabled() and getEnabled() in valid state 204 public void test2_0SetEnabledGetEnabled() throws Exception { 205 getEqualizer(getSessionId()); 206 try { 207 mEqualizer.setEnabled(true); 208 assertTrue("invalid state from getEnabled", mEqualizer.getEnabled()); 209 mEqualizer.setEnabled(false); 210 assertFalse("invalid state to getEnabled", mEqualizer.getEnabled()); 211 212 } catch (IllegalStateException e) { 213 fail("setEnabled() in wrong state"); 214 } finally { 215 releaseEqualizer(); 216 } 217 } 218 219 //Test case 2.1: test setEnabled() throws exception after release 220 public void test2_1SetEnabledAfterRelease() throws Exception { 221 getEqualizer(getSessionId()); 222 mEqualizer.release(); 223 try { 224 mEqualizer.setEnabled(true); 225 } catch (IllegalStateException e) { 226 // test passed 227 } finally { 228 releaseEqualizer(); 229 } 230 } 231 232 //----------------------------------------------------------------- 233 // 3 priority and listeners 234 //---------------------------------- 235 236 //Test case 3.0: test control status listener 237 public void test3_0ControlStatusListener() throws Exception { 238 synchronized(mLock) { 239 mHasControl = true; 240 mInitialized = false; 241 createListenerLooper(true, false, false); 242 waitForLooperInitialization_l(); 243 244 getEqualizer(mSession); 245 int looperWaitCount = MAX_LOOPER_WAIT_COUNT; 246 while (mHasControl && (looperWaitCount-- > 0)) { 247 try { 248 mLock.wait(); 249 } catch(Exception e) { 250 } 251 } 252 terminateListenerLooper(); 253 releaseEqualizer(); 254 } 255 assertFalse("effect control not lost by effect1", mHasControl); 256 } 257 258 //Test case 3.1: test enable status listener 259 public void test3_1EnableStatusListener() throws Exception { 260 synchronized(mLock) { 261 mInitialized = false; 262 createListenerLooper(false, true, false); 263 waitForLooperInitialization_l(); 264 265 mEqualizer2.setEnabled(true); 266 mIsEnabled = true; 267 getEqualizer(mSession); 268 mEqualizer.setEnabled(false); 269 int looperWaitCount = MAX_LOOPER_WAIT_COUNT; 270 while (mIsEnabled && (looperWaitCount-- > 0)) { 271 try { 272 mLock.wait(); 273 } catch(Exception e) { 274 } 275 } 276 terminateListenerLooper(); 277 releaseEqualizer(); 278 } 279 assertFalse("enable status not updated", mIsEnabled); 280 } 281 282 //Test case 3.2: test parameter changed listener 283 public void test3_2ParameterChangedListener() throws Exception { 284 synchronized(mLock) { 285 mInitialized = false; 286 createListenerLooper(false, false, true); 287 waitForLooperInitialization_l(); 288 289 getEqualizer(mSession); 290 mChangedParameter = -1; 291 mEqualizer.setBandLevel((short)0, (short)0); 292 293 int looperWaitCount = MAX_LOOPER_WAIT_COUNT; 294 while ((mChangedParameter == -1) && (looperWaitCount-- > 0)) { 295 try { 296 mLock.wait(); 297 } catch(Exception e) { 298 } 299 } 300 terminateListenerLooper(); 301 releaseEqualizer(); 302 } 303 assertEquals("parameter change not received", 304 Equalizer.PARAM_BAND_LEVEL, mChangedParameter); 305 } 306 307 //----------------------------------------------------------------- 308 // private methods 309 //---------------------------------- 310 311 private void getEqualizer(int session) { 312 if (mEqualizer == null || session != mSession) { 313 if (session != mSession && mEqualizer != null) { 314 mEqualizer.release(); 315 mEqualizer = null; 316 } 317 try { 318 mEqualizer = new Equalizer(0, session); 319 mSession = session; 320 } catch (IllegalArgumentException e) { 321 Log.e(TAG, "getEqualizer() Equalizer not found exception: "+e); 322 } catch (UnsupportedOperationException e) { 323 Log.e(TAG, "getEqualizer() Effect library not loaded exception: "+e); 324 } 325 } 326 assertNotNull("could not create mEqualizer", mEqualizer); 327 } 328 329 private void releaseEqualizer() { 330 if (mEqualizer != null) { 331 mEqualizer.release(); 332 mEqualizer = null; 333 } 334 } 335 336 private void waitForLooperInitialization_l() { 337 int looperWaitCount = MAX_LOOPER_WAIT_COUNT; 338 while (!mInitialized && (looperWaitCount-- > 0)) { 339 try { 340 mLock.wait(); 341 } catch(Exception e) { 342 } 343 } 344 assertTrue(mInitialized); 345 } 346 347 // Initializes the equalizer listener looper 348 class ListenerThread extends Thread { 349 boolean mControl; 350 boolean mEnable; 351 boolean mParameter; 352 353 public ListenerThread(boolean control, boolean enable, boolean parameter) { 354 super(); 355 mControl = control; 356 mEnable = enable; 357 mParameter = parameter; 358 } 359 360 public void cleanUp() { 361 if (mEqualizer2 != null) { 362 mEqualizer2.setControlStatusListener(null); 363 mEqualizer2.setEnableStatusListener(null); 364 mEqualizer2.setParameterListener((Equalizer.OnParameterChangeListener)null); 365 } 366 } 367 } 368 369 private void createListenerLooper(boolean control, boolean enable, boolean parameter) { 370 mEffectListenerLooper = new ListenerThread(control, enable, parameter) { 371 @Override 372 public void run() { 373 // Set up a looper 374 Looper.prepare(); 375 376 // Save the looper so that we can terminate this thread 377 // after we are done with it. 378 mLooper = Looper.myLooper(); 379 380 mSession = getSessionId(); 381 mEqualizer2 = new Equalizer(0, mSession); 382 assertNotNull("could not create Equalizer2", mEqualizer2); 383 384 synchronized(mLock) { 385 if (mControl) { 386 mEqualizer2.setControlStatusListener( 387 new AudioEffect.OnControlStatusChangeListener() { 388 public void onControlStatusChange( 389 AudioEffect effect, boolean controlGranted) { 390 synchronized(mLock) { 391 if (effect == mEqualizer2) { 392 mHasControl = controlGranted; 393 mLock.notify(); 394 } 395 } 396 } 397 }); 398 } 399 if (mEnable) { 400 mEqualizer2.setEnableStatusListener( 401 new AudioEffect.OnEnableStatusChangeListener() { 402 public void onEnableStatusChange(AudioEffect effect, boolean enabled) { 403 synchronized(mLock) { 404 if (effect == mEqualizer2) { 405 mIsEnabled = enabled; 406 mLock.notify(); 407 } 408 } 409 } 410 }); 411 } 412 if (mParameter) { 413 mEqualizer2.setParameterListener(new Equalizer.OnParameterChangeListener() { 414 public void onParameterChange(Equalizer effect, 415 int status, int param1, int param2, int value) 416 { 417 synchronized(mLock) { 418 if (effect == mEqualizer2) { 419 mChangedParameter = param1; 420 mLock.notify(); 421 } 422 } 423 } 424 }); 425 } 426 mInitialized = true; 427 mLock.notify(); 428 } 429 Looper.loop(); // Blocks forever until Looper.quit() is called. 430 } 431 }; 432 mEffectListenerLooper.start(); 433 } 434 435 // Terminates the listener looper thread. 436 private void terminateListenerLooper() { 437 if (mEffectListenerLooper != null) { 438 mEffectListenerLooper.cleanUp(); 439 if (mLooper != null) { 440 mLooper.quit(); 441 mLooper = null; 442 } 443 try { 444 mEffectListenerLooper.join(); 445 } catch(InterruptedException e) { 446 } 447 mEffectListenerLooper = null; 448 } 449 if (mEqualizer2 != null) { 450 mEqualizer2.release(); 451 mEqualizer2 = null; 452 } 453 } 454 } 455