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 
17 package com.android.effectstest;
18 
19 import android.app.Activity;
20 import android.content.Context;
21 import android.content.Intent;
22 import android.os.Bundle;
23 import android.util.Log;
24 import android.view.KeyEvent;
25 import android.view.Menu;
26 import android.view.View.OnClickListener;
27 import android.view.View;
28 import android.view.ViewGroup;
29 import android.widget.Button;
30 import android.widget.TextView;
31 import android.widget.SeekBar;
32 import android.widget.ToggleButton;
33 import android.widget.CompoundButton;
34 import android.widget.CompoundButton.OnCheckedChangeListener;
35 import android.widget.ImageButton;
36 import android.widget.ImageView;
37 import java.util.HashMap;
38 import java.util.Map;
39 
40 import android.media.audiofx.EnvironmentalReverb;
41 import android.media.audiofx.AudioEffect;
42 import android.media.AudioManager;
43 
44 public class EnvReverbTest extends Activity implements OnCheckedChangeListener, SeekBar.OnSeekBarChangeListener {
45 
46     private final static String TAG = "EnvReverbTest";
47 
48     private static int NUM_PARAMS = 10;
49 
50     private EffectParameter[] mParameters = new EffectParameter[NUM_PARAMS];
51     private EnvironmentalReverb mReverb;
52     ToggleButton mOnOffButton;
53     ToggleButton mReleaseButton;
54     ToggleButton mAttachButton;
55     private static HashMap<Integer, EnvironmentalReverb> sInstances = new HashMap<Integer, EnvironmentalReverb>(10);
56     static SimplePlayer sPlayerController = null;
57     SeekBar mSendLevelSeekBar;
58     TextView mSendLevelDisplay;
59     static float sSendLevel = linToExp(50,100);
60     static boolean sAttached = false;
61     String mSettings = "";
62 
EnvReverbTest()63     public EnvReverbTest() {
64         Log.d(TAG, "contructor");
65     }
66 
67     @Override
onCreate(Bundle icicle)68     public void onCreate(Bundle icicle) {
69         super.onCreate(icicle);
70         Log.d(TAG, "onCreate");
71         SeekBar seekBar;
72         TextView textView;
73         ToggleButton button;
74         setContentView(R.layout.envreverbtest);
75 
76         ImageView playPause = (ImageView) findViewById(R.id.playPause1);
77         ImageView stop = (ImageView) findViewById(R.id.stop1);
78         textView = (TextView) findViewById(R.id.sessionText);
79         if (sPlayerController == null) {
80             sPlayerController = new SimplePlayer(this, R.id.playPause1, playPause,
81                     R.id.stop1, stop, textView,
82                     R.raw.mp3_sample, AudioManager.STREAM_MUSIC, 0);
83         } else {
84             sPlayerController.set(this, R.id.playPause1, playPause,
85                     R.id.stop1, stop, textView,
86                     AudioManager.STREAM_MUSIC, 0);
87         }
88 
89         // send level
90         mSendLevelSeekBar = (SeekBar)findViewById(R.id.sendLevelSeekBar);
91         mSendLevelDisplay = (TextView)findViewById(R.id.sendLevelValue);
92         mSendLevelSeekBar.setMax(100);
93         mSendLevelSeekBar.setOnSeekBarChangeListener(this);
94         mSendLevelSeekBar.setProgress(expToLin(sSendLevel,100));
95         sPlayerController.setAuxEffectSendLevel(sSendLevel);
96 
97         mOnOffButton = (ToggleButton)findViewById(R.id.rvbOnOff);
98         mReleaseButton = (ToggleButton)findViewById(R.id.rvbReleaseButton);
99         mAttachButton = (ToggleButton)findViewById(R.id.attachButton);
100 
101         getEffect(0);
102 
103         if (mReverb != null) {
104             mOnOffButton.setOnCheckedChangeListener(this);
105             mReleaseButton.setOnCheckedChangeListener(this);
106             mAttachButton.setOnCheckedChangeListener(this);
107 
108 //            button = (ToggleButton)findViewById(R.id.rvbBypass);
109 //            button.setChecked(false);
110 //            button.setOnCheckedChangeListener(this);
111 
112             // Room level
113             seekBar = (SeekBar)findViewById(R.id.rvbParam1SeekBar);
114             textView = (TextView)findViewById(R.id.rvbParam1Value);
115             mParameters[0] = new RoomLevelParam(mReverb, seekBar, textView);
116             seekBar.setOnSeekBarChangeListener(mParameters[0]);
117 
118             // Room HF level
119             seekBar = (SeekBar)findViewById(R.id.rvbParam2SeekBar);
120             textView = (TextView)findViewById(R.id.rvbParam2Value);
121             mParameters[1] = new RoomHFLevelParam(mReverb, seekBar, textView);
122             seekBar.setOnSeekBarChangeListener(mParameters[1]);
123 
124             // Decay time
125             seekBar = (SeekBar)findViewById(R.id.rvbParam3SeekBar);
126             textView = (TextView)findViewById(R.id.rvbParam3Value);
127             mParameters[2] = new DecayTimeParam(mReverb, seekBar, textView);
128             seekBar.setOnSeekBarChangeListener(mParameters[2]);
129 
130             // Decay HF ratio
131             seekBar = (SeekBar)findViewById(R.id.rvbParam4SeekBar);
132             textView = (TextView)findViewById(R.id.rvbParam4Value);
133             mParameters[3] = new DecayHFRatioParam(mReverb, seekBar, textView);
134             seekBar.setOnSeekBarChangeListener(mParameters[3]);
135 
136             // Reflections level
137             seekBar = (SeekBar)findViewById(R.id.rvbParam5SeekBar);
138             textView = (TextView)findViewById(R.id.rvbParam5Value);
139             mParameters[4] = new ReflectionsLevelParam(mReverb, seekBar, textView);
140             seekBar.setOnSeekBarChangeListener(mParameters[4]);
141 
142             // Reflections delay
143             seekBar = (SeekBar)findViewById(R.id.rvbParam6SeekBar);
144             textView = (TextView)findViewById(R.id.rvbParam6Value);
145             mParameters[5] = new ReflectionsDelayParam(mReverb, seekBar, textView);
146             seekBar.setOnSeekBarChangeListener(mParameters[5]);
147 
148             // Reverb level
149             seekBar = (SeekBar)findViewById(R.id.rvbParam7SeekBar);
150             textView = (TextView)findViewById(R.id.rvbParam7Value);
151             mParameters[6] = new ReverbLevelParam(mReverb, seekBar, textView);
152             seekBar.setOnSeekBarChangeListener(mParameters[6]);
153 
154             // Reverb delay
155             seekBar = (SeekBar)findViewById(R.id.rvbParam8SeekBar);
156             textView = (TextView)findViewById(R.id.rvbParam8Value);
157             mParameters[7] = new ReverbDelayParam(mReverb, seekBar, textView);
158             seekBar.setOnSeekBarChangeListener(mParameters[7]);
159 
160             // Diffusion
161             seekBar = (SeekBar)findViewById(R.id.rvbParam9SeekBar);
162             textView = (TextView)findViewById(R.id.rvbParam9Value);
163             mParameters[8] = new DiffusionParam(mReverb, seekBar, textView);
164             seekBar.setOnSeekBarChangeListener(mParameters[8]);
165 
166             // Density
167             seekBar = (SeekBar)findViewById(R.id.rvbParam10SeekBar);
168             textView = (TextView)findViewById(R.id.rvbParam10Value);
169             mParameters[9] = new DensityParam(mReverb, seekBar, textView);
170             seekBar.setOnSeekBarChangeListener(mParameters[9]);
171         }
172     }
173     @Override
onResume()174     public void onResume() {
175         super.onResume();
176         Log.d(TAG, "onResume");
177     }
178 
179     @Override
onPause()180     public void onPause() {
181         super.onPause();
182     }
183 
184     // OnCheckedChangeListener
onCheckedChanged(CompoundButton buttonView, boolean isChecked)185     public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
186         if (buttonView.getId() == R.id.rvbOnOff) {
187             if (mReverb != null) {
188                 mReverb.setEnabled(isChecked);
189                 Log.d(TAG,"onCheckedChanged: rvbOnOff");
190                 for (int i = 0 ; i < mParameters.length; i++) {
191                     mParameters[i].updateDisplay();
192                 }
193             }
194         }
195         if (buttonView.getId() == R.id.rvbReleaseButton) {
196             if (isChecked) {
197                 if (mReverb == null) {
198                     getEffect(0);
199                     for (int i = 0 ; i < mParameters.length; i++) {
200                         mParameters[i].setEffect(mReverb);
201                         mParameters[i].setEnabled(true);
202                     }
203                 }
204             } else {
205                 if (mReverb != null) {
206                     for (int i = 0 ; i < mParameters.length; i++) {
207                         mParameters[i].setEnabled(false);
208                     }
209                     putEffect(0);
210                 }
211             }
212         }
213 //        if (buttonView.getId() == R.id.rvbBypass) {
214 //            // REVERB_PARAM_BYPASS parametervalue is 11 in EffectEnvironmentalReverApi.h
215 //            if (mReverb != null) {
216 //                if (isChecked) {
217 //                    mReverb.setParameter((int)11, (int)1);
218 //                } else {
219 //                    mReverb.setParameter((int)11, (int)0);
220 //                }
221 //            }
222 //        }
223         if (buttonView.getId() == R.id.attachButton) {
224             if (mReverb != null) {
225                 if (isChecked) {
226                     sPlayerController.attachAuxEffect(mReverb.getId());
227                     sAttached = true;
228                 } else {
229                     sPlayerController.attachAuxEffect(0);
230                     sAttached = false;
231                 }
232             }
233         }
234     }
235 
236     // SeekBar.OnSeekBarChangeListener
onProgressChanged(SeekBar seekBar, int progress, boolean fromTouch)237     public void onProgressChanged(SeekBar seekBar, int progress, boolean fromTouch) {
238 
239         if (seekBar != mSendLevelSeekBar) {
240             Log.e(TAG, "onProgressChanged called with wrong seekBar");
241             return;
242         }
243 
244         sSendLevel = linToExp(progress,100);
245         if (fromTouch) {
246             sPlayerController.setAuxEffectSendLevel(sSendLevel);
247         }
248         String text = Float.toString(sSendLevel);
249         mSendLevelDisplay.setText(text);
250         if (!fromTouch) {
251             seekBar.setProgress(progress);
252         }
253     }
254 
linToExp(int lin, int range)255     static float linToExp(int lin, int range) {
256         if (lin == 0) return 0;
257         return (float)Math.pow((double)10,(double)72*(lin-range)/(20*range));
258     }
259 
expToLin(float exp, int range)260     static int expToLin(float exp, int range) {
261         if (exp == 0) return 0;
262         return (int)(20*range*Math.log10((double)exp)/72 + range);
263     }
264 
onStartTrackingTouch(SeekBar seekBar)265     public void onStartTrackingTouch(SeekBar seekBar) {
266     }
267 
onStopTrackingTouch(SeekBar seekBar)268     public void onStopTrackingTouch(SeekBar seekBar) {
269     }
270 
271     private class EnvReverbParam extends EffectParameter {
272         private EnvironmentalReverb mReverb;
273 
EnvReverbParam(EnvironmentalReverb reverb, int min, int max, SeekBar seekBar, TextView textView, String unit)274         public EnvReverbParam(EnvironmentalReverb reverb, int min, int max, SeekBar seekBar, TextView textView, String unit) {
275             super (min, max, seekBar, textView, unit);
276             mReverb = reverb;
277             updateDisplay();
278         }
279 
280         @Override
setParameter(Integer value)281         public void setParameter(Integer value) {
282         }
283 
284         @Override
getParameter()285         public Integer getParameter() {
286             return new Integer(0);
287         }
288 
289         @Override
setEffect(Object reverb)290         public void setEffect(Object reverb) {
291             mReverb = (EnvironmentalReverb)reverb;
292         }
293     }
294 
295     private class RoomLevelParam extends EnvReverbParam {
296 
RoomLevelParam(EnvironmentalReverb reverb, SeekBar seekBar, TextView textView)297         public RoomLevelParam(EnvironmentalReverb reverb, SeekBar seekBar, TextView textView) {
298             super (reverb, -9600, 0, seekBar, textView, "mB");
299         }
300 
301         @Override
setParameter(Integer value)302         public void setParameter(Integer value) {
303             if (mReverb != null) {
304                 mReverb.setRoomLevel(value.shortValue());
305             }
306         }
307 
308         @Override
getParameter()309         public Integer getParameter() {
310             if (mReverb != null) {
311                 return new Integer(mReverb.getRoomLevel());
312             }
313             return new Integer(0);
314         }
315     }
316 
317     private class RoomHFLevelParam extends EnvReverbParam {
318 
RoomHFLevelParam(EnvironmentalReverb reverb, SeekBar seekBar, TextView textView)319         public RoomHFLevelParam(EnvironmentalReverb reverb, SeekBar seekBar, TextView textView) {
320             super (reverb, -4000, 0, seekBar, textView, "mB");
321         }
322 
323         @Override
setParameter(Integer value)324         public void setParameter(Integer value) {
325             if (mReverb != null) {
326                 mReverb.setRoomHFLevel(value.shortValue());
327             }
328         }
329 
330         @Override
getParameter()331         public Integer getParameter() {
332             if (mReverb != null) {
333                 return new Integer(mReverb.getRoomHFLevel());
334             }
335             return new Integer(0);
336         }
337     }
338 
339     private class DecayTimeParam extends EnvReverbParam {
340 
DecayTimeParam(EnvironmentalReverb reverb, SeekBar seekBar, TextView textView)341         public DecayTimeParam(EnvironmentalReverb reverb, SeekBar seekBar, TextView textView) {
342             super (reverb, 200, 4000, seekBar, textView, "ms");
343         }
344 
345         @Override
setParameter(Integer value)346         public void setParameter(Integer value) {
347             if (mReverb != null) {
348                 mReverb.setDecayTime(value.intValue());
349             }
350         }
351 
352         @Override
getParameter()353         public Integer getParameter() {
354             if (mReverb != null) {
355                 return mReverb.getDecayTime();
356             }
357             return new Integer(0);
358         }
359     }
360 
361     private class DecayHFRatioParam extends EnvReverbParam {
362 
DecayHFRatioParam(EnvironmentalReverb reverb, SeekBar seekBar, TextView textView)363         public DecayHFRatioParam(EnvironmentalReverb reverb, SeekBar seekBar, TextView textView) {
364             super (reverb, 100, 1000, seekBar, textView, "permilles");
365         }
366 
367         @Override
setParameter(Integer value)368         public void setParameter(Integer value) {
369             if (mReverb != null) {
370                 mReverb.setDecayHFRatio(value.shortValue());
371             }
372         }
373 
374         @Override
getParameter()375         public Integer getParameter() {
376             if (mReverb != null) {
377                 return new Integer(mReverb.getDecayHFRatio());
378             }
379             return new Integer(0);
380         }
381     }
382 
383     private class ReflectionsLevelParam extends EnvReverbParam {
384 
ReflectionsLevelParam(EnvironmentalReverb reverb, SeekBar seekBar, TextView textView)385         public ReflectionsLevelParam(EnvironmentalReverb reverb, SeekBar seekBar, TextView textView) {
386             super (reverb, -9600, 0, seekBar, textView, "mB");
387         }
388 
389         @Override
setParameter(Integer value)390         public void setParameter(Integer value) {
391             if (mReverb != null) {
392                 mReverb.setReflectionsLevel(value.shortValue());
393             }
394         }
395 
396         @Override
getParameter()397         public Integer getParameter() {
398             if (mReverb != null) {
399                 return new Integer(mReverb.getReflectionsLevel());
400             }
401             return new Integer(0);
402         }
403     }
404 
405     private class ReflectionsDelayParam extends EnvReverbParam {
406 
ReflectionsDelayParam(EnvironmentalReverb reverb, SeekBar seekBar, TextView textView)407         public ReflectionsDelayParam(EnvironmentalReverb reverb, SeekBar seekBar, TextView textView) {
408             super (reverb, 0, 65, seekBar, textView, "ms");
409         }
410 
411         @Override
setParameter(Integer value)412         public void setParameter(Integer value) {
413             if (mReverb != null) {
414                 mReverb.setReflectionsDelay(value.intValue());
415             }
416         }
417 
418         @Override
getParameter()419         public Integer getParameter() {
420             if (mReverb != null) {
421                 return mReverb.getReflectionsDelay();
422             }
423             return new Integer(0);
424         }
425     }
426 
427     private class ReverbLevelParam extends EnvReverbParam {
428 
ReverbLevelParam(EnvironmentalReverb reverb, SeekBar seekBar, TextView textView)429         public ReverbLevelParam(EnvironmentalReverb reverb, SeekBar seekBar, TextView textView) {
430             super (reverb, -9600, 2000, seekBar, textView, "mB");
431         }
432 
433         @Override
setParameter(Integer value)434         public void setParameter(Integer value) {
435             if (mReverb != null) {
436                 mReverb.setReverbLevel(value.shortValue());
437             }
438         }
439 
440         @Override
getParameter()441         public Integer getParameter() {
442             if (mReverb != null) {
443                 return new Integer(mReverb.getReverbLevel());
444             }
445             return new Integer(0);
446         }
447     }
448 
449     private class ReverbDelayParam extends EnvReverbParam {
450 
ReverbDelayParam(EnvironmentalReverb reverb, SeekBar seekBar, TextView textView)451         public ReverbDelayParam(EnvironmentalReverb reverb, SeekBar seekBar, TextView textView) {
452             super (reverb, 0, 65, seekBar, textView, "ms");
453         }
454 
455         @Override
setParameter(Integer value)456         public void setParameter(Integer value) {
457             if (mReverb != null) {
458                 mReverb.setReverbDelay(value.intValue());
459             }
460         }
461 
462         @Override
getParameter()463         public Integer getParameter() {
464             if (mReverb != null) {
465                 return mReverb.getReverbDelay();
466             }
467             return new Integer(0);
468         }
469     }
470 
471     private class DiffusionParam extends EnvReverbParam {
472 
DiffusionParam(EnvironmentalReverb reverb, SeekBar seekBar, TextView textView)473         public DiffusionParam(EnvironmentalReverb reverb, SeekBar seekBar, TextView textView) {
474             super (reverb, 0, 1000, seekBar, textView, "permilles");
475         }
476 
477         @Override
setParameter(Integer value)478         public void setParameter(Integer value) {
479             if (mReverb != null) {
480                 mReverb.setDiffusion(value.shortValue());
481             }
482         }
483 
484         @Override
getParameter()485         public Integer getParameter() {
486             if (mReverb != null) {
487                 return new Integer(mReverb.getDiffusion());
488             }
489             return new Integer(0);
490         }
491     }
492 
493     private class DensityParam extends EnvReverbParam {
494 
DensityParam(EnvironmentalReverb reverb, SeekBar seekBar, TextView textView)495         public DensityParam(EnvironmentalReverb reverb, SeekBar seekBar, TextView textView) {
496             super (reverb, 0, 1000, seekBar, textView, "permilles");
497         }
498 
499         @Override
setParameter(Integer value)500         public void setParameter(Integer value) {
501             if (mReverb != null) {
502                 mReverb.setDensity(value.shortValue());
503             }
504         }
505 
506         @Override
getParameter()507         public Integer getParameter() {
508             if (mReverb != null) {
509                 return new Integer(mReverb.getDensity());
510             }
511             return new Integer(0);
512         }
513     }
514 
getEffect(int session)515     private void getEffect(int session) {
516         synchronized (sInstances) {
517             if (sInstances.containsKey(session)) {
518                 mReverb = sInstances.get(session);
519             } else {
520                 try{
521                     mReverb = new EnvironmentalReverb(0, session);
522                 } catch (IllegalArgumentException e) {
523                     Log.e(TAG,"Reverb effect not supported");
524                 } catch (UnsupportedOperationException e) {
525                     Log.e(TAG,"Reverb library not loaded");
526                 } catch (RuntimeException e) {
527                     Log.e(TAG,"Reverb effect not found");
528                 }
529                 Log.d(TAG, "new reverb: "+mReverb);
530                 sInstances.put(session, mReverb);
531             }
532         }
533         mReleaseButton.setEnabled(false);
534         mOnOffButton.setEnabled(false);
535         mAttachButton.setEnabled(false);
536         if (mReverb != null) {
537             if (mSettings != "") {
538                 mReverb.setProperties(new EnvironmentalReverb.Settings(mSettings));
539             }
540             mReleaseButton.setChecked(true);
541             mReleaseButton.setEnabled(true);
542             mOnOffButton.setChecked(mReverb.getEnabled());
543             mOnOffButton.setEnabled(true);
544             mAttachButton.setChecked(false);
545             mAttachButton.setEnabled(true);
546             if (sAttached) {
547                 mAttachButton.setChecked(true);
548                 sPlayerController.attachAuxEffect(mReverb.getId());
549             }
550         }
551     }
552 
putEffect(int session)553     private void putEffect(int session) {
554         mOnOffButton.setChecked(false);
555         mOnOffButton.setEnabled(false);
556         mAttachButton.setChecked(false);
557         mAttachButton.setEnabled(false);
558         synchronized (sInstances) {
559             if (mReverb != null) {
560                 mSettings = mReverb.getProperties().toString();
561                 mReverb.release();
562                 Log.d(TAG,"Reverb released, settings: "+mSettings);
563                 mReverb = null;
564                 sInstances.remove(session);
565             }
566         }
567     }
568 }
569