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;
21a7de44935634f398da1d90dde8cd7d6a822e418cMarco Nelissenimport android.annotation.TestApi;
22fa5ecdc4ac6d7a8db2bb9e4a6a60a3189025df30Svet Ganovimport android.app.ActivityThread;
23948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurentimport android.os.Handler;
24948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurentimport android.os.Looper;
25948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurentimport android.os.Message;
26d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurentimport android.util.Log;
27d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurentimport java.lang.ref.WeakReference;
28948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurentimport java.nio.ByteOrder;
29948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurentimport java.nio.ByteBuffer;
30948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurentimport java.util.UUID;
31948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
32948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent/**
331a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent * AudioEffect is the base class for controlling audio effects provided by the android audio
341a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent * framework.
351a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent * <p>Applications should not use the AudioEffect class directly but one of its derived classes to
361a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent * control specific effects:
371a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent * <ul>
381a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent *   <li> {@link android.media.audiofx.Equalizer}</li>
391a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent *   <li> {@link android.media.audiofx.Virtualizer}</li>
401a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent *   <li> {@link android.media.audiofx.BassBoost}</li>
411a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent *   <li> {@link android.media.audiofx.PresetReverb}</li>
421a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent *   <li> {@link android.media.audiofx.EnvironmentalReverb}</li>
4346a92d90df125cdc5ab131cf4fe795c9c276be90rago *   <li> {@link android.media.audiofx.DynamicsProcessing}</li>
441a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent * </ul>
4562f3617f2f4016ad2f59635d5156d64872989880Eric Laurent * <p>To apply the audio effect to a specific AudioTrack or MediaPlayer instance,
461a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent * the application must specify the audio session ID of that instance when creating the AudioEffect.
471a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent * (see {@link android.media.MediaPlayer#getAudioSessionId()} for details on audio sessions).
4862f3617f2f4016ad2f59635d5156d64872989880Eric Laurent * <p>NOTE: attaching insert effects (equalizer, bass boost, virtualizer) to the global audio output
4962f3617f2f4016ad2f59635d5156d64872989880Eric Laurent * mix by use of session 0 is deprecated.
501a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent * <p>Creating an AudioEffect object will create the corresponding effect engine in the audio
511a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent * framework if no instance of the same effect type exists in the specified audio session.
521a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent * If one exists, this instance will be used.
531a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent * <p>The application creating the AudioEffect object (or a derived class) will either receive
541a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent * control of the effect engine or not depending on the priority parameter. If priority is higher
551a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent * than the priority used by the current effect engine owner, the control will be transfered to the
561a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent * new object. Otherwise control will remain with the previous object. In this case, the new
571a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent * application will be notified of changes in effect engine state or control ownership by the
581c22ae296b85d0eebc305781b4df274ac10dbfcaMark Goldstein * appropriate listener.
59948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent */
601a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent
61df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurentpublic class AudioEffect {
62948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    static {
63948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        System.loadLibrary("audioeffect_jni");
64948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        native_init();
65948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    }
66948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
67948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    private final static String TAG = "AudioEffect-JAVA";
68948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
690f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent    // effect type UUIDs are taken from hardware/libhardware/include/hardware/audio_effect.h
700f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent
71948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    /**
72df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * The following UUIDs define effect types corresponding to standard audio
73df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * effects whose implementation and interface conform to the OpenSL ES
74df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * specification. The definitions match the corresponding interface IDs in
75df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * OpenSLES_IID.h
76948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     */
77df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    /**
7880569f7ff7db28ce98dde6e22bb4521ddbe5490aJean-Michel Trivi     * UUID for environmental reverberation effect
79df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     */
80df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    public static final UUID EFFECT_TYPE_ENV_REVERB = UUID
81df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            .fromString("c2e5d5f0-94bd-4763-9cac-4e234d06839e");
82df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    /**
8380569f7ff7db28ce98dde6e22bb4521ddbe5490aJean-Michel Trivi     * UUID for preset reverberation effect
84df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     */
85df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    public static final UUID EFFECT_TYPE_PRESET_REVERB = UUID
86df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            .fromString("47382d60-ddd8-11db-bf3a-0002a5d5c51b");
87df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    /**
88df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * UUID for equalizer effect
89df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     */
90df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    public static final UUID EFFECT_TYPE_EQUALIZER = UUID
91df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            .fromString("0bed4300-ddd6-11db-8f34-0002a5d5c51b");
92df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    /**
93df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * UUID for bass boost effect
94df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     */
95df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    public static final UUID EFFECT_TYPE_BASS_BOOST = UUID
96df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            .fromString("0634f220-ddd4-11db-a0fc-0002a5d5c51b");
97df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    /**
98df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * UUID for virtualizer effect
99df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     */
100df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    public static final UUID EFFECT_TYPE_VIRTUALIZER = UUID
101df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            .fromString("37cc2c00-dddd-11db-8577-0002a5d5c51b");
102948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
103948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    /**
10480569f7ff7db28ce98dde6e22bb4521ddbe5490aJean-Michel Trivi     * UUIDs for effect types not covered by OpenSL ES.
10580569f7ff7db28ce98dde6e22bb4521ddbe5490aJean-Michel Trivi     */
10680569f7ff7db28ce98dde6e22bb4521ddbe5490aJean-Michel Trivi    /**
10780569f7ff7db28ce98dde6e22bb4521ddbe5490aJean-Michel Trivi     * UUID for Automatic Gain Control (AGC)
1080f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent     */
1090f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent    public static final UUID EFFECT_TYPE_AGC = UUID
1100f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent            .fromString("0a8abfe0-654c-11e0-ba26-0002a5d5c51b");
1110f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent
1120f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent    /**
11380569f7ff7db28ce98dde6e22bb4521ddbe5490aJean-Michel Trivi     * UUID for Acoustic Echo Canceler (AEC)
1140f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent     */
1150f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent    public static final UUID EFFECT_TYPE_AEC = UUID
1160f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent            .fromString("7b491460-8d4d-11e0-bd61-0002a5d5c51b");
1170f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent
1180f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent    /**
11980569f7ff7db28ce98dde6e22bb4521ddbe5490aJean-Michel Trivi     * UUID for Noise Suppressor (NS)
1200f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent     */
1210f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent    public static final UUID EFFECT_TYPE_NS = UUID
1220f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent            .fromString("58b4b260-8e06-11e0-aa8e-0002a5d5c51b");
1230f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent
1240f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent    /**
125d69e4e14226258fd103d0b9c1c5b4d8529e6a3ecJean-Michel Trivi     * UUID for Loudness Enhancer
126d69e4e14226258fd103d0b9c1c5b4d8529e6a3ecJean-Michel Trivi     */
127d69e4e14226258fd103d0b9c1c5b4d8529e6a3ecJean-Michel Trivi    public static final UUID EFFECT_TYPE_LOUDNESS_ENHANCER = UUID
128d69e4e14226258fd103d0b9c1c5b4d8529e6a3ecJean-Michel Trivi              .fromString("fe3199be-aed0-413f-87bb-11260eb63cf1");
129d69e4e14226258fd103d0b9c1c5b4d8529e6a3ecJean-Michel Trivi
130d69e4e14226258fd103d0b9c1c5b4d8529e6a3ecJean-Michel Trivi    /**
13146a92d90df125cdc5ab131cf4fe795c9c276be90rago     * UUID for Dynamics Processing
13246a92d90df125cdc5ab131cf4fe795c9c276be90rago     */
13346a92d90df125cdc5ab131cf4fe795c9c276be90rago    public static final UUID EFFECT_TYPE_DYNAMICS_PROCESSING = UUID
13446a92d90df125cdc5ab131cf4fe795c9c276be90rago              .fromString("7261676f-6d75-7369-6364-28e2fd3ac39e");
13546a92d90df125cdc5ab131cf4fe795c9c276be90rago
13646a92d90df125cdc5ab131cf4fe795c9c276be90rago    /**
137a7de44935634f398da1d90dde8cd7d6a822e418cMarco Nelissen     * Null effect UUID. See {@link AudioEffect(UUID, UUID, int, int)} for use.
1381a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent     * @hide
139df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     */
140a7de44935634f398da1d90dde8cd7d6a822e418cMarco Nelissen    @TestApi
141df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    public static final UUID EFFECT_TYPE_NULL = UUID
142df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            .fromString("ec7178ec-e5e1-4432-a3f4-4657e6795210");
143df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
144df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    /**
145df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * State of an AudioEffect object that was not successfully initialized upon
146df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * creation
1471a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent     * @hide
148948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     */
149948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    public static final int STATE_UNINITIALIZED = 0;
150948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    /**
151948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     * State of an AudioEffect object that is ready to be used.
1521a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent     * @hide
153948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     */
154df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    public static final int STATE_INITIALIZED = 1;
155948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
156df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    // to keep in sync with
1572a6b80bc65c4782b5a7168b300e1dc5ec9f617eeEric Laurent    // frameworks/base/include/media/AudioEffect.h
158948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    /**
1592a6b80bc65c4782b5a7168b300e1dc5ec9f617eeEric Laurent     * Event id for engine control ownership change notification.
1601a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent     * @hide
161948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     */
1622a6b80bc65c4782b5a7168b300e1dc5ec9f617eeEric Laurent    public static final int NATIVE_EVENT_CONTROL_STATUS = 0;
163948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    /**
1642a6b80bc65c4782b5a7168b300e1dc5ec9f617eeEric Laurent     * Event id for engine state change notification.
1651a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent     * @hide
166948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     */
1672a6b80bc65c4782b5a7168b300e1dc5ec9f617eeEric Laurent    public static final int NATIVE_EVENT_ENABLED_STATUS = 1;
168948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    /**
169948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     * Event id for engine parameter change notification.
1701a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent     * @hide
171948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     */
17217cb280e7f1ac3556eac90ab08263712e0348cb9Eric Laurent    public static final int NATIVE_EVENT_PARAMETER_CHANGED = 2;
173948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
174df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    /**
175df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * Successful operation.
176df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     */
177df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    public static final int SUCCESS = 0;
178df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    /**
179df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * Unspecified error.
180df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     */
181df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    public static final int ERROR = -1;
182df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    /**
183ed6eae420fd60dcb7d90f54c3116959b75bd6276Glenn Kasten     * Internal operation status. Not returned by any method.
184df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     */
185df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    public static final int ALREADY_EXISTS = -2;
186df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    /**
187df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * Operation failed due to bad object initialization.
188df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     */
189df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    public static final int ERROR_NO_INIT = -3;
190df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    /**
191df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * Operation failed due to bad parameter value.
192df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     */
193df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    public static final int ERROR_BAD_VALUE = -4;
194df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    /**
195df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * Operation failed because it was requested in wrong state.
196df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     */
197df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    public static final int ERROR_INVALID_OPERATION = -5;
198df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    /**
199df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * Operation failed due to lack of memory.
200df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     */
201df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    public static final int ERROR_NO_MEMORY = -6;
202df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    /**
203df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * Operation failed due to dead remote object.
204df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     */
205df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    public static final int ERROR_DEAD_OBJECT = -7;
206df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
207df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    /**
2081a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent     * The effect descriptor contains information on a particular effect implemented in the
2091a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent     * audio framework:<br>
210df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * <ul>
2111d154187a99d5ad8dd33d47173cf6a4456276e76Scott Main     *  <li>type: UUID identifying the effect type. May be one of:
2121d154187a99d5ad8dd33d47173cf6a4456276e76Scott Main     * {@link AudioEffect#EFFECT_TYPE_AEC}, {@link AudioEffect#EFFECT_TYPE_AGC},
2131d154187a99d5ad8dd33d47173cf6a4456276e76Scott Main     * {@link AudioEffect#EFFECT_TYPE_BASS_BOOST}, {@link AudioEffect#EFFECT_TYPE_ENV_REVERB},
2141d154187a99d5ad8dd33d47173cf6a4456276e76Scott Main     * {@link AudioEffect#EFFECT_TYPE_EQUALIZER}, {@link AudioEffect#EFFECT_TYPE_NS},
21546a92d90df125cdc5ab131cf4fe795c9c276be90rago     * {@link AudioEffect#EFFECT_TYPE_PRESET_REVERB}, {@link AudioEffect#EFFECT_TYPE_VIRTUALIZER},
21646a92d90df125cdc5ab131cf4fe795c9c276be90rago     * {@link AudioEffect#EFFECT_TYPE_DYNAMICS_PROCESSING}.
2171d154187a99d5ad8dd33d47173cf6a4456276e76Scott Main     *  </li>
2181a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent     *  <li>uuid: UUID for this particular implementation</li>
2191d154187a99d5ad8dd33d47173cf6a4456276e76Scott Main     *  <li>connectMode: {@link #EFFECT_INSERT} or {@link #EFFECT_AUXILIARY}</li>
2201a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent     *  <li>name: human readable effect name</li>
2211a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent     *  <li>implementor: human readable effect implementor name</li>
222df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * </ul>
2231a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent     * The method {@link #queryEffects()} returns an array of Descriptors to facilitate effects
2241a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent     * enumeration.
225df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     */
226df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    public static class Descriptor {
227df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
228df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        public Descriptor() {
229df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        }
230df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
2311d154187a99d5ad8dd33d47173cf6a4456276e76Scott Main        /**
2321d154187a99d5ad8dd33d47173cf6a4456276e76Scott Main         * @param type          UUID identifying the effect type. May be one of:
2331d154187a99d5ad8dd33d47173cf6a4456276e76Scott Main         * {@link AudioEffect#EFFECT_TYPE_AEC}, {@link AudioEffect#EFFECT_TYPE_AGC},
2341d154187a99d5ad8dd33d47173cf6a4456276e76Scott Main         * {@link AudioEffect#EFFECT_TYPE_BASS_BOOST}, {@link AudioEffect#EFFECT_TYPE_ENV_REVERB},
2351d154187a99d5ad8dd33d47173cf6a4456276e76Scott Main         * {@link AudioEffect#EFFECT_TYPE_EQUALIZER}, {@link AudioEffect#EFFECT_TYPE_NS},
2361d154187a99d5ad8dd33d47173cf6a4456276e76Scott Main         * {@link AudioEffect#EFFECT_TYPE_PRESET_REVERB},
23746a92d90df125cdc5ab131cf4fe795c9c276be90rago         * {@link AudioEffect#EFFECT_TYPE_VIRTUALIZER},
23846a92d90df125cdc5ab131cf4fe795c9c276be90rago         * {@link AudioEffect#EFFECT_TYPE_DYNAMICS_PROCESSING}.
2391d154187a99d5ad8dd33d47173cf6a4456276e76Scott Main         * @param uuid         UUID for this particular implementation
2401d154187a99d5ad8dd33d47173cf6a4456276e76Scott Main         * @param connectMode  {@link #EFFECT_INSERT} or {@link #EFFECT_AUXILIARY}
2411d154187a99d5ad8dd33d47173cf6a4456276e76Scott Main         * @param name         human readable effect name
2421d154187a99d5ad8dd33d47173cf6a4456276e76Scott Main         * @param implementor  human readable effect implementor name
2431d154187a99d5ad8dd33d47173cf6a4456276e76Scott Main        *
2441d154187a99d5ad8dd33d47173cf6a4456276e76Scott Main        */
245df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        public Descriptor(String type, String uuid, String connectMode,
246df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent                String name, String implementor) {
2471a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent            this.type = UUID.fromString(type);
2481a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent            this.uuid = UUID.fromString(uuid);
2491a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent            this.connectMode = connectMode;
2501a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent            this.name = name;
2511a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent            this.implementor = implementor;
252df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        }
253df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
2541a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent        /**
25580569f7ff7db28ce98dde6e22bb4521ddbe5490aJean-Michel Trivi         *  Indicates the generic type of the effect (Equalizer, Bass boost ...).
25680569f7ff7db28ce98dde6e22bb4521ddbe5490aJean-Michel Trivi         *  One of {@link AudioEffect#EFFECT_TYPE_AEC},
25780569f7ff7db28ce98dde6e22bb4521ddbe5490aJean-Michel Trivi         *  {@link AudioEffect#EFFECT_TYPE_AGC}, {@link AudioEffect#EFFECT_TYPE_BASS_BOOST},
25880569f7ff7db28ce98dde6e22bb4521ddbe5490aJean-Michel Trivi         *  {@link AudioEffect#EFFECT_TYPE_ENV_REVERB}, {@link AudioEffect#EFFECT_TYPE_EQUALIZER},
25980569f7ff7db28ce98dde6e22bb4521ddbe5490aJean-Michel Trivi         *  {@link AudioEffect#EFFECT_TYPE_NS}, {@link AudioEffect#EFFECT_TYPE_PRESET_REVERB}
26046a92d90df125cdc5ab131cf4fe795c9c276be90rago         *  {@link AudioEffect#EFFECT_TYPE_VIRTUALIZER}
26146a92d90df125cdc5ab131cf4fe795c9c276be90rago         *   or {@link AudioEffect#EFFECT_TYPE_DYNAMICS_PROCESSING}.<br>
26280569f7ff7db28ce98dde6e22bb4521ddbe5490aJean-Michel Trivi         *  For reverberation, bass boost, EQ and virtualizer, the UUID
26380569f7ff7db28ce98dde6e22bb4521ddbe5490aJean-Michel Trivi         *  corresponds to the OpenSL ES Interface ID.
2641a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent         */
2651a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent        public UUID type;
2661a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent        /**
2671a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent         *  Indicates the particular implementation of the effect in that type. Several effects
2681a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent         *  can have the same type but this uuid is unique to a given implementation.
2691a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent         */
2701a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent        public UUID uuid;
2711a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent        /**
2721d154187a99d5ad8dd33d47173cf6a4456276e76Scott Main         *  Indicates if the effect is of insert category {@link #EFFECT_INSERT} or auxiliary
2731d154187a99d5ad8dd33d47173cf6a4456276e76Scott Main         *  category {@link #EFFECT_AUXILIARY}.
2741d154187a99d5ad8dd33d47173cf6a4456276e76Scott Main         *  Insert effects (typically an {@link Equalizer}) are applied
2751a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent         *  to the entire audio source and usually not shared by several sources. Auxiliary effects
2761a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent         *  (typically a reverberator) are applied to part of the signal (wet) and the effect output
2771a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent         *  is added to the original signal (dry).
2781d154187a99d5ad8dd33d47173cf6a4456276e76Scott Main         *  Audio pre processing are applied to audio captured on a particular
2791d154187a99d5ad8dd33d47173cf6a4456276e76Scott Main         * {@link android.media.AudioRecord}.
2801a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent         */
2811a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent        public String connectMode;
2821a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent        /**
2831a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent         * Human readable effect name
2841a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent         */
2851a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent        public String name;
2861a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent        /**
2871a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent         * Human readable effect implementor name
2881a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent         */
2891a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent        public String implementor;
290df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    };
291df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
292df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    /**
293df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * Effect connection mode is insert. Specifying an audio session ID when creating the effect
294df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * will insert this effect after all players in the same audio session.
295df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     */
296df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    public static final String EFFECT_INSERT = "Insert";
297df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    /**
298df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * Effect connection mode is auxiliary.
299df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * <p>Auxiliary effects must be created on session 0 (global output mix). In order for a
300df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * MediaPlayer or AudioTrack to be fed into this effect, they must be explicitely attached to
301df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * this effect and a send level must be specified.
302df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * <p>Use the effect ID returned by {@link #getId()} to designate this particular effect when
303df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * attaching it to the MediaPlayer or AudioTrack.
304df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     */
305df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    public static final String EFFECT_AUXILIARY = "Auxiliary";
3060f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent    /**
3070f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent     * Effect connection mode is pre processing.
3080f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent     * The audio pre processing effects are attached to an audio input (AudioRecord).
3090f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent     * @hide
3100f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent     */
3110f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent    public static final String EFFECT_PRE_PROCESSING = "Pre Processing";
312948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
313df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    // --------------------------------------------------------------------------
314948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    // Member variables
315df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    // --------------------
316948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    /**
317948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     * Indicates the state of the AudioEffect instance
318948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     */
31917cb280e7f1ac3556eac90ab08263712e0348cb9Eric Laurent    private int mState = STATE_UNINITIALIZED;
320948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    /**
321948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     * Lock to synchronize access to mState
322948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     */
32317cb280e7f1ac3556eac90ab08263712e0348cb9Eric Laurent    private final Object mStateLock = new Object();
324948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    /**
325948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     * System wide unique effect ID
326948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     */
32717cb280e7f1ac3556eac90ab08263712e0348cb9Eric Laurent    private int mId;
328948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
329948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    // accessed by native methods
330ea7861c918567d17d40a762b38f97c053d88b839Ashok Bhat    private long mNativeAudioEffect;
331ea7861c918567d17d40a762b38f97c053d88b839Ashok Bhat    private long mJniData;
332948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
333948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    /**
334948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     * Effect descriptor
335948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     */
336948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    private Descriptor mDescriptor;
337948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
338948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    /**
339948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     * Listener for effect engine state change notifications.
340df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     *
341df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * @see #setEnableStatusListener(OnEnableStatusChangeListener)
342948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     */
34317cb280e7f1ac3556eac90ab08263712e0348cb9Eric Laurent    private OnEnableStatusChangeListener mEnableStatusChangeListener = null;
344948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    /**
345948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     * Listener for effect engine control ownership change notifications.
346df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     *
347df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * @see #setControlStatusListener(OnControlStatusChangeListener)
348948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     */
34917cb280e7f1ac3556eac90ab08263712e0348cb9Eric Laurent    private OnControlStatusChangeListener mControlChangeStatusListener = null;
350948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    /**
351948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     * Listener for effect engine control ownership change notifications.
352df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     *
353df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * @see #setParameterListener(OnParameterChangeListener)
354948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     */
35517cb280e7f1ac3556eac90ab08263712e0348cb9Eric Laurent    private OnParameterChangeListener mParameterChangeListener = null;
356948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    /**
357948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     * Lock to protect listeners updates against event notifications
3581a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent     * @hide
359948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     */
36017cb280e7f1ac3556eac90ab08263712e0348cb9Eric Laurent    public final Object mListenerLock = new Object();
361948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    /**
362948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     * Handler for events coming from the native code
3631a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent     * @hide
364948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     */
36517cb280e7f1ac3556eac90ab08263712e0348cb9Eric Laurent    public NativeEventHandler mNativeEventHandler = null;
366948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
367df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    // --------------------------------------------------------------------------
368948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    // Constructor, Finalize
369df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    // --------------------
370948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    /**
371948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     * Class constructor.
372df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     *
373df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * @param type type of effect engine created. See {@link #EFFECT_TYPE_ENV_REVERB},
374df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     *            {@link #EFFECT_TYPE_EQUALIZER} ... Types corresponding to
375df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     *            built-in effects are defined by AudioEffect class. Other types
376df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     *            can be specified provided they correspond an existing OpenSL
377df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     *            ES interface ID and the corresponsing effect is available on
378df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     *            the platform. If an unspecified effect type is requested, the
379df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     *            constructor with throw the IllegalArgumentException. This
380df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     *            parameter can be set to {@link #EFFECT_TYPE_NULL} in which
381df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     *            case only the uuid will be used to select the effect.
382df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * @param uuid unique identifier of a particular effect implementation.
383df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     *            Must be specified if the caller wants to use a particular
384df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     *            implementation of an effect type. This parameter can be set to
385df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     *            {@link #EFFECT_TYPE_NULL} in which case only the type will
386df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     *            be used to select the effect.
387df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * @param priority the priority level requested by the application for
388df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     *            controlling the effect engine. As the same effect engine can
389df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     *            be shared by several applications, this parameter indicates
390df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     *            how much the requesting application needs control of effect
391df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     *            parameters. The normal priority is 0, above normal is a
392df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     *            positive number, below normal a negative number.
39362f3617f2f4016ad2f59635d5156d64872989880Eric Laurent     * @param audioSession system wide unique audio session identifier.
39462f3617f2f4016ad2f59635d5156d64872989880Eric Laurent     *            The effect will be attached to the MediaPlayer or AudioTrack in
39562f3617f2f4016ad2f59635d5156d64872989880Eric Laurent     *            the same audio session.
396948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     *
397948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     * @throws java.lang.IllegalArgumentException
398948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     * @throws java.lang.UnsupportedOperationException
399948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     * @throws java.lang.RuntimeException
4001a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent     * @hide
401948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     */
402948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
403948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    public AudioEffect(UUID type, UUID uuid, int priority, int audioSession)
404df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            throws IllegalArgumentException, UnsupportedOperationException,
405df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            RuntimeException {
406948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        int[] id = new int[1];
407948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        Descriptor[] desc = new Descriptor[1];
408948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        // native initialization
409948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        int initResult = native_setup(new WeakReference<AudioEffect>(this),
410df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent                type.toString(), uuid.toString(), priority, audioSession, id,
411fbf0ecabac5d7a929628b43ffe8f4f953e47bd54Svetoslav                desc, ActivityThread.currentOpPackageName());
412948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        if (initResult != SUCCESS && initResult != ALREADY_EXISTS) {
413df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            Log.e(TAG, "Error code " + initResult
414df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent                    + " when initializing AudioEffect.");
415948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent            switch (initResult) {
416df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            case ERROR_BAD_VALUE:
417df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent                throw (new IllegalArgumentException("Effect type: " + type
418df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent                        + " not supported."));
419df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            case ERROR_INVALID_OPERATION:
420df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent                throw (new UnsupportedOperationException(
421df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent                        "Effect library not loaded"));
422948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent            default:
423df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent                throw (new RuntimeException(
424df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent                        "Cannot initialize effect engine for type: " + type
4255bb8f80fc4a72ad70d7d38cdc9f7988edce476e4Glenn Kasten                                + " Error: " + initResult));
426948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent            }
427948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        }
428948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        mId = id[0];
429948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        mDescriptor = desc[0];
430948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        synchronized (mStateLock) {
431948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent            mState = STATE_INITIALIZED;
432948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        }
433948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    }
434948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
435948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    /**
436df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * Releases the native AudioEffect resources. It is a good practice to
437df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * release the effect engine when not in use as control can be returned to
438df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * other applications or the native resources released.
439948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     */
440948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    public void release() {
441948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        synchronized (mStateLock) {
442948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent            native_release();
443948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent            mState = STATE_UNINITIALIZED;
444948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        }
445948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    }
446948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
447948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    @Override
448948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    protected void finalize() {
449948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        native_finalize();
450948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    }
451948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
452948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    /**
453948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     * Get the effect descriptor.
454df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     *
4551a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent     * @see android.media.audiofx.AudioEffect.Descriptor
456948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     * @throws IllegalStateException
457948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     */
458df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    public Descriptor getDescriptor() throws IllegalStateException {
459948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        checkState("getDescriptor()");
460948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        return mDescriptor;
461948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    }
462948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
463df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    // --------------------------------------------------------------------------
464948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    // Effects Enumeration
465df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    // --------------------
466948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
467948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    /**
468948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     * Query all effects available on the platform. Returns an array of
4691a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent     * {@link android.media.audiofx.AudioEffect.Descriptor} objects
470948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     *
471948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     * @throws IllegalStateException
472948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     */
473948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
474948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    static public Descriptor[] queryEffects() {
475df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        return (Descriptor[]) native_query_effects();
476948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    }
477948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
4780f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent    /**
47980569f7ff7db28ce98dde6e22bb4521ddbe5490aJean-Michel Trivi     * Query all audio pre-processing effects applied to the AudioRecord with the supplied
4800f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent     * audio session ID. Returns an array of {@link android.media.audiofx.AudioEffect.Descriptor}
4810f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent     * objects.
4820f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent     * @param audioSession system wide unique audio session identifier.
4830f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent     * @throws IllegalStateException
4840f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent     * @hide
4850f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent     */
4860f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent
4870f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent    static public Descriptor[] queryPreProcessings(int audioSession) {
4880f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent        return (Descriptor[]) native_query_pre_processing(audioSession);
4890f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent    }
490855255d89fe0a14abe796355bebb64031ec6ff47Eric Laurent
491855255d89fe0a14abe796355bebb64031ec6ff47Eric Laurent    /**
492855255d89fe0a14abe796355bebb64031ec6ff47Eric Laurent     * Checks if the device implements the specified effect type.
493855255d89fe0a14abe796355bebb64031ec6ff47Eric Laurent     * @param type the requested effect type.
494855255d89fe0a14abe796355bebb64031ec6ff47Eric Laurent     * @return true if the device implements the specified effect type, false otherwise.
495855255d89fe0a14abe796355bebb64031ec6ff47Eric Laurent     * @hide
496855255d89fe0a14abe796355bebb64031ec6ff47Eric Laurent     */
4973ce023b02eec04874b4c659f0973b6a05182970bAndy Hung    @TestApi
498855255d89fe0a14abe796355bebb64031ec6ff47Eric Laurent    public static boolean isEffectTypeAvailable(UUID type) {
499855255d89fe0a14abe796355bebb64031ec6ff47Eric Laurent        AudioEffect.Descriptor[] desc = AudioEffect.queryEffects();
500de709869ae10263c4c325aaa72cdc6aada0ae8d5Jason Parks        if (desc == null) {
501de709869ae10263c4c325aaa72cdc6aada0ae8d5Jason Parks            return false;
502de709869ae10263c4c325aaa72cdc6aada0ae8d5Jason Parks        }
503de709869ae10263c4c325aaa72cdc6aada0ae8d5Jason Parks
504855255d89fe0a14abe796355bebb64031ec6ff47Eric Laurent        for (int i = 0; i < desc.length; i++) {
505855255d89fe0a14abe796355bebb64031ec6ff47Eric Laurent            if (desc[i].type.equals(type)) {
506855255d89fe0a14abe796355bebb64031ec6ff47Eric Laurent                return true;
507855255d89fe0a14abe796355bebb64031ec6ff47Eric Laurent            }
508855255d89fe0a14abe796355bebb64031ec6ff47Eric Laurent        }
509855255d89fe0a14abe796355bebb64031ec6ff47Eric Laurent        return false;
510855255d89fe0a14abe796355bebb64031ec6ff47Eric Laurent    }
5110f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent
512df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    // --------------------------------------------------------------------------
513948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    // Control methods
514df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    // --------------------
515948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
516948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    /**
5171a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent     * Enable or disable the effect.
5181a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent     * Creating an audio effect does not automatically apply this effect on the audio source. It
5191a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent     * creates the resources necessary to process this effect but the audio signal is still bypassed
5201a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent     * through the effect engine. Calling this method will make that the effect is actually applied
5211a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent     * or not to the audio content being played in the corresponding audio session.
522df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     *
523df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * @param enabled the requested enable state
524df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * @return {@link #SUCCESS} in case of success, {@link #ERROR_INVALID_OPERATION}
525df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     *         or {@link #ERROR_DEAD_OBJECT} in case of failure.
526948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     * @throws IllegalStateException
527948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     */
528df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    public int setEnabled(boolean enabled) throws IllegalStateException {
529df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        checkState("setEnabled()");
530df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        return native_setEnabled(enabled);
531948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    }
532948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
533948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    /**
534948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     * Set effect parameter. The setParameter method is provided in several
535df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * forms addressing most common parameter formats. This form is the most
536df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * generic one where the parameter and its value are both specified as an
537df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * array of bytes. The parameter and value type and length are therefore
538df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * totally free. For standard effect defined by OpenSL ES, the parameter
539df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * format and values must match the definitions in the corresponding OpenSL
540df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * ES interface.
541948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     *
542df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * @param param the identifier of the parameter to set
543df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * @param value the new value for the specified parameter
544df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * @return {@link #SUCCESS} in case of success, {@link #ERROR_BAD_VALUE},
545df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     *         {@link #ERROR_NO_MEMORY}, {@link #ERROR_INVALID_OPERATION} or
546df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     *         {@link #ERROR_DEAD_OBJECT} in case of failure
547948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     * @throws IllegalStateException
5481a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent     * @hide
549948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     */
5503ce023b02eec04874b4c659f0973b6a05182970bAndy Hung    @TestApi
551948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    public int setParameter(byte[] param, byte[] value)
552df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            throws IllegalStateException {
553948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        checkState("setParameter()");
554948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        return native_setParameter(param.length, param, value.length, value);
555948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    }
556948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
557948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    /**
558948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     * Set effect parameter. The parameter and its value are integers.
559df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     *
560df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * @see #setParameter(byte[], byte[])
5611a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent     * @hide
562948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     */
5633ce023b02eec04874b4c659f0973b6a05182970bAndy Hung    @TestApi
564df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    public int setParameter(int param, int value) throws IllegalStateException {
565948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        byte[] p = intToByteArray(param);
566948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        byte[] v = intToByteArray(value);
567948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        return setParameter(p, v);
568948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    }
569948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
570948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    /**
571df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * Set effect parameter. The parameter is an integer and the value is a
572df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * short integer.
573df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     *
574df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * @see #setParameter(byte[], byte[])
5751a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent     * @hide
576948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     */
5773ce023b02eec04874b4c659f0973b6a05182970bAndy Hung    @TestApi
578948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    public int setParameter(int param, short value)
579df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            throws IllegalStateException {
580948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        byte[] p = intToByteArray(param);
581948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        byte[] v = shortToByteArray(value);
582948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        return setParameter(p, v);
583948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    }
584948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
585948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    /**
586df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * Set effect parameter. The parameter is an integer and the value is an
587df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * array of bytes.
588df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     *
589df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * @see #setParameter(byte[], byte[])
5901a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent     * @hide
591948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     */
5923ce023b02eec04874b4c659f0973b6a05182970bAndy Hung    @TestApi
593948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    public int setParameter(int param, byte[] value)
594df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            throws IllegalStateException {
595948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        byte[] p = intToByteArray(param);
596948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        return setParameter(p, value);
597948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    }
598948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
599948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    /**
600df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * Set effect parameter. The parameter is an array of 1 or 2 integers and
601df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * the value is also an array of 1 or 2 integers
602df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     *
603df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * @see #setParameter(byte[], byte[])
6041a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent     * @hide
605948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     */
6063ce023b02eec04874b4c659f0973b6a05182970bAndy Hung    @TestApi
607948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    public int setParameter(int[] param, int[] value)
608df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            throws IllegalStateException {
609948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        if (param.length > 2 || value.length > 2) {
610df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            return ERROR_BAD_VALUE;
611948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        }
612948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        byte[] p = intToByteArray(param[0]);
613948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        if (param.length > 1) {
614948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent            byte[] p2 = intToByteArray(param[1]);
615948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent            p = concatArrays(p, p2);
616948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        }
617948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        byte[] v = intToByteArray(value[0]);
618948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        if (value.length > 1) {
619948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent            byte[] v2 = intToByteArray(value[1]);
620948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent            v = concatArrays(v, v2);
621948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        }
622948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        return setParameter(p, v);
623948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    }
624948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
625948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    /**
626df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * Set effect parameter. The parameter is an array of 1 or 2 integers and
627df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * the value is an array of 1 or 2 short integers
628df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     *
629df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * @see #setParameter(byte[], byte[])
6301a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent     * @hide
631948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     */
632948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    public int setParameter(int[] param, short[] value)
633df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            throws IllegalStateException {
634948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        if (param.length > 2 || value.length > 2) {
635df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            return ERROR_BAD_VALUE;
636948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        }
637948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        byte[] p = intToByteArray(param[0]);
638948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        if (param.length > 1) {
639948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent            byte[] p2 = intToByteArray(param[1]);
640948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent            p = concatArrays(p, p2);
641948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        }
642948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
643948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        byte[] v = shortToByteArray(value[0]);
644948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        if (value.length > 1) {
645948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent            byte[] v2 = shortToByteArray(value[1]);
646948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent            v = concatArrays(v, v2);
647948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        }
648948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        return setParameter(p, v);
649948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    }
650948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
651948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    /**
652df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * Set effect parameter. The parameter is an array of 1 or 2 integers and
653df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * the value is an array of bytes
654df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     *
655df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * @see #setParameter(byte[], byte[])
6561a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent     * @hide
657948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     */
6583ce023b02eec04874b4c659f0973b6a05182970bAndy Hung    @TestApi
659948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    public int setParameter(int[] param, byte[] value)
660df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            throws IllegalStateException {
661948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        if (param.length > 2) {
662df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            return ERROR_BAD_VALUE;
663948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        }
664948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        byte[] p = intToByteArray(param[0]);
665948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        if (param.length > 1) {
666948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent            byte[] p2 = intToByteArray(param[1]);
667948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent            p = concatArrays(p, p2);
668948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        }
669948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        return setParameter(p, value);
670948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    }
671948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
672948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    /**
673948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     * Get effect parameter. The getParameter method is provided in several
674df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * forms addressing most common parameter formats. This form is the most
675df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * generic one where the parameter and its value are both specified as an
676df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * array of bytes. The parameter and value type and length are therefore
677948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     * totally free.
678df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     *
679df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * @param param the identifier of the parameter to set
680df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * @param value the new value for the specified parameter
681602b3286ffe7da6e70bf2d9e4861a5d74ff7c473Eric Laurent     * @return the number of meaningful bytes in value array in case of success or
682602b3286ffe7da6e70bf2d9e4861a5d74ff7c473Eric Laurent     *  {@link #ERROR_BAD_VALUE}, {@link #ERROR_NO_MEMORY}, {@link #ERROR_INVALID_OPERATION}
683602b3286ffe7da6e70bf2d9e4861a5d74ff7c473Eric Laurent     *  or {@link #ERROR_DEAD_OBJECT} in case of failure.
684948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     * @throws IllegalStateException
6851a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent     * @hide
686948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     */
6873ce023b02eec04874b4c659f0973b6a05182970bAndy Hung    @TestApi
688948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    public int getParameter(byte[] param, byte[] value)
689df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            throws IllegalStateException {
690948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        checkState("getParameter()");
691602b3286ffe7da6e70bf2d9e4861a5d74ff7c473Eric Laurent        return native_getParameter(param.length, param, value.length, value);
692948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    }
693948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
694948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    /**
695df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * Get effect parameter. The parameter is an integer and the value is an
696df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * array of bytes.
697df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     *
698df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * @see #getParameter(byte[], byte[])
6991a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent     * @hide
700948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     */
7013ce023b02eec04874b4c659f0973b6a05182970bAndy Hung    @TestApi
702948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    public int getParameter(int param, byte[] value)
703df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            throws IllegalStateException {
704948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        byte[] p = intToByteArray(param);
705948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
706948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        return getParameter(p, value);
707948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    }
708948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
709948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    /**
710df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * Get effect parameter. The parameter is an integer and the value is an
711df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * array of 1 or 2 integers
712df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     *
713df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * @see #getParameter(byte[], byte[])
714602b3286ffe7da6e70bf2d9e4861a5d74ff7c473Eric Laurent     * In case of success, returns the number of meaningful integers in value array.
7151a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent     * @hide
716948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     */
7173ce023b02eec04874b4c659f0973b6a05182970bAndy Hung    @TestApi
718948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    public int getParameter(int param, int[] value)
719df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            throws IllegalStateException {
720948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        if (value.length > 2) {
721df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            return ERROR_BAD_VALUE;
722948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        }
723948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        byte[] p = intToByteArray(param);
724948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
725948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        byte[] v = new byte[value.length * 4];
726948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
727948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        int status = getParameter(p, v);
728948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
729602b3286ffe7da6e70bf2d9e4861a5d74ff7c473Eric Laurent        if (status == 4 || status == 8) {
730602b3286ffe7da6e70bf2d9e4861a5d74ff7c473Eric Laurent            value[0] = byteArrayToInt(v);
731602b3286ffe7da6e70bf2d9e4861a5d74ff7c473Eric Laurent            if (status == 8) {
732602b3286ffe7da6e70bf2d9e4861a5d74ff7c473Eric Laurent                value[1] = byteArrayToInt(v, 4);
733602b3286ffe7da6e70bf2d9e4861a5d74ff7c473Eric Laurent            }
734602b3286ffe7da6e70bf2d9e4861a5d74ff7c473Eric Laurent            status /= 4;
735602b3286ffe7da6e70bf2d9e4861a5d74ff7c473Eric Laurent        } else {
736602b3286ffe7da6e70bf2d9e4861a5d74ff7c473Eric Laurent            status = ERROR;
737948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        }
738948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        return status;
739948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    }
740948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
741948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    /**
742df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * Get effect parameter. The parameter is an integer and the value is an
743df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * array of 1 or 2 short integers
744df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     *
745df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * @see #getParameter(byte[], byte[])
746602b3286ffe7da6e70bf2d9e4861a5d74ff7c473Eric Laurent     * In case of success, returns the number of meaningful short integers in value array.
7471a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent     * @hide
748948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     */
7493ce023b02eec04874b4c659f0973b6a05182970bAndy Hung    @TestApi
750948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    public int getParameter(int param, short[] value)
751df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            throws IllegalStateException {
752948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        if (value.length > 2) {
753df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            return ERROR_BAD_VALUE;
754948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        }
755948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        byte[] p = intToByteArray(param);
756948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
757948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        byte[] v = new byte[value.length * 2];
758948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
759948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        int status = getParameter(p, v);
760948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
761602b3286ffe7da6e70bf2d9e4861a5d74ff7c473Eric Laurent        if (status == 2 || status == 4) {
762602b3286ffe7da6e70bf2d9e4861a5d74ff7c473Eric Laurent            value[0] = byteArrayToShort(v);
763602b3286ffe7da6e70bf2d9e4861a5d74ff7c473Eric Laurent            if (status == 4) {
764602b3286ffe7da6e70bf2d9e4861a5d74ff7c473Eric Laurent                value[1] = byteArrayToShort(v, 2);
765602b3286ffe7da6e70bf2d9e4861a5d74ff7c473Eric Laurent            }
766602b3286ffe7da6e70bf2d9e4861a5d74ff7c473Eric Laurent            status /= 2;
767602b3286ffe7da6e70bf2d9e4861a5d74ff7c473Eric Laurent        } else {
768602b3286ffe7da6e70bf2d9e4861a5d74ff7c473Eric Laurent            status = ERROR;
769948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        }
770948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        return status;
771948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    }
772948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
773948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    /**
774df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * Get effect parameter. The parameter is an array of 1 or 2 integers and
775df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * the value is also an array of 1 or 2 integers
776df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     *
777df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * @see #getParameter(byte[], byte[])
778602b3286ffe7da6e70bf2d9e4861a5d74ff7c473Eric Laurent     * In case of success, the returns the number of meaningful integers in value array.
7791a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent     * @hide
780948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     */
781948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    public int getParameter(int[] param, int[] value)
782df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            throws IllegalStateException {
783948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        if (param.length > 2 || value.length > 2) {
784df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            return ERROR_BAD_VALUE;
785948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        }
786948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        byte[] p = intToByteArray(param[0]);
787948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        if (param.length > 1) {
788948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent            byte[] p2 = intToByteArray(param[1]);
789948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent            p = concatArrays(p, p2);
790948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        }
791948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        byte[] v = new byte[value.length * 4];
792948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
793948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        int status = getParameter(p, v);
794948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
795602b3286ffe7da6e70bf2d9e4861a5d74ff7c473Eric Laurent        if (status == 4 || status == 8) {
796602b3286ffe7da6e70bf2d9e4861a5d74ff7c473Eric Laurent            value[0] = byteArrayToInt(v);
797602b3286ffe7da6e70bf2d9e4861a5d74ff7c473Eric Laurent            if (status == 8) {
798602b3286ffe7da6e70bf2d9e4861a5d74ff7c473Eric Laurent                value[1] = byteArrayToInt(v, 4);
799602b3286ffe7da6e70bf2d9e4861a5d74ff7c473Eric Laurent            }
800602b3286ffe7da6e70bf2d9e4861a5d74ff7c473Eric Laurent            status /= 4;
801602b3286ffe7da6e70bf2d9e4861a5d74ff7c473Eric Laurent        } else {
802602b3286ffe7da6e70bf2d9e4861a5d74ff7c473Eric Laurent            status = ERROR;
803948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        }
804948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        return status;
805948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    }
806948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
807948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    /**
808df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * Get effect parameter. The parameter is an array of 1 or 2 integers and
809df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * the value is an array of 1 or 2 short integers
810df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     *
811df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * @see #getParameter(byte[], byte[])
812602b3286ffe7da6e70bf2d9e4861a5d74ff7c473Eric Laurent     * In case of success, returns the number of meaningful short integers in value array.
8131a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent     * @hide
814948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     */
8153ce023b02eec04874b4c659f0973b6a05182970bAndy Hung    @TestApi
816948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    public int getParameter(int[] param, short[] value)
817df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            throws IllegalStateException {
818948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        if (param.length > 2 || value.length > 2) {
819df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            return ERROR_BAD_VALUE;
820948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        }
821948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        byte[] p = intToByteArray(param[0]);
822948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        if (param.length > 1) {
823948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent            byte[] p2 = intToByteArray(param[1]);
824948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent            p = concatArrays(p, p2);
825948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        }
826948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        byte[] v = new byte[value.length * 2];
827948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
828948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        int status = getParameter(p, v);
829948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
830602b3286ffe7da6e70bf2d9e4861a5d74ff7c473Eric Laurent        if (status == 2 || status == 4) {
831602b3286ffe7da6e70bf2d9e4861a5d74ff7c473Eric Laurent            value[0] = byteArrayToShort(v);
832602b3286ffe7da6e70bf2d9e4861a5d74ff7c473Eric Laurent            if (status == 4) {
833602b3286ffe7da6e70bf2d9e4861a5d74ff7c473Eric Laurent                value[1] = byteArrayToShort(v, 2);
834602b3286ffe7da6e70bf2d9e4861a5d74ff7c473Eric Laurent            }
835602b3286ffe7da6e70bf2d9e4861a5d74ff7c473Eric Laurent            status /= 2;
836602b3286ffe7da6e70bf2d9e4861a5d74ff7c473Eric Laurent        } else {
837602b3286ffe7da6e70bf2d9e4861a5d74ff7c473Eric Laurent            status = ERROR;
838948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        }
839948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        return status;
840948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    }
841948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
842948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    /**
843df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * Get effect parameter. The parameter is an array of 1 or 2 integers and
844df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * the value is an array of bytes
845df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     *
846df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * @see #getParameter(byte[], byte[])
8471a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent     * @hide
848948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     */
849948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    public int getParameter(int[] param, byte[] value)
850df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            throws IllegalStateException {
851948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        if (param.length > 2) {
852df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            return ERROR_BAD_VALUE;
853948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        }
854948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        byte[] p = intToByteArray(param[0]);
855948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        if (param.length > 1) {
856948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent            byte[] p2 = intToByteArray(param[1]);
857948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent            p = concatArrays(p, p2);
858948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        }
859948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
860948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        return getParameter(p, value);
861948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    }
862948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
863948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    /**
864df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * Send a command to the effect engine. This method is intended to send
865df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * proprietary commands to a particular effect implementation.
866602b3286ffe7da6e70bf2d9e4861a5d74ff7c473Eric Laurent     * In case of success, returns the number of meaningful bytes in reply array.
867602b3286ffe7da6e70bf2d9e4861a5d74ff7c473Eric Laurent     * In case of failure, the returned value is negative and implementation specific.
8681a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent     * @hide
869948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     */
870948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    public int command(int cmdCode, byte[] command, byte[] reply)
871df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            throws IllegalStateException {
872948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        checkState("command()");
873602b3286ffe7da6e70bf2d9e4861a5d74ff7c473Eric Laurent        return native_command(cmdCode, command.length, command, reply.length, reply);
874948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    }
875948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
876df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    // --------------------------------------------------------------------------
877948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    // Getters
878df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    // --------------------
879948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
880948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    /**
881df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * Returns effect unique identifier. This system wide unique identifier can
882df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * be used to attach this effect to a MediaPlayer or an AudioTrack when the
883df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * effect is an auxiliary effect (Reverb)
884df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     *
885948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     * @return the effect identifier.
886948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     * @throws IllegalStateException
887948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     */
888df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    public int getId() throws IllegalStateException {
889948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        checkState("getId()");
890948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        return mId;
891948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    }
892948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
893948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    /**
8941a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent     * Returns effect enabled state
895df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     *
896948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     * @return true if the effect is enabled, false otherwise.
897948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     * @throws IllegalStateException
898948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     */
899df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    public boolean getEnabled() throws IllegalStateException {
900df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        checkState("getEnabled()");
901df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        return native_getEnabled();
902948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    }
903948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
904948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    /**
905948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     * Checks if this AudioEffect object is controlling the effect engine.
906df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     *
907df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * @return true if this instance has control of effect engine, false
908df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     *         otherwise.
909948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     * @throws IllegalStateException
910948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     */
911df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    public boolean hasControl() throws IllegalStateException {
912948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        checkState("hasControl()");
913948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        return native_hasControl();
914948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    }
915948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
916df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    // --------------------------------------------------------------------------
917948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    // Initialization / configuration
918df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    // --------------------
919948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    /**
920948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     * Sets the listener AudioEffect notifies when the effect engine is enabled
921948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     * or disabled.
922df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     *
923948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     * @param listener
924948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     */
925948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    public void setEnableStatusListener(OnEnableStatusChangeListener listener) {
926948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        synchronized (mListenerLock) {
927948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent            mEnableStatusChangeListener = listener;
928948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        }
929948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        if ((listener != null) && (mNativeEventHandler == null)) {
930948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent            createNativeEventHandler();
931948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        }
932948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    }
933948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
934948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    /**
935df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * Sets the listener AudioEffect notifies when the effect engine control is
936df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * taken or returned.
937df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     *
938948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     * @param listener
939948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     */
940948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    public void setControlStatusListener(OnControlStatusChangeListener listener) {
941948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        synchronized (mListenerLock) {
942948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent            mControlChangeStatusListener = listener;
943948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        }
944948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        if ((listener != null) && (mNativeEventHandler == null)) {
945948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent            createNativeEventHandler();
946948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        }
947948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    }
948948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
949948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    /**
950948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     * Sets the listener AudioEffect notifies when a parameter is changed.
951df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     *
952948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     * @param listener
9531a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent     * @hide
954948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     */
9553ce023b02eec04874b4c659f0973b6a05182970bAndy Hung    @TestApi
956948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    public void setParameterListener(OnParameterChangeListener listener) {
957948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        synchronized (mListenerLock) {
958948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent            mParameterChangeListener = listener;
959948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        }
960948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        if ((listener != null) && (mNativeEventHandler == null)) {
961948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent            createNativeEventHandler();
962948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        }
963948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    }
964948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
965948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    // Convenience method for the creation of the native event handler
966948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    // It is called only when a non-null event listener is set.
967948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    // precondition:
968df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    // mNativeEventHandler is null
969948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    private void createNativeEventHandler() {
970948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        Looper looper;
971948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        if ((looper = Looper.myLooper()) != null) {
972948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent            mNativeEventHandler = new NativeEventHandler(this, looper);
973948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        } else if ((looper = Looper.getMainLooper()) != null) {
974948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent            mNativeEventHandler = new NativeEventHandler(this, looper);
975948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        } else {
976948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent            mNativeEventHandler = null;
977948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        }
978948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    }
979948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
980df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    // ---------------------------------------------------------
981948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    // Interface definitions
982df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    // --------------------
983948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    /**
9842a6b80bc65c4782b5a7168b300e1dc5ec9f617eeEric Laurent     * The OnEnableStatusChangeListener interface defines a method called by the AudioEffect
985df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * when a the enabled state of the effect engine was changed by the controlling application.
986948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     */
987df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    public interface OnEnableStatusChangeListener {
988948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        /**
989df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent         * Called on the listener to notify it that the effect engine has been
990df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent         * enabled or disabled.
991df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent         * @param effect the effect on which the interface is registered.
992df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent         * @param enabled new effect state.
993948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent         */
994948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        void onEnableStatusChange(AudioEffect effect, boolean enabled);
995948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    }
996948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
997948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    /**
998df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * The OnControlStatusChangeListener interface defines a method called by the AudioEffect
999df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * when a the control of the effect engine is gained or lost by the application
1000948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     */
1001df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    public interface OnControlStatusChangeListener {
1002948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        /**
1003df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent         * Called on the listener to notify it that the effect engine control
1004df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent         * has been taken or returned.
1005df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent         * @param effect the effect on which the interface is registered.
1006df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent         * @param controlGranted true if the application has been granted control of the effect
1007df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent         * engine, false otherwise.
1008948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent         */
1009948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        void onControlStatusChange(AudioEffect effect, boolean controlGranted);
1010948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    }
1011948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
1012948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    /**
1013df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * The OnParameterChangeListener interface defines a method called by the AudioEffect
1014df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * when a parameter is changed in the effect engine by the controlling application.
10151a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent     * @hide
1016948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     */
10173ce023b02eec04874b4c659f0973b6a05182970bAndy Hung    @TestApi
1018df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    public interface OnParameterChangeListener {
1019948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        /**
1020948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent         * Called on the listener to notify it that a parameter value has changed.
1021df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent         * @param effect the effect on which the interface is registered.
1022df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent         * @param status status of the set parameter operation.
1023df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent         * @param param ID of the modified parameter.
1024df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent         * @param value the new parameter value.
1025948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent         */
1026df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        void onParameterChange(AudioEffect effect, int status, byte[] param,
1027df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent                byte[] value);
1028948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    }
1029948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
1030d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent
1031d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent    // -------------------------------------------------------------------------
1032d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent    // Audio Effect Control panel intents
1033d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent    // -------------------------------------------------------------------------
1034d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent
1035d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent    /**
103692cf2d60851462d91a1eb4b9615ea93579dd4330Eric Laurent     *  Intent to launch an audio effect control panel UI.
103792cf2d60851462d91a1eb4b9615ea93579dd4330Eric Laurent     *  <p>The goal of this intent is to enable separate implementations of music/media player
103892cf2d60851462d91a1eb4b9615ea93579dd4330Eric Laurent     *  applications and audio effect control application or services.
103992cf2d60851462d91a1eb4b9615ea93579dd4330Eric Laurent     *  This will allow platform vendors to offer more advanced control options for standard effects
104092cf2d60851462d91a1eb4b9615ea93579dd4330Eric Laurent     *  or control for platform specific effects.
1041d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent     *  <p>The intent carries a number of extras used by the player application to communicate
1042d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent     *  necessary pieces of information to the control panel application.
1043d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent     *  <p>The calling application must use the
1044d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent     *  {@link android.app.Activity#startActivityForResult(Intent, int)} method to launch the
1045d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent     *  control panel so that its package name is indicated and used by the control panel
1046d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent     *  application to keep track of changes for this particular application.
104792cf2d60851462d91a1eb4b9615ea93579dd4330Eric Laurent     *  <p>The {@link #EXTRA_AUDIO_SESSION} extra will indicate an audio session to which the
1048d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent     *  audio effects should be applied. If no audio session is specified, either one of the
1049d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent     *  follownig will happen:
105092cf2d60851462d91a1eb4b9615ea93579dd4330Eric Laurent     *  <p>- If an audio session was previously opened by the calling application with
1051d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent     *  {@link #ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION} intent, the effect changes will
1052d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent     *  be applied to that session.
105392cf2d60851462d91a1eb4b9615ea93579dd4330Eric Laurent     *  <p>- If no audio session is opened, the changes will be stored in the package specific
105492cf2d60851462d91a1eb4b9615ea93579dd4330Eric Laurent     *  storage area and applied whenever a new audio session is opened by this application.
105592cf2d60851462d91a1eb4b9615ea93579dd4330Eric Laurent     *  <p>The {@link #EXTRA_CONTENT_TYPE} extra will help the control panel application
1056d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent     *  customize both the UI layout and the default audio effect settings if none are already
1057d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent     *  stored for the calling application.
1058d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent     */
1059d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent    @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
1060d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent    public static final String ACTION_DISPLAY_AUDIO_EFFECT_CONTROL_PANEL =
1061d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent        "android.media.action.DISPLAY_AUDIO_EFFECT_CONTROL_PANEL";
1062d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent
1063d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent    /**
106492cf2d60851462d91a1eb4b9615ea93579dd4330Eric Laurent     *  Intent to signal to the effect control application or service that a new audio session
106592cf2d60851462d91a1eb4b9615ea93579dd4330Eric Laurent     *  is opened and requires audio effects to be applied.
106692cf2d60851462d91a1eb4b9615ea93579dd4330Eric Laurent     *  <p>This is different from {@link #ACTION_DISPLAY_AUDIO_EFFECT_CONTROL_PANEL} in that no
106792cf2d60851462d91a1eb4b9615ea93579dd4330Eric Laurent     *  UI should be displayed in this case. Music player applications can broadcast this intent
106892cf2d60851462d91a1eb4b9615ea93579dd4330Eric Laurent     *  before starting playback to make sure that any audio effect settings previously selected
106992cf2d60851462d91a1eb4b9615ea93579dd4330Eric Laurent     *  by the user are applied.
1070d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent     *  <p>The effect control application receiving this intent will look for previously stored
1071d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent     *  settings for the calling application, create all required audio effects and apply the
1072d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent     *  effect settings to the specified audio session.
1073d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent     *  <p>The calling package name is indicated by the {@link #EXTRA_PACKAGE_NAME} extra and the
1074d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent     *  audio session ID by the {@link #EXTRA_AUDIO_SESSION} extra. Both extras are mandatory.
1075d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent     *  <p>If no stored settings are found for the calling application, default settings for the
1076d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent     *  content type indicated by {@link #EXTRA_CONTENT_TYPE} will be applied. The default settings
1077d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent     *  for a given content type are platform specific.
1078d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent     */
1079d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
1080d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent    public static final String ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION =
1081d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent        "android.media.action.OPEN_AUDIO_EFFECT_CONTROL_SESSION";
1082d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent
1083d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent    /**
108492cf2d60851462d91a1eb4b9615ea93579dd4330Eric Laurent     *  Intent to signal to the effect control application or service that an audio session
1085d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent     *  is closed and that effects should not be applied anymore.
108692cf2d60851462d91a1eb4b9615ea93579dd4330Eric Laurent     *  <p>The effect control application receiving this intent will delete all effects on
108792cf2d60851462d91a1eb4b9615ea93579dd4330Eric Laurent     *  this session and store current settings in package specific storage.
1088d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent     *  <p>The calling package name is indicated by the {@link #EXTRA_PACKAGE_NAME} extra and the
1089d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent     *  audio session ID by the {@link #EXTRA_AUDIO_SESSION} extra. Both extras are mandatory.
1090d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent     *  <p>It is good practice for applications to broadcast this intent when music playback stops
1091d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent     *  and/or when exiting to free system resources consumed by audio effect engines.
1092d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent     */
1093d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
1094d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent    public static final String ACTION_CLOSE_AUDIO_EFFECT_CONTROL_SESSION =
1095d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent        "android.media.action.CLOSE_AUDIO_EFFECT_CONTROL_SESSION";
1096d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent
1097d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent    /**
109892cf2d60851462d91a1eb4b9615ea93579dd4330Eric Laurent     * Contains the ID of the audio session the effects should be applied to.
109992cf2d60851462d91a1eb4b9615ea93579dd4330Eric Laurent     * <p>This extra is for use with {@link #ACTION_DISPLAY_AUDIO_EFFECT_CONTROL_PANEL},
110092cf2d60851462d91a1eb4b9615ea93579dd4330Eric Laurent     * {@link #ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION} and
110192cf2d60851462d91a1eb4b9615ea93579dd4330Eric Laurent     * {@link #ACTION_CLOSE_AUDIO_EFFECT_CONTROL_SESSION} intents.
1102d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent     * <p>The extra value is of type int and is the audio session ID.
11031a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent     *  @see android.media.MediaPlayer#getAudioSessionId() for details on audio sessions.
1104d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent     */
1105d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent     public static final String EXTRA_AUDIO_SESSION = "android.media.extra.AUDIO_SESSION";
1106d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent
1107d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent    /**
110892cf2d60851462d91a1eb4b9615ea93579dd4330Eric Laurent     * Contains the package name of the calling application.
110992cf2d60851462d91a1eb4b9615ea93579dd4330Eric Laurent     * <p>This extra is for use with {@link #ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION} and
1110d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent     * {@link #ACTION_CLOSE_AUDIO_EFFECT_CONTROL_SESSION} intents.
1111d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent     * <p>The extra value is a string containing the full package name.
1112d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent     */
1113d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent    public static final String EXTRA_PACKAGE_NAME = "android.media.extra.PACKAGE_NAME";
1114d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent
1115d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent    /**
111692cf2d60851462d91a1eb4b9615ea93579dd4330Eric Laurent     * Indicates which type of content is played by the application.
111792cf2d60851462d91a1eb4b9615ea93579dd4330Eric Laurent     * <p>This extra is for use with {@link #ACTION_DISPLAY_AUDIO_EFFECT_CONTROL_PANEL} and
111892cf2d60851462d91a1eb4b9615ea93579dd4330Eric Laurent     * {@link #ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION} intents.
111992cf2d60851462d91a1eb4b9615ea93579dd4330Eric Laurent     * <p>This information is used by the effect control application to customize UI and select
112092cf2d60851462d91a1eb4b9615ea93579dd4330Eric Laurent     * appropriate default effect settings. The content type is one of the following:
1121d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent     * <ul>
1122d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent     *   <li>{@link #CONTENT_TYPE_MUSIC}</li>
1123d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent     *   <li>{@link #CONTENT_TYPE_MOVIE}</li>
1124d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent     *   <li>{@link #CONTENT_TYPE_GAME}</li>
1125d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent     *   <li>{@link #CONTENT_TYPE_VOICE}</li>
1126d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent     * </ul>
1127d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent     * If omitted, the content type defaults to {@link #CONTENT_TYPE_MUSIC}.
1128d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent     */
1129d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent    public static final String EXTRA_CONTENT_TYPE = "android.media.extra.CONTENT_TYPE";
1130d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent
1131d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent    /**
1132d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent     * Value for {@link #EXTRA_CONTENT_TYPE} when the type of content played is music
1133d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent     */
1134d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent    public static final int  CONTENT_TYPE_MUSIC = 0;
1135d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent    /**
113692cf2d60851462d91a1eb4b9615ea93579dd4330Eric Laurent     * Value for {@link #EXTRA_CONTENT_TYPE} when the type of content played is video or movie
1137d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent     */
1138d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent    public static final int  CONTENT_TYPE_MOVIE = 1;
1139d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent    /**
1140d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent     * Value for {@link #EXTRA_CONTENT_TYPE} when the type of content played is game audio
1141d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent     */
1142d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent    public static final int  CONTENT_TYPE_GAME = 2;
1143d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent    /**
1144d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent     * Value for {@link #EXTRA_CONTENT_TYPE} when the type of content played is voice audio
1145d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent     */
1146d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent    public static final int  CONTENT_TYPE_VOICE = 3;
1147d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent
1148d09af7d5518d0a5b3c8070784c13a1070f46f460Eric Laurent
1149df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    // ---------------------------------------------------------
1150948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    // Inner classes
1151df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    // --------------------
1152948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    /**
1153df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * Helper class to handle the forwarding of native events to the appropriate
1154df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent     * listeners
1155948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent     */
1156df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    private class NativeEventHandler extends Handler {
1157948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        private AudioEffect mAudioEffect;
1158948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
1159948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        public NativeEventHandler(AudioEffect ae, Looper looper) {
1160948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent            super(looper);
1161948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent            mAudioEffect = ae;
1162948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        }
1163948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
1164948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        @Override
1165948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        public void handleMessage(Message msg) {
1166948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent            if (mAudioEffect == null) {
1167948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent                return;
1168948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent            }
1169df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            switch (msg.what) {
1170948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent            case NATIVE_EVENT_ENABLED_STATUS:
1171948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent                OnEnableStatusChangeListener enableStatusChangeListener = null;
1172948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent                synchronized (mListenerLock) {
1173948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent                    enableStatusChangeListener = mAudioEffect.mEnableStatusChangeListener;
1174948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent                }
1175948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent                if (enableStatusChangeListener != null) {
1176df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent                    enableStatusChangeListener.onEnableStatusChange(
1177df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent                            mAudioEffect, (boolean) (msg.arg1 != 0));
1178948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent                }
1179948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent                break;
1180948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent            case NATIVE_EVENT_CONTROL_STATUS:
1181948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent                OnControlStatusChangeListener controlStatusChangeListener = null;
1182948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent                synchronized (mListenerLock) {
1183948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent                    controlStatusChangeListener = mAudioEffect.mControlChangeStatusListener;
1184948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent                }
1185948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent                if (controlStatusChangeListener != null) {
1186df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent                    controlStatusChangeListener.onControlStatusChange(
1187df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent                            mAudioEffect, (boolean) (msg.arg1 != 0));
1188948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent                }
1189948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent                break;
1190948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent            case NATIVE_EVENT_PARAMETER_CHANGED:
1191948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent                OnParameterChangeListener parameterChangeListener = null;
1192948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent                synchronized (mListenerLock) {
1193948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent                    parameterChangeListener = mAudioEffect.mParameterChangeListener;
1194948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent                }
1195948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent                if (parameterChangeListener != null) {
1196df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent                    // arg1 contains offset of parameter value from start of
1197df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent                    // byte array
1198948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent                    int vOffset = msg.arg1;
1199df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent                    byte[] p = (byte[]) msg.obj;
1200df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent                    // See effect_param_t in EffectApi.h for psize and vsize
1201df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent                    // fields offsets
1202948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent                    int status = byteArrayToInt(p, 0);
1203948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent                    int psize = byteArrayToInt(p, 4);
1204948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent                    int vsize = byteArrayToInt(p, 8);
1205948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent                    byte[] param = new byte[psize];
1206948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent                    byte[] value = new byte[vsize];
1207948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent                    System.arraycopy(p, 12, param, 0, psize);
1208948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent                    System.arraycopy(p, vOffset, value, 0, vsize);
1209948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
1210df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent                    parameterChangeListener.onParameterChange(mAudioEffect,
1211df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent                            status, param, value);
1212948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent                }
1213948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent                break;
1214948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
1215df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            default:
1216948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent                Log.e(TAG, "handleMessage() Unknown event type: " + msg.what);
1217948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent                break;
1218948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent            }
1219948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        }
1220948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    }
1221948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
1222df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    // ---------------------------------------------------------
1223948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    // Java methods called from the native side
1224df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    // --------------------
1225948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    @SuppressWarnings("unused")
1226df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    private static void postEventFromNative(Object effect_ref, int what,
1227df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            int arg1, int arg2, Object obj) {
1228df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        AudioEffect effect = (AudioEffect) ((WeakReference) effect_ref).get();
1229948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        if (effect == null) {
1230948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent            return;
1231948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        }
1232948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        if (effect.mNativeEventHandler != null) {
1233df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            Message m = effect.mNativeEventHandler.obtainMessage(what, arg1,
1234df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent                    arg2, obj);
1235948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent            effect.mNativeEventHandler.sendMessage(m);
1236948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        }
1237948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
1238948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    }
1239948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
1240df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    // ---------------------------------------------------------
1241948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    // Native methods called from the Java side
1242df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    // --------------------
1243948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
1244948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    private static native final void native_init();
1245948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
1246df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    private native final int native_setup(Object audioeffect_this, String type,
1247fa5ecdc4ac6d7a8db2bb9e4a6a60a3189025df30Svet Ganov            String uuid, int priority, int audioSession, int[] id, Object[] desc,
1248fa5ecdc4ac6d7a8db2bb9e4a6a60a3189025df30Svet Ganov            String opPackageName);
1249948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
1250948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    private native final void native_finalize();
1251948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
1252948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    private native final void native_release();
1253948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
1254df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    private native final int native_setEnabled(boolean enabled);
1255948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
1256df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    private native final boolean native_getEnabled();
1257948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
1258948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    private native final boolean native_hasControl();
1259948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
1260df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    private native final int native_setParameter(int psize, byte[] param,
1261df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent            int vsize, byte[] value);
1262948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
1263df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    private native final int native_getParameter(int psize, byte[] param,
1264602b3286ffe7da6e70bf2d9e4861a5d74ff7c473Eric Laurent            int vsize, byte[] value);
1265948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
1266df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    private native final int native_command(int cmdCode, int cmdSize,
1267602b3286ffe7da6e70bf2d9e4861a5d74ff7c473Eric Laurent            byte[] cmdData, int repSize, byte[] repData);
1268948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
1269948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    private static native Object[] native_query_effects();
1270948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
12710f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent    private static native Object[] native_query_pre_processing(int audioSession);
12720f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent
1273df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    // ---------------------------------------------------------
1274948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    // Utility methods
1275df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent    // ------------------
1276948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
12771a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent    /**
12781a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent    * @hide
12791a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent    */
128017cb280e7f1ac3556eac90ab08263712e0348cb9Eric Laurent    public void checkState(String methodName) throws IllegalStateException {
1281948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        synchronized (mStateLock) {
1282948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent            if (mState != STATE_INITIALIZED) {
1283df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent                throw (new IllegalStateException(methodName
1284df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent                        + " called on uninitialized AudioEffect."));
1285948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent            }
1286948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        }
1287948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    }
1288948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
12891a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent    /**
12901a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent     * @hide
12911a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent     */
129217cb280e7f1ac3556eac90ab08263712e0348cb9Eric Laurent    public void checkStatus(int status) {
1293602b3286ffe7da6e70bf2d9e4861a5d74ff7c473Eric Laurent        if (isError(status)) {
1294602b3286ffe7da6e70bf2d9e4861a5d74ff7c473Eric Laurent            switch (status) {
1295602b3286ffe7da6e70bf2d9e4861a5d74ff7c473Eric Laurent            case AudioEffect.ERROR_BAD_VALUE:
1296602b3286ffe7da6e70bf2d9e4861a5d74ff7c473Eric Laurent                throw (new IllegalArgumentException(
1297602b3286ffe7da6e70bf2d9e4861a5d74ff7c473Eric Laurent                        "AudioEffect: bad parameter value"));
1298602b3286ffe7da6e70bf2d9e4861a5d74ff7c473Eric Laurent            case AudioEffect.ERROR_INVALID_OPERATION:
1299602b3286ffe7da6e70bf2d9e4861a5d74ff7c473Eric Laurent                throw (new UnsupportedOperationException(
1300602b3286ffe7da6e70bf2d9e4861a5d74ff7c473Eric Laurent                        "AudioEffect: invalid parameter operation"));
1301602b3286ffe7da6e70bf2d9e4861a5d74ff7c473Eric Laurent            default:
1302602b3286ffe7da6e70bf2d9e4861a5d74ff7c473Eric Laurent                throw (new RuntimeException("AudioEffect: set/get parameter error"));
1303602b3286ffe7da6e70bf2d9e4861a5d74ff7c473Eric Laurent            }
1304948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        }
1305948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    }
1306948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
13071a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent    /**
13081a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent     * @hide
13091a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent     */
13103ce023b02eec04874b4c659f0973b6a05182970bAndy Hung    @TestApi
1311602b3286ffe7da6e70bf2d9e4861a5d74ff7c473Eric Laurent    public static boolean isError(int status) {
1312602b3286ffe7da6e70bf2d9e4861a5d74ff7c473Eric Laurent        return (status < 0);
1313602b3286ffe7da6e70bf2d9e4861a5d74ff7c473Eric Laurent    }
1314602b3286ffe7da6e70bf2d9e4861a5d74ff7c473Eric Laurent
1315602b3286ffe7da6e70bf2d9e4861a5d74ff7c473Eric Laurent    /**
1316602b3286ffe7da6e70bf2d9e4861a5d74ff7c473Eric Laurent     * @hide
1317602b3286ffe7da6e70bf2d9e4861a5d74ff7c473Eric Laurent     */
13183ce023b02eec04874b4c659f0973b6a05182970bAndy Hung    @TestApi
1319d2bebb3ab86177c0d27664af86b30b7dce2c9bcbJean-Michel Trivi    public static int byteArrayToInt(byte[] valueBuf) {
1320948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        return byteArrayToInt(valueBuf, 0);
1321948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
1322948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    }
1323df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent
13241a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent    /**
13251a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent     * @hide
13261a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent     */
1327d2bebb3ab86177c0d27664af86b30b7dce2c9bcbJean-Michel Trivi    public static int byteArrayToInt(byte[] valueBuf, int offset) {
1328948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        ByteBuffer converter = ByteBuffer.wrap(valueBuf);
1329948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        converter.order(ByteOrder.nativeOrder());
1330948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        return converter.getInt(offset);
1331948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
1332948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    }
1333948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
13341a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent    /**
13351a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent     * @hide
13361a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent     */
13373ce023b02eec04874b4c659f0973b6a05182970bAndy Hung    @TestApi
1338d2bebb3ab86177c0d27664af86b30b7dce2c9bcbJean-Michel Trivi    public static byte[] intToByteArray(int value) {
1339948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        ByteBuffer converter = ByteBuffer.allocate(4);
1340948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        converter.order(ByteOrder.nativeOrder());
1341948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        converter.putInt(value);
1342948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        return converter.array();
1343948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    }
1344948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
13451a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent    /**
13461a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent     * @hide
13471a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent     */
13483ce023b02eec04874b4c659f0973b6a05182970bAndy Hung    @TestApi
1349d2bebb3ab86177c0d27664af86b30b7dce2c9bcbJean-Michel Trivi    public static short byteArrayToShort(byte[] valueBuf) {
1350948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        return byteArrayToShort(valueBuf, 0);
1351948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    }
1352948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
13531a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent    /**
13541a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent     * @hide
13551a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent     */
1356d2bebb3ab86177c0d27664af86b30b7dce2c9bcbJean-Michel Trivi    public static short byteArrayToShort(byte[] valueBuf, int offset) {
1357948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        ByteBuffer converter = ByteBuffer.wrap(valueBuf);
1358948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        converter.order(ByteOrder.nativeOrder());
1359948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        return converter.getShort(offset);
1360948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
1361948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    }
1362948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
13631a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent    /**
13641a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent     * @hide
13651a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent     */
13663ce023b02eec04874b4c659f0973b6a05182970bAndy Hung    @TestApi
1367d2bebb3ab86177c0d27664af86b30b7dce2c9bcbJean-Michel Trivi    public static byte[] shortToByteArray(short value) {
1368948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        ByteBuffer converter = ByteBuffer.allocate(2);
1369948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        converter.order(ByteOrder.nativeOrder());
1370df9b81ced437b11f8a3fcf4ba3ea6af703d121e2Eric Laurent        short sValue = (short) value;
1371948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        converter.putShort(sValue);
1372948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        return converter.array();
1373948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    }
1374948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
13751a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent    /**
13761a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent     * @hide
13771a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent     */
137846a92d90df125cdc5ab131cf4fe795c9c276be90rago    public static float byteArrayToFloat(byte[] valueBuf) {
137946a92d90df125cdc5ab131cf4fe795c9c276be90rago        return byteArrayToFloat(valueBuf, 0);
138046a92d90df125cdc5ab131cf4fe795c9c276be90rago
138146a92d90df125cdc5ab131cf4fe795c9c276be90rago    }
138246a92d90df125cdc5ab131cf4fe795c9c276be90rago
138346a92d90df125cdc5ab131cf4fe795c9c276be90rago    /**
138446a92d90df125cdc5ab131cf4fe795c9c276be90rago     * @hide
138546a92d90df125cdc5ab131cf4fe795c9c276be90rago     */
138646a92d90df125cdc5ab131cf4fe795c9c276be90rago    public static float byteArrayToFloat(byte[] valueBuf, int offset) {
138746a92d90df125cdc5ab131cf4fe795c9c276be90rago        ByteBuffer converter = ByteBuffer.wrap(valueBuf);
138846a92d90df125cdc5ab131cf4fe795c9c276be90rago        converter.order(ByteOrder.nativeOrder());
138946a92d90df125cdc5ab131cf4fe795c9c276be90rago        return converter.getFloat(offset);
139046a92d90df125cdc5ab131cf4fe795c9c276be90rago
139146a92d90df125cdc5ab131cf4fe795c9c276be90rago    }
139246a92d90df125cdc5ab131cf4fe795c9c276be90rago
139346a92d90df125cdc5ab131cf4fe795c9c276be90rago    /**
139446a92d90df125cdc5ab131cf4fe795c9c276be90rago     * @hide
139546a92d90df125cdc5ab131cf4fe795c9c276be90rago     */
139646a92d90df125cdc5ab131cf4fe795c9c276be90rago    public static byte[] floatToByteArray(float value) {
139746a92d90df125cdc5ab131cf4fe795c9c276be90rago        ByteBuffer converter = ByteBuffer.allocate(4);
139846a92d90df125cdc5ab131cf4fe795c9c276be90rago        converter.order(ByteOrder.nativeOrder());
139946a92d90df125cdc5ab131cf4fe795c9c276be90rago        converter.putFloat(value);
140046a92d90df125cdc5ab131cf4fe795c9c276be90rago        return converter.array();
140146a92d90df125cdc5ab131cf4fe795c9c276be90rago    }
140246a92d90df125cdc5ab131cf4fe795c9c276be90rago
140346a92d90df125cdc5ab131cf4fe795c9c276be90rago    /**
140446a92d90df125cdc5ab131cf4fe795c9c276be90rago     * @hide
140546a92d90df125cdc5ab131cf4fe795c9c276be90rago     */
1406d2bebb3ab86177c0d27664af86b30b7dce2c9bcbJean-Michel Trivi    public static byte[] concatArrays(byte[]... arrays) {
1407948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        int len = 0;
1408948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        for (byte[] a : arrays) {
1409948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent            len += a.length;
1410948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        }
1411948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        byte[] b = new byte[len];
1412948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent
1413948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        int offs = 0;
1414948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        for (byte[] a : arrays) {
1415948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent            System.arraycopy(a, 0, b, offs, a.length);
1416948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent            offs += a.length;
1417948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        }
1418948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent        return b;
1419948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent    }
1420948235c06ed0d49190b2f49d9299b473c4dd61a9Eric Laurent}
1421