1df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent/*
2df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * Copyright (C) 2010 The Android Open Source Project
3df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent *
4df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * Licensed under the Apache License, Version 2.0 (the "License");
5df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * you may not use this file except in compliance with the License.
6df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * You may obtain a copy of the License at
7df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent *
8df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent *      http://www.apache.org/licenses/LICENSE-2.0
9df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent *
10df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * Unless required by applicable law or agreed to in writing, software
11df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * distributed under the License is distributed on an "AS IS" BASIS,
12df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * See the License for the specific language governing permissions and
14df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * limitations under the License.
15df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent */
16df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
171a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurentpackage android.media.audiofx;
18df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
19df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurentimport android.util.Log;
20df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurentimport java.lang.ref.WeakReference;
21df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurentimport java.io.IOException;
22df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurentimport android.os.Handler;
23df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurentimport android.os.Looper;
24df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurentimport android.os.Message;
25df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
26df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent/**
27df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * The Visualizer class enables application to retrieve part of the currently playing audio for
28df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * visualization purpose. It is not an audio recording interface and only returns partial and low
29df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * quality audio content. However, to protect privacy of certain audio data (e.g voice mail) the use
30df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * of the visualizer requires the permission android.permission.RECORD_AUDIO.
31df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * <p>The audio session ID passed to the constructor indicates which audio content should be
32df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * visualized:<br>
33df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * <ul>
34df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent *   <li>If the session is 0, the audio output mix is visualized</li>
351a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent *   <li>If the session is not 0, the audio from a particular {@link android.media.MediaPlayer} or
361a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent *   {@link android.media.AudioTrack}
37df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent *   using this audio session is visualized </li>
38df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * </ul>
39df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * <p>Two types of representation of audio content can be captured: <br>
40df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * <ul>
41df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent *   <li>Waveform data: consecutive 8-bit (unsigned) mono samples by using the
42df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent *   {@link #getWaveForm(byte[])} method</li>
43df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent *   <li>Frequency data: 8-bit magnitude FFT by using the {@link #getFft(byte[])} method</li>
44df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * </ul>
45df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * <p>The length of the capture can be retrieved or specified by calling respectively
4603a4090b4d5965ff01cbb03dcf6d96b30d634fa3Eric Laurent * {@link #getCaptureSize()} and {@link #setCaptureSize(int)} methods. The capture size must be a
4703a4090b4d5965ff01cbb03dcf6d96b30d634fa3Eric Laurent * power of 2 in the range returned by {@link #getCaptureSizeRange()}.
48df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * <p>In addition to the polling capture mode described above with {@link #getWaveForm(byte[])} and
49df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent *  {@link #getFft(byte[])} methods, a callback mode is also available by installing a listener by
50df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent *  use of the {@link #setDataCaptureListener(OnDataCaptureListener, int, boolean, boolean)} method.
51df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent *  The rate at which the listener capture method is called as well as the type of data returned is
52df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent *  specified.
53df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * <p>Before capturing data, the Visualizer must be enabled by calling the
54df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * {@link #setEnabled(boolean)} method.
55df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * When data capture is not needed any more, the Visualizer should be disabled.
56df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * <p>It is good practice to call the {@link #release()} method when the Visualizer is not used
57df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * anymore to free up native resources associated to the Visualizer instance.
581a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent * <p>Creating a Visualizer on the output mix (audio session 0) requires permission
591a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent * {@link android.Manifest.permission#MODIFY_AUDIO_SETTINGS}
60df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent */
61df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
62df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurentpublic class Visualizer {
63df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
64df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    static {
65df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        System.loadLibrary("audioeffect_jni");
66df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        native_init();
67df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    }
68df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
69df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    private final static String TAG = "Visualizer-JAVA";
70df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
71df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    /**
72df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * State of a Visualizer object that was not successfully initialized upon creation
73df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     */
74df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    public static final int STATE_UNINITIALIZED = 0;
75df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    /**
76df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * State of a Visualizer object that is ready to be used.
77df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     */
78df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    public static final int STATE_INITIALIZED   = 1;
79df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    /**
80df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * State of a Visualizer object that is active.
81df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     */
82df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    public static final int STATE_ENABLED   = 2;
83df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
84e1123e7f36723a8b888501c9a22a589297849ca2Jean-Michel Trivi    // to keep in sync with system/media/audio_effects/include/audio_effects/effect_visualizer.h
85e1123e7f36723a8b888501c9a22a589297849ca2Jean-Michel Trivi    /**
86e1123e7f36723a8b888501c9a22a589297849ca2Jean-Michel Trivi     * Defines a capture mode where amplification is applied based on the content of the captured
87e1123e7f36723a8b888501c9a22a589297849ca2Jean-Michel Trivi     * data. This is the default Visualizer mode, and is suitable for music visualization.
88e1123e7f36723a8b888501c9a22a589297849ca2Jean-Michel Trivi     */
89e1123e7f36723a8b888501c9a22a589297849ca2Jean-Michel Trivi    public static final int SCALING_MODE_NORMALIZED = 0;
90e1123e7f36723a8b888501c9a22a589297849ca2Jean-Michel Trivi    /**
91e1123e7f36723a8b888501c9a22a589297849ca2Jean-Michel Trivi     * Defines a capture mode where the playback volume will affect (scale) the range of the
92e1123e7f36723a8b888501c9a22a589297849ca2Jean-Michel Trivi     * captured data. A low playback volume will lead to low sample and fft values, and vice-versa.
93e1123e7f36723a8b888501c9a22a589297849ca2Jean-Michel Trivi     */
94e1123e7f36723a8b888501c9a22a589297849ca2Jean-Michel Trivi    public static final int SCALING_MODE_AS_PLAYED = 1;
95e1123e7f36723a8b888501c9a22a589297849ca2Jean-Michel Trivi
96df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    // to keep in sync with frameworks/base/media/jni/audioeffect/android_media_Visualizer.cpp
9717cb280e7f1ac3556eac90ab08263712e0348cb9Eric Laurent    private static final int NATIVE_EVENT_PCM_CAPTURE = 0;
9817cb280e7f1ac3556eac90ab08263712e0348cb9Eric Laurent    private static final int NATIVE_EVENT_FFT_CAPTURE = 1;
993540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman    private static final int NATIVE_EVENT_SERVER_DIED = 2;
100df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
101df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    // Error codes:
102df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    /**
103df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * Successful operation.
104df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     */
105df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    public  static final int SUCCESS              = 0;
106df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    /**
107df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * Unspecified error.
108df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     */
109df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    public  static final int ERROR                = -1;
110df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    /**
111ed6eae420fd60dcb7d90f54c3116959b75bd6276Glenn Kasten     * Internal operation status. Not returned by any method.
112df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     */
113df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    public  static final int ALREADY_EXISTS       = -2;
114df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    /**
115df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * Operation failed due to bad object initialization.
116df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     */
117df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    public  static final int ERROR_NO_INIT              = -3;
118df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    /**
119df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * Operation failed due to bad parameter value.
120df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     */
121df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    public  static final int ERROR_BAD_VALUE            = -4;
122df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    /**
123df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * Operation failed because it was requested in wrong state.
124df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     */
125df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    public  static final int ERROR_INVALID_OPERATION    = -5;
126df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    /**
127df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * Operation failed due to lack of memory.
128df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     */
129df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    public  static final int ERROR_NO_MEMORY            = -6;
130df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    /**
131df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * Operation failed due to dead remote object.
132df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     */
133df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    public  static final int ERROR_DEAD_OBJECT          = -7;
134df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
135df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    //--------------------------------------------------------------------------
136df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    // Member variables
137df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    //--------------------
138df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    /**
139df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * Indicates the state of the Visualizer instance
140df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     */
14117cb280e7f1ac3556eac90ab08263712e0348cb9Eric Laurent    private int mState = STATE_UNINITIALIZED;
142df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    /**
143df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * Lock to synchronize access to mState
144df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     */
14517cb280e7f1ac3556eac90ab08263712e0348cb9Eric Laurent    private final Object mStateLock = new Object();
146df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    /**
147df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * System wide unique Identifier of the visualizer engine used by this Visualizer instance
148df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     */
14917cb280e7f1ac3556eac90ab08263712e0348cb9Eric Laurent    private int mId;
150df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
151df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    /**
152df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * Lock to protect listeners updates against event notifications
153df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     */
15417cb280e7f1ac3556eac90ab08263712e0348cb9Eric Laurent    private final Object mListenerLock = new Object();
155df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    /**
156df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * Handler for events coming from the native code
157df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     */
15817cb280e7f1ac3556eac90ab08263712e0348cb9Eric Laurent    private NativeEventHandler mNativeEventHandler = null;
159df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    /**
160df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     *  PCM and FFT capture listener registered by client
161df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     */
16217cb280e7f1ac3556eac90ab08263712e0348cb9Eric Laurent    private OnDataCaptureListener mCaptureListener = null;
1633540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman    /**
1643540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman     *  Server Died listener registered by client
1653540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman     */
1663540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman    private OnServerDiedListener mServerDiedListener = null;
167df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
168df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    // accessed by native methods
169df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    private int mNativeVisualizer;
170df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    private int mJniData;
171df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
172df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    //--------------------------------------------------------------------------
173df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    // Constructor, Finalize
174df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    //--------------------
175df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    /**
176df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * Class constructor.
17717cb280e7f1ac3556eac90ab08263712e0348cb9Eric Laurent     * @param audioSession system wide unique audio session identifier. If audioSession
178df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     *  is not 0, the visualizer will be attached to the MediaPlayer or AudioTrack in the
179df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     *  same audio session. Otherwise, the Visualizer will apply to the output mix.
180df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     *
181df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * @throws java.lang.UnsupportedOperationException
182df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * @throws java.lang.RuntimeException
183df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     */
184df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
185df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    public Visualizer(int audioSession)
186df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    throws UnsupportedOperationException, RuntimeException {
187df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        int[] id = new int[1];
188df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
189df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        synchronized (mStateLock) {
190df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            mState = STATE_UNINITIALIZED;
191df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            // native initialization
192df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            int result = native_setup(new WeakReference<Visualizer>(this), audioSession, id);
193df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            if (result != SUCCESS && result != ALREADY_EXISTS) {
194df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent                Log.e(TAG, "Error code "+result+" when initializing Visualizer.");
195df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent                switch (result) {
196df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent                case ERROR_INVALID_OPERATION:
197df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent                    throw (new UnsupportedOperationException("Effect library not loaded"));
198df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent                default:
199df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent                    throw (new RuntimeException("Cannot initialize Visualizer engine, error: "
200df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent                            +result));
201df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent                }
202df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            }
203df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            mId = id[0];
204df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            if (native_getEnabled()) {
205df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent                mState = STATE_ENABLED;
206df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            } else {
207df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent                mState = STATE_INITIALIZED;
208df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            }
209df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        }
210df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    }
211df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
212df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    /**
213df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * Releases the native Visualizer resources. It is a good practice to release the
214df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * visualization engine when not in use.
215df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     */
216df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    public void release() {
217df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        synchronized (mStateLock) {
218df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            native_release();
219df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            mState = STATE_UNINITIALIZED;
220df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        }
221df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    }
222df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
223df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    @Override
224df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    protected void finalize() {
225df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        native_finalize();
226df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    }
227df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
228df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    /**
229df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * Enable or disable the visualization engine.
230df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * @param enabled requested enable state
231df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * @return {@link #SUCCESS} in case of success,
232df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * {@link #ERROR_INVALID_OPERATION} or {@link #ERROR_DEAD_OBJECT} in case of failure.
233df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * @throws IllegalStateException
234df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     */
235df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    public int setEnabled(boolean enabled)
236df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    throws IllegalStateException {
237df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        synchronized (mStateLock) {
238672c0dc3a04cb149691603342c319994e21235cbEric Laurent            if (mState == STATE_UNINITIALIZED) {
239df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent                throw(new IllegalStateException("setEnabled() called in wrong state: "+mState));
240df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            }
241672c0dc3a04cb149691603342c319994e21235cbEric Laurent            int status = SUCCESS;
242672c0dc3a04cb149691603342c319994e21235cbEric Laurent            if ((enabled && (mState == STATE_INITIALIZED)) ||
243672c0dc3a04cb149691603342c319994e21235cbEric Laurent                    (!enabled && (mState == STATE_ENABLED))) {
244672c0dc3a04cb149691603342c319994e21235cbEric Laurent                status = native_setEnabled(enabled);
245672c0dc3a04cb149691603342c319994e21235cbEric Laurent                if (status == SUCCESS) {
246672c0dc3a04cb149691603342c319994e21235cbEric Laurent                    mState = enabled ? STATE_ENABLED : STATE_INITIALIZED;
247672c0dc3a04cb149691603342c319994e21235cbEric Laurent                }
248df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            }
249df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            return status;
250df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        }
251df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    }
252df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
253df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    /**
254df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * Get current activation state of the visualizer.
255df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * @return true if the visualizer is active, false otherwise
256df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     */
257df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    public boolean getEnabled()
258df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    {
259df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        synchronized (mStateLock) {
260df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            if (mState == STATE_UNINITIALIZED) {
261df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent                throw(new IllegalStateException("getEnabled() called in wrong state: "+mState));
262df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            }
263df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            return native_getEnabled();
264df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        }
265df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    }
266df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
267df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    /**
268df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * Returns the capture size range.
269df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * @return the mininum capture size is returned in first array element and the maximum in second
270df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * array element.
271df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     */
272df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    public static native int[] getCaptureSizeRange();
273df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
274df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    /**
275df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * Returns the maximum capture rate for the callback capture method. This is the maximum value
276df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * for the rate parameter of the
277df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * {@link #setDataCaptureListener(OnDataCaptureListener, int, boolean, boolean)} method.
278df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * @return the maximum capture rate expressed in milliHertz
279df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     */
280df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    public static native int getMaxCaptureRate();
281df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
282df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    /**
283df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * Sets the capture size, i.e. the number of bytes returned by {@link #getWaveForm(byte[])} and
284df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * {@link #getFft(byte[])} methods. The capture size must be a power of 2 in the range returned
285df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * by {@link #getCaptureSizeRange()}.
286df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * This method must not be called when the Visualizer is enabled.
287df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * @param size requested capture size
288df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * @return {@link #SUCCESS} in case of success,
289df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * {@link #ERROR_BAD_VALUE} in case of failure.
290df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * @throws IllegalStateException
291df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     */
292df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    public int setCaptureSize(int size)
293df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    throws IllegalStateException {
294df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        synchronized (mStateLock) {
295df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            if (mState != STATE_INITIALIZED) {
296df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent                throw(new IllegalStateException("setCaptureSize() called in wrong state: "+mState));
297df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            }
298df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            return native_setCaptureSize(size);
299df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        }
300df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    }
301df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
302df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    /**
303df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * Returns current capture size.
304df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * @return the capture size in bytes.
305df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     */
306df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    public int getCaptureSize()
307df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    throws IllegalStateException {
308df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        synchronized (mStateLock) {
309df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            if (mState == STATE_UNINITIALIZED) {
310df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent                throw(new IllegalStateException("getCaptureSize() called in wrong state: "+mState));
311df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            }
312df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            return native_getCaptureSize();
313df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        }
314df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    }
315df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
316df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    /**
317e1123e7f36723a8b888501c9a22a589297849ca2Jean-Michel Trivi     * Set the type of scaling applied on the captured visualization data.
318e1123e7f36723a8b888501c9a22a589297849ca2Jean-Michel Trivi     * @param mode see {@link #SCALING_MODE_NORMALIZED}
319e1123e7f36723a8b888501c9a22a589297849ca2Jean-Michel Trivi     *     and {@link #SCALING_MODE_AS_PLAYED}
320e1123e7f36723a8b888501c9a22a589297849ca2Jean-Michel Trivi     * @return {@link #SUCCESS} in case of success,
321e1123e7f36723a8b888501c9a22a589297849ca2Jean-Michel Trivi     *     {@link #ERROR_BAD_VALUE} in case of failure.
322e1123e7f36723a8b888501c9a22a589297849ca2Jean-Michel Trivi     * @throws IllegalStateException
323e1123e7f36723a8b888501c9a22a589297849ca2Jean-Michel Trivi     */
324e1123e7f36723a8b888501c9a22a589297849ca2Jean-Michel Trivi    public int setScalingMode(int mode)
325e1123e7f36723a8b888501c9a22a589297849ca2Jean-Michel Trivi    throws IllegalStateException {
326e1123e7f36723a8b888501c9a22a589297849ca2Jean-Michel Trivi        synchronized (mStateLock) {
327e1123e7f36723a8b888501c9a22a589297849ca2Jean-Michel Trivi            if (mState == STATE_UNINITIALIZED) {
328e1123e7f36723a8b888501c9a22a589297849ca2Jean-Michel Trivi                throw(new IllegalStateException("setScalingMode() called in wrong state: "
329e1123e7f36723a8b888501c9a22a589297849ca2Jean-Michel Trivi                        + mState));
330e1123e7f36723a8b888501c9a22a589297849ca2Jean-Michel Trivi            }
331e1123e7f36723a8b888501c9a22a589297849ca2Jean-Michel Trivi            return native_setScalingMode(mode);
332e1123e7f36723a8b888501c9a22a589297849ca2Jean-Michel Trivi        }
333e1123e7f36723a8b888501c9a22a589297849ca2Jean-Michel Trivi    }
334e1123e7f36723a8b888501c9a22a589297849ca2Jean-Michel Trivi
335e1123e7f36723a8b888501c9a22a589297849ca2Jean-Michel Trivi    /**
336e1123e7f36723a8b888501c9a22a589297849ca2Jean-Michel Trivi     * Returns the current scaling mode on the captured visualization data.
337e1123e7f36723a8b888501c9a22a589297849ca2Jean-Michel Trivi     * @return the scaling mode, see {@link #SCALING_MODE_NORMALIZED}
338e1123e7f36723a8b888501c9a22a589297849ca2Jean-Michel Trivi     *     and {@link #SCALING_MODE_AS_PLAYED}.
339e1123e7f36723a8b888501c9a22a589297849ca2Jean-Michel Trivi     * @throws IllegalStateException
340e1123e7f36723a8b888501c9a22a589297849ca2Jean-Michel Trivi     */
341e1123e7f36723a8b888501c9a22a589297849ca2Jean-Michel Trivi    public int getScalingMode()
342e1123e7f36723a8b888501c9a22a589297849ca2Jean-Michel Trivi    throws IllegalStateException {
343e1123e7f36723a8b888501c9a22a589297849ca2Jean-Michel Trivi        synchronized (mStateLock) {
344e1123e7f36723a8b888501c9a22a589297849ca2Jean-Michel Trivi            if (mState == STATE_UNINITIALIZED) {
345e1123e7f36723a8b888501c9a22a589297849ca2Jean-Michel Trivi                throw(new IllegalStateException("getScalingMode() called in wrong state: "
346e1123e7f36723a8b888501c9a22a589297849ca2Jean-Michel Trivi                        + mState));
347e1123e7f36723a8b888501c9a22a589297849ca2Jean-Michel Trivi            }
348e1123e7f36723a8b888501c9a22a589297849ca2Jean-Michel Trivi            return native_getScalingMode();
349e1123e7f36723a8b888501c9a22a589297849ca2Jean-Michel Trivi        }
350e1123e7f36723a8b888501c9a22a589297849ca2Jean-Michel Trivi    }
351e1123e7f36723a8b888501c9a22a589297849ca2Jean-Michel Trivi
352e1123e7f36723a8b888501c9a22a589297849ca2Jean-Michel Trivi    /**
353df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * Returns the sampling rate of the captured audio.
354df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * @return the sampling rate in milliHertz.
355df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     */
356df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    public int getSamplingRate()
357df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    throws IllegalStateException {
358df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        synchronized (mStateLock) {
359df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            if (mState == STATE_UNINITIALIZED) {
360df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent                throw(new IllegalStateException("getSamplingRate() called in wrong state: "+mState));
361df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            }
362df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            return native_getSamplingRate();
363df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        }
364df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    }
365df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
366df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    /**
367df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * Returns a waveform capture of currently playing audio content. The capture consists in
368df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * a number of consecutive 8-bit (unsigned) mono PCM samples equal to the capture size returned
369df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * by {@link #getCaptureSize()}.
370df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * <p>This method must be called when the Visualizer is enabled.
371df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * @param waveform array of bytes where the waveform should be returned
372df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * @return {@link #SUCCESS} in case of success,
373df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * {@link #ERROR_NO_MEMORY}, {@link #ERROR_INVALID_OPERATION} or {@link #ERROR_DEAD_OBJECT}
374df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * in case of failure.
375df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * @throws IllegalStateException
376df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     */
377df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    public int getWaveForm(byte[] waveform)
378df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    throws IllegalStateException {
379df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        synchronized (mStateLock) {
380df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            if (mState != STATE_ENABLED) {
381df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent                throw(new IllegalStateException("getWaveForm() called in wrong state: "+mState));
382df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            }
383df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            return native_getWaveForm(waveform);
384df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        }
385df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    }
386df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    /**
38703a4090b4d5965ff01cbb03dcf6d96b30d634fa3Eric Laurent     * Returns a frequency capture of currently playing audio content.
388df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * <p>This method must be called when the Visualizer is enabled.
38903a4090b4d5965ff01cbb03dcf6d96b30d634fa3Eric Laurent     * <p>The capture is an 8-bit magnitude FFT, the frequency range covered being 0 (DC) to half of
39003a4090b4d5965ff01cbb03dcf6d96b30d634fa3Eric Laurent     * the sampling rate returned by {@link #getSamplingRate()}. The capture returns the real and
39103a4090b4d5965ff01cbb03dcf6d96b30d634fa3Eric Laurent     * imaginary parts of a number of frequency points equal to half of the capture size plus one.
39203a4090b4d5965ff01cbb03dcf6d96b30d634fa3Eric Laurent     * <p>Note: only the real part is returned for the first point (DC) and the last point
39303a4090b4d5965ff01cbb03dcf6d96b30d634fa3Eric Laurent     * (sampling frequency / 2).
39403a4090b4d5965ff01cbb03dcf6d96b30d634fa3Eric Laurent     * <p>The layout in the returned byte array is as follows:
39503a4090b4d5965ff01cbb03dcf6d96b30d634fa3Eric Laurent     * <ul>
39603a4090b4d5965ff01cbb03dcf6d96b30d634fa3Eric Laurent     *   <li> n is the capture size returned by getCaptureSize()</li>
39703a4090b4d5965ff01cbb03dcf6d96b30d634fa3Eric Laurent     *   <li> Rfk, Ifk are respectively  the real and imaginary parts of the kth frequency
39803a4090b4d5965ff01cbb03dcf6d96b30d634fa3Eric Laurent     *   component</li>
39903a4090b4d5965ff01cbb03dcf6d96b30d634fa3Eric Laurent     *   <li> If Fs is the sampling frequency retuned by getSamplingRate() the kth frequency is:
40003a4090b4d5965ff01cbb03dcf6d96b30d634fa3Eric Laurent     *   (k*Fs)/(n/2) </li>
40103a4090b4d5965ff01cbb03dcf6d96b30d634fa3Eric Laurent     * </ul>
40203a4090b4d5965ff01cbb03dcf6d96b30d634fa3Eric Laurent     * <table border="0" cellspacing="0" cellpadding="0">
40303a4090b4d5965ff01cbb03dcf6d96b30d634fa3Eric Laurent     * <tr><td>Index </p></td>
40403a4090b4d5965ff01cbb03dcf6d96b30d634fa3Eric Laurent     *     <td>0 </p></td>
40503a4090b4d5965ff01cbb03dcf6d96b30d634fa3Eric Laurent     *     <td>1 </p></td>
40603a4090b4d5965ff01cbb03dcf6d96b30d634fa3Eric Laurent     *     <td>2 </p></td>
40703a4090b4d5965ff01cbb03dcf6d96b30d634fa3Eric Laurent     *     <td>3 </p></td>
40803a4090b4d5965ff01cbb03dcf6d96b30d634fa3Eric Laurent     *     <td>4 </p></td>
40903a4090b4d5965ff01cbb03dcf6d96b30d634fa3Eric Laurent     *     <td>5 </p></td>
41003a4090b4d5965ff01cbb03dcf6d96b30d634fa3Eric Laurent     *     <td>... </p></td>
41103a4090b4d5965ff01cbb03dcf6d96b30d634fa3Eric Laurent     *     <td>n - 2 </p></td>
41203a4090b4d5965ff01cbb03dcf6d96b30d634fa3Eric Laurent     *     <td>n - 1 </p></td></tr>
41303a4090b4d5965ff01cbb03dcf6d96b30d634fa3Eric Laurent     * <tr><td>Data </p></td>
41403a4090b4d5965ff01cbb03dcf6d96b30d634fa3Eric Laurent     *     <td>Rf0 </p></td>
41503a4090b4d5965ff01cbb03dcf6d96b30d634fa3Eric Laurent     *     <td>Rf(n/2) </p></td>
41603a4090b4d5965ff01cbb03dcf6d96b30d634fa3Eric Laurent     *     <td>Rf1 </p></td>
41703a4090b4d5965ff01cbb03dcf6d96b30d634fa3Eric Laurent     *     <td>If1 </p></td>
41803a4090b4d5965ff01cbb03dcf6d96b30d634fa3Eric Laurent     *     <td>Rf2 </p></td>
41903a4090b4d5965ff01cbb03dcf6d96b30d634fa3Eric Laurent     *     <td>If2 </p></td>
42003a4090b4d5965ff01cbb03dcf6d96b30d634fa3Eric Laurent     *     <td>... </p></td>
42103a4090b4d5965ff01cbb03dcf6d96b30d634fa3Eric Laurent     *     <td>Rf(n-1)/2 </p></td>
42203a4090b4d5965ff01cbb03dcf6d96b30d634fa3Eric Laurent     *     <td>If(n-1)/2 </p></td></tr>
42303a4090b4d5965ff01cbb03dcf6d96b30d634fa3Eric Laurent     * </table>
424df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * @param fft array of bytes where the FFT should be returned
425df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * @return {@link #SUCCESS} in case of success,
426df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * {@link #ERROR_NO_MEMORY}, {@link #ERROR_INVALID_OPERATION} or {@link #ERROR_DEAD_OBJECT}
427df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * in case of failure.
428df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * @throws IllegalStateException
429df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     */
430df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    public int getFft(byte[] fft)
431df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    throws IllegalStateException {
432df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        synchronized (mStateLock) {
433df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            if (mState != STATE_ENABLED) {
434df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent                throw(new IllegalStateException("getFft() called in wrong state: "+mState));
435df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            }
436df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            return native_getFft(fft);
437df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        }
438df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    }
439df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
440df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    //---------------------------------------------------------
441df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    // Interface definitions
442df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    //--------------------
443df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    /**
444df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * The OnDataCaptureListener interface defines methods called by the Visualizer to periodically
445df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * update the audio visualization capture.
446df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * The client application can implement this interface and register the listener with the
447df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * {@link #setDataCaptureListener(OnDataCaptureListener, int, boolean, boolean)} method.
448df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     */
449df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    public interface OnDataCaptureListener  {
450df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        /**
451df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent         * Method called when a new waveform capture is available.
452449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman         * <p>Data in the waveform buffer is valid only within the scope of the callback.
453449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman         * Applications which needs access to the waveform data after returning from the callback
454449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman         * should make a copy of the data instead of holding a reference.
455df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent         * @param visualizer Visualizer object on which the listener is registered.
456df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent         * @param waveform array of bytes containing the waveform representation.
457df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent         * @param samplingRate sampling rate of the audio visualized.
458df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent         */
459df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        void onWaveFormDataCapture(Visualizer visualizer, byte[] waveform, int samplingRate);
460df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
461df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        /**
462df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent         * Method called when a new frequency capture is available.
463449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman         * <p>Data in the fft buffer is valid only within the scope of the callback.
464449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman         * Applications which needs access to the fft data after returning from the callback
465449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman         * should make a copy of the data instead of holding a reference.
466df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent         * @param visualizer Visualizer object on which the listener is registered.
467df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent         * @param fft array of bytes containing the frequency representation.
468df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent         * @param samplingRate sampling rate of the audio visualized.
469df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent         */
470df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        void onFftDataCapture(Visualizer visualizer, byte[] fft, int samplingRate);
471df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    }
472df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
473df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    /**
474df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * Registers an OnDataCaptureListener interface and specifies the rate at which the capture
475df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * should be updated as well as the type of capture requested.
476df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * <p>Call this method with a null listener to stop receiving the capture updates.
477df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * @param listener OnDataCaptureListener registered
478df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * @param rate rate in milliHertz at which the capture should be updated
479df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * @param waveform true if a waveform capture is requested: the onWaveFormDataCapture()
480df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * method will be called on the OnDataCaptureListener interface.
481df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * @param fft true if a frequency capture is requested: the onFftDataCapture() method will be
482df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * called on the OnDataCaptureListener interface.
483df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * @return {@link #SUCCESS} in case of success,
484df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * {@link #ERROR_NO_INIT} or {@link #ERROR_BAD_VALUE} in case of failure.
485df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     */
486df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    public int setDataCaptureListener(OnDataCaptureListener listener,
487df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            int rate, boolean waveform, boolean fft) {
488df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        synchronized (mListenerLock) {
489df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            mCaptureListener = listener;
490df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        }
491df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        if (listener == null) {
492df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            // make sure capture callback is stopped in native code
493df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            waveform = false;
494df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            fft = false;
495df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        }
496df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        int status = native_setPeriodicCapture(rate, waveform, fft);
497df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        if (status == SUCCESS) {
498df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            if ((listener != null) && (mNativeEventHandler == null)) {
499df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent                Looper looper;
500df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent                if ((looper = Looper.myLooper()) != null) {
501df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent                    mNativeEventHandler = new NativeEventHandler(this, looper);
502df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent                } else if ((looper = Looper.getMainLooper()) != null) {
503df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent                    mNativeEventHandler = new NativeEventHandler(this, looper);
504df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent                } else {
505df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent                    mNativeEventHandler = null;
506df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent                    status = ERROR_NO_INIT;
507df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent                }
508df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            }
509df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        }
510df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        return status;
511df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    }
512df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
513df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    /**
5143540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman     * @hide
5153540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman     *
5163540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman     * The OnServerDiedListener interface defines a method called by the Visualizer to indicate that
5173540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman     * the connection to the native media server has been broken and that the Visualizer object will
5183540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman     * need to be released and re-created.
5193540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman     * The client application can implement this interface and register the listener with the
5203540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman     * {@link #setServerDiedListener(OnServerDiedListener)} method.
5213540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman     */
5223540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman    public interface OnServerDiedListener  {
5233540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman        /**
5243540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman         * @hide
5253540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman         *
5263540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman         * Method called when the native media server has died.
5273540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman         * <p>If the native media server encounters a fatal error and needs to restart, the binder
5283540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman         * connection from the {@link #Visualizer} to the media server will be broken.  Data capture
5293540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman         * callbacks will stop happening, and client initiated calls to the {@link #Visualizer}
5303540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman         * instance will fail with the error code {@link #DEAD_OBJECT}.  To restore functionality,
5313540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman         * clients should {@link #release()} their old visualizer and create a new instance.
5323540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman         */
5333540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman        void onServerDied();
5343540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman    }
5353540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman
5363540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman    /**
5373540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman     * @hide
5383540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman     *
5393540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman     * Registers an OnServerDiedListener interface.
5403540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman     * <p>Call this method with a null listener to stop receiving server death notifications.
5413540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman     * @return {@link #SUCCESS} in case of success,
5423540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman     */
5433540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman    public int setServerDiedListener(OnServerDiedListener listener) {
5443540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman        synchronized (mListenerLock) {
5453540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman            mServerDiedListener = listener;
5463540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman        }
5473540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman        return SUCCESS;
5483540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman    }
5493540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman
5503540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman    /**
551df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * Helper class to handle the forwarding of native events to the appropriate listeners
552df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     */
553df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    private class NativeEventHandler extends Handler
554df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    {
555df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        private Visualizer mVisualizer;
556df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
557df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        public NativeEventHandler(Visualizer v, Looper looper) {
558df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            super(looper);
559df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            mVisualizer = v;
560df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        }
561df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
5623540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman        private void handleCaptureMessage(Message msg) {
563df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            OnDataCaptureListener l = null;
564df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            synchronized (mListenerLock) {
565df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent                l = mVisualizer.mCaptureListener;
566df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            }
567df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
568df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            if (l != null) {
569df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent                byte[] data = (byte[])msg.obj;
570df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent                int samplingRate = msg.arg1;
5713540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman
572df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent                switch(msg.what) {
573df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent                case NATIVE_EVENT_PCM_CAPTURE:
574df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent                    l.onWaveFormDataCapture(mVisualizer, data, samplingRate);
575df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent                    break;
576df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent                case NATIVE_EVENT_FFT_CAPTURE:
577df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent                    l.onFftDataCapture(mVisualizer, data, samplingRate);
578df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent                    break;
579df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent                default:
5803540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman                    Log.e(TAG,"Unknown native event in handleCaptureMessge: "+msg.what);
581df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent                    break;
582df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent                }
583df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            }
584df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        }
5853540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman
5863540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman        private void handleServerDiedMessage(Message msg) {
5873540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman            OnServerDiedListener l = null;
5883540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman            synchronized (mListenerLock) {
5893540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman                l = mVisualizer.mServerDiedListener;
5903540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman            }
5913540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman
5923540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman            if (l != null)
5933540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman                l.onServerDied();
5943540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman        }
5953540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman
5963540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman        @Override
5973540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman        public void handleMessage(Message msg) {
5983540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman            if (mVisualizer == null) {
5993540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman                return;
6003540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman            }
6013540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman
6023540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman            switch(msg.what) {
6033540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman            case NATIVE_EVENT_PCM_CAPTURE:
6043540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman            case NATIVE_EVENT_FFT_CAPTURE:
6053540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman                handleCaptureMessage(msg);
6063540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman                break;
6073540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman            case NATIVE_EVENT_SERVER_DIED:
6083540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman                handleServerDiedMessage(msg);
6093540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman                break;
6103540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman            default:
6113540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman                Log.e(TAG,"Unknown native event: "+msg.what);
6123540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman                break;
6133540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman            }
6143540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman        }
615df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    }
616df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
617df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    //---------------------------------------------------------
618df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    // Interface definitions
619df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    //--------------------
620df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
621df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    private static native final void native_init();
622df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
623df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    private native final int native_setup(Object audioeffect_this,
624df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent                                          int audioSession,
625df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent                                          int[] id);
626df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
627df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    private native final void native_finalize();
628df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
629df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    private native final void native_release();
630df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
631df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    private native final int native_setEnabled(boolean enabled);
632df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
633df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    private native final boolean native_getEnabled();
634df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
635df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    private native final int native_setCaptureSize(int size);
636df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
637df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    private native final int native_getCaptureSize();
638df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
639e1123e7f36723a8b888501c9a22a589297849ca2Jean-Michel Trivi    private native final int native_setScalingMode(int mode);
640e1123e7f36723a8b888501c9a22a589297849ca2Jean-Michel Trivi
641e1123e7f36723a8b888501c9a22a589297849ca2Jean-Michel Trivi    private native final int native_getScalingMode();
642e1123e7f36723a8b888501c9a22a589297849ca2Jean-Michel Trivi
643df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    private native final int native_getSamplingRate();
644df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
645df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    private native final int native_getWaveForm(byte[] waveform);
646df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
647df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    private native final int native_getFft(byte[] fft);
648df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
649df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    private native final int native_setPeriodicCapture(int rate, boolean waveForm, boolean fft);
650df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
651df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    //---------------------------------------------------------
652df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    // Java methods called from the native side
653df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    //--------------------
654df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    @SuppressWarnings("unused")
655df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    private static void postEventFromNative(Object effect_ref,
656df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            int what, int arg1, int arg2, Object obj) {
657df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        Visualizer visu = (Visualizer)((WeakReference)effect_ref).get();
658df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        if (visu == null) {
659df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            return;
660df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        }
661df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
662df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        if (visu.mNativeEventHandler != null) {
663df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            Message m = visu.mNativeEventHandler.obtainMessage(what, arg1, arg2, obj);
664df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            visu.mNativeEventHandler.sendMessage(m);
665df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        }
666df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
667df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    }
668df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
669df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent}
670df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
671