1441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent/*
2441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent * Copyright (C) 2010 The Android Open Source Project
3441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent *
4441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent * Licensed under the Apache License, Version 2.0 (the "License");
5441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent * you may not use this file except in compliance with the License.
6441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent * You may obtain a copy of the License at
7441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent *
8441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent *      http://www.apache.org/licenses/LICENSE-2.0
9441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent *
10441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent * Unless required by applicable law or agreed to in writing, software
11441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent * distributed under the License is distributed on an "AS IS" BASIS,
12441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent * See the License for the specific language governing permissions and
14441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent * limitations under the License.
15441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent */
16441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent
17db6028508c8eb31a0de1dcdfc410ddfe6df7c5adXia Wangpackage com.android.mediaframeworktest.functional.audio;
18441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent
19441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurentimport com.android.mediaframeworktest.MediaFrameworkTest;
20441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurentimport com.android.mediaframeworktest.MediaNames;
21441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurentimport android.content.Context;
22441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurentimport android.content.res.AssetFileDescriptor;
231a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurentimport android.media.audiofx.AudioEffect;
24441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurentimport android.media.AudioManager;
251a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurentimport android.media.audiofx.Visualizer;
26441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurentimport android.media.MediaPlayer;
27441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent
28441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurentimport android.os.Looper;
29441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurentimport android.test.suitebuilder.annotation.LargeTest;
30441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurentimport android.test.suitebuilder.annotation.MediumTest;
31441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurentimport android.test.suitebuilder.annotation.Suppress;
32441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurentimport android.test.ActivityInstrumentationTestCase2;
33441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurentimport android.util.Log;
34441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent
35441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurentimport java.nio.ByteOrder;
36441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurentimport java.nio.ByteBuffer;
37441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurentimport java.util.UUID;
38441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent
39441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent/**
40441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent * Junit / Instrumentation test case for the media AudioTrack api
41441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent
42441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent */
43441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurentpublic class MediaVisualizerTest extends ActivityInstrumentationTestCase2<MediaFrameworkTest> {
44441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent    private String TAG = "MediaVisualizerTest";
45441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent    private final static int MIN_CAPTURE_RATE_MAX = 20000;
46441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent    private final static int MIN_SAMPLING_RATE = 8000000;
47441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent    private final static int MAX_SAMPLING_RATE = 48000000;
48441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent    private final static int MIN_CAPTURE_SIZE_MAX = 1024;
49441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent    private final static int MAX_CAPTURE_SIZE_MIN = 128;
505e7acae2c3e4cf345e3fa7bf10e3c62f9e69e6beEric Laurent    // Implementor UUID for volume controller effect defined in
515e7acae2c3e4cf345e3fa7bf10e3c62f9e69e6beEric Laurent    // frameworks/base/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp
525e7acae2c3e4cf345e3fa7bf10e3c62f9e69e6beEric Laurent    private final static UUID VOLUME_EFFECT_UUID =
535e7acae2c3e4cf345e3fa7bf10e3c62f9e69e6beEric Laurent        UUID.fromString("119341a0-8469-11df-81f9-0002a5d5c51b");
54441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent
55441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent    private Visualizer mVisualizer = null;
56441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent    private int mSession = -1;
57441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent    private boolean mInitialized = false;
58441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent    private Looper mLooper = null;
59441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent    private final Object lock = new Object();
60441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent    private byte[] mWaveform = null;
61441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent    private byte[] mFft = null;
62441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent    private boolean mCaptureWaveform = false;
63441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent    private boolean mCaptureFft = false;
64441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent
65441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent    public MediaVisualizerTest() {
66441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent        super("com.android.mediaframeworktest", MediaFrameworkTest.class);
67441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent    }
68441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent
69441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent    @Override
70441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent    protected void setUp() throws Exception {
71441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent      super.setUp();
72441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent    }
73441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent
74441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent    @Override
75441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent    protected void tearDown() throws Exception {
76441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent        super.tearDown();
77441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent        releaseVisualizer();
78441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent    }
79441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent
80441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent    private static void assumeTrue(String message, boolean cond) {
81441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent        assertTrue("(assume)"+message, cond);
82441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent    }
83441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent
84441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent    private void log(String testName, String message) {
85441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent        Log.v(TAG, "["+testName+"] "+message);
86441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent    }
87441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent
88441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent    private void loge(String testName, String message) {
89441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent        Log.e(TAG, "["+testName+"] "+message);
90441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent    }
91441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent
92441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent    //-----------------------------------------------------------------
93441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent    // VISUALIZER TESTS:
94441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent    //----------------------------------
95441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent
96441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent
97441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent    //-----------------------------------------------------------------
98441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent    // 0 - constructor
99441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent    //----------------------------------
100441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent
101441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent    //Test case 0.0: test constructor and release
102441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent    @LargeTest
103441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent    public void test0_0ConstructorAndRelease() throws Exception {
104441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent        boolean result = false;
105441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent        String msg = "test1_0ConstructorAndRelease()";
106441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent        Visualizer visualizer = null;
107441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent         try {
108441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent            visualizer = new Visualizer(0);
109441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent            assertNotNull(msg + ": could not create Visualizer", visualizer);
110441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent            result = true;
111441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent        } catch (IllegalArgumentException e) {
112441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent            msg = msg.concat(": Visualizer not found");
113441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent        } catch (UnsupportedOperationException e) {
114441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent            msg = msg.concat(": Effect library not loaded");
115441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent        } finally {
116441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent            if (visualizer != null) {
117441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent                visualizer.release();
118441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent            }
119441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent        }
120441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent        assertTrue(msg, result);
121441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent    }
122441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent
123441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent
124441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent    //-----------------------------------------------------------------
125441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent    // 1 - get/set parameters
126441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent    //----------------------------------
127441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent
128441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent    //Test case 1.0: check capture rate and sampling rate
129441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent    @LargeTest
130441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent    public void test1_0CaptureRates() throws Exception {
131441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent        boolean result = false;
132441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent        String msg = "test1_0CaptureRates()";
133441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent        getVisualizer(0);
134441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent        try {
135441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent            int captureRate = mVisualizer.getMaxCaptureRate();
136441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent            assertTrue(msg +": insufficient max capture rate",
137441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent                    captureRate >= MIN_CAPTURE_RATE_MAX);
138441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent            int samplingRate = mVisualizer.getSamplingRate();
139441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent            assertTrue(msg +": invalid sampling rate",
140441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent                    samplingRate >= MIN_SAMPLING_RATE && samplingRate <= MAX_SAMPLING_RATE);
141441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent            result = true;
142441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent        } catch (IllegalArgumentException e) {
143441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent            msg = msg.concat(": Bad parameter value");
144441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent            loge(msg, "Bad parameter value");
145441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent        } catch (UnsupportedOperationException e) {
146441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent            msg = msg.concat(": get parameter() rejected");
147441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent            loge(msg, "get parameter() rejected");
148441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent        } catch (IllegalStateException e) {
149441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent            msg = msg.concat("get parameter() called in wrong state");
150441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent            loge(msg, "get parameter() called in wrong state");
151441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent        } finally {
152441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent            releaseVisualizer();
153441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent        }
154441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent        assertTrue(msg, result);
155441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent    }
156441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent
157441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent    //Test case 1.1: check capture size
158441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent    @LargeTest
159441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent    public void test1_1CaptureSize() throws Exception {
160441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent        boolean result = false;
161441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent        String msg = "test1_1CaptureSize()";
162441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent        getVisualizer(0);
163441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent        try {
164441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent            int[] range = mVisualizer.getCaptureSizeRange();
165441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent            assertTrue(msg +": insufficient min capture size",
166441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent                    range[0] <= MAX_CAPTURE_SIZE_MIN);
167441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent            assertTrue(msg +": insufficient min capture size",
168441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent                    range[1] >= MIN_CAPTURE_SIZE_MAX);
169441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent            mVisualizer.setCaptureSize(range[0]);
170441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent            assertEquals(msg +": insufficient min capture size",
171441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent                    range[0], mVisualizer.getCaptureSize());
172441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent            mVisualizer.setCaptureSize(range[1]);
173441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent            assertEquals(msg +": insufficient min capture size",
174441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent                    range[1], mVisualizer.getCaptureSize());
175441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent            result = true;
176441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent        } catch (IllegalArgumentException e) {
177441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent            msg = msg.concat(": Bad parameter value");
178441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent            loge(msg, "Bad parameter value");
179441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent        } catch (UnsupportedOperationException e) {
180441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent            msg = msg.concat(": get parameter() rejected");
181441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent            loge(msg, "get parameter() rejected");
182441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent        } catch (IllegalStateException e) {
183441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent            msg = msg.concat("get parameter() called in wrong state");
184441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent            loge(msg, "get parameter() called in wrong state");
185441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent        } finally {
186441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent            releaseVisualizer();
187441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent        }
188441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent        assertTrue(msg, result);
189441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent    }
190441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent
191997592b3ce5492e500aebb87066bbeab6c4e4599Jean-Michel Trivi    //Test case 1.2: check scaling mode
192997592b3ce5492e500aebb87066bbeab6c4e4599Jean-Michel Trivi    @LargeTest
193997592b3ce5492e500aebb87066bbeab6c4e4599Jean-Michel Trivi    public void test1_2ScalingMode() throws Exception {
194997592b3ce5492e500aebb87066bbeab6c4e4599Jean-Michel Trivi        boolean result = false;
195997592b3ce5492e500aebb87066bbeab6c4e4599Jean-Michel Trivi        String msg = "test1_2ScalingMode()";
196997592b3ce5492e500aebb87066bbeab6c4e4599Jean-Michel Trivi        getVisualizer(0);
197997592b3ce5492e500aebb87066bbeab6c4e4599Jean-Michel Trivi        try {
198997592b3ce5492e500aebb87066bbeab6c4e4599Jean-Michel Trivi            int res = mVisualizer.setScalingMode(Visualizer.SCALING_MODE_AS_PLAYED);
199997592b3ce5492e500aebb87066bbeab6c4e4599Jean-Michel Trivi            assertEquals(msg + ": setting SCALING_MODE_AS_PLAYED failed",
200997592b3ce5492e500aebb87066bbeab6c4e4599Jean-Michel Trivi                    res, Visualizer.SUCCESS);
201997592b3ce5492e500aebb87066bbeab6c4e4599Jean-Michel Trivi            int mode = mVisualizer.getScalingMode();
202997592b3ce5492e500aebb87066bbeab6c4e4599Jean-Michel Trivi            assertEquals(msg + ": setting SCALING_MODE_AS_PLAYED didn't stick",
203997592b3ce5492e500aebb87066bbeab6c4e4599Jean-Michel Trivi                    mode, Visualizer.SCALING_MODE_AS_PLAYED);
204997592b3ce5492e500aebb87066bbeab6c4e4599Jean-Michel Trivi
205997592b3ce5492e500aebb87066bbeab6c4e4599Jean-Michel Trivi            res = mVisualizer.setScalingMode(Visualizer.SCALING_MODE_NORMALIZED);
206997592b3ce5492e500aebb87066bbeab6c4e4599Jean-Michel Trivi            assertEquals(msg + ": setting SCALING_MODE_NORMALIZED failed",
207997592b3ce5492e500aebb87066bbeab6c4e4599Jean-Michel Trivi                    res, Visualizer.SUCCESS);
208997592b3ce5492e500aebb87066bbeab6c4e4599Jean-Michel Trivi            mode = mVisualizer.getScalingMode();
209997592b3ce5492e500aebb87066bbeab6c4e4599Jean-Michel Trivi            assertEquals(msg + ": setting SCALING_MODE_NORMALIZED didn't stick",
210997592b3ce5492e500aebb87066bbeab6c4e4599Jean-Michel Trivi                    mode, Visualizer.SCALING_MODE_NORMALIZED);
211997592b3ce5492e500aebb87066bbeab6c4e4599Jean-Michel Trivi
212997592b3ce5492e500aebb87066bbeab6c4e4599Jean-Michel Trivi            result = true;
213997592b3ce5492e500aebb87066bbeab6c4e4599Jean-Michel Trivi        } catch (IllegalStateException e) {
214997592b3ce5492e500aebb87066bbeab6c4e4599Jean-Michel Trivi            msg = msg.concat("IllegalStateException");
215997592b3ce5492e500aebb87066bbeab6c4e4599Jean-Michel Trivi            loge(msg, "set/get parameter() called in wrong state: " + e);
216997592b3ce5492e500aebb87066bbeab6c4e4599Jean-Michel Trivi        } finally {
217997592b3ce5492e500aebb87066bbeab6c4e4599Jean-Michel Trivi            releaseVisualizer();
218997592b3ce5492e500aebb87066bbeab6c4e4599Jean-Michel Trivi        }
219997592b3ce5492e500aebb87066bbeab6c4e4599Jean-Michel Trivi        assertTrue(msg, result);
220997592b3ce5492e500aebb87066bbeab6c4e4599Jean-Michel Trivi    }
221997592b3ce5492e500aebb87066bbeab6c4e4599Jean-Michel Trivi
222441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent    //-----------------------------------------------------------------
223441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent    // 2 - check capture
224441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent    //----------------------------------
225441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent
226441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent    //Test case 2.0: test capture in polling mode
227441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent    @LargeTest
228441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent    public void test2_0PollingCapture() throws Exception {
229441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent        boolean result = false;
230441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent        String msg = "test2_0PollingCapture()";
231441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent        AudioEffect vc = null;
232441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent        MediaPlayer mp = null;
233441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent        AudioManager am = (AudioManager) getActivity().getSystemService(Context.AUDIO_SERVICE);
234c81e0ad9bd438575389623f523a28e2e6ca69236Eric Laurent        int ringerMode = am.getRingerMode();
235c81e0ad9bd438575389623f523a28e2e6ca69236Eric Laurent        am.setRingerMode(AudioManager.RINGER_MODE_NORMAL);
236441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent        int volume = am.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
237441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent        am.setStreamVolume(AudioManager.STREAM_MUSIC,
238441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent                           am.getStreamMaxVolume(AudioManager.STREAM_MUSIC),
239441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent                           0);
240441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent
241441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent        try {
242441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent            // creating a volume controller on output mix ensures that ro.audio.silent mutes
243441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent            // audio after the effects and not before
244441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent            vc = new AudioEffect(
2455e7acae2c3e4cf345e3fa7bf10e3c62f9e69e6beEric Laurent                                AudioEffect.EFFECT_TYPE_NULL,
2465e7acae2c3e4cf345e3fa7bf10e3c62f9e69e6beEric Laurent                                VOLUME_EFFECT_UUID,
2475e7acae2c3e4cf345e3fa7bf10e3c62f9e69e6beEric Laurent                                0,
2485e7acae2c3e4cf345e3fa7bf10e3c62f9e69e6beEric Laurent                                0);
249441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent            vc.setEnabled(true);
250441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent
251441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent            mp = new MediaPlayer();
252441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent            mp.setDataSource(MediaNames.SINE_200_1000);
253441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent            mp.setAudioStreamType(AudioManager.STREAM_MUSIC);
254441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent            getVisualizer(mp.getAudioSessionId());
255441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent            mVisualizer.setEnabled(true);
256441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent            // check capture on silence
257441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent            byte[] data = new byte[mVisualizer.getCaptureSize()];
258441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent            mVisualizer.getWaveForm(data);
259441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent            int energy = computeEnergy(data, true);
260441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent            assertEquals(msg +": getWaveForm reports energy for silence",
261441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent                    0, energy);
262441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent            mVisualizer.getFft(data);
263441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent            energy = computeEnergy(data, false);
264441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent            assertEquals(msg +": getFft reports energy for silence",
265441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent                    0, energy);
266441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent            mp.prepare();
267441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent            mp.start();
268441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent            Thread.sleep(500);
269441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent            // check capture on sound
270441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent            mVisualizer.getWaveForm(data);
271441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent            energy = computeEnergy(data, true);
272441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent            assertTrue(msg +": getWaveForm reads insufficient level",
273441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent                    energy > 0);
274441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent            mVisualizer.getFft(data);
275441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent            energy = computeEnergy(data, false);
276441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent            assertTrue(msg +": getFft reads insufficient level",
277441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent                    energy > 0);
278441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent            result = true;
279441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent        } catch (IllegalArgumentException e) {
280441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent            msg = msg.concat(": Bad parameter value");
281441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent            loge(msg, "Bad parameter value");
282441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent        } catch (UnsupportedOperationException e) {
283441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent            msg = msg.concat(": get parameter() rejected");
284441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent            loge(msg, "get parameter() rejected");
285441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent        } catch (IllegalStateException e) {
286441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent            msg = msg.concat("get parameter() called in wrong state");
287441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent            loge(msg, "get parameter() called in wrong state");
288441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent        } catch (InterruptedException e) {
289441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent            loge(msg, "sleep() interrupted");
290441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent        }
291441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent        finally {
292441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent            releaseVisualizer();
293441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent            if (mp != null) {
294441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent                mp.release();
295441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent            }
296441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent            if (vc != null) {
297441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent                vc.release();
298441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent            }
299441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent            am.setStreamVolume(AudioManager.STREAM_MUSIC, volume, 0);
300c81e0ad9bd438575389623f523a28e2e6ca69236Eric Laurent            am.setRingerMode(ringerMode);
301441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent        }
302441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent        assertTrue(msg, result);
303441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent    }
304441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent
305441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent    //Test case 2.1: test capture with listener
306441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent    @LargeTest
307441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent    public void test2_1ListenerCapture() throws Exception {
308441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent        boolean result = false;
309441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent        String msg = "test2_1ListenerCapture()";
310441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent        AudioEffect vc = null;
311441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent        MediaPlayer mp = null;
312441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent        AudioManager am = (AudioManager) getActivity().getSystemService(Context.AUDIO_SERVICE);
313c81e0ad9bd438575389623f523a28e2e6ca69236Eric Laurent        int ringerMode = am.getRingerMode();
314c81e0ad9bd438575389623f523a28e2e6ca69236Eric Laurent        am.setRingerMode(AudioManager.RINGER_MODE_NORMAL);
315441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent        int volume = am.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
316441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent        am.setStreamVolume(AudioManager.STREAM_MUSIC,
317441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent                           am.getStreamMaxVolume(AudioManager.STREAM_MUSIC),
318441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent                           0);
319441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent
320441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent        try {
321441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent            // creating a volume controller on output mix ensures that ro.audio.silent mutes
322441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent            // audio after the effects and not before
323441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent            vc = new AudioEffect(
3245e7acae2c3e4cf345e3fa7bf10e3c62f9e69e6beEric Laurent                                AudioEffect.EFFECT_TYPE_NULL,
3255e7acae2c3e4cf345e3fa7bf10e3c62f9e69e6beEric Laurent                                VOLUME_EFFECT_UUID,
3265e7acae2c3e4cf345e3fa7bf10e3c62f9e69e6beEric Laurent                                0,
3275e7acae2c3e4cf345e3fa7bf10e3c62f9e69e6beEric Laurent                                0);
328441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent            vc.setEnabled(true);
329441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent
330441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent            mp = new MediaPlayer();
331441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent            mp.setDataSource(MediaNames.SINE_200_1000);
332441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent            mp.setAudioStreamType(AudioManager.STREAM_MUSIC);
333441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent
334441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent            getVisualizer(mp.getAudioSessionId());
335441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent            createListenerLooper();
336441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent            synchronized(lock) {
337441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent                try {
338441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent                    lock.wait(1000);
339441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent                } catch(Exception e) {
340441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent                    Log.e(TAG, "Looper creation: wait was interrupted.");
341441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent                }
342441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent            }
343441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent            assertTrue(mInitialized);
344441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent
345441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent            mVisualizer.setEnabled(true);
346441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent
347441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent            // check capture on silence
348441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent            synchronized(lock) {
349441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent                try {
350441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent                    mCaptureWaveform = true;
351441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent                    lock.wait(1000);
352441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent                    mCaptureWaveform = false;
353441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent                } catch(Exception e) {
354441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent                    Log.e(TAG, "Capture waveform: wait was interrupted.");
355441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent                }
356441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent            }
357441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent            assertNotNull(msg +": waveform capture failed", mWaveform);
358441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent            int energy = computeEnergy(mWaveform, true);
359441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent            assertEquals(msg +": getWaveForm reports energy for silence",
360441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent                    0, energy);
361441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent
362441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent            synchronized(lock) {
363441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent                try {
364441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent                    mCaptureFft = true;
365441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent                    lock.wait(1000);
366441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent                    mCaptureFft = false;
367441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent                } catch(Exception e) {
368441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent                    Log.e(TAG, "Capture FFT: wait was interrupted.");
369441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent                }
370441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent            }
371441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent            assertNotNull(msg +": FFT capture failed", mFft);
372441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent            energy = computeEnergy(mFft, false);
373441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent            assertEquals(msg +": getFft reports energy for silence",
374441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent                    0, energy);
375441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent
376441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent            mp.prepare();
377441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent            mp.start();
378441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent            Thread.sleep(500);
379441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent
380441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent            // check capture on sound
381441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent            synchronized(lock) {
382441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent                try {
383441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent                    mCaptureWaveform = true;
384441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent                    lock.wait(1000);
385441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent                    mCaptureWaveform = false;
386441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent                } catch(Exception e) {
387441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent                    Log.e(TAG, "Capture waveform: wait was interrupted.");
388441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent                }
389441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent            }
390441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent            assertNotNull(msg +": waveform capture failed", mWaveform);
391441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent            energy = computeEnergy(mWaveform, true);
392441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent            assertTrue(msg +": getWaveForm reads insufficient level",
393441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent                    energy > 0);
394441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent
395441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent            synchronized(lock) {
396441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent                try {
397441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent                    mCaptureFft = true;
398441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent                    lock.wait(1000);
399441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent                    mCaptureFft = false;
400441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent                } catch(Exception e) {
401441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent                    Log.e(TAG, "Capture FFT: wait was interrupted.");
402441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent                }
403441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent            }
404441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent            assertNotNull(msg +": FFT capture failed", mFft);
405441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent            energy = computeEnergy(mFft, false);
406441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent            assertTrue(msg +": getFft reads insufficient level",
407441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent                    energy > 0);
408441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent
409441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent            result = true;
410441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent        } catch (IllegalArgumentException e) {
411441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent            msg = msg.concat(": Bad parameter value");
412441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent            loge(msg, "Bad parameter value");
413441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent        } catch (UnsupportedOperationException e) {
414441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent            msg = msg.concat(": get parameter() rejected");
415441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent            loge(msg, "get parameter() rejected");
416441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent        } catch (IllegalStateException e) {
417441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent            msg = msg.concat("get parameter() called in wrong state");
418441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent            loge(msg, "get parameter() called in wrong state");
419441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent        } catch (InterruptedException e) {
420441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent            loge(msg, "sleep() interrupted");
421441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent        }
422441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent        finally {
423441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent            terminateListenerLooper();
424441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent            releaseVisualizer();
425441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent            if (mp != null) {
426441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent                mp.release();
427441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent            }
428441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent            if (vc != null) {
429441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent                vc.release();
430441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent            }
431441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent            am.setStreamVolume(AudioManager.STREAM_MUSIC, volume, 0);
432c81e0ad9bd438575389623f523a28e2e6ca69236Eric Laurent            am.setRingerMode(ringerMode);
433441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent        }
434441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent        assertTrue(msg, result);
435441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent    }
436441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent
437997592b3ce5492e500aebb87066bbeab6c4e4599Jean-Michel Trivi    //Test case 2.2: test capture in polling mode with volume scaling
438997592b3ce5492e500aebb87066bbeab6c4e4599Jean-Michel Trivi    @LargeTest
439997592b3ce5492e500aebb87066bbeab6c4e4599Jean-Michel Trivi    public void test2_2PollingCaptureVolumeScaling() throws Exception {
440997592b3ce5492e500aebb87066bbeab6c4e4599Jean-Michel Trivi        // test that when playing a sound, the energy measured with Visualizer in
441997592b3ce5492e500aebb87066bbeab6c4e4599Jean-Michel Trivi        //   SCALING_MODE_AS_PLAYED mode decreases when lowering the volume
442997592b3ce5492e500aebb87066bbeab6c4e4599Jean-Michel Trivi        boolean result = false;
443997592b3ce5492e500aebb87066bbeab6c4e4599Jean-Michel Trivi        String msg = "test2_2PollingCaptureVolumeScaling()";
444997592b3ce5492e500aebb87066bbeab6c4e4599Jean-Michel Trivi        AudioEffect vc = null;
445997592b3ce5492e500aebb87066bbeab6c4e4599Jean-Michel Trivi        MediaPlayer mp = null;
446997592b3ce5492e500aebb87066bbeab6c4e4599Jean-Michel Trivi        AudioManager am = (AudioManager) getActivity().getSystemService(Context.AUDIO_SERVICE);
447997592b3ce5492e500aebb87066bbeab6c4e4599Jean-Michel Trivi        int ringerMode = am.getRingerMode();
448997592b3ce5492e500aebb87066bbeab6c4e4599Jean-Michel Trivi        am.setRingerMode(AudioManager.RINGER_MODE_NORMAL);
449997592b3ce5492e500aebb87066bbeab6c4e4599Jean-Michel Trivi        final int volMax = am.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
450997592b3ce5492e500aebb87066bbeab6c4e4599Jean-Michel Trivi        am.setStreamVolume(AudioManager.STREAM_MUSIC, volMax, 0);
451997592b3ce5492e500aebb87066bbeab6c4e4599Jean-Michel Trivi
452997592b3ce5492e500aebb87066bbeab6c4e4599Jean-Michel Trivi        try {
453997592b3ce5492e500aebb87066bbeab6c4e4599Jean-Michel Trivi            // test setup not related to tested functionality:
454997592b3ce5492e500aebb87066bbeab6c4e4599Jean-Michel Trivi            // creating a volume controller on output mix ensures that ro.audio.silent mutes
455997592b3ce5492e500aebb87066bbeab6c4e4599Jean-Michel Trivi            // audio after the effects and not before
456997592b3ce5492e500aebb87066bbeab6c4e4599Jean-Michel Trivi            vc = new AudioEffect(
457997592b3ce5492e500aebb87066bbeab6c4e4599Jean-Michel Trivi                                AudioEffect.EFFECT_TYPE_NULL,
458997592b3ce5492e500aebb87066bbeab6c4e4599Jean-Michel Trivi                                VOLUME_EFFECT_UUID,
459997592b3ce5492e500aebb87066bbeab6c4e4599Jean-Michel Trivi                                0,
460997592b3ce5492e500aebb87066bbeab6c4e4599Jean-Michel Trivi                                0);
461997592b3ce5492e500aebb87066bbeab6c4e4599Jean-Michel Trivi            vc.setEnabled(true);
462997592b3ce5492e500aebb87066bbeab6c4e4599Jean-Michel Trivi
463997592b3ce5492e500aebb87066bbeab6c4e4599Jean-Michel Trivi            mp = new MediaPlayer();
464997592b3ce5492e500aebb87066bbeab6c4e4599Jean-Michel Trivi            mp.setDataSource(MediaNames.SINE_200_1000);
465997592b3ce5492e500aebb87066bbeab6c4e4599Jean-Michel Trivi            mp.setAudioStreamType(AudioManager.STREAM_MUSIC);
466997592b3ce5492e500aebb87066bbeab6c4e4599Jean-Michel Trivi            getVisualizer(mp.getAudioSessionId());
467997592b3ce5492e500aebb87066bbeab6c4e4599Jean-Michel Trivi
468997592b3ce5492e500aebb87066bbeab6c4e4599Jean-Michel Trivi            // verify we successfully set the Visualizer in SCALING_MODE_AS_PLAYED mode
469997592b3ce5492e500aebb87066bbeab6c4e4599Jean-Michel Trivi            mVisualizer.setScalingMode(Visualizer.SCALING_MODE_AS_PLAYED);
470997592b3ce5492e500aebb87066bbeab6c4e4599Jean-Michel Trivi            assertTrue(msg + " get volume scaling doesn't return SCALING_MODE_AS_PLAYED",
471997592b3ce5492e500aebb87066bbeab6c4e4599Jean-Michel Trivi                    mVisualizer.getScalingMode() == Visualizer.SCALING_MODE_AS_PLAYED);
472997592b3ce5492e500aebb87066bbeab6c4e4599Jean-Michel Trivi            mVisualizer.setEnabled(true);
473997592b3ce5492e500aebb87066bbeab6c4e4599Jean-Michel Trivi            mp.prepare();
474997592b3ce5492e500aebb87066bbeab6c4e4599Jean-Michel Trivi            mp.start();
475997592b3ce5492e500aebb87066bbeab6c4e4599Jean-Michel Trivi            Thread.sleep(500);
476997592b3ce5492e500aebb87066bbeab6c4e4599Jean-Michel Trivi
477997592b3ce5492e500aebb87066bbeab6c4e4599Jean-Michel Trivi            // check capture on sound with music volume at max
478997592b3ce5492e500aebb87066bbeab6c4e4599Jean-Michel Trivi            byte[] data = new byte[mVisualizer.getCaptureSize()];
479997592b3ce5492e500aebb87066bbeab6c4e4599Jean-Michel Trivi            mVisualizer.getWaveForm(data);
480997592b3ce5492e500aebb87066bbeab6c4e4599Jean-Michel Trivi            int energyAtVolMax = computeEnergy(data, true);
481997592b3ce5492e500aebb87066bbeab6c4e4599Jean-Michel Trivi            assertTrue(msg +": getWaveForm reads insufficient level",
482997592b3ce5492e500aebb87066bbeab6c4e4599Jean-Michel Trivi                    energyAtVolMax > 0);
483997592b3ce5492e500aebb87066bbeab6c4e4599Jean-Michel Trivi            log(msg, " engergy at max volume = "+energyAtVolMax);
484997592b3ce5492e500aebb87066bbeab6c4e4599Jean-Michel Trivi
485997592b3ce5492e500aebb87066bbeab6c4e4599Jean-Michel Trivi            // check capture on sound with music volume lowered from max
486997592b3ce5492e500aebb87066bbeab6c4e4599Jean-Michel Trivi            am.setStreamVolume(AudioManager.STREAM_MUSIC, (volMax * 2) / 3, 0);
487997592b3ce5492e500aebb87066bbeab6c4e4599Jean-Michel Trivi            Thread.sleep(500);
488997592b3ce5492e500aebb87066bbeab6c4e4599Jean-Michel Trivi            mVisualizer.getWaveForm(data);
489997592b3ce5492e500aebb87066bbeab6c4e4599Jean-Michel Trivi            int energyAtLowerVol = computeEnergy(data, true);
490997592b3ce5492e500aebb87066bbeab6c4e4599Jean-Michel Trivi            assertTrue(msg +": getWaveForm at lower volume reads insufficient level",
491997592b3ce5492e500aebb87066bbeab6c4e4599Jean-Michel Trivi                    energyAtLowerVol > 0);
492997592b3ce5492e500aebb87066bbeab6c4e4599Jean-Michel Trivi            log(msg, "energy at lower volume = "+energyAtLowerVol);
493997592b3ce5492e500aebb87066bbeab6c4e4599Jean-Michel Trivi            assertTrue(msg +": getWaveForm didn't report lower energy when volume decreases",
494997592b3ce5492e500aebb87066bbeab6c4e4599Jean-Michel Trivi                    energyAtVolMax > energyAtLowerVol);
495997592b3ce5492e500aebb87066bbeab6c4e4599Jean-Michel Trivi
496997592b3ce5492e500aebb87066bbeab6c4e4599Jean-Michel Trivi            result = true;
497997592b3ce5492e500aebb87066bbeab6c4e4599Jean-Michel Trivi        } catch (IllegalArgumentException e) {
498997592b3ce5492e500aebb87066bbeab6c4e4599Jean-Michel Trivi            msg = msg.concat(": IllegalArgumentException");
499997592b3ce5492e500aebb87066bbeab6c4e4599Jean-Michel Trivi            loge(msg, " hit exception " + e);
500997592b3ce5492e500aebb87066bbeab6c4e4599Jean-Michel Trivi        } catch (UnsupportedOperationException e) {
501997592b3ce5492e500aebb87066bbeab6c4e4599Jean-Michel Trivi            msg = msg.concat(": UnsupportedOperationException");
502997592b3ce5492e500aebb87066bbeab6c4e4599Jean-Michel Trivi            loge(msg, " hit exception " + e);
503997592b3ce5492e500aebb87066bbeab6c4e4599Jean-Michel Trivi        } catch (IllegalStateException e) {
504997592b3ce5492e500aebb87066bbeab6c4e4599Jean-Michel Trivi            msg = msg.concat("IllegalStateException");
505997592b3ce5492e500aebb87066bbeab6c4e4599Jean-Michel Trivi            loge(msg, " hit exception " + e);
506997592b3ce5492e500aebb87066bbeab6c4e4599Jean-Michel Trivi        } catch (InterruptedException e) {
507997592b3ce5492e500aebb87066bbeab6c4e4599Jean-Michel Trivi            loge(msg, " sleep() interrupted");
508997592b3ce5492e500aebb87066bbeab6c4e4599Jean-Michel Trivi        }
509997592b3ce5492e500aebb87066bbeab6c4e4599Jean-Michel Trivi        finally {
510997592b3ce5492e500aebb87066bbeab6c4e4599Jean-Michel Trivi            releaseVisualizer();
511997592b3ce5492e500aebb87066bbeab6c4e4599Jean-Michel Trivi            if (mp != null) {
512997592b3ce5492e500aebb87066bbeab6c4e4599Jean-Michel Trivi                mp.release();
513997592b3ce5492e500aebb87066bbeab6c4e4599Jean-Michel Trivi            }
514997592b3ce5492e500aebb87066bbeab6c4e4599Jean-Michel Trivi            if (vc != null) {
515997592b3ce5492e500aebb87066bbeab6c4e4599Jean-Michel Trivi                vc.release();
516997592b3ce5492e500aebb87066bbeab6c4e4599Jean-Michel Trivi            }
517997592b3ce5492e500aebb87066bbeab6c4e4599Jean-Michel Trivi            am.setRingerMode(ringerMode);
518997592b3ce5492e500aebb87066bbeab6c4e4599Jean-Michel Trivi        }
519997592b3ce5492e500aebb87066bbeab6c4e4599Jean-Michel Trivi        assertTrue(msg, result);
520997592b3ce5492e500aebb87066bbeab6c4e4599Jean-Michel Trivi    }
521997592b3ce5492e500aebb87066bbeab6c4e4599Jean-Michel Trivi
522441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent    //-----------------------------------------------------------------
523441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent    // private methods
524441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent    //----------------------------------
525441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent
526441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent    private int computeEnergy(byte[] data, boolean unsigned) {
527441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent        int energy = 0;
528441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent        if (data.length != 0) {
529441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent            for (int i = 0; i < data.length; i++) {
530441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent                int tmp;
531441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent                // convert from unsigned 8 bit to signed 16 bit
532441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent                if (unsigned) {
533441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent                    tmp = ((int)data[i] & 0xFF) - 128;
534441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent                } else {
535441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent                    tmp = (int)data[i];
536441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent                }
537441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent                energy += tmp*tmp;
538441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent            }
539441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent            energy /= data.length;
540441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent        }
541441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent        return energy;
542441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent    }
543441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent
544441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent    private void getVisualizer(int session) {
545441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent         if (mVisualizer == null || session != mSession) {
546441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent             if (session != mSession && mVisualizer != null) {
547441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent                 mVisualizer.release();
548441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent                 mVisualizer = null;
549441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent             }
550441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent             try {
551441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent                mVisualizer = new Visualizer(session);
552441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent                mSession = session;
553441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent            } catch (IllegalArgumentException e) {
554441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent                Log.e(TAG, "getVisualizer() Visualizer not found exception: "+e);
555441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent            } catch (UnsupportedOperationException e) {
556441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent                Log.e(TAG, "getVisualizer() Effect library not loaded exception: "+e);
557441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent            }
558441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent         }
559441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent         assertNotNull("could not create mVisualizer", mVisualizer);
560441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent    }
561441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent
562441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent    private void releaseVisualizer() {
563441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent        if (mVisualizer != null) {
564441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent            mVisualizer.release();
565441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent            mVisualizer = null;
566441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent        }
567441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent   }
568441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent
569441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent    private void createListenerLooper() {
570441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent
571441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent        new Thread() {
572441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent            @Override
573441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent            public void run() {
574441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent                // Set up a looper to be used by mEffect.
575441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent                Looper.prepare();
576441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent
577441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent                // Save the looper so that we can terminate this thread
578441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent                // after we are done with it.
579441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent                mLooper = Looper.myLooper();
580441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent
581441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent                if (mVisualizer != null) {
582441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent                    mVisualizer.setDataCaptureListener(new Visualizer.OnDataCaptureListener() {
583441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent                        public void onWaveFormDataCapture(
584441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent                                Visualizer visualizer, byte[] waveform, int samplingRate) {
585441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent                            synchronized(lock) {
586441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent                                if (visualizer == mVisualizer) {
587441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent                                    if (mCaptureWaveform) {
588441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent                                        mWaveform = waveform;
589441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent                                        lock.notify();
590441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent                                    }
591441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent                                }
592441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent                            }
593441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent                        }
594441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent
595441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent                        public void onFftDataCapture(
596441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent                                Visualizer visualizer, byte[] fft, int samplingRate) {
597441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent                            synchronized(lock) {
598441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent                                if (visualizer == mVisualizer) {
599441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent                                    if (mCaptureFft) {
600441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent                                        mFft = fft;
601441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent                                        lock.notify();
602441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent                                    }
603441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent                                }
604441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent                            }
605441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent                        }
606441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent                    },
607441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent                    10000,
608441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent                    true,
609441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent                    true);
610441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent                }
611441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent
612441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent                synchronized(lock) {
613441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent                    mInitialized = true;
614441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent                    lock.notify();
615441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent                }
616441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent                Looper.loop();  // Blocks forever until Looper.quit() is called.
617441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent            }
618441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent        }.start();
619441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent    }
620441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent    /*
621441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent     * Terminates the listener looper thread.
622441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent     */
623441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent    private void terminateListenerLooper() {
624441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent        if (mLooper != null) {
625441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent            mLooper.quit();
626441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent            mLooper = null;
627441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent        }
628441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent    }
629441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent
630441ec6bd106a6ac09ff0ceed1f8d437c33cfc156Eric Laurent}
631