1fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent/*
217cb280e7f1ac3556eac90ab08263712e0348cb9Eric Laurent * Copyright (C) 2010 The Android Open Source Project
3fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent *
4fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent * Licensed under the Apache License, Version 2.0 (the "License");
5fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent * you may not use this file except in compliance with the License.
6fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent * You may obtain a copy of the License at
7fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent *
8fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent *      http://www.apache.org/licenses/LICENSE-2.0
9fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent *
10fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent * Unless required by applicable law or agreed to in writing, software
11fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent * distributed under the License is distributed on an "AS IS" BASIS,
12fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent * See the License for the specific language governing permissions and
14fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent * limitations under the License.
15fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent */
16fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent
171a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurentpackage android.media.audiofx;
18fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent
19fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurentimport android.app.Activity;
20fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurentimport android.content.Context;
21fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurentimport android.content.Intent;
221a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurentimport android.media.audiofx.AudioEffect;
23fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurentimport android.os.Bundle;
24fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurentimport android.util.Log;
25ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent
26fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurentimport java.nio.ByteOrder;
27fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurentimport java.nio.ByteBuffer;
28ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurentimport java.util.StringTokenizer;
29fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent
30fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent
31fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent/**
32fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent * A sound generated within a room travels in many directions. The listener first hears the
33fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent * direct sound from the source itself. Later, he or she hears discrete echoes caused by sound
34fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent * bouncing off nearby walls, the ceiling and the floor. As sound waves arrive after
35fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent * undergoing more and more reflections, individual reflections become indistinguishable and
36fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent * the listener hears continuous reverberation that decays over time.
37fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent * Reverb is vital for modeling a listener's environment. It can be used in music applications
38fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent * to simulate music being played back in various environments, or in games to immerse the
39fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent * listener within the game's environment.
40fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent * The PresetReverb class allows an application to configure the global reverb using a reverb preset.
41fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent * This is primarily used for adding some reverb in a music playback context. Applications
42fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent * requiring control over a more advanced environmental reverb are advised to use the
431a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent * {@link android.media.audiofx.EnvironmentalReverb} class.
44fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent * <p>An application creates a PresetReverb object to instantiate and control a reverb engine in the
45fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent * audio framework.
46fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent * <p>The methods, parameter types and units exposed by the PresetReverb implementation are
47fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent * directly mapping those defined by the OpenSL ES 1.0.1 Specification
48fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent * (http://www.khronos.org/opensles/) for the SLPresetReverbItf interface.
49fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent * Please refer to this specification for more details.
50fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent * <p>The PresetReverb is an output mix auxiliary effect and should be created on
51fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent * Audio session 0. In order for a MediaPlayer or AudioTrack to be fed into this effect,
52fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent * they must be explicitely attached to it and a send level must be specified. Use the effect ID
53fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent * returned by getId() method to designate this particular effect when attaching it to the
54fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent * MediaPlayer or AudioTrack.
551a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent * <p>Creating a reverb on the output mix (audio session 0) requires permission
561a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent * {@link android.Manifest.permission#MODIFY_AUDIO_SETTINGS}
571a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent * <p>See {@link android.media.audiofx.AudioEffect} class for more details on controlling
581a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent * audio effects.
59fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent */
60fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent
61fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurentpublic class PresetReverb extends AudioEffect {
62fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent
63fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent    private final static String TAG = "PresetReverb";
64fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent
65fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent    // These constants must be synchronized with those in
66fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent    // frameworks/base/include/media/EffectPresetReverbApi.h
67fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent
68fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent    /**
69fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent     * Preset. Parameter ID for
701a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent     * {@link android.media.audiofx.PresetReverb.OnParameterChangeListener}
71fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent     */
72fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent    public static final int PARAM_PRESET = 0;
73fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent
74fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent    /**
7517cb280e7f1ac3556eac90ab08263712e0348cb9Eric Laurent     * No reverb or reflections
76fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent     */
7771450f813991bb76b477aaffd7cad28e8ae8af7cEric Laurent    public static final short PRESET_NONE        = 0;
7817cb280e7f1ac3556eac90ab08263712e0348cb9Eric Laurent    /**
7917cb280e7f1ac3556eac90ab08263712e0348cb9Eric Laurent     * Reverb preset representing a small room less than five meters in length
8017cb280e7f1ac3556eac90ab08263712e0348cb9Eric Laurent     */
8171450f813991bb76b477aaffd7cad28e8ae8af7cEric Laurent    public static final short PRESET_SMALLROOM   = 1;
8217cb280e7f1ac3556eac90ab08263712e0348cb9Eric Laurent    /**
8317cb280e7f1ac3556eac90ab08263712e0348cb9Eric Laurent     * Reverb preset representing a medium room with a length of ten meters or less
8417cb280e7f1ac3556eac90ab08263712e0348cb9Eric Laurent     */
8571450f813991bb76b477aaffd7cad28e8ae8af7cEric Laurent    public static final short PRESET_MEDIUMROOM  = 2;
8617cb280e7f1ac3556eac90ab08263712e0348cb9Eric Laurent    /**
8717cb280e7f1ac3556eac90ab08263712e0348cb9Eric Laurent     * Reverb preset representing a large-sized room suitable for live performances
8817cb280e7f1ac3556eac90ab08263712e0348cb9Eric Laurent     */
8971450f813991bb76b477aaffd7cad28e8ae8af7cEric Laurent    public static final short PRESET_LARGEROOM   = 3;
9017cb280e7f1ac3556eac90ab08263712e0348cb9Eric Laurent    /**
9117cb280e7f1ac3556eac90ab08263712e0348cb9Eric Laurent     * Reverb preset representing a medium-sized hall
9217cb280e7f1ac3556eac90ab08263712e0348cb9Eric Laurent     */
9371450f813991bb76b477aaffd7cad28e8ae8af7cEric Laurent    public static final short PRESET_MEDIUMHALL  = 4;
9417cb280e7f1ac3556eac90ab08263712e0348cb9Eric Laurent    /**
9517cb280e7f1ac3556eac90ab08263712e0348cb9Eric Laurent     * Reverb preset representing a large-sized hall suitable for a full orchestra
9617cb280e7f1ac3556eac90ab08263712e0348cb9Eric Laurent     */
9771450f813991bb76b477aaffd7cad28e8ae8af7cEric Laurent    public static final short PRESET_LARGEHALL   = 5;
9817cb280e7f1ac3556eac90ab08263712e0348cb9Eric Laurent    /**
9917cb280e7f1ac3556eac90ab08263712e0348cb9Eric Laurent     * Reverb preset representing a synthesis of the traditional plate reverb
10017cb280e7f1ac3556eac90ab08263712e0348cb9Eric Laurent     */
10171450f813991bb76b477aaffd7cad28e8ae8af7cEric Laurent    public static final short PRESET_PLATE       = 6;
102fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent
103fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent    /**
104fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent     * Registered listener for parameter changes.
105fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent     */
106fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent    private OnParameterChangeListener mParamListener = null;
107fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent
108fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent    /**
109fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent     * Listener used internally to to receive raw parameter change event from AudioEffect super class
110fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent     */
111fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent    private BaseParameterListener mBaseParamListener = null;
112fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent
113fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent    /**
114fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent     * Lock for access to mParamListener
115fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent     */
116fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent    private final Object mParamListenerLock = new Object();
117fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent
118fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent    /**
119fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent     * Class constructor.
120fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent     * @param priority the priority level requested by the application for controlling the
121fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent     * PresetReverb engine. As the same engine can be shared by several applications, this
122fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent     * parameter indicates how much the requesting application needs control of effect parameters.
123fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent     * The normal priority is 0, above normal is a positive number, below normal a negative number.
12417cb280e7f1ac3556eac90ab08263712e0348cb9Eric Laurent     * @param audioSession  system wide unique audio session identifier. If audioSession
125fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent     *  is not 0, the PresetReverb will be attached to the MediaPlayer or AudioTrack in the
126fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent     *  same audio session. Otherwise, the PresetReverb will apply to the output mix.
127fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent     *  As the PresetReverb is an auxiliary effect it is recommended to instantiate it on
128fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent     *  audio session 0 and to attach it to the MediaPLayer auxiliary output.
129fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent     *
130fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent     * @throws java.lang.IllegalArgumentException
131fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent     * @throws java.lang.UnsupportedOperationException
132fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent     * @throws java.lang.RuntimeException
133fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent     */
134fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent    public PresetReverb(int priority, int audioSession)
135fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent    throws IllegalArgumentException, UnsupportedOperationException, RuntimeException {
136fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent        super(EFFECT_TYPE_PRESET_REVERB, EFFECT_TYPE_NULL, priority, audioSession);
137fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent    }
138fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent
139fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent    /**
140fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent     *  Enables a preset on the reverb.
141fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent     *  <p>The reverb PRESET_NONE disables any reverb from the current output but does not free the
142fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent     *  resources associated with the reverb. For an application to signal to the implementation
143fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent     *  to free the resources, it must call the release() method.
14417cb280e7f1ac3556eac90ab08263712e0348cb9Eric Laurent     * @param preset this must be one of the the preset constants defined in this class.
145fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent     * e.g. {@link #PRESET_SMALLROOM}
146fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent     * @throws IllegalStateException
147fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent     * @throws IllegalArgumentException
148fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent     * @throws UnsupportedOperationException
149fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent     */
150fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent    public void setPreset(short preset)
151fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent    throws IllegalStateException, IllegalArgumentException, UnsupportedOperationException {
152fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent        checkStatus(setParameter(PARAM_PRESET, preset));
153fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent    }
154fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent
155fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent    /**
156fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent     * Gets current reverb preset.
15717cb280e7f1ac3556eac90ab08263712e0348cb9Eric Laurent     * @return the preset that is set at the moment.
158fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent     * @throws IllegalStateException
159fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent     * @throws IllegalArgumentException
160fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent     * @throws UnsupportedOperationException
161fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent     */
162fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent    public short getPreset()
163fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent    throws IllegalStateException, IllegalArgumentException, UnsupportedOperationException {
164fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent        short[] value = new short[1];
165ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent        checkStatus(getParameter(PARAM_PRESET, value));
166fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent        return value[0];
167fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent    }
168fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent
169fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent    /**
170fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent     * The OnParameterChangeListener interface defines a method called by the PresetReverb
171fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent     * when a parameter value has changed.
172fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent     */
173fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent    public interface OnParameterChangeListener  {
174fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent        /**
175fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent         * Method called when a parameter value has changed. The method is called only if the
176fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent         * parameter was changed by another application having the control of the same
177fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent         * PresetReverb engine.
178fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent         * @param effect the PresetReverb on which the interface is registered.
179fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent         * @param status status of the set parameter operation.
180fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent         * @param param ID of the modified parameter. See {@link #PARAM_PRESET} ...
181fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent         * @param value the new parameter value.
182fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent         */
183fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent        void onParameterChange(PresetReverb effect, int status, int param, short value);
184fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent    }
185fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent
186fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent    /**
187fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent     * Listener used internally to receive unformatted parameter change events from AudioEffect
188fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent     * super class.
189fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent     */
190fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent    private class BaseParameterListener implements AudioEffect.OnParameterChangeListener {
191fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent        private BaseParameterListener() {
192fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent
193fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent        }
194fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent        public void onParameterChange(AudioEffect effect, int status, byte[] param, byte[] value) {
195fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent            OnParameterChangeListener l = null;
196fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent
197fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent            synchronized (mParamListenerLock) {
198fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent                if (mParamListener != null) {
199fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent                    l = mParamListener;
200fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent                }
201fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent            }
202fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent            if (l != null) {
203fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent                int p = -1;
204fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent                short v = -1;
205fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent
206fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent                if (param.length == 4) {
207fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent                    p = byteArrayToInt(param, 0);
208fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent                }
209fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent                if (value.length == 2) {
210fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent                    v = byteArrayToShort(value, 0);
211fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent                }
212fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent                if (p != -1 && v != -1) {
213fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent                    l.onParameterChange(PresetReverb.this, status, p, v);
214fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent                }
215fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent            }
216fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent        }
217fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent    }
218fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent
219fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent    /**
220fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent     * Registers an OnParameterChangeListener interface.
221fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent     * @param listener OnParameterChangeListener interface registered
222fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent     */
223fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent    public void setParameterListener(OnParameterChangeListener listener) {
224fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent        synchronized (mParamListenerLock) {
225fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent            if (mParamListener == null) {
226fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent                mParamListener = listener;
227fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent                mBaseParamListener = new BaseParameterListener();
228fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent                super.setParameterListener(mBaseParamListener);
229fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent            }
230fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent        }
231fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent    }
232ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent
233ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent    /**
234ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent     * The Settings class regroups all preset reverb parameters. It is used in
235ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent     * conjuntion with getProperties() and setProperties() methods to backup and restore
236ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent     * all parameters in a single call.
237ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent     */
238ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent    public static class Settings {
239ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent        public short preset;
240ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent
241ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent        public Settings() {
242ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent        }
243ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent
244ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent        /**
245ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent         * Settings class constructor from a key=value; pairs formatted string. The string is
246ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent         * typically returned by Settings.toString() method.
247ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent         * @throws IllegalArgumentException if the string is not correctly formatted.
248ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent         */
249ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent        public Settings(String settings) {
250ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent            StringTokenizer st = new StringTokenizer(settings, "=;");
251ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent            int tokens = st.countTokens();
252ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent            if (st.countTokens() != 3) {
253ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent                throw new IllegalArgumentException("settings: " + settings);
254ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent            }
255ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent            String key = st.nextToken();
256ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent            if (!key.equals("PresetReverb")) {
257ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent                throw new IllegalArgumentException(
258ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent                        "invalid settings for PresetReverb: " + key);
259ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent            }
260ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent            try {
261ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent                key = st.nextToken();
262ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent                if (!key.equals("preset")) {
263ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent                    throw new IllegalArgumentException("invalid key name: " + key);
264ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent                }
265ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent                preset = Short.parseShort(st.nextToken());
266ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent             } catch (NumberFormatException nfe) {
267ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent                throw new IllegalArgumentException("invalid value for key: " + key);
268ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent            }
269ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent        }
270ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent
271ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent        @Override
272ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent        public String toString() {
273ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent            String str = new String (
274ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent                    "PresetReverb"+
275ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent                    ";preset="+Short.toString(preset)
276ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent                    );
277ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent            return str;
278ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent        }
279ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent    };
280ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent
281ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent
282ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent    /**
283ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent     * Gets the preset reverb properties. This method is useful when a snapshot of current
284ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent     * preset reverb settings must be saved by the application.
285ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent     * @return a PresetReverb.Settings object containing all current parameters values
286ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent     * @throws IllegalStateException
287ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent     * @throws IllegalArgumentException
288ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent     * @throws UnsupportedOperationException
289ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent     */
290ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent    public PresetReverb.Settings getProperties()
291ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent    throws IllegalStateException, IllegalArgumentException, UnsupportedOperationException {
292ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent        Settings settings = new Settings();
293ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent        short[] value = new short[1];
294ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent        checkStatus(getParameter(PARAM_PRESET, value));
295ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent        settings.preset = value[0];
296ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent        return settings;
297ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent    }
298ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent
299ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent    /**
300ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent     * Sets the preset reverb properties. This method is useful when preset reverb settings have to
301ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent     * be applied from a previous backup.
30217cb280e7f1ac3556eac90ab08263712e0348cb9Eric Laurent     * @param settings a PresetReverb.Settings object containing the properties to apply
303ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent     * @throws IllegalStateException
304ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent     * @throws IllegalArgumentException
305ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent     * @throws UnsupportedOperationException
306ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent     */
307ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent    public void setProperties(PresetReverb.Settings settings)
308ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent    throws IllegalStateException, IllegalArgumentException, UnsupportedOperationException {
309ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent        checkStatus(setParameter(PARAM_PRESET, settings.preset));
310ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent    }
311fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent}
312