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 android.os.Handler; 22df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurentimport android.os.Looper; 23df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurentimport android.os.Message; 24df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent 25df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent/** 26df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * The Visualizer class enables application to retrieve part of the currently playing audio for 27df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * visualization purpose. It is not an audio recording interface and only returns partial and low 28df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * quality audio content. However, to protect privacy of certain audio data (e.g voice mail) the use 29df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * of the visualizer requires the permission android.permission.RECORD_AUDIO. 30df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * <p>The audio session ID passed to the constructor indicates which audio content should be 31df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * visualized:<br> 32df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * <ul> 33df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * <li>If the session is 0, the audio output mix is visualized</li> 341a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent * <li>If the session is not 0, the audio from a particular {@link android.media.MediaPlayer} or 351a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent * {@link android.media.AudioTrack} 36df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * using this audio session is visualized </li> 37df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * </ul> 38df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * <p>Two types of representation of audio content can be captured: <br> 39df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * <ul> 40df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * <li>Waveform data: consecutive 8-bit (unsigned) mono samples by using the 41df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * {@link #getWaveForm(byte[])} method</li> 42df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * <li>Frequency data: 8-bit magnitude FFT by using the {@link #getFft(byte[])} method</li> 43df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * </ul> 44df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * <p>The length of the capture can be retrieved or specified by calling respectively 4503a4090b4d5965ff01cbb03dcf6d96b30d634fa3Eric Laurent * {@link #getCaptureSize()} and {@link #setCaptureSize(int)} methods. The capture size must be a 4603a4090b4d5965ff01cbb03dcf6d96b30d634fa3Eric Laurent * power of 2 in the range returned by {@link #getCaptureSizeRange()}. 47df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * <p>In addition to the polling capture mode described above with {@link #getWaveForm(byte[])} and 48df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * {@link #getFft(byte[])} methods, a callback mode is also available by installing a listener by 49df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * use of the {@link #setDataCaptureListener(OnDataCaptureListener, int, boolean, boolean)} method. 50df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * The rate at which the listener capture method is called as well as the type of data returned is 51df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * specified. 52df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * <p>Before capturing data, the Visualizer must be enabled by calling the 53df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * {@link #setEnabled(boolean)} method. 54df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * When data capture is not needed any more, the Visualizer should be disabled. 55df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * <p>It is good practice to call the {@link #release()} method when the Visualizer is not used 56df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * anymore to free up native resources associated to the Visualizer instance. 571a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent * <p>Creating a Visualizer on the output mix (audio session 0) requires permission 581a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent * {@link android.Manifest.permission#MODIFY_AUDIO_SETTINGS} 5901b5743aee4473c3bdbcb0decde47952a4cb739dJean-Michel Trivi * <p>The Visualizer class can also be used to perform measurements on the audio being played back. 6001b5743aee4473c3bdbcb0decde47952a4cb739dJean-Michel Trivi * The measurements to perform are defined by setting a mask of the requested measurement modes with 6101b5743aee4473c3bdbcb0decde47952a4cb739dJean-Michel Trivi * {@link #setMeasurementMode(int)}. Supported values are {@link #MEASUREMENT_MODE_NONE} to cancel 6201b5743aee4473c3bdbcb0decde47952a4cb739dJean-Michel Trivi * any measurement, and {@link #MEASUREMENT_MODE_PEAK_RMS} for peak and RMS monitoring. 6301b5743aee4473c3bdbcb0decde47952a4cb739dJean-Michel Trivi * Measurements can be retrieved through {@link #getMeasurementPeakRms(MeasurementPeakRms)}. 64df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent */ 65df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent 66df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurentpublic class Visualizer { 67df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent 68df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent static { 69df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent System.loadLibrary("audioeffect_jni"); 70df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent native_init(); 71df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent } 72df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent 73df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent private final static String TAG = "Visualizer-JAVA"; 74df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent 75df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent /** 76df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * State of a Visualizer object that was not successfully initialized upon creation 77df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent */ 78df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent public static final int STATE_UNINITIALIZED = 0; 79df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent /** 80df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * State of a Visualizer object that is ready to be used. 81df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent */ 82df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent public static final int STATE_INITIALIZED = 1; 83df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent /** 84df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * State of a Visualizer object that is active. 85df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent */ 86df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent public static final int STATE_ENABLED = 2; 87df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent 88e1123e7f36723a8b888501c9a22a589297849ca2Jean-Michel Trivi // to keep in sync with system/media/audio_effects/include/audio_effects/effect_visualizer.h 89e1123e7f36723a8b888501c9a22a589297849ca2Jean-Michel Trivi /** 90e1123e7f36723a8b888501c9a22a589297849ca2Jean-Michel Trivi * Defines a capture mode where amplification is applied based on the content of the captured 91e1123e7f36723a8b888501c9a22a589297849ca2Jean-Michel Trivi * data. This is the default Visualizer mode, and is suitable for music visualization. 92e1123e7f36723a8b888501c9a22a589297849ca2Jean-Michel Trivi */ 93e1123e7f36723a8b888501c9a22a589297849ca2Jean-Michel Trivi public static final int SCALING_MODE_NORMALIZED = 0; 94e1123e7f36723a8b888501c9a22a589297849ca2Jean-Michel Trivi /** 95e1123e7f36723a8b888501c9a22a589297849ca2Jean-Michel Trivi * Defines a capture mode where the playback volume will affect (scale) the range of the 96e1123e7f36723a8b888501c9a22a589297849ca2Jean-Michel Trivi * captured data. A low playback volume will lead to low sample and fft values, and vice-versa. 97e1123e7f36723a8b888501c9a22a589297849ca2Jean-Michel Trivi */ 98e1123e7f36723a8b888501c9a22a589297849ca2Jean-Michel Trivi public static final int SCALING_MODE_AS_PLAYED = 1; 99e1123e7f36723a8b888501c9a22a589297849ca2Jean-Michel Trivi 100badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi /** 10101b5743aee4473c3bdbcb0decde47952a4cb739dJean-Michel Trivi * Defines a measurement mode in which no measurements are performed. 102badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi */ 103badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi public static final int MEASUREMENT_MODE_NONE = 0; 104badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi 105badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi /** 106badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi * Defines a measurement mode which computes the peak and RMS value in mB, where 0mB is the 107badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi * maximum sample value, and -9600mB is the minimum value. 10801b5743aee4473c3bdbcb0decde47952a4cb739dJean-Michel Trivi * Values for peak and RMS can be retrieved with 10901b5743aee4473c3bdbcb0decde47952a4cb739dJean-Michel Trivi * {@link #getMeasurementPeakRms(MeasurementPeakRms)}. 110badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi */ 111badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi public static final int MEASUREMENT_MODE_PEAK_RMS = 1 << 0; 112badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi 113df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent // to keep in sync with frameworks/base/media/jni/audioeffect/android_media_Visualizer.cpp 11417cb280e7f1ac3556eac90ab08263712e0348cb9Eric Laurent private static final int NATIVE_EVENT_PCM_CAPTURE = 0; 11517cb280e7f1ac3556eac90ab08263712e0348cb9Eric Laurent private static final int NATIVE_EVENT_FFT_CAPTURE = 1; 1163540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman private static final int NATIVE_EVENT_SERVER_DIED = 2; 117df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent 118df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent // Error codes: 119df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent /** 120df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * Successful operation. 121df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent */ 122df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent public static final int SUCCESS = 0; 123df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent /** 124df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * Unspecified error. 125df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent */ 126df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent public static final int ERROR = -1; 127df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent /** 128ed6eae420fd60dcb7d90f54c3116959b75bd6276Glenn Kasten * Internal operation status. Not returned by any method. 129df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent */ 130df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent public static final int ALREADY_EXISTS = -2; 131df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent /** 132df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * Operation failed due to bad object initialization. 133df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent */ 134df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent public static final int ERROR_NO_INIT = -3; 135df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent /** 136df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * Operation failed due to bad parameter value. 137df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent */ 138df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent public static final int ERROR_BAD_VALUE = -4; 139df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent /** 140df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * Operation failed because it was requested in wrong state. 141df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent */ 142df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent public static final int ERROR_INVALID_OPERATION = -5; 143df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent /** 144df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * Operation failed due to lack of memory. 145df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent */ 146df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent public static final int ERROR_NO_MEMORY = -6; 147df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent /** 148df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * Operation failed due to dead remote object. 149df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent */ 150df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent public static final int ERROR_DEAD_OBJECT = -7; 151df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent 152df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent //-------------------------------------------------------------------------- 153df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent // Member variables 154df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent //-------------------- 155df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent /** 156df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * Indicates the state of the Visualizer instance 157df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent */ 15817cb280e7f1ac3556eac90ab08263712e0348cb9Eric Laurent private int mState = STATE_UNINITIALIZED; 159df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent /** 160df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * Lock to synchronize access to mState 161df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent */ 16217cb280e7f1ac3556eac90ab08263712e0348cb9Eric Laurent private final Object mStateLock = new Object(); 163df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent /** 164df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * System wide unique Identifier of the visualizer engine used by this Visualizer instance 165df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent */ 16617cb280e7f1ac3556eac90ab08263712e0348cb9Eric Laurent private int mId; 167df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent 168df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent /** 169df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * Lock to protect listeners updates against event notifications 170df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent */ 17117cb280e7f1ac3556eac90ab08263712e0348cb9Eric Laurent private final Object mListenerLock = new Object(); 172df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent /** 173df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * Handler for events coming from the native code 174df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent */ 17517cb280e7f1ac3556eac90ab08263712e0348cb9Eric Laurent private NativeEventHandler mNativeEventHandler = null; 176df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent /** 177df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * PCM and FFT capture listener registered by client 178df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent */ 17917cb280e7f1ac3556eac90ab08263712e0348cb9Eric Laurent private OnDataCaptureListener mCaptureListener = null; 1803540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman /** 1813540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman * Server Died listener registered by client 1823540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman */ 1833540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman private OnServerDiedListener mServerDiedListener = null; 184df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent 185df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent // accessed by native methods 186ea7861c918567d17d40a762b38f97c053d88b839Ashok Bhat private long mNativeVisualizer; 187ea7861c918567d17d40a762b38f97c053d88b839Ashok Bhat private long mJniData; 188df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent 189df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent //-------------------------------------------------------------------------- 190df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent // Constructor, Finalize 191df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent //-------------------- 192df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent /** 193df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * Class constructor. 19417cb280e7f1ac3556eac90ab08263712e0348cb9Eric Laurent * @param audioSession system wide unique audio session identifier. If audioSession 195df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * is not 0, the visualizer will be attached to the MediaPlayer or AudioTrack in the 196df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * same audio session. Otherwise, the Visualizer will apply to the output mix. 197df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * 198df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * @throws java.lang.UnsupportedOperationException 199df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * @throws java.lang.RuntimeException 200df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent */ 201df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent 202df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent public Visualizer(int audioSession) 203df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent throws UnsupportedOperationException, RuntimeException { 204df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent int[] id = new int[1]; 205df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent 206df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent synchronized (mStateLock) { 207df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent mState = STATE_UNINITIALIZED; 208df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent // native initialization 209df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent int result = native_setup(new WeakReference<Visualizer>(this), audioSession, id); 210df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent if (result != SUCCESS && result != ALREADY_EXISTS) { 211df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent Log.e(TAG, "Error code "+result+" when initializing Visualizer."); 212df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent switch (result) { 213df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent case ERROR_INVALID_OPERATION: 214df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent throw (new UnsupportedOperationException("Effect library not loaded")); 215df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent default: 216df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent throw (new RuntimeException("Cannot initialize Visualizer engine, error: " 217df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent +result)); 218df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent } 219df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent } 220df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent mId = id[0]; 221df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent if (native_getEnabled()) { 222df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent mState = STATE_ENABLED; 223df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent } else { 224df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent mState = STATE_INITIALIZED; 225df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent } 226df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent } 227df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent } 228df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent 229df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent /** 230df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * Releases the native Visualizer resources. It is a good practice to release the 231df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * visualization engine when not in use. 232df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent */ 233df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent public void release() { 234df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent synchronized (mStateLock) { 235df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent native_release(); 236df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent mState = STATE_UNINITIALIZED; 237df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent } 238df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent } 239df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent 240df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent @Override 241df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent protected void finalize() { 242df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent native_finalize(); 243df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent } 244df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent 245df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent /** 246df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * Enable or disable the visualization engine. 247df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * @param enabled requested enable state 248df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * @return {@link #SUCCESS} in case of success, 249df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * {@link #ERROR_INVALID_OPERATION} or {@link #ERROR_DEAD_OBJECT} in case of failure. 250df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * @throws IllegalStateException 251df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent */ 252df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent public int setEnabled(boolean enabled) 253df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent throws IllegalStateException { 254df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent synchronized (mStateLock) { 255672c0dc3a04cb149691603342c319994e21235cbEric Laurent if (mState == STATE_UNINITIALIZED) { 256df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent throw(new IllegalStateException("setEnabled() called in wrong state: "+mState)); 257df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent } 258672c0dc3a04cb149691603342c319994e21235cbEric Laurent int status = SUCCESS; 259672c0dc3a04cb149691603342c319994e21235cbEric Laurent if ((enabled && (mState == STATE_INITIALIZED)) || 260672c0dc3a04cb149691603342c319994e21235cbEric Laurent (!enabled && (mState == STATE_ENABLED))) { 261672c0dc3a04cb149691603342c319994e21235cbEric Laurent status = native_setEnabled(enabled); 262672c0dc3a04cb149691603342c319994e21235cbEric Laurent if (status == SUCCESS) { 263672c0dc3a04cb149691603342c319994e21235cbEric Laurent mState = enabled ? STATE_ENABLED : STATE_INITIALIZED; 264672c0dc3a04cb149691603342c319994e21235cbEric Laurent } 265df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent } 266df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent return status; 267df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent } 268df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent } 269df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent 270df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent /** 271df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * Get current activation state of the visualizer. 272df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * @return true if the visualizer is active, false otherwise 273df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent */ 274df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent public boolean getEnabled() 275df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent { 276df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent synchronized (mStateLock) { 277df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent if (mState == STATE_UNINITIALIZED) { 278df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent throw(new IllegalStateException("getEnabled() called in wrong state: "+mState)); 279df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent } 280df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent return native_getEnabled(); 281df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent } 282df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent } 283df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent 284df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent /** 285df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * Returns the capture size range. 286df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * @return the mininum capture size is returned in first array element and the maximum in second 287df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * array element. 288df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent */ 289df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent public static native int[] getCaptureSizeRange(); 290df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent 291df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent /** 292df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * Returns the maximum capture rate for the callback capture method. This is the maximum value 293df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * for the rate parameter of the 294df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * {@link #setDataCaptureListener(OnDataCaptureListener, int, boolean, boolean)} method. 295df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * @return the maximum capture rate expressed in milliHertz 296df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent */ 297df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent public static native int getMaxCaptureRate(); 298df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent 299df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent /** 300df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * Sets the capture size, i.e. the number of bytes returned by {@link #getWaveForm(byte[])} and 301df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * {@link #getFft(byte[])} methods. The capture size must be a power of 2 in the range returned 302df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * by {@link #getCaptureSizeRange()}. 303df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * This method must not be called when the Visualizer is enabled. 304df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * @param size requested capture size 305df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * @return {@link #SUCCESS} in case of success, 306df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * {@link #ERROR_BAD_VALUE} in case of failure. 307df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * @throws IllegalStateException 308df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent */ 309df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent public int setCaptureSize(int size) 310df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent throws IllegalStateException { 311df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent synchronized (mStateLock) { 312df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent if (mState != STATE_INITIALIZED) { 313df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent throw(new IllegalStateException("setCaptureSize() called in wrong state: "+mState)); 314df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent } 315df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent return native_setCaptureSize(size); 316df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent } 317df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent } 318df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent 319df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent /** 320df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * Returns current capture size. 321df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * @return the capture size in bytes. 322df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent */ 323df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent public int getCaptureSize() 324df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent throws IllegalStateException { 325df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent synchronized (mStateLock) { 326df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent if (mState == STATE_UNINITIALIZED) { 327df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent throw(new IllegalStateException("getCaptureSize() called in wrong state: "+mState)); 328df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent } 329df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent return native_getCaptureSize(); 330df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent } 331df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent } 332df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent 333df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent /** 334e1123e7f36723a8b888501c9a22a589297849ca2Jean-Michel Trivi * Set the type of scaling applied on the captured visualization data. 335e1123e7f36723a8b888501c9a22a589297849ca2Jean-Michel Trivi * @param mode see {@link #SCALING_MODE_NORMALIZED} 336e1123e7f36723a8b888501c9a22a589297849ca2Jean-Michel Trivi * and {@link #SCALING_MODE_AS_PLAYED} 337e1123e7f36723a8b888501c9a22a589297849ca2Jean-Michel Trivi * @return {@link #SUCCESS} in case of success, 338e1123e7f36723a8b888501c9a22a589297849ca2Jean-Michel Trivi * {@link #ERROR_BAD_VALUE} in case of failure. 339e1123e7f36723a8b888501c9a22a589297849ca2Jean-Michel Trivi * @throws IllegalStateException 340e1123e7f36723a8b888501c9a22a589297849ca2Jean-Michel Trivi */ 341e1123e7f36723a8b888501c9a22a589297849ca2Jean-Michel Trivi public int setScalingMode(int mode) 342e1123e7f36723a8b888501c9a22a589297849ca2Jean-Michel Trivi throws IllegalStateException { 343e1123e7f36723a8b888501c9a22a589297849ca2Jean-Michel Trivi synchronized (mStateLock) { 344e1123e7f36723a8b888501c9a22a589297849ca2Jean-Michel Trivi if (mState == STATE_UNINITIALIZED) { 345e1123e7f36723a8b888501c9a22a589297849ca2Jean-Michel Trivi throw(new IllegalStateException("setScalingMode() called in wrong state: " 346e1123e7f36723a8b888501c9a22a589297849ca2Jean-Michel Trivi + mState)); 347e1123e7f36723a8b888501c9a22a589297849ca2Jean-Michel Trivi } 348e1123e7f36723a8b888501c9a22a589297849ca2Jean-Michel Trivi return native_setScalingMode(mode); 349e1123e7f36723a8b888501c9a22a589297849ca2Jean-Michel Trivi } 350e1123e7f36723a8b888501c9a22a589297849ca2Jean-Michel Trivi } 351e1123e7f36723a8b888501c9a22a589297849ca2Jean-Michel Trivi 352e1123e7f36723a8b888501c9a22a589297849ca2Jean-Michel Trivi /** 353e1123e7f36723a8b888501c9a22a589297849ca2Jean-Michel Trivi * Returns the current scaling mode on the captured visualization data. 354e1123e7f36723a8b888501c9a22a589297849ca2Jean-Michel Trivi * @return the scaling mode, see {@link #SCALING_MODE_NORMALIZED} 355e1123e7f36723a8b888501c9a22a589297849ca2Jean-Michel Trivi * and {@link #SCALING_MODE_AS_PLAYED}. 356e1123e7f36723a8b888501c9a22a589297849ca2Jean-Michel Trivi * @throws IllegalStateException 357e1123e7f36723a8b888501c9a22a589297849ca2Jean-Michel Trivi */ 358e1123e7f36723a8b888501c9a22a589297849ca2Jean-Michel Trivi public int getScalingMode() 359e1123e7f36723a8b888501c9a22a589297849ca2Jean-Michel Trivi throws IllegalStateException { 360e1123e7f36723a8b888501c9a22a589297849ca2Jean-Michel Trivi synchronized (mStateLock) { 361e1123e7f36723a8b888501c9a22a589297849ca2Jean-Michel Trivi if (mState == STATE_UNINITIALIZED) { 362e1123e7f36723a8b888501c9a22a589297849ca2Jean-Michel Trivi throw(new IllegalStateException("getScalingMode() called in wrong state: " 363e1123e7f36723a8b888501c9a22a589297849ca2Jean-Michel Trivi + mState)); 364e1123e7f36723a8b888501c9a22a589297849ca2Jean-Michel Trivi } 365e1123e7f36723a8b888501c9a22a589297849ca2Jean-Michel Trivi return native_getScalingMode(); 366e1123e7f36723a8b888501c9a22a589297849ca2Jean-Michel Trivi } 367e1123e7f36723a8b888501c9a22a589297849ca2Jean-Michel Trivi } 368e1123e7f36723a8b888501c9a22a589297849ca2Jean-Michel Trivi 369e1123e7f36723a8b888501c9a22a589297849ca2Jean-Michel Trivi /** 370badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi * Sets the combination of measurement modes to be performed by this audio effect. 371badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi * @param mode a mask of the measurements to perform. The valid values are 372badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi * {@link #MEASUREMENT_MODE_NONE} (to cancel any measurement) 373badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi * or {@link #MEASUREMENT_MODE_PEAK_RMS}. 374badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi * @return {@link #SUCCESS} in case of success, {@link #ERROR_BAD_VALUE} in case of failure. 375badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi * @throws IllegalStateException 376badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi */ 377badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi public int setMeasurementMode(int mode) 378badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi throws IllegalStateException { 379badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi synchronized (mStateLock) { 380badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi if (mState == STATE_UNINITIALIZED) { 381badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi throw(new IllegalStateException("setMeasurementMode() called in wrong state: " 382badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi + mState)); 383badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi } 384badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi return native_setMeasurementMode(mode); 385badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi } 386badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi } 387badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi 388badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi /** 389badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi * Returns the current measurement modes performed by this audio effect 390badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi * @return the mask of the measurements, 391badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi * {@link #MEASUREMENT_MODE_NONE} (when no measurements are performed) 392badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi * or {@link #MEASUREMENT_MODE_PEAK_RMS}. 393badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi * @throws IllegalStateException 394badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi */ 395badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi public int getMeasurementMode() 396badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi throws IllegalStateException { 397badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi synchronized (mStateLock) { 398badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi if (mState == STATE_UNINITIALIZED) { 399badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi throw(new IllegalStateException("getMeasurementMode() called in wrong state: " 400badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi + mState)); 401badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi } 402badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi return native_getMeasurementMode(); 403badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi } 404badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi } 405badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi 406badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi /** 407df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * Returns the sampling rate of the captured audio. 408df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * @return the sampling rate in milliHertz. 409df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent */ 410df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent public int getSamplingRate() 411df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent throws IllegalStateException { 412df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent synchronized (mStateLock) { 413df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent if (mState == STATE_UNINITIALIZED) { 414df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent throw(new IllegalStateException("getSamplingRate() called in wrong state: "+mState)); 415df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent } 416df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent return native_getSamplingRate(); 417df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent } 418df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent } 419df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent 420df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent /** 421df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * Returns a waveform capture of currently playing audio content. The capture consists in 422df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * a number of consecutive 8-bit (unsigned) mono PCM samples equal to the capture size returned 423df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * by {@link #getCaptureSize()}. 424df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * <p>This method must be called when the Visualizer is enabled. 425df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * @param waveform array of bytes where the waveform should be returned 426df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * @return {@link #SUCCESS} in case of success, 427df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * {@link #ERROR_NO_MEMORY}, {@link #ERROR_INVALID_OPERATION} or {@link #ERROR_DEAD_OBJECT} 428df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * in case of failure. 429df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * @throws IllegalStateException 430df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent */ 431df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent public int getWaveForm(byte[] waveform) 432df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent throws IllegalStateException { 433df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent synchronized (mStateLock) { 434df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent if (mState != STATE_ENABLED) { 435df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent throw(new IllegalStateException("getWaveForm() called in wrong state: "+mState)); 436df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent } 437df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent return native_getWaveForm(waveform); 438df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent } 439df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent } 440df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent /** 44103a4090b4d5965ff01cbb03dcf6d96b30d634fa3Eric Laurent * Returns a frequency capture of currently playing audio content. 442df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * <p>This method must be called when the Visualizer is enabled. 44303a4090b4d5965ff01cbb03dcf6d96b30d634fa3Eric Laurent * <p>The capture is an 8-bit magnitude FFT, the frequency range covered being 0 (DC) to half of 44403a4090b4d5965ff01cbb03dcf6d96b30d634fa3Eric Laurent * the sampling rate returned by {@link #getSamplingRate()}. The capture returns the real and 44503a4090b4d5965ff01cbb03dcf6d96b30d634fa3Eric Laurent * imaginary parts of a number of frequency points equal to half of the capture size plus one. 44603a4090b4d5965ff01cbb03dcf6d96b30d634fa3Eric Laurent * <p>Note: only the real part is returned for the first point (DC) and the last point 44703a4090b4d5965ff01cbb03dcf6d96b30d634fa3Eric Laurent * (sampling frequency / 2). 44803a4090b4d5965ff01cbb03dcf6d96b30d634fa3Eric Laurent * <p>The layout in the returned byte array is as follows: 44903a4090b4d5965ff01cbb03dcf6d96b30d634fa3Eric Laurent * <ul> 45003a4090b4d5965ff01cbb03dcf6d96b30d634fa3Eric Laurent * <li> n is the capture size returned by getCaptureSize()</li> 45103a4090b4d5965ff01cbb03dcf6d96b30d634fa3Eric Laurent * <li> Rfk, Ifk are respectively the real and imaginary parts of the kth frequency 45203a4090b4d5965ff01cbb03dcf6d96b30d634fa3Eric Laurent * component</li> 45303a4090b4d5965ff01cbb03dcf6d96b30d634fa3Eric Laurent * <li> If Fs is the sampling frequency retuned by getSamplingRate() the kth frequency is: 45403a4090b4d5965ff01cbb03dcf6d96b30d634fa3Eric Laurent * (k*Fs)/(n/2) </li> 45503a4090b4d5965ff01cbb03dcf6d96b30d634fa3Eric Laurent * </ul> 45603a4090b4d5965ff01cbb03dcf6d96b30d634fa3Eric Laurent * <table border="0" cellspacing="0" cellpadding="0"> 45703a4090b4d5965ff01cbb03dcf6d96b30d634fa3Eric Laurent * <tr><td>Index </p></td> 45803a4090b4d5965ff01cbb03dcf6d96b30d634fa3Eric Laurent * <td>0 </p></td> 45903a4090b4d5965ff01cbb03dcf6d96b30d634fa3Eric Laurent * <td>1 </p></td> 46003a4090b4d5965ff01cbb03dcf6d96b30d634fa3Eric Laurent * <td>2 </p></td> 46103a4090b4d5965ff01cbb03dcf6d96b30d634fa3Eric Laurent * <td>3 </p></td> 46203a4090b4d5965ff01cbb03dcf6d96b30d634fa3Eric Laurent * <td>4 </p></td> 46303a4090b4d5965ff01cbb03dcf6d96b30d634fa3Eric Laurent * <td>5 </p></td> 46403a4090b4d5965ff01cbb03dcf6d96b30d634fa3Eric Laurent * <td>... </p></td> 46503a4090b4d5965ff01cbb03dcf6d96b30d634fa3Eric Laurent * <td>n - 2 </p></td> 46603a4090b4d5965ff01cbb03dcf6d96b30d634fa3Eric Laurent * <td>n - 1 </p></td></tr> 46703a4090b4d5965ff01cbb03dcf6d96b30d634fa3Eric Laurent * <tr><td>Data </p></td> 46803a4090b4d5965ff01cbb03dcf6d96b30d634fa3Eric Laurent * <td>Rf0 </p></td> 46903a4090b4d5965ff01cbb03dcf6d96b30d634fa3Eric Laurent * <td>Rf(n/2) </p></td> 47003a4090b4d5965ff01cbb03dcf6d96b30d634fa3Eric Laurent * <td>Rf1 </p></td> 47103a4090b4d5965ff01cbb03dcf6d96b30d634fa3Eric Laurent * <td>If1 </p></td> 47203a4090b4d5965ff01cbb03dcf6d96b30d634fa3Eric Laurent * <td>Rf2 </p></td> 47303a4090b4d5965ff01cbb03dcf6d96b30d634fa3Eric Laurent * <td>If2 </p></td> 47403a4090b4d5965ff01cbb03dcf6d96b30d634fa3Eric Laurent * <td>... </p></td> 47503a4090b4d5965ff01cbb03dcf6d96b30d634fa3Eric Laurent * <td>Rf(n-1)/2 </p></td> 47603a4090b4d5965ff01cbb03dcf6d96b30d634fa3Eric Laurent * <td>If(n-1)/2 </p></td></tr> 47703a4090b4d5965ff01cbb03dcf6d96b30d634fa3Eric Laurent * </table> 478df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * @param fft array of bytes where the FFT should be returned 479df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * @return {@link #SUCCESS} in case of success, 480df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * {@link #ERROR_NO_MEMORY}, {@link #ERROR_INVALID_OPERATION} or {@link #ERROR_DEAD_OBJECT} 481df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * in case of failure. 482df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * @throws IllegalStateException 483df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent */ 484df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent public int getFft(byte[] fft) 485df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent throws IllegalStateException { 486df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent synchronized (mStateLock) { 487df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent if (mState != STATE_ENABLED) { 488df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent throw(new IllegalStateException("getFft() called in wrong state: "+mState)); 489df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent } 490df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent return native_getFft(fft); 491df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent } 492df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent } 493df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent 494badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi /** 495badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi * A class to store peak and RMS values. 496badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi * Peak and RMS are expressed in mB, as described in the 497badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi * {@link Visualizer#MEASUREMENT_MODE_PEAK_RMS} measurement mode. 498badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi */ 499badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi public static final class MeasurementPeakRms { 500badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi /** 50101b5743aee4473c3bdbcb0decde47952a4cb739dJean-Michel Trivi * The peak value in mB. 502badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi */ 503badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi public int mPeak; 504badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi /** 50501b5743aee4473c3bdbcb0decde47952a4cb739dJean-Michel Trivi * The RMS value in mB. 506badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi */ 507badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi public int mRms; 508badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi } 509badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi 510badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi /** 511badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi * Retrieves the latest peak and RMS measurement. 51201b5743aee4473c3bdbcb0decde47952a4cb739dJean-Michel Trivi * Sets the peak and RMS fields of the supplied {@link Visualizer.MeasurementPeakRms} to the 51301b5743aee4473c3bdbcb0decde47952a4cb739dJean-Michel Trivi * latest measured values. 514badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi * @param measurement a non-null {@link Visualizer.MeasurementPeakRms} instance to store 515badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi * the measurement values. 516badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi * @return {@link #SUCCESS} in case of success, {@link #ERROR_BAD_VALUE}, 517badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi * {@link #ERROR_NO_MEMORY}, {@link #ERROR_INVALID_OPERATION} or {@link #ERROR_DEAD_OBJECT} 518badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi * in case of failure. 519badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi */ 520badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi public int getMeasurementPeakRms(MeasurementPeakRms measurement) { 521badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi if (measurement == null) { 522badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi Log.e(TAG, "Cannot store measurements in a null object"); 523badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi return ERROR_BAD_VALUE; 524badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi } 525badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi synchronized (mStateLock) { 526badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi if (mState != STATE_ENABLED) { 527badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi throw (new IllegalStateException("getMeasurementPeakRms() called in wrong state: " 528badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi + mState)); 529badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi } 530badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi return native_getPeakRms(measurement); 531badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi } 532badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi } 533badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi 534df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent //--------------------------------------------------------- 535df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent // Interface definitions 536df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent //-------------------- 537df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent /** 538df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * The OnDataCaptureListener interface defines methods called by the Visualizer to periodically 539df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * update the audio visualization capture. 540df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * The client application can implement this interface and register the listener with the 541df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * {@link #setDataCaptureListener(OnDataCaptureListener, int, boolean, boolean)} method. 542df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent */ 543df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent public interface OnDataCaptureListener { 544df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent /** 545df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * Method called when a new waveform capture is available. 546449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman * <p>Data in the waveform buffer is valid only within the scope of the callback. 547449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman * Applications which needs access to the waveform data after returning from the callback 548449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman * should make a copy of the data instead of holding a reference. 549df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * @param visualizer Visualizer object on which the listener is registered. 550df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * @param waveform array of bytes containing the waveform representation. 551df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * @param samplingRate sampling rate of the audio visualized. 552df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent */ 553df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent void onWaveFormDataCapture(Visualizer visualizer, byte[] waveform, int samplingRate); 554df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent 555df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent /** 556df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * Method called when a new frequency capture is available. 557449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman * <p>Data in the fft buffer is valid only within the scope of the callback. 558449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman * Applications which needs access to the fft data after returning from the callback 559449725f9aa67136a38c7554ba76ac4e27e5e3bd3John Grossman * should make a copy of the data instead of holding a reference. 560df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * @param visualizer Visualizer object on which the listener is registered. 561df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * @param fft array of bytes containing the frequency representation. 562df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * @param samplingRate sampling rate of the audio visualized. 563df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent */ 564df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent void onFftDataCapture(Visualizer visualizer, byte[] fft, int samplingRate); 565df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent } 566df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent 567df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent /** 568df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * Registers an OnDataCaptureListener interface and specifies the rate at which the capture 569df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * should be updated as well as the type of capture requested. 570df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * <p>Call this method with a null listener to stop receiving the capture updates. 571df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * @param listener OnDataCaptureListener registered 572df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * @param rate rate in milliHertz at which the capture should be updated 573df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * @param waveform true if a waveform capture is requested: the onWaveFormDataCapture() 574df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * method will be called on the OnDataCaptureListener interface. 575df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * @param fft true if a frequency capture is requested: the onFftDataCapture() method will be 576df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * called on the OnDataCaptureListener interface. 577df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * @return {@link #SUCCESS} in case of success, 578df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * {@link #ERROR_NO_INIT} or {@link #ERROR_BAD_VALUE} in case of failure. 579df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent */ 580df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent public int setDataCaptureListener(OnDataCaptureListener listener, 581df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent int rate, boolean waveform, boolean fft) { 582df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent synchronized (mListenerLock) { 583df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent mCaptureListener = listener; 584df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent } 585df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent if (listener == null) { 586df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent // make sure capture callback is stopped in native code 587df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent waveform = false; 588df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent fft = false; 589df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent } 590df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent int status = native_setPeriodicCapture(rate, waveform, fft); 591df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent if (status == SUCCESS) { 592df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent if ((listener != null) && (mNativeEventHandler == null)) { 593df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent Looper looper; 594df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent if ((looper = Looper.myLooper()) != null) { 595df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent mNativeEventHandler = new NativeEventHandler(this, looper); 596df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent } else if ((looper = Looper.getMainLooper()) != null) { 597df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent mNativeEventHandler = new NativeEventHandler(this, looper); 598df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent } else { 599df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent mNativeEventHandler = null; 600df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent status = ERROR_NO_INIT; 601df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent } 602df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent } 603df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent } 604df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent return status; 605df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent } 606df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent 607df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent /** 6083540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman * @hide 6093540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman * 6103540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman * The OnServerDiedListener interface defines a method called by the Visualizer to indicate that 6113540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman * the connection to the native media server has been broken and that the Visualizer object will 6123540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman * need to be released and re-created. 6133540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman * The client application can implement this interface and register the listener with the 6143540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman * {@link #setServerDiedListener(OnServerDiedListener)} method. 6153540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman */ 6163540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman public interface OnServerDiedListener { 6173540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman /** 6183540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman * @hide 6193540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman * 6203540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman * Method called when the native media server has died. 6213540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman * <p>If the native media server encounters a fatal error and needs to restart, the binder 6223540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman * connection from the {@link #Visualizer} to the media server will be broken. Data capture 6233540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman * callbacks will stop happening, and client initiated calls to the {@link #Visualizer} 6243540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman * instance will fail with the error code {@link #DEAD_OBJECT}. To restore functionality, 6253540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman * clients should {@link #release()} their old visualizer and create a new instance. 6263540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman */ 6273540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman void onServerDied(); 6283540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman } 6293540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman 6303540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman /** 6313540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman * @hide 6323540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman * 6333540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman * Registers an OnServerDiedListener interface. 6343540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman * <p>Call this method with a null listener to stop receiving server death notifications. 6353540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman * @return {@link #SUCCESS} in case of success, 6363540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman */ 6373540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman public int setServerDiedListener(OnServerDiedListener listener) { 6383540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman synchronized (mListenerLock) { 6393540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman mServerDiedListener = listener; 6403540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman } 6413540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman return SUCCESS; 6423540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman } 6433540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman 6443540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman /** 645df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent * Helper class to handle the forwarding of native events to the appropriate listeners 646df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent */ 647df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent private class NativeEventHandler extends Handler 648df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent { 649df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent private Visualizer mVisualizer; 650df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent 651df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent public NativeEventHandler(Visualizer v, Looper looper) { 652df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent super(looper); 653df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent mVisualizer = v; 654df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent } 655df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent 6563540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman private void handleCaptureMessage(Message msg) { 657df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent OnDataCaptureListener l = null; 658df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent synchronized (mListenerLock) { 659df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent l = mVisualizer.mCaptureListener; 660df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent } 661df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent 662df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent if (l != null) { 663df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent byte[] data = (byte[])msg.obj; 664df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent int samplingRate = msg.arg1; 6653540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman 666df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent switch(msg.what) { 667df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent case NATIVE_EVENT_PCM_CAPTURE: 668df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent l.onWaveFormDataCapture(mVisualizer, data, samplingRate); 669df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent break; 670df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent case NATIVE_EVENT_FFT_CAPTURE: 671df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent l.onFftDataCapture(mVisualizer, data, samplingRate); 672df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent break; 673df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent default: 6743540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman Log.e(TAG,"Unknown native event in handleCaptureMessge: "+msg.what); 675df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent break; 676df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent } 677df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent } 678df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent } 6793540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman 6803540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman private void handleServerDiedMessage(Message msg) { 6813540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman OnServerDiedListener l = null; 6823540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman synchronized (mListenerLock) { 6833540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman l = mVisualizer.mServerDiedListener; 6843540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman } 6853540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman 6863540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman if (l != null) 6873540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman l.onServerDied(); 6883540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman } 6893540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman 6903540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman @Override 6913540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman public void handleMessage(Message msg) { 6923540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman if (mVisualizer == null) { 6933540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman return; 6943540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman } 6953540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman 6963540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman switch(msg.what) { 6973540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman case NATIVE_EVENT_PCM_CAPTURE: 6983540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman case NATIVE_EVENT_FFT_CAPTURE: 6993540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman handleCaptureMessage(msg); 7003540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman break; 7013540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman case NATIVE_EVENT_SERVER_DIED: 7023540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman handleServerDiedMessage(msg); 7033540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman break; 7043540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman default: 7053540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman Log.e(TAG,"Unknown native event: "+msg.what); 7063540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman break; 7073540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman } 7083540a0197f56c4bcd7d7419f4502bfca34257de2John Grossman } 709df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent } 710df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent 711df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent //--------------------------------------------------------- 712df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent // Interface definitions 713df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent //-------------------- 714df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent 715df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent private static native final void native_init(); 716df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent 717df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent private native final int native_setup(Object audioeffect_this, 718df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent int audioSession, 719df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent int[] id); 720df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent 721df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent private native final void native_finalize(); 722df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent 723df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent private native final void native_release(); 724df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent 725df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent private native final int native_setEnabled(boolean enabled); 726df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent 727df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent private native final boolean native_getEnabled(); 728df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent 729df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent private native final int native_setCaptureSize(int size); 730df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent 731df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent private native final int native_getCaptureSize(); 732df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent 733e1123e7f36723a8b888501c9a22a589297849ca2Jean-Michel Trivi private native final int native_setScalingMode(int mode); 734e1123e7f36723a8b888501c9a22a589297849ca2Jean-Michel Trivi 735e1123e7f36723a8b888501c9a22a589297849ca2Jean-Michel Trivi private native final int native_getScalingMode(); 736e1123e7f36723a8b888501c9a22a589297849ca2Jean-Michel Trivi 737badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi private native final int native_setMeasurementMode(int mode); 738badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi 739badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi private native final int native_getMeasurementMode(); 740badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi 741df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent private native final int native_getSamplingRate(); 742df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent 743df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent private native final int native_getWaveForm(byte[] waveform); 744df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent 745df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent private native final int native_getFft(byte[] fft); 746df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent 747badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi private native final int native_getPeakRms(MeasurementPeakRms measurement); 748badca26cb218852d32862dada36ee52fce865ad2Jean-Michel Trivi 749df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent private native final int native_setPeriodicCapture(int rate, boolean waveForm, boolean fft); 750df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent 751df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent //--------------------------------------------------------- 752df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent // Java methods called from the native side 753df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent //-------------------- 754df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent @SuppressWarnings("unused") 755df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent private static void postEventFromNative(Object effect_ref, 756df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent int what, int arg1, int arg2, Object obj) { 757df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent Visualizer visu = (Visualizer)((WeakReference)effect_ref).get(); 758df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent if (visu == null) { 759df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent return; 760df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent } 761df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent 762df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent if (visu.mNativeEventHandler != null) { 763df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent Message m = visu.mNativeEventHandler.obtainMessage(what, arg1, arg2, obj); 764df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent visu.mNativeEventHandler.sendMessage(m); 765df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent } 766df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent 767df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent } 768df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent 769df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent} 770df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent 771