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.cts.R; 20 21 import android.content.res.AssetFileDescriptor; 22 import android.media.audiofx.AudioEffect; 23 import android.media.AudioFormat; 24 import android.media.AudioManager; 25 import android.media.AudioRecord; 26 import android.media.AudioTrack; 27 import android.media.audiofx.PresetReverb; 28 import android.media.audiofx.EnvironmentalReverb; 29 import android.media.audiofx.Equalizer; 30 import android.media.MediaPlayer; 31 import android.media.MediaRecorder; 32 33 import android.os.Looper; 34 import android.test.AndroidTestCase; 35 import android.util.Log; 36 import java.util.UUID; 37 38 public class AudioEffectTest extends PostProcTestBase { 39 40 private String TAG = "AudioEffectTest"; 41 private final static int MIN_NUMBER_EFFECTS = 1; 42 // allow +/- 5% tolerance between set and get delays 43 private final static float DELAY_TOLERANCE = 1.05f; 44 // allow +/- 5% tolerance between set and get ratios 45 private final static float RATIO_TOLERANCE = 1.05f; 46 // AudioRecord sampling rate 47 private final static int SAMPLING_RATE = 44100; 48 49 private final static int MAX_LOOPER_WAIT_COUNT = 10; 50 51 private AudioEffect mEffect = null; 52 private AudioEffect mEffect2 = null; 53 private MediaPlayer mMediaPlayer = null; 54 private int mError = 0; 55 56 private ListenerThread mEffectListenerLooper = null; 57 58 //----------------------------------------------------------------- 59 // AUDIOEFFECT TESTS: 60 //---------------------------------- 61 62 @Override tearDown()63 protected void tearDown() throws Exception { 64 releaseEffect(); 65 terminateMediaPlayerLooper(); 66 terminateListenerLooper(); 67 } 68 69 //----------------------------------------------------------------- 70 // 0 - static methods 71 //---------------------------------- 72 73 //Test case 0.0: test queryEffects() and platfrom at least provides an Equalizer test0_0QueryEffects()74 public void test0_0QueryEffects() throws Exception { 75 76 AudioEffect.Descriptor[] desc = AudioEffect.queryEffects(); 77 78 assertTrue("test0_0QueryEffects: number of effects < MIN_NUMBER_EFFECTS: "+desc.length, 79 (desc.length >= MIN_NUMBER_EFFECTS)); 80 81 boolean hasEQ = false; 82 83 for (int i = 0; i < desc.length; i++) { 84 if (desc[i].type.equals(AudioEffect.EFFECT_TYPE_EQUALIZER)) { 85 hasEQ = true; 86 break; 87 } 88 } 89 assertTrue("test0_0QueryEffects: equalizer not found", hasEQ); 90 } 91 92 //----------------------------------------------------------------- 93 // 1 - constructor 94 //---------------------------------- 95 getAudioRecord()96 private AudioRecord getAudioRecord() { 97 AudioRecord ar = null; 98 try { 99 ar = new AudioRecord(MediaRecorder.AudioSource.DEFAULT, 100 SAMPLING_RATE, 101 AudioFormat.CHANNEL_CONFIGURATION_MONO, 102 AudioFormat.ENCODING_PCM_16BIT, 103 AudioRecord.getMinBufferSize(SAMPLING_RATE, 104 AudioFormat.CHANNEL_CONFIGURATION_MONO, 105 AudioFormat.ENCODING_PCM_16BIT) * 10); 106 assertNotNull("Could not create AudioRecord", ar); 107 assertEquals("AudioRecord not initialized", 108 AudioRecord.STATE_INITIALIZED, ar.getState()); 109 } catch (IllegalArgumentException e) { 110 fail("AudioRecord invalid parameter"); 111 } 112 return ar; 113 } 114 115 // // Test case 1.0: test constructor from effect type and get effect ID 116 // public void test1_0ConstructorFromType() ... 117 // Note: This test was removed because it used hidden api's. 118 119 120 // //Test case 1.1: test constructor from effect uuid 121 // public void test1_1ConstructorFromUuid() ... 122 // Note: This test was removed because: 123 // 1. will fail in devices that offload effects 124 // 2. it used hidden api's. 125 126 // //Test case 1.2: test constructor failure from unknown type 127 // public void test1_2ConstructorUnknownType() ... 128 // Note: This test was removed because it used hidden api's. 129 130 //Test case 1.3: test getEnabled() failure when called on released effect test1_3GetEnabledAfterRelease()131 public void test1_3GetEnabledAfterRelease() throws Exception { 132 try { 133 AudioEffect effect = new AudioEffect(AudioEffect.EFFECT_TYPE_EQUALIZER, 134 AudioEffect.EFFECT_TYPE_NULL, 135 0, 136 0); 137 assertNotNull("could not create AudioEffect", effect); 138 effect.release(); 139 try { 140 effect.getEnabled(); 141 fail("getEnabled() processed after release()"); 142 } catch (IllegalStateException e) { 143 144 } 145 } catch (IllegalArgumentException e) { 146 fail("AudioEffect not found"); 147 } catch (UnsupportedOperationException e) { 148 fail("Effect library not loaded"); 149 } 150 } 151 152 //Test case 1.4: test contructor on mediaPlayer audio session test1_4InsertOnMediaPlayer()153 public void test1_4InsertOnMediaPlayer() throws Exception { 154 MediaPlayer mp = new MediaPlayer(); 155 assertNotNull("could not create mediaplayer", mp); 156 AssetFileDescriptor afd = mContext.getResources().openRawResourceFd(R.raw.testmp3); 157 mp.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength()); 158 afd.close(); 159 getEffect(AudioEffect.EFFECT_TYPE_EQUALIZER, mp.getAudioSessionId()); 160 try { 161 mEffect.setEnabled(true); 162 163 } catch (IllegalStateException e) { 164 fail("AudioEffect not initialized"); 165 } finally { 166 mp.release(); 167 releaseEffect(); 168 } 169 } 170 171 //Test case 1.5: test auxiliary effect attachement on MediaPlayer test1_5AuxiliaryOnMediaPlayer()172 public void test1_5AuxiliaryOnMediaPlayer() throws Exception { 173 if (!isPresetReverbAvailable()) { 174 return; 175 } 176 synchronized(mLock) { 177 mInitialized = false; 178 createMediaPlayerLooper(); 179 waitForLooperInitialization_l(); 180 181 mError = 0; 182 AssetFileDescriptor afd = mContext.getResources().openRawResourceFd(R.raw.testmp3); 183 mMediaPlayer.setDataSource(afd.getFileDescriptor(), 184 afd.getStartOffset(), 185 afd.getLength()); 186 afd.close(); 187 getEffect(AudioEffect.EFFECT_TYPE_PRESET_REVERB, 0); 188 try { 189 try { 190 mMediaPlayer.attachAuxEffect(mEffect.getId()); 191 mMediaPlayer.setAuxEffectSendLevel(1.0f); 192 mLock.wait(1000); 193 } catch(Exception e) { 194 fail("Attach effect: wait was interrupted."); 195 } 196 assertTrue("error on attachAuxEffect", mError == 0); 197 } catch (IllegalStateException e) { 198 fail("attach aux effect failed"); 199 } finally { 200 terminateMediaPlayerLooper(); 201 releaseEffect(); 202 } 203 } 204 } 205 206 //Test case 1.6: test auxiliary effect attachement failure before setDatasource test1_6AuxiliaryOnMediaPlayerFailure()207 public void test1_6AuxiliaryOnMediaPlayerFailure() throws Exception { 208 if (!isPresetReverbAvailable()) { 209 return; 210 } 211 synchronized(mLock) { 212 mInitialized = false; 213 createMediaPlayerLooper(); 214 waitForLooperInitialization_l(); 215 216 getEffect(AudioEffect.EFFECT_TYPE_PRESET_REVERB, 0); 217 218 mError = 0; 219 int looperWaitCount = MAX_LOOPER_WAIT_COUNT; 220 while (mError == 0 && (looperWaitCount-- > 0)) { 221 try { 222 try { 223 mMediaPlayer.attachAuxEffect(mEffect.getId()); 224 } catch (IllegalStateException e) { 225 terminateMediaPlayerLooper(); 226 releaseEffect(); 227 fail("attach aux effect failed"); 228 } 229 mLock.wait(); 230 } catch(Exception e) { 231 } 232 } 233 assertTrue("no error on attachAuxEffect", mError != 0); 234 } 235 terminateMediaPlayerLooper(); 236 releaseEffect(); 237 } 238 239 240 //Test case 1.7: test auxiliary effect attachement on AudioTrack test1_7AuxiliaryOnAudioTrack()241 public void test1_7AuxiliaryOnAudioTrack() throws Exception { 242 if (!isPresetReverbAvailable()) { 243 return; 244 } 245 AudioTrack track = null; 246 getEffect(AudioEffect.EFFECT_TYPE_PRESET_REVERB, 0); 247 try { 248 track = new AudioTrack( 249 AudioManager.STREAM_MUSIC, 250 44100, 251 AudioFormat.CHANNEL_OUT_MONO, 252 AudioFormat.ENCODING_PCM_16BIT, 253 AudioTrack.getMinBufferSize(44100, 254 AudioFormat.CHANNEL_OUT_MONO, 255 AudioFormat.ENCODING_PCM_16BIT), 256 AudioTrack.MODE_STREAM); 257 assertNotNull("could not create AudioTrack", track); 258 259 int status = track.attachAuxEffect(mEffect.getId()); 260 if (status != AudioTrack.SUCCESS) { 261 fail("could not attach aux effect"); 262 } 263 status = track.setAuxEffectSendLevel(1.0f); 264 if (status != AudioTrack.SUCCESS) { 265 fail("could not set send level"); 266 } 267 } catch (IllegalStateException e) { 268 fail("could not attach aux effect"); 269 } catch (IllegalArgumentException e) { 270 fail("could not create AudioTrack"); 271 } finally { 272 if (track != null) { 273 track.release(); 274 } 275 releaseEffect(); 276 } 277 } 278 279 //----------------------------------------------------------------- 280 // 2 - enable/ disable 281 //---------------------------------- 282 283 284 //Test case 2.0: test setEnabled() and getEnabled() in valid state test2_0SetEnabledGetEnabled()285 public void test2_0SetEnabledGetEnabled() throws Exception { 286 try { 287 AudioEffect effect = new AudioEffect(AudioEffect.EFFECT_TYPE_EQUALIZER, 288 AudioEffect.EFFECT_TYPE_NULL, 289 0, 290 0); 291 assertNotNull("could not create AudioEffect", effect); 292 try { 293 effect.setEnabled(true); 294 assertTrue("invalid state from getEnabled", effect.getEnabled()); 295 effect.setEnabled(false); 296 assertFalse("invalid state to getEnabled", effect.getEnabled()); 297 298 } catch (IllegalStateException e) { 299 fail("setEnabled() in wrong state"); 300 } finally { 301 effect.release(); 302 } 303 } catch (IllegalArgumentException e) { 304 fail("AudioEffect not found"); 305 306 } catch (UnsupportedOperationException e) { 307 fail("Effect library not loaded"); 308 } 309 } 310 311 //Test case 2.1: test setEnabled() throws exception after release test2_1SetEnabledAfterRelease()312 public void test2_1SetEnabledAfterRelease() throws Exception { 313 try { 314 AudioEffect effect = new AudioEffect(AudioEffect.EFFECT_TYPE_EQUALIZER, 315 AudioEffect.EFFECT_TYPE_NULL, 316 0, 317 0); 318 assertNotNull("could not create AudioEffect", effect); 319 effect.release(); 320 try { 321 effect.setEnabled(true); 322 fail("setEnabled() processed after release"); 323 } catch (IllegalStateException e) { 324 // test passed 325 } 326 } catch (IllegalArgumentException e) { 327 fail("AudioEffect not found"); 328 } catch (UnsupportedOperationException e) { 329 fail("Effect library not loaded"); 330 } 331 } 332 333 //----------------------------------------------------------------- 334 // 3 - set/get parameters 335 //---------------------------------- 336 337 //Test case 3.0: test setParameter(byte[], byte[]) / getParameter(byte[], byte[]) test3_0SetParameterByteArrayByteArray()338 public void test3_0SetParameterByteArrayByteArray() throws Exception { 339 if (!isPresetReverbAvailable()) { 340 return; 341 } 342 getEffect(AudioEffect.EFFECT_TYPE_PRESET_REVERB, 0); 343 try { 344 byte[] param = mEffect.intToByteArray(PresetReverb.PARAM_PRESET); 345 byte[] value = new byte[2]; 346 int status = mEffect.getParameter(param, value); 347 assertFalse("getParameter 1 failed", AudioEffect.isError(status)); 348 short preset = PresetReverb.PRESET_SMALLROOM; 349 if (mEffect.byteArrayToShort(value) == preset) { 350 preset = PresetReverb.PRESET_MEDIUMROOM; 351 } 352 value = mEffect.shortToByteArray(preset); 353 status = mEffect.setParameter(param, value); 354 assertEquals("setParameter failed", AudioEffect.SUCCESS, status); 355 status = mEffect.getParameter(param, value); 356 assertFalse("getParameter 2 failed", AudioEffect.isError(status)); 357 assertEquals("get/set Parameter failed", preset, 358 mEffect.byteArrayToShort(value)); 359 360 } catch (IllegalArgumentException e) { 361 fail("Bad parameter value"); 362 } catch (UnsupportedOperationException e) { 363 fail("setParameter() rejected"); 364 } catch (IllegalStateException e) { 365 fail("setParameter() called in wrong state"); 366 } finally { 367 releaseEffect(); 368 } 369 } 370 371 //Test case 3.1: test setParameter(int, int) / getParameter(int, int[]) test3_1SetParameterIntInt()372 public void test3_1SetParameterIntInt() throws Exception { 373 if (!isEnvReverbAvailable()) { 374 return; 375 } 376 getEffect(AudioEffect.EFFECT_TYPE_ENV_REVERB, 0); 377 try { 378 int param = EnvironmentalReverb.PARAM_DECAY_TIME; 379 int[] value = new int[1]; 380 int status = mEffect.getParameter(param, value); 381 assertFalse("getParameter 1 failed", AudioEffect.isError(status)); 382 int time = 500; 383 if (value[0] == time) { 384 time = 1000; 385 } 386 status = mEffect.setParameter(param, time); 387 assertEquals("setParameter failed", AudioEffect.SUCCESS, status); 388 status = mEffect.getParameter(param, value); 389 assertFalse("getParameter 2 failed", AudioEffect.isError(status)); 390 assertTrue("got incorrect decay time", 391 ((float)value[0] > (float)(time / DELAY_TOLERANCE)) && 392 ((float)value[0] < (float)(time * DELAY_TOLERANCE))); 393 394 } catch (IllegalArgumentException e) { 395 fail("Bad parameter value"); 396 } catch (UnsupportedOperationException e) { 397 fail("setParameter() rejected"); 398 } catch (IllegalStateException e) { 399 fail("setParameter() called in wrong state"); 400 } finally { 401 releaseEffect(); 402 } 403 } 404 405 //Test case 3.2: test setParameter(int, short) / getParameter(int, short[]) test3_2SetParameterIntShort()406 public void test3_2SetParameterIntShort() throws Exception { 407 if (!isPresetReverbAvailable()) { 408 return; 409 } 410 getEffect(AudioEffect.EFFECT_TYPE_PRESET_REVERB, 0); 411 try { 412 int param = PresetReverb.PARAM_PRESET; 413 short[] value = new short[1]; 414 int status = mEffect.getParameter(param, value); 415 assertFalse("getParameter 1 failed", AudioEffect.isError(status)); 416 short preset = PresetReverb.PRESET_SMALLROOM; 417 if (value[0] == preset) { 418 preset = PresetReverb.PRESET_MEDIUMROOM; 419 } 420 status = mEffect.setParameter(param, preset); 421 assertEquals("setParameter failed", AudioEffect.SUCCESS, status); 422 status = mEffect.getParameter(param, value); 423 assertFalse("getParameter 2 failed", AudioEffect.isError(status)); 424 assertEquals("get/set Parameter failed", preset, value[0]); 425 426 } catch (IllegalArgumentException e) { 427 fail("Bad parameter value"); 428 } catch (UnsupportedOperationException e) { 429 fail("setParameter() rejected"); 430 } catch (IllegalStateException e) { 431 fail("setParameter() called in wrong state"); 432 } finally { 433 releaseEffect(); 434 } 435 } 436 437 //Test case 3.3: test setParameter(int, byte[]) / getParameter(int, byte[]) test3_3SetParameterIntByteArray()438 public void test3_3SetParameterIntByteArray() throws Exception { 439 if (!isEnvReverbAvailable()) { 440 return; 441 } 442 getEffect(AudioEffect.EFFECT_TYPE_ENV_REVERB, 0); 443 try { 444 int param = EnvironmentalReverb.PARAM_DECAY_TIME; 445 byte[] value = new byte[4]; 446 int status = mEffect.getParameter(param, value); 447 assertFalse("getParameter 1 failed", AudioEffect.isError(status)); 448 int time = 500; 449 if (mEffect.byteArrayToInt(value) == time) { 450 time = 1000; 451 } 452 value = mEffect.intToByteArray(time); 453 status = mEffect.setParameter(param, value); 454 assertEquals("setParameter failed", AudioEffect.SUCCESS, status); 455 status = mEffect.getParameter(param, value); 456 assertFalse("getParameter 2 failed", AudioEffect.isError(status)); 457 int time2 = mEffect.byteArrayToInt(value); 458 assertTrue("got incorrect decay time", 459 ((float)time2 > (float)(time / DELAY_TOLERANCE)) && 460 ((float)time2 < (float)(time * DELAY_TOLERANCE))); 461 462 } catch (IllegalArgumentException e) { 463 fail("Bad parameter value"); 464 } catch (UnsupportedOperationException e) { 465 fail("setParameter() rejected"); 466 } catch (IllegalStateException e) { 467 fail("setParameter() called in wrong state"); 468 } finally { 469 releaseEffect(); 470 } 471 } 472 473 //Test case 3.4: test setParameter(int[], int[]) / getParameter(int[], int[]) test3_4SetParameterIntArrayIntArray()474 public void test3_4SetParameterIntArrayIntArray() throws Exception { 475 if (!isEnvReverbAvailable()) { 476 return; 477 } 478 getEffect(AudioEffect.EFFECT_TYPE_ENV_REVERB, 0); 479 try { 480 int[] param = new int[1]; 481 int[] value = new int[1]; 482 param[0] = EnvironmentalReverb.PARAM_DECAY_TIME; 483 int status = mEffect.getParameter(param, value); 484 assertFalse("getParameter 1 failed", AudioEffect.isError(status)); 485 int[] time = new int[1]; 486 time[0] = 500; 487 if (value[0] == time[0]) { 488 time[0] = 1000; 489 } 490 status = mEffect.setParameter(param, time); 491 assertEquals("setParameter failed", AudioEffect.SUCCESS, status); 492 status = mEffect.getParameter(param, value); 493 assertFalse("getParameter 2 failed", AudioEffect.isError(status)); 494 assertTrue("got incorrect decay time", 495 ((float)value[0] > (float)(time[0] / DELAY_TOLERANCE)) && 496 ((float)value[0] < (float)(time[0] * DELAY_TOLERANCE))); 497 498 } catch (IllegalArgumentException e) { 499 fail("Bad parameter value"); 500 } catch (UnsupportedOperationException e) { 501 fail("setParameter() rejected"); 502 } catch (IllegalStateException e) { 503 fail("setParameter() called in wrong state"); 504 } finally { 505 releaseEffect(); 506 } 507 } 508 509 //Test case 3.5: test setParameter(int[], short[]) / getParameter(int[], short[]) 510 test3_5SetParameterIntArrayShortArray()511 public void test3_5SetParameterIntArrayShortArray() throws Exception { 512 if (!isPresetReverbAvailable()) { 513 return; 514 } 515 getEffect(AudioEffect.EFFECT_TYPE_PRESET_REVERB, 0); 516 try { 517 int[] param = new int[1]; 518 param[0] = PresetReverb.PARAM_PRESET; 519 short[] value = new short[1]; 520 int status = mEffect.getParameter(param, value); 521 assertFalse("getParameter 1 failed", AudioEffect.isError(status)); 522 short[] preset = new short[1]; 523 preset[0] = PresetReverb.PRESET_SMALLROOM; 524 if (value[0] == preset[0]) { 525 preset[0] = PresetReverb.PRESET_MEDIUMROOM; 526 } 527 status = mEffect.setParameter(param, preset); 528 assertEquals("setParameter failed", AudioEffect.SUCCESS, status); 529 status = mEffect.getParameter(param, value); 530 assertFalse("getParameter 2 failed", AudioEffect.isError(status)); 531 assertEquals("get/set Parameter failed", preset[0], value[0]); 532 533 } catch (IllegalArgumentException e) { 534 fail("Bad parameter value"); 535 } catch (UnsupportedOperationException e) { 536 fail("setParameter() rejected"); 537 } catch (IllegalStateException e) { 538 fail("setParameter() called in wrong state"); 539 } finally { 540 releaseEffect(); 541 } 542 } 543 544 //Test case 3.6: test setParameter(int[], byte[]) / getParameter(int[], byte[]) test3_6SetParameterIntArrayByteArray()545 public void test3_6SetParameterIntArrayByteArray() throws Exception { 546 if (!isEnvReverbAvailable()) { 547 return; 548 } 549 getEffect(AudioEffect.EFFECT_TYPE_ENV_REVERB, 0); 550 try { 551 int[] param = new int[1]; 552 param[0] = EnvironmentalReverb.PARAM_DECAY_TIME; 553 byte[] value = new byte[4]; 554 int status = mEffect.getParameter(param, value); 555 assertFalse("getParameter 1 failed", AudioEffect.isError(status)); 556 int time = 500; 557 if (mEffect.byteArrayToInt(value) == time) { 558 time = 1000; 559 } 560 561 status = mEffect.setParameter(param, mEffect.intToByteArray(time)); 562 assertEquals("setParameter failed", AudioEffect.SUCCESS, status); 563 status = mEffect.getParameter(param, value); 564 assertFalse("getParameter 2 failed", AudioEffect.isError(status)); 565 int time2 = mEffect.byteArrayToInt(value); 566 assertTrue("got incorrect decay time", 567 ((float)time2 > (float)(time / DELAY_TOLERANCE)) && 568 ((float)time2 < (float)(time * DELAY_TOLERANCE))); 569 570 } catch (IllegalArgumentException e) { 571 fail("Bad parameter value"); 572 } catch (UnsupportedOperationException e) { 573 fail("setParameter() rejected"); 574 } catch (IllegalStateException e) { 575 fail("setParameter() called in wrong state"); 576 } finally { 577 releaseEffect(); 578 } 579 } 580 581 //Test case 3.7: test setParameter() throws exception after release() test3_7SetParameterAfterRelease()582 public void test3_7SetParameterAfterRelease() throws Exception { 583 if (!isPresetReverbAvailable()) { 584 return; 585 } 586 AudioEffect effect = null; 587 try { 588 effect = new AudioEffect(AudioEffect.EFFECT_TYPE_PRESET_REVERB, 589 AudioEffect.EFFECT_TYPE_NULL, 590 0, 591 0); 592 assertNotNull("could not create AudioEffect", effect); 593 effect.release(); 594 effect.setParameter(PresetReverb.PARAM_PRESET, PresetReverb.PRESET_SMALLROOM); 595 fail("setParameter() processed after release"); 596 } catch (IllegalArgumentException e) { 597 fail("Bad parameter value"); 598 } catch (UnsupportedOperationException e) { 599 fail("setParameter() rejected"); 600 } catch (IllegalStateException e) { 601 // test passed 602 } finally { 603 if (effect != null) { 604 effect.release(); 605 } 606 } 607 } 608 609 //Test case 3.8: test getParameter() throws exception after release() test3_8GetParameterAfterRelease()610 public void test3_8GetParameterAfterRelease() throws Exception { 611 if (!isPresetReverbAvailable()) { 612 return; 613 } 614 AudioEffect effect = null; 615 try { 616 effect = new AudioEffect(AudioEffect.EFFECT_TYPE_PRESET_REVERB, 617 AudioEffect.EFFECT_TYPE_NULL, 618 0, 619 0); 620 assertNotNull("could not create AudioEffect", effect); 621 effect.release(); 622 short[] value = new short[1]; 623 effect.getParameter(PresetReverb.PARAM_PRESET, value); 624 fail("getParameter() processed after release"); 625 } catch (IllegalArgumentException e) { 626 fail("Bad parameter value"); 627 } catch (UnsupportedOperationException e) { 628 fail("getParameter() rejected"); 629 } catch (IllegalStateException e) { 630 // test passed 631 } finally { 632 if (effect != null) { 633 effect.release(); 634 } 635 } 636 } 637 638 //----------------------------------------------------------------- 639 // 4 priority and listeners 640 //---------------------------------- 641 642 //Test case 4.0: test control passed to higher priority client test4_0setEnabledLowerPriority()643 public void test4_0setEnabledLowerPriority() throws Exception { 644 AudioEffect effect1 = null; 645 AudioEffect effect2 = null; 646 try { 647 effect1 = new AudioEffect(AudioEffect.EFFECT_TYPE_EQUALIZER, 648 AudioEffect.EFFECT_TYPE_NULL, 649 0, 650 0); 651 effect2 = new AudioEffect(AudioEffect.EFFECT_TYPE_EQUALIZER, 652 AudioEffect.EFFECT_TYPE_NULL, 653 1, 654 0); 655 656 assertNotNull("could not create AudioEffect", effect1); 657 assertNotNull("could not create AudioEffect", effect2); 658 659 assertTrue("Effect2 does not have control", effect2.hasControl()); 660 assertFalse("Effect1 has control", effect1.hasControl()); 661 assertTrue("Effect1 can enable", 662 effect1.setEnabled(true) == AudioEffect.ERROR_INVALID_OPERATION); 663 assertFalse("Effect1 has enabled", effect2.getEnabled()); 664 665 } catch (IllegalArgumentException e) { 666 fail("Effect not found"); 667 } catch (UnsupportedOperationException e) { 668 fail("Effect library not loaded"); 669 } finally { 670 if (effect1 != null) { 671 effect1.release(); 672 } 673 if (effect2 != null) { 674 effect2.release(); 675 } 676 } 677 } 678 679 //Test case 4.1: test control passed to higher priority client test4_1setParameterLowerPriority()680 public void test4_1setParameterLowerPriority() throws Exception { 681 if (!isPresetReverbAvailable()) { 682 return; 683 } 684 AudioEffect effect1 = null; 685 AudioEffect effect2 = null; 686 try { 687 effect1 = new AudioEffect(AudioEffect.EFFECT_TYPE_PRESET_REVERB, 688 AudioEffect.EFFECT_TYPE_NULL, 689 0, 690 0); 691 effect2 = new AudioEffect(AudioEffect.EFFECT_TYPE_PRESET_REVERB, 692 AudioEffect.EFFECT_TYPE_NULL, 693 1, 694 0); 695 696 assertNotNull("could not create AudioEffect", effect1); 697 assertNotNull("could not create AudioEffect", effect2); 698 699 int status = effect2.setParameter(PresetReverb.PARAM_PRESET, 700 PresetReverb.PRESET_SMALLROOM); 701 assertEquals("Effect2 setParameter failed", 702 AudioEffect.SUCCESS, status); 703 704 status = effect1.setParameter(PresetReverb.PARAM_PRESET, 705 PresetReverb.PRESET_MEDIUMROOM); 706 assertEquals("Effect1 setParameter did not fail", 707 AudioEffect.ERROR_INVALID_OPERATION, status); 708 709 short[] value = new short[1]; 710 status = effect2.getParameter(PresetReverb.PARAM_PRESET, value); 711 assertFalse("Effect2 getParameter failed", 712 AudioEffect.isError(status)); 713 assertEquals("Effect1 changed parameter", PresetReverb.PRESET_SMALLROOM 714 , value[0]); 715 716 717 } catch (IllegalArgumentException e) { 718 fail("Effect not found"); 719 } catch (UnsupportedOperationException e) { 720 fail("Effect library not loaded"); 721 } finally { 722 if (effect1 != null) { 723 effect1.release(); 724 } 725 if (effect2 != null) { 726 effect2.release(); 727 } 728 } 729 } 730 731 //Test case 4.2: test control status listener test4_2ControlStatusListener()732 public void test4_2ControlStatusListener() throws Exception { 733 if (!isPresetReverbAvailable()) { 734 return; 735 } 736 synchronized(mLock) { 737 mHasControl = true; 738 mInitialized = false; 739 createListenerLooper(true, false, false); 740 waitForLooperInitialization_l(); 741 742 getEffect(AudioEffect.EFFECT_TYPE_PRESET_REVERB, 0); 743 int looperWaitCount = MAX_LOOPER_WAIT_COUNT; 744 while (mHasControl && (looperWaitCount-- > 0)) { 745 try { 746 mLock.wait(); 747 } catch(Exception e) { 748 } 749 } 750 terminateListenerLooper(); 751 releaseEffect(); 752 } 753 assertFalse("effect control not lost by effect1", mHasControl); 754 } 755 756 //Test case 4.3: test enable status listener test4_3EnableStatusListener()757 public void test4_3EnableStatusListener() throws Exception { 758 if (!isPresetReverbAvailable()) { 759 return; 760 } 761 synchronized(mLock) { 762 mInitialized = false; 763 createListenerLooper(false, true, false); 764 waitForLooperInitialization_l(); 765 766 mEffect2.setEnabled(true); 767 mIsEnabled = true; 768 769 getEffect(AudioEffect.EFFECT_TYPE_PRESET_REVERB, 0); 770 assertTrue("effect not enabled", mEffect.getEnabled()); 771 int looperWaitCount = MAX_LOOPER_WAIT_COUNT; 772 while (mIsEnabled && (looperWaitCount-- > 0)) { 773 try { 774 mEffect.setEnabled(false); 775 mLock.wait(); 776 } catch(Exception e) { 777 } 778 } 779 terminateListenerLooper(); 780 releaseEffect(); 781 } 782 assertFalse("enable status not updated", mIsEnabled); 783 } 784 785 //Test case 4.4: test parameter changed listener test4_4ParameterChangedListener()786 public void test4_4ParameterChangedListener() throws Exception { 787 if (!isPresetReverbAvailable()) { 788 return; 789 } 790 synchronized(mLock) { 791 mInitialized = false; 792 createListenerLooper(false, false, true); 793 waitForLooperInitialization_l(); 794 int status = mEffect2.setParameter(PresetReverb.PARAM_PRESET, 795 PresetReverb.PRESET_SMALLROOM); 796 assertEquals("mEffect2 setParameter failed", 797 AudioEffect.SUCCESS, status); 798 getEffect(AudioEffect.EFFECT_TYPE_PRESET_REVERB, 0); 799 mChangedParameter = -1; 800 mEffect.setParameter(PresetReverb.PARAM_PRESET, 801 PresetReverb.PRESET_MEDIUMROOM); 802 int looperWaitCount = MAX_LOOPER_WAIT_COUNT; 803 while (mChangedParameter == -1 && (looperWaitCount-- > 0)) { 804 try { 805 mLock.wait(); 806 } catch(Exception e) { 807 } 808 } 809 terminateListenerLooper(); 810 releaseEffect(); 811 } 812 assertEquals("parameter change not received", 813 PresetReverb.PARAM_PRESET, mChangedParameter); 814 } 815 816 //----------------------------------------------------------------- 817 // 5 command method 818 //---------------------------------- 819 820 821 //Test case 5.0: test command method test5_0Command()822 public void test5_0Command() throws Exception { 823 if (!isPresetReverbAvailable()) { 824 return; 825 } 826 getEffect(AudioEffect.EFFECT_TYPE_PRESET_REVERB, 0); 827 try { 828 byte[] cmd = new byte[0]; 829 byte[] reply = new byte[4]; 830 // command 3 is ENABLE 831 int status = mEffect.command(3, cmd, reply); 832 assertFalse("command failed", AudioEffect.isError(status)); 833 assertTrue("effect not enabled", mEffect.getEnabled()); 834 835 } catch (IllegalStateException e) { 836 fail("command in illegal state"); 837 } finally { 838 releaseEffect(); 839 } 840 } 841 842 843 //----------------------------------------------------------------- 844 // private methods 845 //---------------------------------- 846 getEffect(UUID type, int session)847 private void getEffect(UUID type, int session) { 848 if (mEffect == null || session != mSession) { 849 if (session != mSession && mEffect != null) { 850 mEffect.release(); 851 mEffect = null; 852 } 853 try { 854 mEffect = new AudioEffect(type, 855 AudioEffect.EFFECT_TYPE_NULL, 856 0, 857 session); 858 mSession = session; 859 } catch (IllegalArgumentException e) { 860 Log.e(TAG, "getEffect() AudioEffect not found exception: "+e); 861 } catch (UnsupportedOperationException e) { 862 Log.e(TAG, "getEffect() Effect library not loaded exception: "+e); 863 } 864 } 865 assertNotNull("could not create mEffect", mEffect); 866 } 867 releaseEffect()868 private void releaseEffect() { 869 if (mEffect != null) { 870 mEffect.release(); 871 mEffect = null; 872 } 873 } 874 waitForLooperInitialization_l()875 private void waitForLooperInitialization_l() { 876 int looperWaitCount = MAX_LOOPER_WAIT_COUNT; 877 while (!mInitialized && (looperWaitCount-- > 0)) { 878 try { 879 mLock.wait(); 880 } catch(Exception e) { 881 } 882 } 883 assertTrue(mInitialized); 884 } 885 886 // Initializes the equalizer listener looper 887 class ListenerThread extends Thread { 888 boolean mControl; 889 boolean mEnable; 890 boolean mParameter; 891 ListenerThread(boolean control, boolean enable, boolean parameter)892 public ListenerThread(boolean control, boolean enable, boolean parameter) { 893 super(); 894 mControl = control; 895 mEnable = enable; 896 mParameter = parameter; 897 } 898 cleanUp()899 public void cleanUp() { 900 if (mEffect2 != null) { 901 mEffect2.setControlStatusListener(null); 902 mEffect2.setEnableStatusListener(null); 903 mEffect2.setParameterListener(null); 904 } 905 } 906 } 907 createListenerLooper(boolean control, boolean enable, boolean parameter)908 private void createListenerLooper(boolean control, boolean enable, boolean parameter) { 909 mEffectListenerLooper = new ListenerThread(control, enable, parameter) { 910 @Override 911 public void run() { 912 // Set up a looper 913 Looper.prepare(); 914 915 // Save the looper so that we can terminate this thread 916 // after we are done with it. 917 mLooper = Looper.myLooper(); 918 919 mEffect2 = new AudioEffect(AudioEffect.EFFECT_TYPE_PRESET_REVERB, 920 AudioEffect.EFFECT_TYPE_NULL, 921 0, 922 0); 923 assertNotNull("could not create Equalizer2", mEffect2); 924 925 synchronized(mLock) { 926 if (mControl) { 927 mEffect2.setControlStatusListener( 928 new AudioEffect.OnControlStatusChangeListener() { 929 public void onControlStatusChange( 930 AudioEffect effect, boolean controlGranted) { 931 synchronized(mLock) { 932 if (effect == mEffect2) { 933 mHasControl = controlGranted; 934 mLock.notify(); 935 } 936 } 937 } 938 }); 939 } 940 if (mEnable) { 941 mEffect2.setEnableStatusListener( 942 new AudioEffect.OnEnableStatusChangeListener() { 943 public void onEnableStatusChange(AudioEffect effect, boolean enabled) { 944 synchronized(mLock) { 945 if (effect == mEffect2) { 946 mIsEnabled = enabled; 947 mLock.notify(); 948 } 949 } 950 } 951 }); 952 } 953 if (mParameter) { 954 mEffect2.setParameterListener(new AudioEffect.OnParameterChangeListener() { 955 public void onParameterChange(AudioEffect effect, int status, byte[] param, 956 byte[] value) 957 { 958 synchronized(mLock) { 959 if (effect == mEffect2) { 960 mChangedParameter = mEffect2.byteArrayToInt(param); 961 mLock.notify(); 962 } 963 } 964 } 965 }); 966 } 967 mInitialized = true; 968 mLock.notify(); 969 } 970 Looper.loop(); // Blocks forever until Looper.quit() is called. 971 } 972 }; 973 mEffectListenerLooper.start(); 974 } 975 976 // Terminates the listener looper thread. terminateListenerLooper()977 private void terminateListenerLooper() { 978 if (mEffectListenerLooper != null) { 979 mEffectListenerLooper.cleanUp(); 980 if (mLooper != null) { 981 mLooper.quit(); 982 mLooper = null; 983 } 984 try { 985 mEffectListenerLooper.join(); 986 } catch(InterruptedException e) { 987 } 988 mEffectListenerLooper = null; 989 } 990 if (mEffect2 != null) { 991 mEffect2.release(); 992 mEffect2 = null; 993 } 994 } 995 996 /* 997 * Initializes the message looper so that the MediaPlayer object can 998 * receive the callback messages. 999 */ createMediaPlayerLooper()1000 private void createMediaPlayerLooper() { 1001 new Thread() { 1002 @Override 1003 public void run() { 1004 // Set up a looper to be used by mMediaPlayer. 1005 Looper.prepare(); 1006 1007 // Save the looper so that we can terminate this thread 1008 // after we are done with it. 1009 mLooper = Looper.myLooper(); 1010 1011 mMediaPlayer = new MediaPlayer(); 1012 1013 synchronized(mLock) { 1014 mMediaPlayer.setOnErrorListener(new MediaPlayer.OnErrorListener() { 1015 public boolean onError(MediaPlayer player, int what, int extra) { 1016 synchronized(mLock) { 1017 mError = what; 1018 mLock.notify(); 1019 } 1020 return true; 1021 } 1022 }); 1023 mMediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() { 1024 public void onCompletion(MediaPlayer player) { 1025 synchronized(mLock) { 1026 mLock.notify(); 1027 } 1028 } 1029 }); 1030 mInitialized = true; 1031 mLock.notify(); 1032 } 1033 Looper.loop(); // Blocks forever until Looper.quit() is called. 1034 } 1035 }.start(); 1036 } 1037 /* 1038 * Terminates the message looper thread. 1039 */ terminateMediaPlayerLooper()1040 private void terminateMediaPlayerLooper() { 1041 if (mLooper != null) { 1042 mLooper.quit(); 1043 mLooper = null; 1044 } 1045 if (mMediaPlayer != null) { 1046 mMediaPlayer.release(); 1047 } 1048 } 1049 1050 } 1051