Home | History | Annotate | Download | only in audio
      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 com.android.mediaframeworktest.functional.audio;
     18 
     19 import com.android.mediaframeworktest.MediaFrameworkTest;
     20 import com.android.mediaframeworktest.MediaNames;
     21 import com.android.mediaframeworktest.functional.EnergyProbe;
     22 import android.content.Context;
     23 import android.content.res.AssetFileDescriptor;
     24 import android.media.audiofx.AudioEffect;
     25 import android.media.AudioManager;
     26 import android.media.audiofx.PresetReverb;
     27 import android.media.audiofx.Visualizer;
     28 import android.media.MediaPlayer;
     29 
     30 import android.os.Looper;
     31 import android.test.suitebuilder.annotation.LargeTest;
     32 import android.test.suitebuilder.annotation.MediumTest;
     33 import android.test.suitebuilder.annotation.Suppress;
     34 import android.test.ActivityInstrumentationTestCase2;
     35 import android.util.Log;
     36 
     37 import java.nio.ByteOrder;
     38 import java.nio.ByteBuffer;
     39 import java.util.UUID;
     40 
     41 /**
     42  * Junit / Instrumentation test case for the media AudioTrack api
     43 
     44  */
     45 public 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