MediaVirtualizerTest.java revision db6028508c8eb31a0de1dcdfc410ddfe6df7c5ad
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.Virtualizer;
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 MediaVirtualizerTest extends ActivityInstrumentationTestCase2<MediaFrameworkTest> {
46    private String TAG = "MediaVirtualizerTest";
47    private final static int MIN_ENERGY_RATIO_2 = 3;
48    private final static short TEST_STRENGTH = 500;
49    private final static int TEST_VOLUME = 4;
50
51    private Virtualizer mVirtualizer = null;
52    private int mSession = -1;
53
54    public MediaVirtualizerTest() {
55        super("com.android.mediaframeworktest", MediaFrameworkTest.class);
56    }
57
58    @Override
59    protected void setUp() throws Exception {
60      super.setUp();
61    }
62
63    @Override
64    protected void tearDown() throws Exception {
65        super.tearDown();
66        releaseVirtualizer();
67    }
68
69    private static void assumeTrue(String message, boolean cond) {
70        assertTrue("(assume)"+message, cond);
71    }
72
73    private void log(String testName, String message) {
74        Log.v(TAG, "["+testName+"] "+message);
75    }
76
77    private void loge(String testName, String message) {
78        Log.e(TAG, "["+testName+"] "+message);
79    }
80
81    //-----------------------------------------------------------------
82    // VIRTUALIZER TESTS:
83    //----------------------------------
84
85
86    //-----------------------------------------------------------------
87    // 0 - constructor
88    //----------------------------------
89
90    //Test case 0.0: test constructor and release
91    @LargeTest
92    public void test0_0ConstructorAndRelease() throws Exception {
93        boolean result = false;
94        String msg = "test1_0ConstructorAndRelease()";
95        Virtualizer virtualizer = null;
96         try {
97            virtualizer = new Virtualizer(0, 0);
98            assertNotNull(msg + ": could not create Virtualizer", virtualizer);
99            try {
100                assertTrue(msg +": invalid effect ID", (virtualizer.getId() != 0));
101            } catch (IllegalStateException e) {
102                msg = msg.concat(": Virtualizer not initialized");
103            }
104            result = true;
105        } catch (IllegalArgumentException e) {
106            msg = msg.concat(": Virtualizer not found");
107        } catch (UnsupportedOperationException e) {
108            msg = msg.concat(": Effect library not loaded");
109        } finally {
110            if (virtualizer != null) {
111                virtualizer.release();
112            }
113        }
114        assertTrue(msg, result);
115    }
116
117
118    //-----------------------------------------------------------------
119    // 1 - get/set parameters
120    //----------------------------------
121
122    //Test case 1.0: test strength
123    @LargeTest
124    public void test1_0Strength() throws Exception {
125        boolean result = false;
126        String msg = "test1_0Strength()";
127        getVirtualizer(0);
128        try {
129            if (mVirtualizer.getStrengthSupported()) {
130                mVirtualizer.setStrength((short)TEST_STRENGTH);
131                short strength = mVirtualizer.getRoundedStrength();
132                // allow 10% difference between set strength and rounded strength
133                assertTrue(msg +": got incorrect strength",
134                        ((float)strength > (float)TEST_STRENGTH * 0.9f) &&
135                        ((float)strength < (float)TEST_STRENGTH * 1.1f));
136            } else {
137                short strength = mVirtualizer.getRoundedStrength();
138                assertTrue(msg +": got incorrect strength", strength >= 0 && strength <= 1000);
139            }
140            result = true;
141        } catch (IllegalArgumentException e) {
142            msg = msg.concat(": Bad parameter value");
143            loge(msg, "Bad parameter value");
144        } catch (UnsupportedOperationException e) {
145            msg = msg.concat(": get parameter() rejected");
146            loge(msg, "get parameter() rejected");
147        } catch (IllegalStateException e) {
148            msg = msg.concat("get parameter() called in wrong state");
149            loge(msg, "get parameter() called in wrong state");
150        } finally {
151            releaseVirtualizer();
152        }
153        assertTrue(msg, result);
154    }
155
156    //Test case 1.1: test properties
157    @LargeTest
158    public void test1_1Properties() throws Exception {
159        boolean result = false;
160        String msg = "test1_1Properties()";
161        getVirtualizer(0);
162        try {
163            Virtualizer.Settings settings = mVirtualizer.getProperties();
164            String str = settings.toString();
165            settings = new Virtualizer.Settings(str);
166            mVirtualizer.setProperties(settings);
167            result = true;
168        } catch (IllegalArgumentException e) {
169            msg = msg.concat(": Bad parameter value");
170            loge(msg, "Bad parameter value");
171        } catch (UnsupportedOperationException e) {
172            msg = msg.concat(": get parameter() rejected");
173            loge(msg, "get parameter() rejected");
174        } catch (IllegalStateException e) {
175            msg = msg.concat("get parameter() called in wrong state");
176            loge(msg, "get parameter() called in wrong state");
177        } finally {
178            releaseVirtualizer();
179        }
180        assertTrue(msg, result);
181    }
182
183    //-----------------------------------------------------------------
184    // 2 - Effect action
185    //----------------------------------
186
187    //Test case 2.0: test actual virtualizer influence on sound
188    @LargeTest
189    public void test2_0SoundModification() throws Exception {
190        boolean result = false;
191        String msg = "test2_0SoundModification()";
192        EnergyProbe probe = null;
193        AudioEffect vc = null;
194        MediaPlayer mp = null;
195        AudioManager am = (AudioManager) getActivity().getSystemService(Context.AUDIO_SERVICE);
196        int volume = am.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
197        am.setStreamVolume(AudioManager.STREAM_MUSIC,
198                           TEST_VOLUME,
199                           0);
200
201        try {
202            probe = new EnergyProbe(0);
203            // creating a volume controller on output mix ensures that ro.audio.silent mutes
204            // audio after the effects and not before
205            vc = new AudioEffect(
206                    AudioEffect.EFFECT_TYPE_NULL,
207                    UUID.fromString("119341a0-8469-11df-81f9-0002a5d5c51b"),
208                      0,
209                      0);
210            vc.setEnabled(true);
211
212            mp = new MediaPlayer();
213            mp.setDataSource(MediaNames.SINE_200_1000);
214            mp.setAudioStreamType(AudioManager.STREAM_MUSIC);
215            getVirtualizer(mp.getAudioSessionId());
216            mp.prepare();
217            mp.start();
218            Thread.sleep(200);
219            // measure reference energy around 1kHz
220            int refEnergy200 = probe.capture(200);
221            int refEnergy1000 = probe.capture(1000);
222            mVirtualizer.setStrength((short)1000);
223            mVirtualizer.setEnabled(true);
224            Thread.sleep(500);
225            // measure energy around 1kHz with band level at min
226            int energy200 = probe.capture(200);
227            int energy1000 = probe.capture(1000);
228            // verify that the energy ration between low and high frequencies is at least
229            // MIN_ENERGY_RATIO_2 times higher with virtualizer on.
230            // NOTE: this is what is observed with current virtualizer implementation and the test
231            // audio file but is not the primary effect of the virtualizer. A better way would
232            // be to have a stereo PCM capture and check that a strongly paned input is centered
233            // when output. However, we cannot capture stereo with the visualizer.
234            assertTrue(msg + ": virtiualizer has no effect",
235                    ((float)energy200/(float)energy1000) >
236                    (MIN_ENERGY_RATIO_2 * ((float)refEnergy200/(float)refEnergy1000)));
237            result = true;
238        } catch (IllegalArgumentException e) {
239            msg = msg.concat(": Bad parameter value");
240            loge(msg, "Bad parameter value");
241        } catch (UnsupportedOperationException e) {
242            msg = msg.concat(": get parameter() rejected");
243            loge(msg, "get parameter() rejected");
244        } catch (IllegalStateException e) {
245            msg = msg.concat("get parameter() called in wrong state");
246            loge(msg, "get parameter() called in wrong state");
247        } catch (InterruptedException e) {
248            loge(msg, "sleep() interrupted");
249        }
250        finally {
251            releaseVirtualizer();
252            if (mp != null) {
253                mp.release();
254            }
255            if (vc != null) {
256                vc.release();
257            }
258            if (probe != null) {
259                probe.release();
260            }
261            am.setStreamVolume(AudioManager.STREAM_MUSIC, volume, 0);
262        }
263        assertTrue(msg, result);
264    }
265    //-----------------------------------------------------------------
266    // private methods
267    //----------------------------------
268
269    private void getVirtualizer(int session) {
270         if (mVirtualizer == null || session != mSession) {
271             if (session != mSession && mVirtualizer != null) {
272                 mVirtualizer.release();
273                 mVirtualizer = null;
274             }
275             try {
276                mVirtualizer = new Virtualizer(0, session);
277                mSession = session;
278            } catch (IllegalArgumentException e) {
279                Log.e(TAG, "getVirtualizer() Virtualizer not found exception: "+e);
280            } catch (UnsupportedOperationException e) {
281                Log.e(TAG, "getVirtualizer() Effect library not loaded exception: "+e);
282            }
283         }
284         assertNotNull("could not create mVirtualizer", mVirtualizer);
285    }
286
287    private void releaseVirtualizer() {
288        if (mVirtualizer != null) {
289            mVirtualizer.release();
290            mVirtualizer = null;
291        }
292   }
293
294}
295