Virtualizer.java revision 62f3617f2f4016ad2f59635d5156d64872989880
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;
28fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurentimport java.nio.CharBuffer;
29ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurentimport java.util.StringTokenizer;
30fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent
31fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent
32fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent/**
33fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent * An audio virtualizer is a general name for an effect to spatialize audio channels. The exact
34fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent * behavior of this effect is dependent on the number of audio input channels and the types and
35fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent * number of audio output channels of the device. For example, in the case of a stereo input and
36fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent * stereo headphone output, a stereo widening effect is used when this effect is turned on.
37fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent * <p>An application creates a Virtualizer object to instantiate and control a virtualizer engine
38fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent * in the audio framework.
39fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent * <p>The methods, parameter types and units exposed by the Virtualizer implementation are directly
40fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent * mapping those defined by the OpenSL ES 1.0.1 Specification (http://www.khronos.org/opensles/)
41fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent * for the SLVirtualizerItf interface. Please refer to this specification for more details.
42fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent * <p>To attach the Virtualizer to a particular AudioTrack or MediaPlayer, specify the audio session
4362f3617f2f4016ad2f59635d5156d64872989880Eric Laurent * ID of this AudioTrack or MediaPlayer when constructing the Virtualizer.
4462f3617f2f4016ad2f59635d5156d64872989880Eric Laurent * <p>NOTE: attaching a Virtualizer to the global audio output mix by use of session 0 is
4562f3617f2f4016ad2f59635d5156d64872989880Eric Laurent * deprecated.
461a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent * <p>See {@link android.media.MediaPlayer#getAudioSessionId()} for details on audio sessions.
471a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent * <p>See {@link android.media.audiofx.AudioEffect} class for more details on controlling
481a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent * audio effects.
49fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent */
50fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent
51fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurentpublic class Virtualizer extends AudioEffect {
52fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent
53fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent    private final static String TAG = "Virtualizer";
54fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent
55fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent    // These constants must be synchronized with those in frameworks/base/include/media/EffectVirtualizerApi.h
56fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent    /**
57fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent     * Is strength parameter supported by virtualizer engine. Parameter ID for getParameter().
58fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent     */
59fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent    public static final int PARAM_STRENGTH_SUPPORTED = 0;
60fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent    /**
61fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent     * Virtualizer effect strength. Parameter ID for
621a5149e5d7f2dddc8b324f7695e69fd89af73c52Eric Laurent     * {@link android.media.audiofx.Virtualizer.OnParameterChangeListener}
63fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent     */
64fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent    public static final int PARAM_STRENGTH = 1;
65fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent
66fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent    /**
67fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent     * Indicates if strength parameter is supported by the virtualizer engine
68fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent     */
69fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent    private boolean mStrengthSupported = false;
70fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent
71fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent    /**
72fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent     * Registered listener for parameter changes.
73fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent     */
74fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent    private OnParameterChangeListener mParamListener = null;
75fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent
76fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent    /**
77fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent     * Listener used internally to to receive raw parameter change event from AudioEffect super class
78fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent     */
79fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent    private BaseParameterListener mBaseParamListener = null;
80fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent
81fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent    /**
82fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent     * Lock for access to mParamListener
83fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent     */
84fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent    private final Object mParamListenerLock = new Object();
85fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent
86fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent    /**
87fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent     * Class constructor.
88fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent     * @param priority the priority level requested by the application for controlling the Virtualizer
89fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent     * engine. As the same engine can be shared by several applications, this parameter indicates
90fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent     * how much the requesting application needs control of effect parameters. The normal priority
91fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent     * is 0, above normal is a positive number, below normal a negative number.
9262f3617f2f4016ad2f59635d5156d64872989880Eric Laurent     * @param audioSession  system wide unique audio session identifier. The Virtualizer will
9362f3617f2f4016ad2f59635d5156d64872989880Eric Laurent     * be attached to the MediaPlayer or AudioTrack in the same audio session.
94fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent     *
95fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent     * @throws java.lang.IllegalStateException
96fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent     * @throws java.lang.IllegalArgumentException
97fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent     * @throws java.lang.UnsupportedOperationException
98fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent     * @throws java.lang.RuntimeException
99fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent     */
100fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent    public Virtualizer(int priority, int audioSession)
101fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent    throws IllegalStateException, IllegalArgumentException,
102fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent           UnsupportedOperationException, RuntimeException {
103fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent        super(EFFECT_TYPE_VIRTUALIZER, EFFECT_TYPE_NULL, priority, audioSession);
104fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent
10562f3617f2f4016ad2f59635d5156d64872989880Eric Laurent        if (audioSession == 0) {
10662f3617f2f4016ad2f59635d5156d64872989880Eric Laurent            Log.w(TAG, "WARNING: attaching a Virtualizer to global output mix is deprecated!");
10762f3617f2f4016ad2f59635d5156d64872989880Eric Laurent        }
10862f3617f2f4016ad2f59635d5156d64872989880Eric Laurent
109ba8da2e61b1d9ebb7a4758f1f7849ff8440bd20cEric Laurent        int[] value = new int[1];
110fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent        checkStatus(getParameter(PARAM_STRENGTH_SUPPORTED, value));
111fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent        mStrengthSupported = (value[0] != 0);
112fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent    }
113fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent
114fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent    /**
115fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent     * Indicates whether setting strength is supported. If this method returns false, only one
116fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent     * strength is supported and the setStrength() method always rounds to that value.
117fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent     * @return true is strength parameter is supported, false otherwise
118fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent     */
119fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent    public boolean getStrengthSupported() {
120fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent       return mStrengthSupported;
121fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent    }
122fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent
123fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent    /**
124fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent     * Sets the strength of the virtualizer effect. If the implementation does not support per mille
125fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent     * accuracy for setting the strength, it is allowed to round the given strength to the nearest
126fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent     * supported value. You can use the {@link #getRoundedStrength()} method to query the
127fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent     * (possibly rounded) value that was actually set.
12817cb280e7f1ac3556eac90ab08263712e0348cb9Eric Laurent     * @param strength strength of the effect. The valid range for strength strength is [0, 1000],
129fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent     * where 0 per mille designates the mildest effect and 1000 per mille designates the strongest.
130fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent     * @throws IllegalStateException
131fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent     * @throws IllegalArgumentException
132fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent     * @throws UnsupportedOperationException
133fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent     */
134fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent    public void setStrength(short strength)
135fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent    throws IllegalStateException, IllegalArgumentException, UnsupportedOperationException {
136fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent        checkStatus(setParameter(PARAM_STRENGTH, strength));
137fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent    }
138fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent
139fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent    /**
140fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent     * Gets the current strength of the effect.
14117cb280e7f1ac3556eac90ab08263712e0348cb9Eric Laurent     * @return the strength of the effect. The valid range for strength is [0, 1000], where 0 per
142fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent     * mille designates the mildest effect and 1000 per mille the strongest
143fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent     * @throws IllegalStateException
144fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent     * @throws IllegalArgumentException
145fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent     * @throws UnsupportedOperationException
146fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent     */
147fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent    public short getRoundedStrength()
148fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent    throws IllegalStateException, IllegalArgumentException, UnsupportedOperationException {
149fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent        short[] value = new short[1];
150fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent        checkStatus(getParameter(PARAM_STRENGTH, value));
151fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent        return value[0];
152fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent    }
153fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent
154fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent    /**
155fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent     * The OnParameterChangeListener interface defines a method called by the Virtualizer when a
156fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent     * parameter value has changed.
157fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent     */
158fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent    public interface OnParameterChangeListener  {
159fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent        /**
160fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent         * Method called when a parameter value has changed. The method is called only if the
161fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent         * parameter was changed by another application having the control of the same
162fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent         * Virtualizer engine.
163fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent         * @param effect the Virtualizer on which the interface is registered.
164fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent         * @param status status of the set parameter operation.
165fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent         * @param param ID of the modified parameter. See {@link #PARAM_STRENGTH} ...
166fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent         * @param value the new parameter value.
167fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent         */
168fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent        void onParameterChange(Virtualizer effect, int status, int param, short value);
169fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent    }
170fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent
171fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent    /**
172fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent     * Listener used internally to receive unformatted parameter change events from AudioEffect
173fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent     * super class.
174fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent     */
175fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent    private class BaseParameterListener implements AudioEffect.OnParameterChangeListener {
176fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent        private BaseParameterListener() {
177fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent
178fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent        }
179fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent        public void onParameterChange(AudioEffect effect, int status, byte[] param, byte[] value) {
180fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent            OnParameterChangeListener l = null;
181fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent
182fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent            synchronized (mParamListenerLock) {
183fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent                if (mParamListener != null) {
184fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent                    l = mParamListener;
185fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent                }
186fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent            }
187fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent            if (l != null) {
188fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent                int p = -1;
189fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent                short v = -1;
190fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent
191fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent                if (param.length == 4) {
192fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent                    p = byteArrayToInt(param, 0);
193fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent                }
194fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent                if (value.length == 2) {
195fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent                    v = byteArrayToShort(value, 0);
196fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent                }
197fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent                if (p != -1 && v != -1) {
198fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent                    l.onParameterChange(Virtualizer.this, status, p, v);
199fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent                }
200fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent            }
201fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent        }
202fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent    }
203fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent
204fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent    /**
205fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent     * Registers an OnParameterChangeListener interface.
206fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent     * @param listener OnParameterChangeListener interface registered
207fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent     */
208fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent    public void setParameterListener(OnParameterChangeListener listener) {
209fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent        synchronized (mParamListenerLock) {
210fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent            if (mParamListener == null) {
211fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent                mParamListener = listener;
212fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent                mBaseParamListener = new BaseParameterListener();
213fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent                super.setParameterListener(mBaseParamListener);
214fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent            }
215fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent        }
216fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent    }
217ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent
218ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent    /**
219ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent     * The Settings class regroups all virtualizer parameters. It is used in
220ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent     * conjuntion with getProperties() and setProperties() methods to backup and restore
221ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent     * all parameters in a single call.
222ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent     */
223ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent    public static class Settings {
224ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent        public short strength;
225ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent
226ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent        public Settings() {
227ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent        }
228ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent
229ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent        /**
230ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent         * Settings class constructor from a key=value; pairs formatted string. The string is
231ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent         * typically returned by Settings.toString() method.
232ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent         * @throws IllegalArgumentException if the string is not correctly formatted.
233ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent         */
234ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent        public Settings(String settings) {
235ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent            StringTokenizer st = new StringTokenizer(settings, "=;");
236ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent            int tokens = st.countTokens();
237ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent            if (st.countTokens() != 3) {
238ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent                throw new IllegalArgumentException("settings: " + settings);
239ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent            }
240ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent            String key = st.nextToken();
241ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent            if (!key.equals("Virtualizer")) {
242ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent                throw new IllegalArgumentException(
243ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent                        "invalid settings for Virtualizer: " + key);
244ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent            }
245ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent            try {
246ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent                key = st.nextToken();
247ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent                if (!key.equals("strength")) {
248ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent                    throw new IllegalArgumentException("invalid key name: " + key);
249ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent                }
250ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent                strength = Short.parseShort(st.nextToken());
251ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent             } catch (NumberFormatException nfe) {
252ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent                throw new IllegalArgumentException("invalid value for key: " + key);
253ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent            }
254ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent        }
255ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent
256ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent        @Override
257ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent        public String toString() {
258ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent            String str = new String (
259ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent                    "Virtualizer"+
260ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent                    ";strength="+Short.toString(strength)
261ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent                    );
262ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent            return str;
263ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent        }
264ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent    };
265ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent
266ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent
267ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent    /**
268ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent     * Gets the virtualizer properties. This method is useful when a snapshot of current
269ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent     * virtualizer settings must be saved by the application.
270ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent     * @return a Virtualizer.Settings object containing all current parameters values
271ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent     * @throws IllegalStateException
272ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent     * @throws IllegalArgumentException
273ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent     * @throws UnsupportedOperationException
274ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent     */
275ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent    public Virtualizer.Settings getProperties()
276ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent    throws IllegalStateException, IllegalArgumentException, UnsupportedOperationException {
277ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent        Settings settings = new Settings();
278ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent        short[] value = new short[1];
279ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent        checkStatus(getParameter(PARAM_STRENGTH, value));
280ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent        settings.strength = value[0];
281ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent        return settings;
282ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent    }
283ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent
284ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent    /**
285ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent     * Sets the virtualizer properties. This method is useful when virtualizer settings have to
286ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent     * be applied from a previous backup.
28717cb280e7f1ac3556eac90ab08263712e0348cb9Eric Laurent     * @param settings a Virtualizer.Settings object containing the properties to apply
288ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent     * @throws IllegalStateException
289ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent     * @throws IllegalArgumentException
290ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent     * @throws UnsupportedOperationException
291ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent     */
292ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent    public void setProperties(Virtualizer.Settings settings)
293ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent    throws IllegalStateException, IllegalArgumentException, UnsupportedOperationException {
294ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent        checkStatus(setParameter(PARAM_STRENGTH, settings.strength));
295ca57d1cc89d65dfbd59c749c5736574cd08c7bd3Eric Laurent    }
296fd84f97af4b44d54bba53bb85b31a6dbce07f6e2Eric Laurent}
297