1/*
2 * Copyright (C) 2009 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.effectstest;
18
19import android.app.Activity;
20import android.content.Context;
21import android.content.Intent;
22import android.os.Bundle;
23import android.util.Log;
24import android.view.KeyEvent;
25import android.view.Menu;
26import android.view.View.OnClickListener;
27import android.view.View;
28import android.view.ViewGroup;
29import android.widget.Button;
30import android.widget.TextView;
31import android.widget.EditText;
32import android.widget.SeekBar;
33import android.widget.ToggleButton;
34import android.widget.CompoundButton;
35import android.widget.CompoundButton.OnCheckedChangeListener;
36import java.nio.ByteOrder;
37import java.nio.ByteBuffer;
38import java.util.HashMap;
39import java.util.Map;
40
41import android.media.audiofx.PresetReverb;
42import android.media.audiofx.AudioEffect;
43
44public class PresetReverbTest extends Activity implements OnCheckedChangeListener {
45
46    private final static String TAG = "PresetReverbTest";
47
48    private static int NUM_PARAMS = 1;
49
50    private EffectParameter[] mParameters = new EffectParameter[NUM_PARAMS];
51    private PresetReverb mPresetReverb;
52    ToggleButton mOnOffButton;
53    ToggleButton mReleaseButton;
54    EditText mSessionText;
55    static int sSession = 0;
56    EffectListner mEffectListener = new EffectListner();
57    private static HashMap<Integer, PresetReverb> sInstances = new HashMap<Integer, PresetReverb>(10);
58    String mSettings = "";
59
60    public PresetReverbTest() {
61        Log.d(TAG, "contructor");
62    }
63
64    private static String[] sPresetNames = {
65        "NONE",         //PresetReverb.PRESET_NONE
66        "SMALLROOM",    //PresetReverb.PRESET_SMALLROOM
67        "MEDIUMROOM",   //PresetReverb.PRESET_MEDIUMROOM
68        "LARGEROOM",    //PresetReverb.PRESET_LARGEROOM
69        "MEDIUMHALL",   //PresetReverb.PRESET_MEDIUMHALL
70        "LARGEHALL",    //PresetReverb.PRESET_LARGEHALL
71        "PLATE",        //PresetReverb.PRESET_PLATE
72    };
73
74    @Override
75    public void onCreate(Bundle icicle) {
76        super.onCreate(icicle);
77
78        setContentView(R.layout.presetreverbtest);
79
80        mSessionText = (EditText) findViewById(R.id.sessionEdit);
81        mSessionText.setOnKeyListener(mSessionKeyListener);
82
83        mSessionText.setText(Integer.toString(sSession));
84
85        mReleaseButton = (ToggleButton)findViewById(R.id.presetrvbReleaseButton);
86        mOnOffButton = (ToggleButton)findViewById(R.id.presetrvbOnOff);
87
88        getEffect(sSession);
89
90        if (mPresetReverb != null) {
91            mReleaseButton.setOnCheckedChangeListener(this);
92            mOnOffButton.setOnCheckedChangeListener(this);
93            // Presets
94            SeekBar seekBar = (SeekBar)findViewById(R.id.presetrvbParam1SeekBar);
95            TextView textView = (TextView)findViewById(R.id.presetrvbParam1Value);
96            mParameters[0] = new PresetParam(mPresetReverb, (short)0, (short)(sPresetNames.length - 1), seekBar, textView);
97            seekBar.setOnSeekBarChangeListener(mParameters[0]);
98        }
99    }
100
101    @Override
102    public void onResume() {
103        super.onResume();
104    }
105
106    @Override
107    public void onPause() {
108        super.onPause();
109    }
110
111    private View.OnKeyListener mSessionKeyListener
112    = new View.OnKeyListener() {
113        public boolean onKey(View v, int keyCode, KeyEvent event) {
114            if (event.getAction() == KeyEvent.ACTION_DOWN) {
115                switch (keyCode) {
116                    case KeyEvent.KEYCODE_DPAD_CENTER:
117                    case KeyEvent.KEYCODE_ENTER:
118                        try {
119                            sSession = Integer.parseInt(mSessionText.getText().toString());
120                            getEffect(sSession);
121                            if (mPresetReverb != null) {
122                                for (int i = 0 ; i < mParameters.length; i++) {
123                                    mParameters[i].setEffect(mPresetReverb);
124                                    mParameters[i].setEnabled(true);
125                                    mParameters[i].updateDisplay();
126                                }
127                            }
128                        } catch (NumberFormatException e) {
129                            Log.d(TAG, "Invalid session #: "+mSessionText.getText().toString());
130                        }
131
132                        return true;
133                }
134            }
135            return false;
136        }
137    };
138
139    // OnCheckedChangeListener
140    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
141        if (buttonView.getId() == R.id.presetrvbOnOff) {
142            if (mPresetReverb != null) {
143                mPresetReverb.setEnabled(isChecked);
144                updateParams();
145            }
146        }
147        if (buttonView.getId() == R.id.presetrvbReleaseButton) {
148            if (isChecked) {
149                if (mPresetReverb == null) {
150                    getEffect(sSession);
151                    if (mPresetReverb != null) {
152                        for (int i = 0 ; i < mParameters.length; i++) {
153                            mParameters[i].setEffect(mPresetReverb);
154                            mParameters[i].setEnabled(true);
155                            mParameters[i].updateDisplay();
156                        }
157                    }
158                }
159            } else {
160                if (mPresetReverb != null) {
161                    for (int i = 0 ; i < mParameters.length; i++) {
162                        mParameters[i].setEnabled(false);
163                    }
164                    putEffect(sSession);
165                }
166            }
167        }
168    }
169
170    private class PresetParam extends EffectParameter {
171        private PresetReverb mPresetReverb;
172
173        public PresetParam(PresetReverb presetrvb, short min, short max, SeekBar seekBar, TextView textView) {
174            super (min, max, seekBar, textView, "");
175
176            mPresetReverb = presetrvb;
177            updateDisplay();
178        }
179
180        @Override
181        public void setParameter(Integer value) {
182            if (mPresetReverb != null) {
183                mPresetReverb.setPreset(value.shortValue());
184            }
185        }
186
187        @Override
188        public Integer getParameter() {
189            if (mPresetReverb != null) {
190                return new Integer(mPresetReverb.getPreset());
191            }
192            return new Integer(0);
193        }
194
195        @Override
196        public void displayValue(int value, boolean fromTouch) {
197            mValueText.setText(sPresetNames[value]);
198            if (!fromTouch) {
199                mSeekBar.setProgress(value - mMin);
200            } else {
201                updateParams();
202            }
203        }
204
205        @Override
206        public void setEffect(Object presetrvb) {
207            mPresetReverb = (PresetReverb)presetrvb;
208        }
209
210    }
211
212    protected void updateParams() {
213        for (int i = 0 ; i < mParameters.length; i++) {
214            mParameters[i].updateDisplay();
215        }
216    }
217
218    public class EffectListner implements AudioEffect.OnEnableStatusChangeListener,
219    AudioEffect.OnControlStatusChangeListener,
220    PresetReverb.OnParameterChangeListener
221   {
222        public EffectListner() {
223        }
224        public void onEnableStatusChange(AudioEffect effect, boolean enabled) {
225            Log.d(TAG,"onEnableStatusChange: "+ enabled);
226        }
227        public void onControlStatusChange(AudioEffect effect, boolean controlGranted) {
228            Log.d(TAG,"onControlStatusChange: "+ controlGranted);
229        }
230
231        public void onParameterChange(PresetReverb effect, int status, int param, short value) {
232            Log.d(TAG,"onParameterChange, status: "+status+" p: "+param+" v: "+value);
233        }
234
235        private int byteArrayToInt(byte[] valueBuf, int offset) {
236            ByteBuffer converter = ByteBuffer.wrap(valueBuf);
237            converter.order(ByteOrder.nativeOrder());
238            return converter.getInt(offset);
239
240        }
241        private short byteArrayToShort(byte[] valueBuf, int offset) {
242            ByteBuffer converter = ByteBuffer.wrap(valueBuf);
243            converter.order(ByteOrder.nativeOrder());
244            return converter.getShort(offset);
245
246        }
247    }
248
249    private void getEffect(int session) {
250        synchronized (sInstances) {
251            if (sInstances.containsKey(session)) {
252                mPresetReverb = sInstances.get(session);
253            } else {
254                try{
255                    mPresetReverb = new PresetReverb(0, session);
256                } catch (IllegalArgumentException e) {
257                    Log.e(TAG,"PresetReverb effect not supported");
258                } catch (UnsupportedOperationException e) {
259                    Log.e(TAG,"PresetReverb library not loaded");
260                } catch (RuntimeException e) {
261                    Log.e(TAG,"PresetReverb effect not found");
262                }
263                sInstances.put(session, mPresetReverb);
264            }
265        }
266        mReleaseButton.setEnabled(false);
267        mOnOffButton.setEnabled(false);
268
269        if (mPresetReverb != null) {
270            if (mSettings != "") {
271                mPresetReverb.setProperties(new PresetReverb.Settings(mSettings));
272            }
273            mPresetReverb.setEnableStatusListener(mEffectListener);
274            mPresetReverb.setControlStatusListener(mEffectListener);
275            mPresetReverb.setParameterListener(mEffectListener);
276
277            mReleaseButton.setChecked(true);
278            mReleaseButton.setEnabled(true);
279
280            mOnOffButton.setChecked(mPresetReverb.getEnabled());
281            mOnOffButton.setEnabled(true);
282        }
283    }
284
285    private void putEffect(int session) {
286        mOnOffButton.setChecked(false);
287        mOnOffButton.setEnabled(false);
288        synchronized (sInstances) {
289            if (mPresetReverb != null) {
290                mSettings = mPresetReverb.getProperties().toString();
291                mPresetReverb.release();
292                Log.d(TAG,"PresetReverb released");
293                mPresetReverb = null;
294                sInstances.remove(session);
295            }
296        }
297    }
298}
299