1948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent/*
2948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent * Copyright (C) 2010 The Android Open Source Project
3948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent *
4948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent * Licensed under the Apache License, Version 2.0 (the "License");
5948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent * you may not use this file except in compliance with the License.
6948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent * You may obtain a copy of the License at
7948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent *
8948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent *      http://www.apache.org/licenses/LICENSE-2.0
9948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent *
10948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent * Unless required by applicable law or agreed to in writing, software
11948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent * distributed under the License is distributed on an "AS IS" BASIS,
12948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent * See the License for the specific language governing permissions and
14948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent * limitations under the License.
15948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent */
16948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
171a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurentpackage android.media.audiofx;
18948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
19d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurentimport android.annotation.SdkConstant;
20d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurentimport android.annotation.SdkConstant.SdkConstantType;
21fa5ecdc4ac6d7a8db2bb9e4a6a60a3189025df30Svet Ganovimport android.app.ActivityThread;
22948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurentimport android.os.Handler;
23948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurentimport android.os.Looper;
24948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurentimport android.os.Message;
25d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurentimport android.util.Log;
26d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurentimport java.lang.ref.WeakReference;
27948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurentimport java.nio.ByteOrder;
28948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurentimport java.nio.ByteBuffer;
29948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurentimport java.util.UUID;
30948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
31948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent/**
321a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent * AudioEffect is the base class for controlling audio effects provided by the android audio
331a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent * framework.
341a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent * <p>Applications should not use the AudioEffect class directly but one of its derived classes to
351a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent * control specific effects:
361a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent * <ul>
371a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent *   <li> {@link android.media.audiofx.Equalizer}</li>
381a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent *   <li> {@link android.media.audiofx.Virtualizer}</li>
391a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent *   <li> {@link android.media.audiofx.BassBoost}</li>
401a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent *   <li> {@link android.media.audiofx.PresetReverb}</li>
411a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent *   <li> {@link android.media.audiofx.EnvironmentalReverb}</li>
421a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent * </ul>
4362f3617f2f4016ad2f59635d5156d64872989880Eric Laurent * <p>To apply the audio effect to a specific AudioTrack or MediaPlayer instance,
441a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent * the application must specify the audio session ID of that instance when creating the AudioEffect.
451a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent * (see {@link android.media.MediaPlayer#getAudioSessionId()} for details on audio sessions).
4662f3617f2f4016ad2f59635d5156d64872989880Eric Laurent * <p>NOTE: attaching insert effects (equalizer, bass boost, virtualizer) to the global audio output
4762f3617f2f4016ad2f59635d5156d64872989880Eric Laurent * mix by use of session 0 is deprecated.
481a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent * <p>Creating an AudioEffect object will create the corresponding effect engine in the audio
491a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent * framework if no instance of the same effect type exists in the specified audio session.
501a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent * If one exists, this instance will be used.
511a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent * <p>The application creating the AudioEffect object (or a derived class) will either receive
521a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent * control of the effect engine or not depending on the priority parameter. If priority is higher
531a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent * than the priority used by the current effect engine owner, the control will be transfered to the
541a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent * new object. Otherwise control will remain with the previous object. In this case, the new
551a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent * application will be notified of changes in effect engine state or control ownership by the
561c22ae296b85d0eebc305781b4df274ac10dbfcaMark Goldstein * appropriate listener.
57948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent */
581a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent
59df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurentpublic class AudioEffect {
60948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    static {
61948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        System.loadLibrary("audioeffect_jni");
62948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        native_init();
63948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    }
64948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
65948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    private final static String TAG = "AudioEffect-JAVA";
66948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
670f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent    // effect type UUIDs are taken from hardware/libhardware/include/hardware/audio_effect.h
680f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent
69948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    /**
70df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * The following UUIDs define effect types corresponding to standard audio
71df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * effects whose implementation and interface conform to the OpenSL ES
72df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * specification. The definitions match the corresponding interface IDs in
73df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * OpenSLES_IID.h
74948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     */
75df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    /**
7680569f7ff7db28ce98dde6e22bb4521ddbe5490aJean-Michel Trivi     * UUID for environmental reverberation effect
77df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     */
78df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    public static final UUID EFFECT_TYPE_ENV_REVERB = UUID
79df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            .fromString("c2e5d5f0-94bd-4763-9cac-4e234d06839e");
80df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    /**
8180569f7ff7db28ce98dde6e22bb4521ddbe5490aJean-Michel Trivi     * UUID for preset reverberation effect
82df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     */
83df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    public static final UUID EFFECT_TYPE_PRESET_REVERB = UUID
84df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            .fromString("47382d60-ddd8-11db-bf3a-0002a5d5c51b");
85df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    /**
86df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * UUID for equalizer effect
87df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     */
88df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    public static final UUID EFFECT_TYPE_EQUALIZER = UUID
89df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            .fromString("0bed4300-ddd6-11db-8f34-0002a5d5c51b");
90df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    /**
91df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * UUID for bass boost effect
92df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     */
93df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    public static final UUID EFFECT_TYPE_BASS_BOOST = UUID
94df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            .fromString("0634f220-ddd4-11db-a0fc-0002a5d5c51b");
95df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    /**
96df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * UUID for virtualizer effect
97df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     */
98df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    public static final UUID EFFECT_TYPE_VIRTUALIZER = UUID
99df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            .fromString("37cc2c00-dddd-11db-8577-0002a5d5c51b");
100948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
101948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    /**
10280569f7ff7db28ce98dde6e22bb4521ddbe5490aJean-Michel Trivi     * UUIDs for effect types not covered by OpenSL ES.
10380569f7ff7db28ce98dde6e22bb4521ddbe5490aJean-Michel Trivi     */
10480569f7ff7db28ce98dde6e22bb4521ddbe5490aJean-Michel Trivi    /**
10580569f7ff7db28ce98dde6e22bb4521ddbe5490aJean-Michel Trivi     * UUID for Automatic Gain Control (AGC)
1060f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent     */
1070f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent    public static final UUID EFFECT_TYPE_AGC = UUID
1080f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent            .fromString("0a8abfe0-654c-11e0-ba26-0002a5d5c51b");
1090f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent
1100f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent    /**
11180569f7ff7db28ce98dde6e22bb4521ddbe5490aJean-Michel Trivi     * UUID for Acoustic Echo Canceler (AEC)
1120f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent     */
1130f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent    public static final UUID EFFECT_TYPE_AEC = UUID
1140f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent            .fromString("7b491460-8d4d-11e0-bd61-0002a5d5c51b");
1150f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent
1160f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent    /**
11780569f7ff7db28ce98dde6e22bb4521ddbe5490aJean-Michel Trivi     * UUID for Noise Suppressor (NS)
1180f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent     */
1190f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent    public static final UUID EFFECT_TYPE_NS = UUID
1200f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent            .fromString("58b4b260-8e06-11e0-aa8e-0002a5d5c51b");
1210f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent
1220f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent    /**
123d69e4e14226258fd103d0b9c1c5b4d8529e6a3ecJean-Michel Trivi     * UUID for Loudness Enhancer
124d69e4e14226258fd103d0b9c1c5b4d8529e6a3ecJean-Michel Trivi     */
125d69e4e14226258fd103d0b9c1c5b4d8529e6a3ecJean-Michel Trivi    public static final UUID EFFECT_TYPE_LOUDNESS_ENHANCER = UUID
126d69e4e14226258fd103d0b9c1c5b4d8529e6a3ecJean-Michel Trivi              .fromString("fe3199be-aed0-413f-87bb-11260eb63cf1");
127d69e4e14226258fd103d0b9c1c5b4d8529e6a3ecJean-Michel Trivi
128d69e4e14226258fd103d0b9c1c5b4d8529e6a3ecJean-Michel Trivi    /**
129df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * Null effect UUID. Used when the UUID for effect type of
1301a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent     * @hide
131df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     */
132df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    public static final UUID EFFECT_TYPE_NULL = UUID
133df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            .fromString("ec7178ec-e5e1-4432-a3f4-4657e6795210");
134df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
135df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    /**
136df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * State of an AudioEffect object that was not successfully initialized upon
137df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * creation
1381a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent     * @hide
139948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     */
140948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    public static final int STATE_UNINITIALIZED = 0;
141948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    /**
142948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     * State of an AudioEffect object that is ready to be used.
1431a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent     * @hide
144948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     */
145df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    public static final int STATE_INITIALIZED = 1;
146948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
147df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    // to keep in sync with
1482a6b80bc65c4782b5a7168b300e1dc5ec9f617eeEric Laurent    // frameworks/base/include/media/AudioEffect.h
149948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    /**
1502a6b80bc65c4782b5a7168b300e1dc5ec9f617eeEric Laurent     * Event id for engine control ownership change notification.
1511a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent     * @hide
152948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     */
1532a6b80bc65c4782b5a7168b300e1dc5ec9f617eeEric Laurent    public static final int NATIVE_EVENT_CONTROL_STATUS = 0;
154948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    /**
1552a6b80bc65c4782b5a7168b300e1dc5ec9f617eeEric Laurent     * Event id for engine state change notification.
1561a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent     * @hide
157948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     */
1582a6b80bc65c4782b5a7168b300e1dc5ec9f617eeEric Laurent    public static final int NATIVE_EVENT_ENABLED_STATUS = 1;
159948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    /**
160948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     * Event id for engine parameter change notification.
1611a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent     * @hide
162948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     */
16317cb280e7f1ac3556eac90ab08263712e0348cb9Eric Laurent    public static final int NATIVE_EVENT_PARAMETER_CHANGED = 2;
164948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
165df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    /**
166df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * Successful operation.
167df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     */
168df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    public static final int SUCCESS = 0;
169df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    /**
170df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * Unspecified error.
171df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     */
172df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    public static final int ERROR = -1;
173df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    /**
174ed6eae420fd60dcb7d90f54c3116959b75bd6276Glenn Kasten     * Internal operation status. Not returned by any method.
175df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     */
176df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    public static final int ALREADY_EXISTS = -2;
177df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    /**
178df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * Operation failed due to bad object initialization.
179df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     */
180df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    public static final int ERROR_NO_INIT = -3;
181df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    /**
182df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * Operation failed due to bad parameter value.
183df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     */
184df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    public static final int ERROR_BAD_VALUE = -4;
185df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    /**
186df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * Operation failed because it was requested in wrong state.
187df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     */
188df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    public static final int ERROR_INVALID_OPERATION = -5;
189df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    /**
190df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * Operation failed due to lack of memory.
191df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     */
192df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    public static final int ERROR_NO_MEMORY = -6;
193df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    /**
194df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * Operation failed due to dead remote object.
195df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     */
196df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    public static final int ERROR_DEAD_OBJECT = -7;
197df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
198df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    /**
1991a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent     * The effect descriptor contains information on a particular effect implemented in the
2001a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent     * audio framework:<br>
201df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * <ul>
2021d154187a99d5ad8dd33d47173cf6a4456276e76Scott Main     *  <li>type: UUID identifying the effect type. May be one of:
2031d154187a99d5ad8dd33d47173cf6a4456276e76Scott Main     * {@link AudioEffect#EFFECT_TYPE_AEC}, {@link AudioEffect#EFFECT_TYPE_AGC},
2041d154187a99d5ad8dd33d47173cf6a4456276e76Scott Main     * {@link AudioEffect#EFFECT_TYPE_BASS_BOOST}, {@link AudioEffect#EFFECT_TYPE_ENV_REVERB},
2051d154187a99d5ad8dd33d47173cf6a4456276e76Scott Main     * {@link AudioEffect#EFFECT_TYPE_EQUALIZER}, {@link AudioEffect#EFFECT_TYPE_NS},
2061d154187a99d5ad8dd33d47173cf6a4456276e76Scott Main     * {@link AudioEffect#EFFECT_TYPE_PRESET_REVERB}, {@link AudioEffect#EFFECT_TYPE_VIRTUALIZER}.
2071d154187a99d5ad8dd33d47173cf6a4456276e76Scott Main     *  </li>
2081a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent     *  <li>uuid: UUID for this particular implementation</li>
2091d154187a99d5ad8dd33d47173cf6a4456276e76Scott Main     *  <li>connectMode: {@link #EFFECT_INSERT} or {@link #EFFECT_AUXILIARY}</li>
2101a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent     *  <li>name: human readable effect name</li>
2111a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent     *  <li>implementor: human readable effect implementor name</li>
212df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * </ul>
2131a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent     * The method {@link #queryEffects()} returns an array of Descriptors to facilitate effects
2141a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent     * enumeration.
215df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     */
216df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    public static class Descriptor {
217df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
218df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        public Descriptor() {
219df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        }
220df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
2211d154187a99d5ad8dd33d47173cf6a4456276e76Scott Main        /**
2221d154187a99d5ad8dd33d47173cf6a4456276e76Scott Main         * @param type          UUID identifying the effect type. May be one of:
2231d154187a99d5ad8dd33d47173cf6a4456276e76Scott Main         * {@link AudioEffect#EFFECT_TYPE_AEC}, {@link AudioEffect#EFFECT_TYPE_AGC},
2241d154187a99d5ad8dd33d47173cf6a4456276e76Scott Main         * {@link AudioEffect#EFFECT_TYPE_BASS_BOOST}, {@link AudioEffect#EFFECT_TYPE_ENV_REVERB},
2251d154187a99d5ad8dd33d47173cf6a4456276e76Scott Main         * {@link AudioEffect#EFFECT_TYPE_EQUALIZER}, {@link AudioEffect#EFFECT_TYPE_NS},
2261d154187a99d5ad8dd33d47173cf6a4456276e76Scott Main         * {@link AudioEffect#EFFECT_TYPE_PRESET_REVERB},
2271d154187a99d5ad8dd33d47173cf6a4456276e76Scott Main         * {@link AudioEffect#EFFECT_TYPE_VIRTUALIZER}.
2281d154187a99d5ad8dd33d47173cf6a4456276e76Scott Main         * @param uuid         UUID for this particular implementation
2291d154187a99d5ad8dd33d47173cf6a4456276e76Scott Main         * @param connectMode  {@link #EFFECT_INSERT} or {@link #EFFECT_AUXILIARY}
2301d154187a99d5ad8dd33d47173cf6a4456276e76Scott Main         * @param name         human readable effect name
2311d154187a99d5ad8dd33d47173cf6a4456276e76Scott Main         * @param implementor  human readable effect implementor name
2321d154187a99d5ad8dd33d47173cf6a4456276e76Scott Main        *
2331d154187a99d5ad8dd33d47173cf6a4456276e76Scott Main        */
234df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        public Descriptor(String type, String uuid, String connectMode,
235df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent                String name, String implementor) {
2361a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent            this.type = UUID.fromString(type);
2371a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent            this.uuid = UUID.fromString(uuid);
2381a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent            this.connectMode = connectMode;
2391a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent            this.name = name;
2401a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent            this.implementor = implementor;
241df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        }
242df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
2431a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent        /**
24480569f7ff7db28ce98dde6e22bb4521ddbe5490aJean-Michel Trivi         *  Indicates the generic type of the effect (Equalizer, Bass boost ...).
24580569f7ff7db28ce98dde6e22bb4521ddbe5490aJean-Michel Trivi         *  One of {@link AudioEffect#EFFECT_TYPE_AEC},
24680569f7ff7db28ce98dde6e22bb4521ddbe5490aJean-Michel Trivi         *  {@link AudioEffect#EFFECT_TYPE_AGC}, {@link AudioEffect#EFFECT_TYPE_BASS_BOOST},
24780569f7ff7db28ce98dde6e22bb4521ddbe5490aJean-Michel Trivi         *  {@link AudioEffect#EFFECT_TYPE_ENV_REVERB}, {@link AudioEffect#EFFECT_TYPE_EQUALIZER},
24880569f7ff7db28ce98dde6e22bb4521ddbe5490aJean-Michel Trivi         *  {@link AudioEffect#EFFECT_TYPE_NS}, {@link AudioEffect#EFFECT_TYPE_PRESET_REVERB}
24980569f7ff7db28ce98dde6e22bb4521ddbe5490aJean-Michel Trivi         *   or {@link AudioEffect#EFFECT_TYPE_VIRTUALIZER}.<br>
25080569f7ff7db28ce98dde6e22bb4521ddbe5490aJean-Michel Trivi         *  For reverberation, bass boost, EQ and virtualizer, the UUID
25180569f7ff7db28ce98dde6e22bb4521ddbe5490aJean-Michel Trivi         *  corresponds to the OpenSL ES Interface ID.
2521a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent         */
2531a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent        public UUID type;
2541a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent        /**
2551a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent         *  Indicates the particular implementation of the effect in that type. Several effects
2561a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent         *  can have the same type but this uuid is unique to a given implementation.
2571a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent         */
2581a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent        public UUID uuid;
2591a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent        /**
2601d154187a99d5ad8dd33d47173cf6a4456276e76Scott Main         *  Indicates if the effect is of insert category {@link #EFFECT_INSERT} or auxiliary
2611d154187a99d5ad8dd33d47173cf6a4456276e76Scott Main         *  category {@link #EFFECT_AUXILIARY}.
2621d154187a99d5ad8dd33d47173cf6a4456276e76Scott Main         *  Insert effects (typically an {@link Equalizer}) are applied
2631a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent         *  to the entire audio source and usually not shared by several sources. Auxiliary effects
2641a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent         *  (typically a reverberator) are applied to part of the signal (wet) and the effect output
2651a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent         *  is added to the original signal (dry).
2661d154187a99d5ad8dd33d47173cf6a4456276e76Scott Main         *  Audio pre processing are applied to audio captured on a particular
2671d154187a99d5ad8dd33d47173cf6a4456276e76Scott Main         * {@link android.media.AudioRecord}.
2681a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent         */
2691a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent        public String connectMode;
2701a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent        /**
2711a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent         * Human readable effect name
2721a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent         */
2731a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent        public String name;
2741a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent        /**
2751a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent         * Human readable effect implementor name
2761a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent         */
2771a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent        public String implementor;
278df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    };
279df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
280df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    /**
281df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * Effect connection mode is insert. Specifying an audio session ID when creating the effect
282df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * will insert this effect after all players in the same audio session.
283df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     */
284df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    public static final String EFFECT_INSERT = "Insert";
285df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    /**
286df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * Effect connection mode is auxiliary.
287df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * <p>Auxiliary effects must be created on session 0 (global output mix). In order for a
288df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * MediaPlayer or AudioTrack to be fed into this effect, they must be explicitely attached to
289df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * this effect and a send level must be specified.
290df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * <p>Use the effect ID returned by {@link #getId()} to designate this particular effect when
291df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * attaching it to the MediaPlayer or AudioTrack.
292df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     */
293df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    public static final String EFFECT_AUXILIARY = "Auxiliary";
2940f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent    /**
2950f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent     * Effect connection mode is pre processing.
2960f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent     * The audio pre processing effects are attached to an audio input (AudioRecord).
2970f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent     * @hide
2980f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent     */
2990f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent    public static final String EFFECT_PRE_PROCESSING = "Pre Processing";
300948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
301df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    // --------------------------------------------------------------------------
302948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    // Member variables
303df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    // --------------------
304948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    /**
305948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     * Indicates the state of the AudioEffect instance
306948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     */
30717cb280e7f1ac3556eac90ab08263712e0348cb9Eric Laurent    private int mState = STATE_UNINITIALIZED;
308948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    /**
309948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     * Lock to synchronize access to mState
310948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     */
31117cb280e7f1ac3556eac90ab08263712e0348cb9Eric Laurent    private final Object mStateLock = new Object();
312948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    /**
313948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     * System wide unique effect ID
314948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     */
31517cb280e7f1ac3556eac90ab08263712e0348cb9Eric Laurent    private int mId;
316948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
317948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    // accessed by native methods
318ea7861c918567d17d40a762b38f97c053d88b839Ashok Bhat    private long mNativeAudioEffect;
319ea7861c918567d17d40a762b38f97c053d88b839Ashok Bhat    private long mJniData;
320948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
321948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    /**
322948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     * Effect descriptor
323948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     */
324948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    private Descriptor mDescriptor;
325948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
326948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    /**
327948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     * Listener for effect engine state change notifications.
328df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     *
329df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * @see #setEnableStatusListener(OnEnableStatusChangeListener)
330948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     */
33117cb280e7f1ac3556eac90ab08263712e0348cb9Eric Laurent    private OnEnableStatusChangeListener mEnableStatusChangeListener = null;
332948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    /**
333948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     * Listener for effect engine control ownership change notifications.
334df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     *
335df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * @see #setControlStatusListener(OnControlStatusChangeListener)
336948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     */
33717cb280e7f1ac3556eac90ab08263712e0348cb9Eric Laurent    private OnControlStatusChangeListener mControlChangeStatusListener = null;
338948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    /**
339948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     * Listener for effect engine control ownership change notifications.
340df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     *
341df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * @see #setParameterListener(OnParameterChangeListener)
342948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     */
34317cb280e7f1ac3556eac90ab08263712e0348cb9Eric Laurent    private OnParameterChangeListener mParameterChangeListener = null;
344948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    /**
345948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     * Lock to protect listeners updates against event notifications
3461a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent     * @hide
347948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     */
34817cb280e7f1ac3556eac90ab08263712e0348cb9Eric Laurent    public final Object mListenerLock = new Object();
349948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    /**
350948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     * Handler for events coming from the native code
3511a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent     * @hide
352948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     */
35317cb280e7f1ac3556eac90ab08263712e0348cb9Eric Laurent    public NativeEventHandler mNativeEventHandler = null;
354948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
355df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    // --------------------------------------------------------------------------
356948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    // Constructor, Finalize
357df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    // --------------------
358948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    /**
359948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     * Class constructor.
360df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     *
361df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * @param type type of effect engine created. See {@link #EFFECT_TYPE_ENV_REVERB},
362df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     *            {@link #EFFECT_TYPE_EQUALIZER} ... Types corresponding to
363df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     *            built-in effects are defined by AudioEffect class. Other types
364df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     *            can be specified provided they correspond an existing OpenSL
365df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     *            ES interface ID and the corresponsing effect is available on
366df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     *            the platform. If an unspecified effect type is requested, the
367df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     *            constructor with throw the IllegalArgumentException. This
368df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     *            parameter can be set to {@link #EFFECT_TYPE_NULL} in which
369df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     *            case only the uuid will be used to select the effect.
370df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * @param uuid unique identifier of a particular effect implementation.
371df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     *            Must be specified if the caller wants to use a particular
372df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     *            implementation of an effect type. This parameter can be set to
373df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     *            {@link #EFFECT_TYPE_NULL} in which case only the type will
374df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     *            be used to select the effect.
375df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * @param priority the priority level requested by the application for
376df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     *            controlling the effect engine. As the same effect engine can
377df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     *            be shared by several applications, this parameter indicates
378df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     *            how much the requesting application needs control of effect
379df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     *            parameters. The normal priority is 0, above normal is a
380df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     *            positive number, below normal a negative number.
38162f3617f2f4016ad2f59635d5156d64872989880Eric Laurent     * @param audioSession system wide unique audio session identifier.
38262f3617f2f4016ad2f59635d5156d64872989880Eric Laurent     *            The effect will be attached to the MediaPlayer or AudioTrack in
38362f3617f2f4016ad2f59635d5156d64872989880Eric Laurent     *            the same audio session.
384948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     *
385948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     * @throws java.lang.IllegalArgumentException
386948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     * @throws java.lang.UnsupportedOperationException
387948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     * @throws java.lang.RuntimeException
3881a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent     * @hide
389948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     */
390948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
391948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    public AudioEffect(UUID type, UUID uuid, int priority, int audioSession)
392df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            throws IllegalArgumentException, UnsupportedOperationException,
393df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            RuntimeException {
394948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        int[] id = new int[1];
395948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        Descriptor[] desc = new Descriptor[1];
396948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        // native initialization
397948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        int initResult = native_setup(new WeakReference<AudioEffect>(this),
398df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent                type.toString(), uuid.toString(), priority, audioSession, id,
399fbf0ecabac5d7a929628b43ffe8f4f953e47bd54Svetoslav                desc, ActivityThread.currentOpPackageName());
400948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        if (initResult != SUCCESS && initResult != ALREADY_EXISTS) {
401df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            Log.e(TAG, "Error code " + initResult
402df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent                    + " when initializing AudioEffect.");
403948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent            switch (initResult) {
404df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            case ERROR_BAD_VALUE:
405df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent                throw (new IllegalArgumentException("Effect type: " + type
406df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent                        + " not supported."));
407df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            case ERROR_INVALID_OPERATION:
408df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent                throw (new UnsupportedOperationException(
409df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent                        "Effect library not loaded"));
410948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent            default:
411df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent                throw (new RuntimeException(
412df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent                        "Cannot initialize effect engine for type: " + type
4135bb8f80fc4a72ad70d7d38cdc9f7988edce476e4Glenn Kasten                                + " Error: " + initResult));
414948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent            }
415948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        }
416948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        mId = id[0];
417948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        mDescriptor = desc[0];
418948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        synchronized (mStateLock) {
419948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent            mState = STATE_INITIALIZED;
420948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        }
421948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    }
422948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
423948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    /**
424df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * Releases the native AudioEffect resources. It is a good practice to
425df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * release the effect engine when not in use as control can be returned to
426df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * other applications or the native resources released.
427948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     */
428948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    public void release() {
429948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        synchronized (mStateLock) {
430948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent            native_release();
431948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent            mState = STATE_UNINITIALIZED;
432948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        }
433948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    }
434948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
435948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    @Override
436948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    protected void finalize() {
437948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        native_finalize();
438948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    }
439948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
440948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    /**
441948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     * Get the effect descriptor.
442df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     *
4431a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent     * @see android.media.audiofx.AudioEffect.Descriptor
444948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     * @throws IllegalStateException
445948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     */
446df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    public Descriptor getDescriptor() throws IllegalStateException {
447948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        checkState("getDescriptor()");
448948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        return mDescriptor;
449948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    }
450948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
451df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    // --------------------------------------------------------------------------
452948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    // Effects Enumeration
453df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    // --------------------
454948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
455948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    /**
456948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     * Query all effects available on the platform. Returns an array of
4571a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent     * {@link android.media.audiofx.AudioEffect.Descriptor} objects
458948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     *
459948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     * @throws IllegalStateException
460948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     */
461948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
462948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    static public Descriptor[] queryEffects() {
463df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        return (Descriptor[]) native_query_effects();
464948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    }
465948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
4660f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent    /**
46780569f7ff7db28ce98dde6e22bb4521ddbe5490aJean-Michel Trivi     * Query all audio pre-processing effects applied to the AudioRecord with the supplied
4680f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent     * audio session ID. Returns an array of {@link android.media.audiofx.AudioEffect.Descriptor}
4690f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent     * objects.
4700f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent     * @param audioSession system wide unique audio session identifier.
4710f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent     * @throws IllegalStateException
4720f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent     * @hide
4730f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent     */
4740f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent
4750f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent    static public Descriptor[] queryPreProcessings(int audioSession) {
4760f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent        return (Descriptor[]) native_query_pre_processing(audioSession);
4770f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent    }
478855255d89fe0a14abe796355bebb64031ec6ff47Eric Laurent
479855255d89fe0a14abe796355bebb64031ec6ff47Eric Laurent    /**
480855255d89fe0a14abe796355bebb64031ec6ff47Eric Laurent     * Checks if the device implements the specified effect type.
481855255d89fe0a14abe796355bebb64031ec6ff47Eric Laurent     * @param type the requested effect type.
482855255d89fe0a14abe796355bebb64031ec6ff47Eric Laurent     * @return true if the device implements the specified effect type, false otherwise.
483855255d89fe0a14abe796355bebb64031ec6ff47Eric Laurent     * @hide
484855255d89fe0a14abe796355bebb64031ec6ff47Eric Laurent     */
485855255d89fe0a14abe796355bebb64031ec6ff47Eric Laurent    public static boolean isEffectTypeAvailable(UUID type) {
486855255d89fe0a14abe796355bebb64031ec6ff47Eric Laurent        AudioEffect.Descriptor[] desc = AudioEffect.queryEffects();
487de709869ae10263c4c325aaa72cdc6aada0ae8d5Jason Parks        if (desc == null) {
488de709869ae10263c4c325aaa72cdc6aada0ae8d5Jason Parks            return false;
489de709869ae10263c4c325aaa72cdc6aada0ae8d5Jason Parks        }
490de709869ae10263c4c325aaa72cdc6aada0ae8d5Jason Parks
491855255d89fe0a14abe796355bebb64031ec6ff47Eric Laurent        for (int i = 0; i < desc.length; i++) {
492855255d89fe0a14abe796355bebb64031ec6ff47Eric Laurent            if (desc[i].type.equals(type)) {
493855255d89fe0a14abe796355bebb64031ec6ff47Eric Laurent                return true;
494855255d89fe0a14abe796355bebb64031ec6ff47Eric Laurent            }
495855255d89fe0a14abe796355bebb64031ec6ff47Eric Laurent        }
496855255d89fe0a14abe796355bebb64031ec6ff47Eric Laurent        return false;
497855255d89fe0a14abe796355bebb64031ec6ff47Eric Laurent    }
4980f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent
499df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    // --------------------------------------------------------------------------
500948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    // Control methods
501df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    // --------------------
502948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
503948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    /**
5041a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent     * Enable or disable the effect.
5051a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent     * Creating an audio effect does not automatically apply this effect on the audio source. It
5061a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent     * creates the resources necessary to process this effect but the audio signal is still bypassed
5071a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent     * through the effect engine. Calling this method will make that the effect is actually applied
5081a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent     * or not to the audio content being played in the corresponding audio session.
509df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     *
510df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * @param enabled the requested enable state
511df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * @return {@link #SUCCESS} in case of success, {@link #ERROR_INVALID_OPERATION}
512df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     *         or {@link #ERROR_DEAD_OBJECT} in case of failure.
513948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     * @throws IllegalStateException
514948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     */
515df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    public int setEnabled(boolean enabled) throws IllegalStateException {
516df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        checkState("setEnabled()");
517df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        return native_setEnabled(enabled);
518948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    }
519948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
520948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    /**
521948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     * Set effect parameter. The setParameter method is provided in several
522df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * forms addressing most common parameter formats. This form is the most
523df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * generic one where the parameter and its value are both specified as an
524df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * array of bytes. The parameter and value type and length are therefore
525df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * totally free. For standard effect defined by OpenSL ES, the parameter
526df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * format and values must match the definitions in the corresponding OpenSL
527df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * ES interface.
528948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     *
529df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * @param param the identifier of the parameter to set
530df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * @param value the new value for the specified parameter
531df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * @return {@link #SUCCESS} in case of success, {@link #ERROR_BAD_VALUE},
532df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     *         {@link #ERROR_NO_MEMORY}, {@link #ERROR_INVALID_OPERATION} or
533df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     *         {@link #ERROR_DEAD_OBJECT} in case of failure
534948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     * @throws IllegalStateException
5351a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent     * @hide
536948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     */
537948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    public int setParameter(byte[] param, byte[] value)
538df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            throws IllegalStateException {
539948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        checkState("setParameter()");
540948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        return native_setParameter(param.length, param, value.length, value);
541948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    }
542948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
543948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    /**
544948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     * Set effect parameter. The parameter and its value are integers.
545df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     *
546df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * @see #setParameter(byte[], byte[])
5471a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent     * @hide
548948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     */
549df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    public int setParameter(int param, int value) throws IllegalStateException {
550948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        byte[] p = intToByteArray(param);
551948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        byte[] v = intToByteArray(value);
552948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        return setParameter(p, v);
553948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    }
554948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
555948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    /**
556df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * Set effect parameter. The parameter is an integer and the value is a
557df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * short integer.
558df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     *
559df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * @see #setParameter(byte[], byte[])
5601a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent     * @hide
561948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     */
562948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    public int setParameter(int param, short value)
563df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            throws IllegalStateException {
564948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        byte[] p = intToByteArray(param);
565948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        byte[] v = shortToByteArray(value);
566948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        return setParameter(p, v);
567948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    }
568948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
569948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    /**
570df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * Set effect parameter. The parameter is an integer and the value is an
571df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * array of bytes.
572df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     *
573df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * @see #setParameter(byte[], byte[])
5741a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent     * @hide
575948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     */
576948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    public int setParameter(int param, byte[] value)
577df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            throws IllegalStateException {
578948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        byte[] p = intToByteArray(param);
579948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        return setParameter(p, value);
580948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    }
581948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
582948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    /**
583df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * Set effect parameter. The parameter is an array of 1 or 2 integers and
584df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * the value is also an array of 1 or 2 integers
585df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     *
586df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * @see #setParameter(byte[], byte[])
5871a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent     * @hide
588948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     */
589948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    public int setParameter(int[] param, int[] value)
590df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            throws IllegalStateException {
591948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        if (param.length > 2 || value.length > 2) {
592df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            return ERROR_BAD_VALUE;
593948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        }
594948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        byte[] p = intToByteArray(param[0]);
595948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        if (param.length > 1) {
596948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent            byte[] p2 = intToByteArray(param[1]);
597948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent            p = concatArrays(p, p2);
598948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        }
599948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        byte[] v = intToByteArray(value[0]);
600948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        if (value.length > 1) {
601948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent            byte[] v2 = intToByteArray(value[1]);
602948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent            v = concatArrays(v, v2);
603948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        }
604948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        return setParameter(p, v);
605948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    }
606948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
607948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    /**
608df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * Set effect parameter. The parameter is an array of 1 or 2 integers and
609df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * the value is an array of 1 or 2 short integers
610df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     *
611df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * @see #setParameter(byte[], byte[])
6121a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent     * @hide
613948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     */
614948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    public int setParameter(int[] param, short[] value)
615df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            throws IllegalStateException {
616948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        if (param.length > 2 || value.length > 2) {
617df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            return ERROR_BAD_VALUE;
618948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        }
619948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        byte[] p = intToByteArray(param[0]);
620948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        if (param.length > 1) {
621948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent            byte[] p2 = intToByteArray(param[1]);
622948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent            p = concatArrays(p, p2);
623948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        }
624948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
625948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        byte[] v = shortToByteArray(value[0]);
626948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        if (value.length > 1) {
627948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent            byte[] v2 = shortToByteArray(value[1]);
628948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent            v = concatArrays(v, v2);
629948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        }
630948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        return setParameter(p, v);
631948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    }
632948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
633948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    /**
634df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * Set effect parameter. The parameter is an array of 1 or 2 integers and
635df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * the value is an array of bytes
636df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     *
637df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * @see #setParameter(byte[], byte[])
6381a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent     * @hide
639948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     */
640948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    public int setParameter(int[] param, byte[] value)
641df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            throws IllegalStateException {
642948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        if (param.length > 2) {
643df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            return ERROR_BAD_VALUE;
644948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        }
645948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        byte[] p = intToByteArray(param[0]);
646948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        if (param.length > 1) {
647948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent            byte[] p2 = intToByteArray(param[1]);
648948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent            p = concatArrays(p, p2);
649948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        }
650948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        return setParameter(p, value);
651948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    }
652948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
653948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    /**
654948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     * Get effect parameter. The getParameter method is provided in several
655df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * forms addressing most common parameter formats. This form is the most
656df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * generic one where the parameter and its value are both specified as an
657df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * array of bytes. The parameter and value type and length are therefore
658948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     * totally free.
659df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     *
660df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * @param param the identifier of the parameter to set
661df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * @param value the new value for the specified parameter
662602b3286ffe7da6e70bf2d9e4861a5d74ff7c473Eric Laurent     * @return the number of meaningful bytes in value array in case of success or
663602b3286ffe7da6e70bf2d9e4861a5d74ff7c473Eric Laurent     *  {@link #ERROR_BAD_VALUE}, {@link #ERROR_NO_MEMORY}, {@link #ERROR_INVALID_OPERATION}
664602b3286ffe7da6e70bf2d9e4861a5d74ff7c473Eric Laurent     *  or {@link #ERROR_DEAD_OBJECT} in case of failure.
665948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     * @throws IllegalStateException
6661a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent     * @hide
667948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     */
668948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    public int getParameter(byte[] param, byte[] value)
669df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            throws IllegalStateException {
670948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        checkState("getParameter()");
671602b3286ffe7da6e70bf2d9e4861a5d74ff7c473Eric Laurent        return native_getParameter(param.length, param, value.length, value);
672948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    }
673948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
674948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    /**
675df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * Get effect parameter. The parameter is an integer and the value is an
676df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * array of bytes.
677df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     *
678df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * @see #getParameter(byte[], byte[])
6791a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent     * @hide
680948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     */
681948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    public int getParameter(int param, byte[] value)
682df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            throws IllegalStateException {
683948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        byte[] p = intToByteArray(param);
684948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
685948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        return getParameter(p, value);
686948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    }
687948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
688948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    /**
689df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * Get effect parameter. The parameter is an integer and the value is an
690df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * array of 1 or 2 integers
691df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     *
692df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * @see #getParameter(byte[], byte[])
693602b3286ffe7da6e70bf2d9e4861a5d74ff7c473Eric Laurent     * In case of success, returns the number of meaningful integers in value array.
6941a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent     * @hide
695948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     */
696948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    public int getParameter(int param, int[] value)
697df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            throws IllegalStateException {
698948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        if (value.length > 2) {
699df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            return ERROR_BAD_VALUE;
700948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        }
701948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        byte[] p = intToByteArray(param);
702948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
703948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        byte[] v = new byte[value.length * 4];
704948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
705948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        int status = getParameter(p, v);
706948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
707602b3286ffe7da6e70bf2d9e4861a5d74ff7c473Eric Laurent        if (status == 4 || status == 8) {
708602b3286ffe7da6e70bf2d9e4861a5d74ff7c473Eric Laurent            value[0] = byteArrayToInt(v);
709602b3286ffe7da6e70bf2d9e4861a5d74ff7c473Eric Laurent            if (status == 8) {
710602b3286ffe7da6e70bf2d9e4861a5d74ff7c473Eric Laurent                value[1] = byteArrayToInt(v, 4);
711602b3286ffe7da6e70bf2d9e4861a5d74ff7c473Eric Laurent            }
712602b3286ffe7da6e70bf2d9e4861a5d74ff7c473Eric Laurent            status /= 4;
713602b3286ffe7da6e70bf2d9e4861a5d74ff7c473Eric Laurent        } else {
714602b3286ffe7da6e70bf2d9e4861a5d74ff7c473Eric Laurent            status = ERROR;
715948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        }
716948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        return status;
717948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    }
718948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
719948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    /**
720df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * Get effect parameter. The parameter is an integer and the value is an
721df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * array of 1 or 2 short integers
722df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     *
723df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * @see #getParameter(byte[], byte[])
724602b3286ffe7da6e70bf2d9e4861a5d74ff7c473Eric Laurent     * In case of success, returns the number of meaningful short integers in value array.
7251a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent     * @hide
726948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     */
727948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    public int getParameter(int param, short[] value)
728df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            throws IllegalStateException {
729948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        if (value.length > 2) {
730df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            return ERROR_BAD_VALUE;
731948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        }
732948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        byte[] p = intToByteArray(param);
733948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
734948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        byte[] v = new byte[value.length * 2];
735948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
736948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        int status = getParameter(p, v);
737948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
738602b3286ffe7da6e70bf2d9e4861a5d74ff7c473Eric Laurent        if (status == 2 || status == 4) {
739602b3286ffe7da6e70bf2d9e4861a5d74ff7c473Eric Laurent            value[0] = byteArrayToShort(v);
740602b3286ffe7da6e70bf2d9e4861a5d74ff7c473Eric Laurent            if (status == 4) {
741602b3286ffe7da6e70bf2d9e4861a5d74ff7c473Eric Laurent                value[1] = byteArrayToShort(v, 2);
742602b3286ffe7da6e70bf2d9e4861a5d74ff7c473Eric Laurent            }
743602b3286ffe7da6e70bf2d9e4861a5d74ff7c473Eric Laurent            status /= 2;
744602b3286ffe7da6e70bf2d9e4861a5d74ff7c473Eric Laurent        } else {
745602b3286ffe7da6e70bf2d9e4861a5d74ff7c473Eric Laurent            status = ERROR;
746948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        }
747948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        return status;
748948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    }
749948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
750948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    /**
751df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * Get effect parameter. The parameter is an array of 1 or 2 integers and
752df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * the value is also an array of 1 or 2 integers
753df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     *
754df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * @see #getParameter(byte[], byte[])
755602b3286ffe7da6e70bf2d9e4861a5d74ff7c473Eric Laurent     * In case of success, the returns the number of meaningful integers in value array.
7561a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent     * @hide
757948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     */
758948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    public int getParameter(int[] param, int[] value)
759df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            throws IllegalStateException {
760948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        if (param.length > 2 || value.length > 2) {
761df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            return ERROR_BAD_VALUE;
762948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        }
763948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        byte[] p = intToByteArray(param[0]);
764948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        if (param.length > 1) {
765948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent            byte[] p2 = intToByteArray(param[1]);
766948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent            p = concatArrays(p, p2);
767948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        }
768948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        byte[] v = new byte[value.length * 4];
769948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
770948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        int status = getParameter(p, v);
771948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
772602b3286ffe7da6e70bf2d9e4861a5d74ff7c473Eric Laurent        if (status == 4 || status == 8) {
773602b3286ffe7da6e70bf2d9e4861a5d74ff7c473Eric Laurent            value[0] = byteArrayToInt(v);
774602b3286ffe7da6e70bf2d9e4861a5d74ff7c473Eric Laurent            if (status == 8) {
775602b3286ffe7da6e70bf2d9e4861a5d74ff7c473Eric Laurent                value[1] = byteArrayToInt(v, 4);
776602b3286ffe7da6e70bf2d9e4861a5d74ff7c473Eric Laurent            }
777602b3286ffe7da6e70bf2d9e4861a5d74ff7c473Eric Laurent            status /= 4;
778602b3286ffe7da6e70bf2d9e4861a5d74ff7c473Eric Laurent        } else {
779602b3286ffe7da6e70bf2d9e4861a5d74ff7c473Eric Laurent            status = ERROR;
780948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        }
781948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        return status;
782948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    }
783948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
784948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    /**
785df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * Get effect parameter. The parameter is an array of 1 or 2 integers and
786df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * the value is an array of 1 or 2 short integers
787df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     *
788df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * @see #getParameter(byte[], byte[])
789602b3286ffe7da6e70bf2d9e4861a5d74ff7c473Eric Laurent     * In case of success, returns the number of meaningful short integers in value array.
7901a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent     * @hide
791948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     */
792948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    public int getParameter(int[] param, short[] value)
793df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            throws IllegalStateException {
794948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        if (param.length > 2 || value.length > 2) {
795df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            return ERROR_BAD_VALUE;
796948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        }
797948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        byte[] p = intToByteArray(param[0]);
798948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        if (param.length > 1) {
799948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent            byte[] p2 = intToByteArray(param[1]);
800948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent            p = concatArrays(p, p2);
801948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        }
802948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        byte[] v = new byte[value.length * 2];
803948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
804948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        int status = getParameter(p, v);
805948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
806602b3286ffe7da6e70bf2d9e4861a5d74ff7c473Eric Laurent        if (status == 2 || status == 4) {
807602b3286ffe7da6e70bf2d9e4861a5d74ff7c473Eric Laurent            value[0] = byteArrayToShort(v);
808602b3286ffe7da6e70bf2d9e4861a5d74ff7c473Eric Laurent            if (status == 4) {
809602b3286ffe7da6e70bf2d9e4861a5d74ff7c473Eric Laurent                value[1] = byteArrayToShort(v, 2);
810602b3286ffe7da6e70bf2d9e4861a5d74ff7c473Eric Laurent            }
811602b3286ffe7da6e70bf2d9e4861a5d74ff7c473Eric Laurent            status /= 2;
812602b3286ffe7da6e70bf2d9e4861a5d74ff7c473Eric Laurent        } else {
813602b3286ffe7da6e70bf2d9e4861a5d74ff7c473Eric Laurent            status = ERROR;
814948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        }
815948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        return status;
816948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    }
817948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
818948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    /**
819df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * Get effect parameter. The parameter is an array of 1 or 2 integers and
820df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * the value is an array of bytes
821df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     *
822df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * @see #getParameter(byte[], byte[])
8231a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent     * @hide
824948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     */
825948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    public int getParameter(int[] param, byte[] value)
826df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            throws IllegalStateException {
827948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        if (param.length > 2) {
828df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            return ERROR_BAD_VALUE;
829948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        }
830948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        byte[] p = intToByteArray(param[0]);
831948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        if (param.length > 1) {
832948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent            byte[] p2 = intToByteArray(param[1]);
833948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent            p = concatArrays(p, p2);
834948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        }
835948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
836948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        return getParameter(p, value);
837948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    }
838948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
839948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    /**
840df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * Send a command to the effect engine. This method is intended to send
841df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * proprietary commands to a particular effect implementation.
842602b3286ffe7da6e70bf2d9e4861a5d74ff7c473Eric Laurent     * In case of success, returns the number of meaningful bytes in reply array.
843602b3286ffe7da6e70bf2d9e4861a5d74ff7c473Eric Laurent     * In case of failure, the returned value is negative and implementation specific.
8441a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent     * @hide
845948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     */
846948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    public int command(int cmdCode, byte[] command, byte[] reply)
847df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            throws IllegalStateException {
848948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        checkState("command()");
849602b3286ffe7da6e70bf2d9e4861a5d74ff7c473Eric Laurent        return native_command(cmdCode, command.length, command, reply.length, reply);
850948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    }
851948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
852df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    // --------------------------------------------------------------------------
853948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    // Getters
854df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    // --------------------
855948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
856948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    /**
857df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * Returns effect unique identifier. This system wide unique identifier can
858df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * be used to attach this effect to a MediaPlayer or an AudioTrack when the
859df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * effect is an auxiliary effect (Reverb)
860df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     *
861948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     * @return the effect identifier.
862948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     * @throws IllegalStateException
863948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     */
864df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    public int getId() throws IllegalStateException {
865948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        checkState("getId()");
866948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        return mId;
867948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    }
868948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
869948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    /**
8701a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent     * Returns effect enabled state
871df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     *
872948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     * @return true if the effect is enabled, false otherwise.
873948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     * @throws IllegalStateException
874948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     */
875df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    public boolean getEnabled() throws IllegalStateException {
876df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        checkState("getEnabled()");
877df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        return native_getEnabled();
878948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    }
879948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
880948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    /**
881948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     * Checks if this AudioEffect object is controlling the effect engine.
882df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     *
883df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * @return true if this instance has control of effect engine, false
884df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     *         otherwise.
885948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     * @throws IllegalStateException
886948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     */
887df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    public boolean hasControl() throws IllegalStateException {
888948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        checkState("hasControl()");
889948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        return native_hasControl();
890948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    }
891948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
892df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    // --------------------------------------------------------------------------
893948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    // Initialization / configuration
894df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    // --------------------
895948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    /**
896948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     * Sets the listener AudioEffect notifies when the effect engine is enabled
897948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     * or disabled.
898df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     *
899948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     * @param listener
900948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     */
901948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    public void setEnableStatusListener(OnEnableStatusChangeListener listener) {
902948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        synchronized (mListenerLock) {
903948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent            mEnableStatusChangeListener = listener;
904948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        }
905948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        if ((listener != null) && (mNativeEventHandler == null)) {
906948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent            createNativeEventHandler();
907948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        }
908948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    }
909948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
910948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    /**
911df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * Sets the listener AudioEffect notifies when the effect engine control is
912df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * taken or returned.
913df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     *
914948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     * @param listener
915948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     */
916948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    public void setControlStatusListener(OnControlStatusChangeListener listener) {
917948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        synchronized (mListenerLock) {
918948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent            mControlChangeStatusListener = listener;
919948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        }
920948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        if ((listener != null) && (mNativeEventHandler == null)) {
921948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent            createNativeEventHandler();
922948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        }
923948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    }
924948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
925948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    /**
926948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     * Sets the listener AudioEffect notifies when a parameter is changed.
927df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     *
928948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     * @param listener
9291a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent     * @hide
930948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     */
931948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    public void setParameterListener(OnParameterChangeListener listener) {
932948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        synchronized (mListenerLock) {
933948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent            mParameterChangeListener = listener;
934948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        }
935948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        if ((listener != null) && (mNativeEventHandler == null)) {
936948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent            createNativeEventHandler();
937948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        }
938948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    }
939948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
940948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    // Convenience method for the creation of the native event handler
941948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    // It is called only when a non-null event listener is set.
942948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    // precondition:
943df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    // mNativeEventHandler is null
944948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    private void createNativeEventHandler() {
945948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        Looper looper;
946948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        if ((looper = Looper.myLooper()) != null) {
947948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent            mNativeEventHandler = new NativeEventHandler(this, looper);
948948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        } else if ((looper = Looper.getMainLooper()) != null) {
949948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent            mNativeEventHandler = new NativeEventHandler(this, looper);
950948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        } else {
951948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent            mNativeEventHandler = null;
952948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        }
953948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    }
954948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
955df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    // ---------------------------------------------------------
956948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    // Interface definitions
957df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    // --------------------
958948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    /**
9592a6b80bc65c4782b5a7168b300e1dc5ec9f617eeEric Laurent     * The OnEnableStatusChangeListener interface defines a method called by the AudioEffect
960df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * when a the enabled state of the effect engine was changed by the controlling application.
961948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     */
962df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    public interface OnEnableStatusChangeListener {
963948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        /**
964df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent         * Called on the listener to notify it that the effect engine has been
965df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent         * enabled or disabled.
966df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent         * @param effect the effect on which the interface is registered.
967df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent         * @param enabled new effect state.
968948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent         */
969948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        void onEnableStatusChange(AudioEffect effect, boolean enabled);
970948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    }
971948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
972948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    /**
973df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * The OnControlStatusChangeListener interface defines a method called by the AudioEffect
974df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * when a the control of the effect engine is gained or lost by the application
975948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     */
976df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    public interface OnControlStatusChangeListener {
977948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        /**
978df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent         * Called on the listener to notify it that the effect engine control
979df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent         * has been taken or returned.
980df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent         * @param effect the effect on which the interface is registered.
981df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent         * @param controlGranted true if the application has been granted control of the effect
982df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent         * engine, false otherwise.
983948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent         */
984948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        void onControlStatusChange(AudioEffect effect, boolean controlGranted);
985948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    }
986948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
987948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    /**
988df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * The OnParameterChangeListener interface defines a method called by the AudioEffect
989df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * when a parameter is changed in the effect engine by the controlling application.
9901a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent     * @hide
991948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     */
992df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    public interface OnParameterChangeListener {
993948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        /**
994948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent         * Called on the listener to notify it that a parameter value has changed.
995df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent         * @param effect the effect on which the interface is registered.
996df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent         * @param status status of the set parameter operation.
997df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent         * @param param ID of the modified parameter.
998df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent         * @param value the new parameter value.
999948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent         */
1000df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        void onParameterChange(AudioEffect effect, int status, byte[] param,
1001df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent                byte[] value);
1002948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    }
1003948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
1004d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent
1005d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent    // -------------------------------------------------------------------------
1006d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent    // Audio Effect Control panel intents
1007d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent    // -------------------------------------------------------------------------
1008d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent
1009d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent    /**
101092cf2d60851462d91a1eb4b9615ea93579dd4330Eric Laurent     *  Intent to launch an audio effect control panel UI.
101192cf2d60851462d91a1eb4b9615ea93579dd4330Eric Laurent     *  <p>The goal of this intent is to enable separate implementations of music/media player
101292cf2d60851462d91a1eb4b9615ea93579dd4330Eric Laurent     *  applications and audio effect control application or services.
101392cf2d60851462d91a1eb4b9615ea93579dd4330Eric Laurent     *  This will allow platform vendors to offer more advanced control options for standard effects
101492cf2d60851462d91a1eb4b9615ea93579dd4330Eric Laurent     *  or control for platform specific effects.
1015d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent     *  <p>The intent carries a number of extras used by the player application to communicate
1016d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent     *  necessary pieces of information to the control panel application.
1017d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent     *  <p>The calling application must use the
1018d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent     *  {@link android.app.Activity#startActivityForResult(Intent, int)} method to launch the
1019d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent     *  control panel so that its package name is indicated and used by the control panel
1020d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent     *  application to keep track of changes for this particular application.
102192cf2d60851462d91a1eb4b9615ea93579dd4330Eric Laurent     *  <p>The {@link #EXTRA_AUDIO_SESSION} extra will indicate an audio session to which the
1022d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent     *  audio effects should be applied. If no audio session is specified, either one of the
1023d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent     *  follownig will happen:
102492cf2d60851462d91a1eb4b9615ea93579dd4330Eric Laurent     *  <p>- If an audio session was previously opened by the calling application with
1025d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent     *  {@link #ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION} intent, the effect changes will
1026d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent     *  be applied to that session.
102792cf2d60851462d91a1eb4b9615ea93579dd4330Eric Laurent     *  <p>- If no audio session is opened, the changes will be stored in the package specific
102892cf2d60851462d91a1eb4b9615ea93579dd4330Eric Laurent     *  storage area and applied whenever a new audio session is opened by this application.
102992cf2d60851462d91a1eb4b9615ea93579dd4330Eric Laurent     *  <p>The {@link #EXTRA_CONTENT_TYPE} extra will help the control panel application
1030d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent     *  customize both the UI layout and the default audio effect settings if none are already
1031d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent     *  stored for the calling application.
1032d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent     */
1033d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent    @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
1034d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent    public static final String ACTION_DISPLAY_AUDIO_EFFECT_CONTROL_PANEL =
1035d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent        "android.media.action.DISPLAY_AUDIO_EFFECT_CONTROL_PANEL";
1036d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent
1037d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent    /**
103892cf2d60851462d91a1eb4b9615ea93579dd4330Eric Laurent     *  Intent to signal to the effect control application or service that a new audio session
103992cf2d60851462d91a1eb4b9615ea93579dd4330Eric Laurent     *  is opened and requires audio effects to be applied.
104092cf2d60851462d91a1eb4b9615ea93579dd4330Eric Laurent     *  <p>This is different from {@link #ACTION_DISPLAY_AUDIO_EFFECT_CONTROL_PANEL} in that no
104192cf2d60851462d91a1eb4b9615ea93579dd4330Eric Laurent     *  UI should be displayed in this case. Music player applications can broadcast this intent
104292cf2d60851462d91a1eb4b9615ea93579dd4330Eric Laurent     *  before starting playback to make sure that any audio effect settings previously selected
104392cf2d60851462d91a1eb4b9615ea93579dd4330Eric Laurent     *  by the user are applied.
1044d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent     *  <p>The effect control application receiving this intent will look for previously stored
1045d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent     *  settings for the calling application, create all required audio effects and apply the
1046d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent     *  effect settings to the specified audio session.
1047d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent     *  <p>The calling package name is indicated by the {@link #EXTRA_PACKAGE_NAME} extra and the
1048d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent     *  audio session ID by the {@link #EXTRA_AUDIO_SESSION} extra. Both extras are mandatory.
1049d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent     *  <p>If no stored settings are found for the calling application, default settings for the
1050d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent     *  content type indicated by {@link #EXTRA_CONTENT_TYPE} will be applied. The default settings
1051d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent     *  for a given content type are platform specific.
1052d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent     */
1053d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
1054d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent    public static final String ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION =
1055d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent        "android.media.action.OPEN_AUDIO_EFFECT_CONTROL_SESSION";
1056d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent
1057d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent    /**
105892cf2d60851462d91a1eb4b9615ea93579dd4330Eric Laurent     *  Intent to signal to the effect control application or service that an audio session
1059d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent     *  is closed and that effects should not be applied anymore.
106092cf2d60851462d91a1eb4b9615ea93579dd4330Eric Laurent     *  <p>The effect control application receiving this intent will delete all effects on
106192cf2d60851462d91a1eb4b9615ea93579dd4330Eric Laurent     *  this session and store current settings in package specific storage.
1062d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent     *  <p>The calling package name is indicated by the {@link #EXTRA_PACKAGE_NAME} extra and the
1063d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent     *  audio session ID by the {@link #EXTRA_AUDIO_SESSION} extra. Both extras are mandatory.
1064d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent     *  <p>It is good practice for applications to broadcast this intent when music playback stops
1065d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent     *  and/or when exiting to free system resources consumed by audio effect engines.
1066d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent     */
1067d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
1068d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent    public static final String ACTION_CLOSE_AUDIO_EFFECT_CONTROL_SESSION =
1069d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent        "android.media.action.CLOSE_AUDIO_EFFECT_CONTROL_SESSION";
1070d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent
1071d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent    /**
107292cf2d60851462d91a1eb4b9615ea93579dd4330Eric Laurent     * Contains the ID of the audio session the effects should be applied to.
107392cf2d60851462d91a1eb4b9615ea93579dd4330Eric Laurent     * <p>This extra is for use with {@link #ACTION_DISPLAY_AUDIO_EFFECT_CONTROL_PANEL},
107492cf2d60851462d91a1eb4b9615ea93579dd4330Eric Laurent     * {@link #ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION} and
107592cf2d60851462d91a1eb4b9615ea93579dd4330Eric Laurent     * {@link #ACTION_CLOSE_AUDIO_EFFECT_CONTROL_SESSION} intents.
1076d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent     * <p>The extra value is of type int and is the audio session ID.
10771a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent     *  @see android.media.MediaPlayer#getAudioSessionId() for details on audio sessions.
1078d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent     */
1079d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent     public static final String EXTRA_AUDIO_SESSION = "android.media.extra.AUDIO_SESSION";
1080d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent
1081d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent    /**
108292cf2d60851462d91a1eb4b9615ea93579dd4330Eric Laurent     * Contains the package name of the calling application.
108392cf2d60851462d91a1eb4b9615ea93579dd4330Eric Laurent     * <p>This extra is for use with {@link #ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION} and
1084d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent     * {@link #ACTION_CLOSE_AUDIO_EFFECT_CONTROL_SESSION} intents.
1085d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent     * <p>The extra value is a string containing the full package name.
1086d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent     */
1087d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent    public static final String EXTRA_PACKAGE_NAME = "android.media.extra.PACKAGE_NAME";
1088d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent
1089d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent    /**
109092cf2d60851462d91a1eb4b9615ea93579dd4330Eric Laurent     * Indicates which type of content is played by the application.
109192cf2d60851462d91a1eb4b9615ea93579dd4330Eric Laurent     * <p>This extra is for use with {@link #ACTION_DISPLAY_AUDIO_EFFECT_CONTROL_PANEL} and
109292cf2d60851462d91a1eb4b9615ea93579dd4330Eric Laurent     * {@link #ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION} intents.
109392cf2d60851462d91a1eb4b9615ea93579dd4330Eric Laurent     * <p>This information is used by the effect control application to customize UI and select
109492cf2d60851462d91a1eb4b9615ea93579dd4330Eric Laurent     * appropriate default effect settings. The content type is one of the following:
1095d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent     * <ul>
1096d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent     *   <li>{@link #CONTENT_TYPE_MUSIC}</li>
1097d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent     *   <li>{@link #CONTENT_TYPE_MOVIE}</li>
1098d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent     *   <li>{@link #CONTENT_TYPE_GAME}</li>
1099d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent     *   <li>{@link #CONTENT_TYPE_VOICE}</li>
1100d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent     * </ul>
1101d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent     * If omitted, the content type defaults to {@link #CONTENT_TYPE_MUSIC}.
1102d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent     */
1103d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent    public static final String EXTRA_CONTENT_TYPE = "android.media.extra.CONTENT_TYPE";
1104d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent
1105d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent    /**
1106d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent     * Value for {@link #EXTRA_CONTENT_TYPE} when the type of content played is music
1107d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent     */
1108d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent    public static final int  CONTENT_TYPE_MUSIC = 0;
1109d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent    /**
111092cf2d60851462d91a1eb4b9615ea93579dd4330Eric Laurent     * Value for {@link #EXTRA_CONTENT_TYPE} when the type of content played is video or movie
1111d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent     */
1112d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent    public static final int  CONTENT_TYPE_MOVIE = 1;
1113d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent    /**
1114d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent     * Value for {@link #EXTRA_CONTENT_TYPE} when the type of content played is game audio
1115d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent     */
1116d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent    public static final int  CONTENT_TYPE_GAME = 2;
1117d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent    /**
1118d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent     * Value for {@link #EXTRA_CONTENT_TYPE} when the type of content played is voice audio
1119d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent     */
1120d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent    public static final int  CONTENT_TYPE_VOICE = 3;
1121d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent
1122d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent
1123df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    // ---------------------------------------------------------
1124948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    // Inner classes
1125df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    // --------------------
1126948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    /**
1127df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * Helper class to handle the forwarding of native events to the appropriate
1128df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * listeners
1129948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     */
1130df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    private class NativeEventHandler extends Handler {
1131948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        private AudioEffect mAudioEffect;
1132948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
1133948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        public NativeEventHandler(AudioEffect ae, Looper looper) {
1134948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent            super(looper);
1135948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent            mAudioEffect = ae;
1136948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        }
1137948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
1138948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        @Override
1139948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        public void handleMessage(Message msg) {
1140948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent            if (mAudioEffect == null) {
1141948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent                return;
1142948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent            }
1143df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            switch (msg.what) {
1144948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent            case NATIVE_EVENT_ENABLED_STATUS:
1145948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent                OnEnableStatusChangeListener enableStatusChangeListener = null;
1146948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent                synchronized (mListenerLock) {
1147948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent                    enableStatusChangeListener = mAudioEffect.mEnableStatusChangeListener;
1148948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent                }
1149948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent                if (enableStatusChangeListener != null) {
1150df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent                    enableStatusChangeListener.onEnableStatusChange(
1151df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent                            mAudioEffect, (boolean) (msg.arg1 != 0));
1152948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent                }
1153948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent                break;
1154948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent            case NATIVE_EVENT_CONTROL_STATUS:
1155948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent                OnControlStatusChangeListener controlStatusChangeListener = null;
1156948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent                synchronized (mListenerLock) {
1157948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent                    controlStatusChangeListener = mAudioEffect.mControlChangeStatusListener;
1158948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent                }
1159948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent                if (controlStatusChangeListener != null) {
1160df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent                    controlStatusChangeListener.onControlStatusChange(
1161df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent                            mAudioEffect, (boolean) (msg.arg1 != 0));
1162948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent                }
1163948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent                break;
1164948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent            case NATIVE_EVENT_PARAMETER_CHANGED:
1165948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent                OnParameterChangeListener parameterChangeListener = null;
1166948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent                synchronized (mListenerLock) {
1167948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent                    parameterChangeListener = mAudioEffect.mParameterChangeListener;
1168948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent                }
1169948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent                if (parameterChangeListener != null) {
1170df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent                    // arg1 contains offset of parameter value from start of
1171df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent                    // byte array
1172948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent                    int vOffset = msg.arg1;
1173df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent                    byte[] p = (byte[]) msg.obj;
1174df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent                    // See effect_param_t in EffectApi.h for psize and vsize
1175df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent                    // fields offsets
1176948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent                    int status = byteArrayToInt(p, 0);
1177948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent                    int psize = byteArrayToInt(p, 4);
1178948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent                    int vsize = byteArrayToInt(p, 8);
1179948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent                    byte[] param = new byte[psize];
1180948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent                    byte[] value = new byte[vsize];
1181948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent                    System.arraycopy(p, 12, param, 0, psize);
1182948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent                    System.arraycopy(p, vOffset, value, 0, vsize);
1183948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
1184df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent                    parameterChangeListener.onParameterChange(mAudioEffect,
1185df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent                            status, param, value);
1186948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent                }
1187948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent                break;
1188948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
1189df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            default:
1190948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent                Log.e(TAG, "handleMessage() Unknown event type: " + msg.what);
1191948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent                break;
1192948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent            }
1193948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        }
1194948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    }
1195948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
1196df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    // ---------------------------------------------------------
1197948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    // Java methods called from the native side
1198df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    // --------------------
1199948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    @SuppressWarnings("unused")
1200df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    private static void postEventFromNative(Object effect_ref, int what,
1201df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            int arg1, int arg2, Object obj) {
1202df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        AudioEffect effect = (AudioEffect) ((WeakReference) effect_ref).get();
1203948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        if (effect == null) {
1204948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent            return;
1205948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        }
1206948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        if (effect.mNativeEventHandler != null) {
1207df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            Message m = effect.mNativeEventHandler.obtainMessage(what, arg1,
1208df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent                    arg2, obj);
1209948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent            effect.mNativeEventHandler.sendMessage(m);
1210948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        }
1211948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
1212948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    }
1213948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
1214df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    // ---------------------------------------------------------
1215948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    // Native methods called from the Java side
1216df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    // --------------------
1217948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
1218948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    private static native final void native_init();
1219948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
1220df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    private native final int native_setup(Object audioeffect_this, String type,
1221fa5ecdc4ac6d7a8db2bb9e4a6a60a3189025df30Svet Ganov            String uuid, int priority, int audioSession, int[] id, Object[] desc,
1222fa5ecdc4ac6d7a8db2bb9e4a6a60a3189025df30Svet Ganov            String opPackageName);
1223948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
1224948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    private native final void native_finalize();
1225948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
1226948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    private native final void native_release();
1227948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
1228df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    private native final int native_setEnabled(boolean enabled);
1229948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
1230df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    private native final boolean native_getEnabled();
1231948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
1232948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    private native final boolean native_hasControl();
1233948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
1234df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    private native final int native_setParameter(int psize, byte[] param,
1235df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            int vsize, byte[] value);
1236948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
1237df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    private native final int native_getParameter(int psize, byte[] param,
1238602b3286ffe7da6e70bf2d9e4861a5d74ff7c473Eric Laurent            int vsize, byte[] value);
1239948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
1240df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    private native final int native_command(int cmdCode, int cmdSize,
1241602b3286ffe7da6e70bf2d9e4861a5d74ff7c473Eric Laurent            byte[] cmdData, int repSize, byte[] repData);
1242948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
1243948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    private static native Object[] native_query_effects();
1244948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
12450f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent    private static native Object[] native_query_pre_processing(int audioSession);
12460f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent
1247df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    // ---------------------------------------------------------
1248948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    // Utility methods
1249df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    // ------------------
1250948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
12511a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent    /**
12521a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent    * @hide
12531a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent    */
125417cb280e7f1ac3556eac90ab08263712e0348cb9Eric Laurent    public void checkState(String methodName) throws IllegalStateException {
1255948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        synchronized (mStateLock) {
1256948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent            if (mState != STATE_INITIALIZED) {
1257df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent                throw (new IllegalStateException(methodName
1258df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent                        + " called on uninitialized AudioEffect."));
1259948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent            }
1260948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        }
1261948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    }
1262948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
12631a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent    /**
12641a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent     * @hide
12651a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent     */
126617cb280e7f1ac3556eac90ab08263712e0348cb9Eric Laurent    public void checkStatus(int status) {
1267602b3286ffe7da6e70bf2d9e4861a5d74ff7c473Eric Laurent        if (isError(status)) {
1268602b3286ffe7da6e70bf2d9e4861a5d74ff7c473Eric Laurent            switch (status) {
1269602b3286ffe7da6e70bf2d9e4861a5d74ff7c473Eric Laurent            case AudioEffect.ERROR_BAD_VALUE:
1270602b3286ffe7da6e70bf2d9e4861a5d74ff7c473Eric Laurent                throw (new IllegalArgumentException(
1271602b3286ffe7da6e70bf2d9e4861a5d74ff7c473Eric Laurent                        "AudioEffect: bad parameter value"));
1272602b3286ffe7da6e70bf2d9e4861a5d74ff7c473Eric Laurent            case AudioEffect.ERROR_INVALID_OPERATION:
1273602b3286ffe7da6e70bf2d9e4861a5d74ff7c473Eric Laurent                throw (new UnsupportedOperationException(
1274602b3286ffe7da6e70bf2d9e4861a5d74ff7c473Eric Laurent                        "AudioEffect: invalid parameter operation"));
1275602b3286ffe7da6e70bf2d9e4861a5d74ff7c473Eric Laurent            default:
1276602b3286ffe7da6e70bf2d9e4861a5d74ff7c473Eric Laurent                throw (new RuntimeException("AudioEffect: set/get parameter error"));
1277602b3286ffe7da6e70bf2d9e4861a5d74ff7c473Eric Laurent            }
1278948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        }
1279948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    }
1280948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
12811a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent    /**
12821a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent     * @hide
12831a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent     */
1284602b3286ffe7da6e70bf2d9e4861a5d74ff7c473Eric Laurent    public static boolean isError(int status) {
1285602b3286ffe7da6e70bf2d9e4861a5d74ff7c473Eric Laurent        return (status < 0);
1286602b3286ffe7da6e70bf2d9e4861a5d74ff7c473Eric Laurent    }
1287602b3286ffe7da6e70bf2d9e4861a5d74ff7c473Eric Laurent
1288602b3286ffe7da6e70bf2d9e4861a5d74ff7c473Eric Laurent    /**
1289602b3286ffe7da6e70bf2d9e4861a5d74ff7c473Eric Laurent     * @hide
1290602b3286ffe7da6e70bf2d9e4861a5d74ff7c473Eric Laurent     */
1291d2bebb3ab86177c0d27664af86b30b7dce2c9bcbJean-Michel Trivi    public static int byteArrayToInt(byte[] valueBuf) {
1292948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        return byteArrayToInt(valueBuf, 0);
1293948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
1294948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    }
1295df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
12961a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent    /**
12971a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent     * @hide
12981a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent     */
1299d2bebb3ab86177c0d27664af86b30b7dce2c9bcbJean-Michel Trivi    public static int byteArrayToInt(byte[] valueBuf, int offset) {
1300948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        ByteBuffer converter = ByteBuffer.wrap(valueBuf);
1301948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        converter.order(ByteOrder.nativeOrder());
1302948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        return converter.getInt(offset);
1303948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
1304948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    }
1305948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
13061a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent    /**
13071a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent     * @hide
13081a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent     */
1309d2bebb3ab86177c0d27664af86b30b7dce2c9bcbJean-Michel Trivi    public static byte[] intToByteArray(int value) {
1310948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        ByteBuffer converter = ByteBuffer.allocate(4);
1311948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        converter.order(ByteOrder.nativeOrder());
1312948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        converter.putInt(value);
1313948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        return converter.array();
1314948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    }
1315948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
13161a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent    /**
13171a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent     * @hide
13181a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent     */
1319d2bebb3ab86177c0d27664af86b30b7dce2c9bcbJean-Michel Trivi    public static short byteArrayToShort(byte[] valueBuf) {
1320948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        return byteArrayToShort(valueBuf, 0);
1321948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    }
1322948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
13231a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent    /**
13241a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent     * @hide
13251a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent     */
1326d2bebb3ab86177c0d27664af86b30b7dce2c9bcbJean-Michel Trivi    public static short byteArrayToShort(byte[] valueBuf, int offset) {
1327948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        ByteBuffer converter = ByteBuffer.wrap(valueBuf);
1328948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        converter.order(ByteOrder.nativeOrder());
1329948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        return converter.getShort(offset);
1330948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
1331948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    }
1332948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
13331a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent    /**
13341a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent     * @hide
13351a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent     */
1336d2bebb3ab86177c0d27664af86b30b7dce2c9bcbJean-Michel Trivi    public static byte[] shortToByteArray(short value) {
1337948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        ByteBuffer converter = ByteBuffer.allocate(2);
1338948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        converter.order(ByteOrder.nativeOrder());
1339df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        short sValue = (short) value;
1340948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        converter.putShort(sValue);
1341948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        return converter.array();
1342948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    }
1343948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
13441a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent    /**
13451a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent     * @hide
13461a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent     */
1347d2bebb3ab86177c0d27664af86b30b7dce2c9bcbJean-Michel Trivi    public static byte[] concatArrays(byte[]... arrays) {
1348948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        int len = 0;
1349948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        for (byte[] a : arrays) {
1350948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent            len += a.length;
1351948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        }
1352948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        byte[] b = new byte[len];
1353948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
1354948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        int offs = 0;
1355948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        for (byte[] a : arrays) {
1356948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent            System.arraycopy(a, 0, b, offs, a.length);
1357948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent            offs += a.length;
1358948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        }
1359948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        return b;
1360948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    }
1361948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent}
1362