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 17package com.android.mediaframeworktest.functional.audio; 18 19import com.android.mediaframeworktest.MediaFrameworkTest; 20import com.android.mediaframeworktest.MediaNames; 21import com.android.mediaframeworktest.functional.EnergyProbe; 22import android.content.Context; 23import android.content.res.AssetFileDescriptor; 24import android.media.audiofx.AudioEffect; 25import android.media.AudioManager; 26import android.media.audiofx.PresetReverb; 27import android.media.audiofx.Visualizer; 28import android.media.MediaPlayer; 29 30import android.os.Looper; 31import android.test.suitebuilder.annotation.LargeTest; 32import android.test.suitebuilder.annotation.MediumTest; 33import android.test.suitebuilder.annotation.Suppress; 34import android.test.ActivityInstrumentationTestCase2; 35import android.util.Log; 36 37import java.nio.ByteOrder; 38import java.nio.ByteBuffer; 39import java.util.UUID; 40 41/** 42 * Junit / Instrumentation test case for the media AudioTrack api 43 44 */ 45public class MediaPresetReverbTest extends ActivityInstrumentationTestCase2<MediaFrameworkTest> { 46 private String TAG = "MediaPresetReverbTest"; 47 // Implementor UUID for volume controller effect defined in 48 // frameworks/base/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp 49 private final static UUID VOLUME_EFFECT_UUID = 50 UUID.fromString("119341a0-8469-11df-81f9-0002a5d5c51b"); 51 // Implementor UUID for preset reverb effect defined in 52 // frameworks/base/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp 53 private final static UUID PRESET_REVERB_EFFECT_UUID = 54 UUID.fromString("172cdf00-a3bc-11df-a72f-0002a5d5c51b"); 55 56 private PresetReverb mReverb = null; 57 private int mSession = -1; 58 59 public MediaPresetReverbTest() { 60 super("com.android.mediaframeworktest", MediaFrameworkTest.class); 61 } 62 63 @Override 64 protected void setUp() throws Exception { 65 super.setUp(); 66 } 67 68 @Override 69 protected void tearDown() throws Exception { 70 super.tearDown(); 71 releaseReverb(); 72 } 73 74 private static void assumeTrue(String message, boolean cond) { 75 assertTrue("(assume)"+message, cond); 76 } 77 78 private void log(String testName, String message) { 79 Log.v(TAG, "["+testName+"] "+message); 80 } 81 82 private void loge(String testName, String message) { 83 Log.e(TAG, "["+testName+"] "+message); 84 } 85 86 //----------------------------------------------------------------- 87 // PRESET REVEB TESTS: 88 //---------------------------------- 89 90 91 //----------------------------------------------------------------- 92 // 0 - constructor 93 //---------------------------------- 94 95 //Test case 0.0: test constructor and release 96 @LargeTest 97 public void test0_0ConstructorAndRelease() throws Exception { 98 boolean result = false; 99 String msg = "test1_0ConstructorAndRelease()"; 100 PresetReverb reverb = null; 101 try { 102 reverb = new PresetReverb(0, 0); 103 assertNotNull(msg + ": could not create PresetReverb", reverb); 104 try { 105 assertTrue(msg +": invalid effect ID", (reverb.getId() != 0)); 106 } catch (IllegalStateException e) { 107 msg = msg.concat(": PresetReverb not initialized"); 108 } 109 result = true; 110 } catch (IllegalArgumentException e) { 111 msg = msg.concat(": PresetReverb not found"); 112 } catch (UnsupportedOperationException e) { 113 msg = msg.concat(": Effect library not loaded"); 114 } finally { 115 if (reverb != null) { 116 reverb.release(); 117 } 118 } 119 assertTrue(msg, result); 120 } 121 122 //----------------------------------------------------------------- 123 // 1 - get/set parameters 124 //---------------------------------- 125 126 //Test case 1.0: test preset 127 @LargeTest 128 public void test1_0Preset() throws Exception { 129 boolean result = false; 130 String msg = "test1_0Preset()"; 131 getReverb(0); 132 try { 133 mReverb.setPreset((short)PresetReverb.PRESET_LARGEROOM); 134 short preset = mReverb.getPreset(); 135 assertEquals(msg +": got incorrect preset", 136 (short)PresetReverb.PRESET_LARGEROOM, 137 preset); 138 result = true; 139 } catch (IllegalArgumentException e) { 140 msg = msg.concat(": Bad parameter value"); 141 loge(msg, "Bad parameter value"); 142 } catch (UnsupportedOperationException e) { 143 msg = msg.concat(": get parameter() rejected"); 144 loge(msg, "get parameter() rejected"); 145 } catch (IllegalStateException e) { 146 msg = msg.concat("get parameter() called in wrong state"); 147 loge(msg, "get parameter() called in wrong state"); 148 } finally { 149 releaseReverb(); 150 } 151 assertTrue(msg, result); 152 } 153 154 //Test case 1.1: test properties 155 @LargeTest 156 public void test1_1Properties() throws Exception { 157 boolean result = false; 158 String msg = "test1_1Properties()"; 159 getReverb(0); 160 try { 161 PresetReverb.Settings settings = mReverb.getProperties(); 162 short newPreset = (short)PresetReverb.PRESET_LARGEROOM; 163 if (settings.preset == (short)PresetReverb.PRESET_LARGEROOM) { 164 newPreset = (short)PresetReverb.PRESET_SMALLROOM; 165 } 166 String str = settings.toString(); 167 settings = new PresetReverb.Settings(str); 168 settings.preset = newPreset; 169 mReverb.setProperties(settings); 170 settings = mReverb.getProperties(); 171 assertEquals(msg +": setProperties failed", newPreset, settings.preset); 172 result = true; 173 } catch (IllegalArgumentException e) { 174 msg = msg.concat(": Bad parameter value"); 175 loge(msg, "Bad parameter value"); 176 } catch (UnsupportedOperationException e) { 177 msg = msg.concat(": get parameter() rejected"); 178 loge(msg, "get parameter() rejected"); 179 } catch (IllegalStateException e) { 180 msg = msg.concat("get parameter() called in wrong state"); 181 loge(msg, "get parameter() called in wrong state"); 182 } finally { 183 releaseReverb(); 184 } 185 assertTrue(msg, result); 186 } 187 188 //----------------------------------------------------------------- 189 // 2 - Effect action 190 //---------------------------------- 191 192 //Test case 2.0: test actual auxiliary reverb influence on sound 193 @LargeTest 194 public void test2_0AuxiliarySoundModification() throws Exception { 195 boolean result = false; 196 String msg = "test2_0AuxiliarySoundModification()"; 197 EnergyProbe probe = null; 198 AudioEffect vc = null; 199 MediaPlayer mp = null; 200 AudioManager am = (AudioManager) getActivity().getSystemService(Context.AUDIO_SERVICE); 201 int ringerMode = am.getRingerMode(); 202 am.setRingerMode(AudioManager.RINGER_MODE_NORMAL); 203 int volume = am.getStreamMaxVolume(AudioManager.STREAM_MUSIC); 204 am.setStreamVolume(AudioManager.STREAM_MUSIC, 205 am.getStreamMaxVolume(AudioManager.STREAM_MUSIC), 206 0); 207 getReverb(0); 208 try { 209 probe = new EnergyProbe(0); 210 // creating a volume controller on output mix ensures that ro.audio.silent mutes 211 // audio after the effects and not before 212 vc = new AudioEffect( 213 AudioEffect.EFFECT_TYPE_NULL, 214 VOLUME_EFFECT_UUID, 215 0, 216 0); 217 vc.setEnabled(true); 218 219 mp = new MediaPlayer(); 220 mp.setDataSource(MediaNames.SINE_200_1000); 221 mp.setAudioStreamType(AudioManager.STREAM_MUSIC); 222 mp.attachAuxEffect(mReverb.getId()); 223 mp.setAuxEffectSendLevel(1.0f); 224 mReverb.setPreset((short)PresetReverb.PRESET_PLATE); 225 mReverb.setEnabled(true); 226 mp.prepare(); 227 mp.start(); 228 Thread.sleep(1000); 229 mp.stop(); 230 Thread.sleep(200); 231 // measure energy around 1kHz after media player was stopped for 200 ms 232 int energy1000 = probe.capture(1000); 233 assertTrue(msg + ": reverb has no effect", energy1000 > 0); 234 result = true; 235 } catch (IllegalArgumentException e) { 236 msg = msg.concat(": Bad parameter value"); 237 loge(msg, "Bad parameter value"); 238 } catch (UnsupportedOperationException e) { 239 msg = msg.concat(": get parameter() rejected"); 240 loge(msg, "get parameter() rejected"); 241 } catch (IllegalStateException e) { 242 msg = msg.concat("get parameter() called in wrong state"); 243 loge(msg, "get parameter() called in wrong state"); 244 } catch (InterruptedException e) { 245 loge(msg, "sleep() interrupted"); 246 } 247 finally { 248 releaseReverb(); 249 if (mp != null) { 250 mp.release(); 251 } 252 if (vc != null) { 253 vc.release(); 254 } 255 if (probe != null) { 256 probe.release(); 257 } 258 am.setStreamVolume(AudioManager.STREAM_MUSIC, volume, 0); 259 am.setRingerMode(ringerMode); 260 } 261 assertTrue(msg, result); 262 } 263 264 //Test case 2.1: test actual insert reverb influence on sound 265 @LargeTest 266 public void test2_1InsertSoundModification() throws Exception { 267 boolean result = false; 268 String msg = "test2_1InsertSoundModification()"; 269 EnergyProbe probe = null; 270 AudioEffect vc = null; 271 MediaPlayer mp = null; 272 AudioEffect rvb = null; 273 AudioManager am = (AudioManager) getActivity().getSystemService(Context.AUDIO_SERVICE); 274 int ringerMode = am.getRingerMode(); 275 am.setRingerMode(AudioManager.RINGER_MODE_NORMAL); 276 int volume = am.getStreamMaxVolume(AudioManager.STREAM_MUSIC); 277 am.setStreamVolume(AudioManager.STREAM_MUSIC, 278 am.getStreamMaxVolume(AudioManager.STREAM_MUSIC), 279 0); 280 try { 281 // creating a volume controller on output mix ensures that ro.audio.silent mutes 282 // audio after the effects and not before 283 vc = new AudioEffect( 284 AudioEffect.EFFECT_TYPE_NULL, 285 VOLUME_EFFECT_UUID, 286 0, 287 0); 288 vc.setEnabled(true); 289 290 mp = new MediaPlayer(); 291 mp.setDataSource(MediaNames.SINE_200_1000); 292 mp.setAudioStreamType(AudioManager.STREAM_MUSIC); 293 294 // create reverb with UUID instead of PresetReverb constructor otherwise an auxiliary 295 // reverb will be chosen by the effect framework as we are on session 0 296 rvb = new AudioEffect( 297 AudioEffect.EFFECT_TYPE_NULL, 298 PRESET_REVERB_EFFECT_UUID, 299 0, 300 0); 301 302 rvb.setParameter(PresetReverb.PARAM_PRESET, PresetReverb.PRESET_PLATE); 303 rvb.setEnabled(true); 304 305 // create probe after reverb so that it is chained behind the reverb in the 306 // effect chain 307 probe = new EnergyProbe(0); 308 309 mp.prepare(); 310 mp.start(); 311 Thread.sleep(1000); 312 mp.stop(); 313 Thread.sleep(200); 314 // measure energy around 1kHz after media player was stopped for 200 ms 315 int energy1000 = probe.capture(1000); 316 assertTrue(msg + ": reverb has no effect", energy1000 > 0); 317 result = true; 318 } catch (IllegalArgumentException e) { 319 msg = msg.concat(": Bad parameter value"); 320 loge(msg, "Bad parameter value"); 321 } catch (UnsupportedOperationException e) { 322 msg = msg.concat(": get parameter() rejected"); 323 loge(msg, "get parameter() rejected"); 324 } catch (IllegalStateException e) { 325 msg = msg.concat("get parameter() called in wrong state"); 326 loge(msg, "get parameter() called in wrong state"); 327 } catch (InterruptedException e) { 328 loge(msg, "sleep() interrupted"); 329 } 330 finally { 331 if (mp != null) { 332 mp.release(); 333 } 334 if (vc != null) { 335 vc.release(); 336 } 337 if (rvb != null) { 338 rvb.release(); 339 } 340 if (probe != null) { 341 probe.release(); 342 } 343 am.setStreamVolume(AudioManager.STREAM_MUSIC, volume, 0); 344 am.setRingerMode(ringerMode); 345 } 346 assertTrue(msg, result); 347 } 348 349 //----------------------------------------------------------------- 350 // private methods 351 //---------------------------------- 352 353 private void getReverb(int session) { 354 if (mReverb == null || session != mSession) { 355 if (session != mSession && mReverb != null) { 356 mReverb.release(); 357 mReverb = null; 358 } 359 try { 360 mReverb = new PresetReverb(0, session); 361 mSession = session; 362 } catch (IllegalArgumentException e) { 363 Log.e(TAG, "getReverb() PresetReverb not found exception: "+e); 364 } catch (UnsupportedOperationException e) { 365 Log.e(TAG, "getReverb() Effect library not loaded exception: "+e); 366 } 367 } 368 assertNotNull("could not create mReverb", mReverb); 369 } 370 371 private void releaseReverb() { 372 if (mReverb != null) { 373 mReverb.release(); 374 mReverb = null; 375 } 376 } 377 378} 379