Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 67400d49 authored by Eric Laurent's avatar Eric Laurent Committed by Android (Google) Code Review
Browse files

Merge "Added tests for audio effects in MediaFrameworkTest" into gingerbread

parents 2a6b80bc 441ec6bd
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -25,6 +25,11 @@ import com.android.mediaframeworktest.functional.MediaRecorderTest;
import com.android.mediaframeworktest.functional.SimTonesTest;
import com.android.mediaframeworktest.functional.MediaPlayerInvokeTest;
import com.android.mediaframeworktest.functional.MediaAudioManagerTest;
import com.android.mediaframeworktest.functional.MediaAudioEffectTest;
import com.android.mediaframeworktest.functional.MediaBassBoostTest;
import com.android.mediaframeworktest.functional.MediaEqualizerTest;
import com.android.mediaframeworktest.functional.MediaVirtualizerTest;
import com.android.mediaframeworktest.functional.MediaVisualizerTest;
import junit.framework.TestSuite;

import android.test.InstrumentationTestRunner;
@@ -55,6 +60,11 @@ public class MediaFrameworkTestRunner extends InstrumentationTestRunner {
        suite.addTestSuite(MediaMimeTest.class);
        suite.addTestSuite(MediaPlayerInvokeTest.class);
        suite.addTestSuite(MediaAudioManagerTest.class);
        suite.addTestSuite(MediaAudioEffectTest.class);
        suite.addTestSuite(MediaBassBoostTest.class);
        suite.addTestSuite(MediaEqualizerTest.class);
        suite.addTestSuite(MediaVirtualizerTest.class);
        suite.addTestSuite(MediaVisualizerTest.class);
        return suite;
    }

+1 −0
Original line number Diff line number Diff line
@@ -35,6 +35,7 @@ public class MediaNames {
    public static final String WAV = "/sdcard/media_api/music/rings_2ch.wav";
    public static final String AMR = "/sdcard/media_api/music/test_amr_ietf.amr";
    public static final String OGG = "/sdcard/media_api/music/Revelation.ogg";
    public static final String SINE_200_1000 = "/sdcard/media_api/music/sine_200+1000Hz_44K_mo.wav";
  
    public static final int MP3CBR_LENGTH = 71000;
    public static final int MP3VBR_LENGTH = 71000;
+1492 −0

File added.

Preview size limit exceeded, changes collapsed.

+334 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2010 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.mediaframeworktest.functional;

import com.android.mediaframeworktest.MediaFrameworkTest;
import com.android.mediaframeworktest.MediaNames;
import android.content.Context;
import android.content.res.AssetFileDescriptor;
import android.media.AudioEffect;
import android.media.AudioManager;
import android.media.BassBoost;
import android.media.Visualizer;
import android.media.MediaPlayer;

import android.os.Looper;
import android.test.suitebuilder.annotation.LargeTest;
import android.test.suitebuilder.annotation.MediumTest;
import android.test.suitebuilder.annotation.Suppress;
import android.test.ActivityInstrumentationTestCase2;
import android.util.Log;

import java.nio.ByteOrder;
import java.nio.ByteBuffer;
import java.util.UUID;

/**
 * Junit / Instrumentation test case for the media AudioTrack api

 */
public class MediaBassBoostTest extends ActivityInstrumentationTestCase2<MediaFrameworkTest> {
    private String TAG = "MediaBassBoostTest";
    private final static int MIN_ENERGY_RATIO_2 = 4;
    private final static short TEST_STRENGTH = 500;

    private BassBoost mBassBoost = null;
    private int mSession = -1;

    public MediaBassBoostTest() {
        super("com.android.mediaframeworktest", MediaFrameworkTest.class);
    }

    @Override
    protected void setUp() throws Exception {
      super.setUp();
    }

    @Override
    protected void tearDown() throws Exception {
        super.tearDown();
        releaseBassBoost();
    }

    private static void assumeTrue(String message, boolean cond) {
        assertTrue("(assume)"+message, cond);
    }

    private void log(String testName, String message) {
        Log.v(TAG, "["+testName+"] "+message);
    }

    private void loge(String testName, String message) {
        Log.e(TAG, "["+testName+"] "+message);
    }

    //-----------------------------------------------------------------
    // BASS BOOST TESTS:
    //----------------------------------


    //-----------------------------------------------------------------
    // 0 - constructor
    //----------------------------------

    //Test case 0.0: test constructor and release
    @LargeTest
    public void test0_0ConstructorAndRelease() throws Exception {
        boolean result = false;
        String msg = "test1_0ConstructorAndRelease()";
        BassBoost bb = null;
         try {
            bb = new BassBoost(0, 0);
            assertNotNull(msg + ": could not create BassBoost", bb);
            try {
                assertTrue(msg +": invalid effect ID", (bb.getId() != 0));
            } catch (IllegalStateException e) {
                msg = msg.concat(": BassBoost not initialized");
            }
            result = true;
        } catch (IllegalArgumentException e) {
            msg = msg.concat(": BassBoost not found");
        } catch (UnsupportedOperationException e) {
            msg = msg.concat(": Effect library not loaded");
        } finally {
            if (bb != null) {
                bb.release();
            }
        }
        assertTrue(msg, result);
    }

    //-----------------------------------------------------------------
    // 1 - get/set parameters
    //----------------------------------

    //Test case 1.0: test strength
    @LargeTest
    public void test1_0Strength() throws Exception {
        boolean result = false;
        String msg = "test1_0Strength()";
        getBassBoost(0);
        try {
            if (mBassBoost.getStrengthSupported()) {
                mBassBoost.setStrength((short)TEST_STRENGTH);
                short strength = mBassBoost.getRoundedStrength();
                // allow 10% difference between set strength and rounded strength
                assertTrue(msg +": got incorrect strength",
                        ((float)strength > (float)TEST_STRENGTH * 0.9f) &&
                        ((float)strength < (float)TEST_STRENGTH * 1.1f));
            } else {
                short strength = mBassBoost.getRoundedStrength();
                assertTrue(msg +": got incorrect strength", strength >= 0 && strength <= 1000);
            }
            result = true;
        } catch (IllegalArgumentException e) {
            msg = msg.concat(": Bad parameter value");
            loge(msg, "Bad parameter value");
        } catch (UnsupportedOperationException e) {
            msg = msg.concat(": get parameter() rejected");
            loge(msg, "get parameter() rejected");
        } catch (IllegalStateException e) {
            msg = msg.concat("get parameter() called in wrong state");
            loge(msg, "get parameter() called in wrong state");
        } finally {
            releaseBassBoost();
        }
        assertTrue(msg, result);
    }

    //Test case 1.1: test properties
    @LargeTest
    public void test1_1Properties() throws Exception {
        boolean result = false;
        String msg = "test1_1Properties()";
        getBassBoost(0);
        try {
            BassBoost.Settings settings = mBassBoost.getProperties();
            String str = settings.toString();
            settings = new BassBoost.Settings(str);
            mBassBoost.setProperties(settings);
            result = true;
        } catch (IllegalArgumentException e) {
            msg = msg.concat(": Bad parameter value");
            loge(msg, "Bad parameter value");
        } catch (UnsupportedOperationException e) {
            msg = msg.concat(": get parameter() rejected");
            loge(msg, "get parameter() rejected");
        } catch (IllegalStateException e) {
            msg = msg.concat("get parameter() called in wrong state");
            loge(msg, "get parameter() called in wrong state");
        } finally {
            releaseBassBoost();
        }
        assertTrue(msg, result);
    }

    //-----------------------------------------------------------------
    // 2 - Effect action
    //----------------------------------

    //Test case 2.0: test actual bass boost influence on sound
    @LargeTest
    public void test2_0SoundModification() throws Exception {
        boolean result = false;
        String msg = "test2_0SoundModification()";
        EnergyProbe probe = null;
        AudioEffect vc = null;
        MediaPlayer mp = null;
        AudioManager am = (AudioManager) getActivity().getSystemService(Context.AUDIO_SERVICE);
        int volume = am.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
        am.setStreamVolume(AudioManager.STREAM_MUSIC,
                           am.getStreamMaxVolume(AudioManager.STREAM_MUSIC),
                           0);

        try {
            probe = new EnergyProbe(0);
            // creating a volume controller on output mix ensures that ro.audio.silent mutes
            // audio after the effects and not before
            vc = new AudioEffect(
                    AudioEffect.EFFECT_TYPE_NULL,
                    UUID.fromString("119341a0-8469-11df-81f9-0002a5d5c51b"),
                      0,
                      0);
            vc.setEnabled(true);

            mp = new MediaPlayer();
            mp.setDataSource(MediaNames.SINE_200_1000);
            mp.setAudioStreamType(AudioManager.STREAM_MUSIC);
            getBassBoost(mp.getAudioSessionId());
            mp.prepare();
            mp.start();
            Thread.sleep(200);
            // measure reference energy around 1kHz
            int refEnergy200 = probe.capture(200);
            int refEnergy1000 = probe.capture(1000);
            mBassBoost.setStrength((short)1000);
            mBassBoost.setEnabled(true);
            Thread.sleep(500);
            // measure energy around 1kHz with band level at min
            int energy200 = probe.capture(200);
            int energy1000 = probe.capture(1000);
            // verify that the energy ration between low and high frequencies is at least
            // MIN_ENERGY_RATIO_2 times higher with bassboost on.
            assertTrue(msg + ": bass boost has no effect",
                    ((float)energy200/(float)energy1000) >
                    (MIN_ENERGY_RATIO_2 * ((float)refEnergy200/(float)refEnergy1000)));
            result = true;
        } catch (IllegalArgumentException e) {
            msg = msg.concat(": Bad parameter value");
            loge(msg, "Bad parameter value");
        } catch (UnsupportedOperationException e) {
            msg = msg.concat(": get parameter() rejected");
            loge(msg, "get parameter() rejected");
        } catch (IllegalStateException e) {
            msg = msg.concat("get parameter() called in wrong state");
            loge(msg, "get parameter() called in wrong state");
        } catch (InterruptedException e) {
            loge(msg, "sleep() interrupted");
        }
        finally {
            releaseBassBoost();
            if (mp != null) {
                mp.release();
            }
            if (vc != null) {
                vc.release();
            }
            if (probe != null) {
                probe.release();
            }
            am.setStreamVolume(AudioManager.STREAM_MUSIC, volume, 0);
        }
        assertTrue(msg, result);
    }
    //-----------------------------------------------------------------
    // private methods
    //----------------------------------

    private class EnergyProbe {
        Visualizer mVisualizer = null;
        private byte[] mFft = new byte[1024];

        public EnergyProbe(int session) {
            mVisualizer = new Visualizer(session);
            mVisualizer.setCaptureSize(1024);
        }

        public int capture(int freq) throws InterruptedException {
            int energy = 0;
            int count = 0;
            if (mVisualizer != null) {
                mVisualizer.setEnabled(true);
                for (int i = 0; i < 10; i++) {
                    if (mVisualizer.getFft(mFft) == Visualizer.SUCCESS) {
                        // TODO: check speex FFT as it seems to return only the number of points
                        // correspondong to valid part of the spectrum (< Fs).
                        // e.g., if the number of points is 1024, it covers the frequency range
                        // 0 to 22050 instead of 0 to 44100 as expected from an FFT.
                        int bin = freq / (22050 / 1024);
                        int tmp = 0;
                        for (int j = bin-2; j < bin+3; j++) {
                            tmp += (int)mFft[j] * (int)mFft[j];
                        }
                        energy += tmp/5;
                        count++;
                    }
                    Thread.sleep(50);
                }
                mVisualizer.setEnabled(false);
            }
            if (count == 0) {
                return 0;
            }
            return energy/count;
        }

        public void release() {
            if (mVisualizer != null) {
                mVisualizer.release();
                mVisualizer = null;
            }
        }
    }

    private void getBassBoost(int session) {
         if (mBassBoost == null || session != mSession) {
             if (session != mSession && mBassBoost != null) {
                 mBassBoost.release();
                 mBassBoost = null;
             }
             try {
                mBassBoost = new BassBoost(0, session);
                mSession = session;
            } catch (IllegalArgumentException e) {
                Log.e(TAG, "getBassBoost() BassBoost not found exception: "+e);
            } catch (UnsupportedOperationException e) {
                Log.e(TAG, "getBassBoost() Effect library not loaded exception: "+e);
            }
         }
         assertNotNull("could not create mBassBoost", mBassBoost);
    }

    private void releaseBassBoost() {
        if (mBassBoost != null) {
            mBassBoost.release();
            mBassBoost = null;
        }
   }

}
+397 −0

File added.

Preview size limit exceeded, changes collapsed.

Loading