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.EditText;
32 import android.widget.SeekBar;
33 import android.widget.ToggleButton;
34 import android.widget.CompoundButton;
35 import android.widget.CompoundButton.OnCheckedChangeListener;
36 import java.nio.ByteOrder;
37 import java.nio.ByteBuffer;
38 import java.util.HashMap;
39 import java.util.Map;
40 
41 import android.media.audiofx.BassBoost;
42 import android.media.audiofx.AudioEffect;
43 
44 public class BassBoostTest extends Activity implements OnCheckedChangeListener {
45 
46     private final static String TAG = "BassBoostTest";
47 
48     private static int NUM_PARAMS = 1;
49 
50     private EffectParameter mStrength;
51     private BassBoost mBassBoost = null;
52     ToggleButton mOnOffButton;
53     ToggleButton mReleaseButton;
54     EditText mSessionText;
55     static int sSession = 0;
56     EffectListner mEffectListener = new EffectListner();
57     private static HashMap<Integer, BassBoost> sInstances = new HashMap<Integer, BassBoost>(10);
58     String mSettings = "";
59 
BassBoostTest()60     public BassBoostTest() {
61         Log.d(TAG, "contructor");
62     }
63 
64     @Override
onCreate(Bundle icicle)65     public void onCreate(Bundle icicle) {
66         super.onCreate(icicle);
67 
68         SeekBar seekBar;
69         TextView textView;
70 
71         setContentView(R.layout.bassboosttest);
72 
73         mSessionText = (EditText) findViewById(R.id.sessionEdit);
74         mSessionText.setOnKeyListener(mSessionKeyListener);
75 
76         mSessionText.setText(Integer.toString(sSession));
77 
78         mReleaseButton = (ToggleButton)findViewById(R.id.bbReleaseButton);
79         mOnOffButton = (ToggleButton)findViewById(R.id.bassboostOnOff);
80 
81         getEffect(sSession);
82 
83         if (mBassBoost != null) {
84             mReleaseButton.setOnCheckedChangeListener(this);
85             mOnOffButton.setOnCheckedChangeListener(this);
86 
87             textView = (TextView)findViewById(R.id.bbStrengthMin);
88             textView.setText("0");
89             textView = (TextView)findViewById(R.id.bbStrengthMax);
90             textView.setText("1000");
91             seekBar = (SeekBar)findViewById(R.id.bbStrengthSeekBar);
92             textView = (TextView)findViewById(R.id.bbStrengthValue);
93             mStrength = new BassBoostParam(mBassBoost, 0, 1000, seekBar, textView);
94             seekBar.setOnSeekBarChangeListener(mStrength);
95             mStrength.setEnabled(mBassBoost.getStrengthSupported());
96         }
97     }
98 
99     @Override
onResume()100     public void onResume() {
101         super.onResume();
102     }
103 
104     @Override
onPause()105     public void onPause() {
106         super.onPause();
107     }
108 
109     private View.OnKeyListener mSessionKeyListener
110     = new View.OnKeyListener() {
111         public boolean onKey(View v, int keyCode, KeyEvent event) {
112             Log.d(TAG, "onKey() keyCode: "+keyCode+" event.getAction(): "+event.getAction());
113             if (event.getAction() == KeyEvent.ACTION_DOWN) {
114                 switch (keyCode) {
115                     case KeyEvent.KEYCODE_DPAD_CENTER:
116                     case KeyEvent.KEYCODE_ENTER:
117                         try {
118                             sSession = Integer.parseInt(mSessionText.getText().toString());
119                             getEffect(sSession);
120                             if (mBassBoost != null) {
121                                 mStrength.setEffect(mBassBoost);
122                                 mStrength.setEnabled(mBassBoost.getStrengthSupported());
123                             }
124                         } catch (NumberFormatException e) {
125                             Log.d(TAG, "Invalid session #: "+mSessionText.getText().toString());
126                         }
127                         return true;
128                 }
129             }
130             return false;
131         }
132     };
133 
134     // OnCheckedChangeListener
onCheckedChanged(CompoundButton buttonView, boolean isChecked)135     public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
136         if (buttonView.getId() == R.id.bassboostOnOff) {
137             if (mBassBoost != null) {
138                 mBassBoost.setEnabled(isChecked);
139                 mStrength.updateDisplay();
140             }
141         }
142         if (buttonView.getId() == R.id.bbReleaseButton) {
143             if (isChecked) {
144                 if (mBassBoost == null) {
145                     getEffect(sSession);
146                     if (mBassBoost != null) {
147                         mStrength.setEffect(mBassBoost);
148                         mStrength.setEnabled(mBassBoost.getStrengthSupported());
149                     }
150                 }
151             } else {
152                 if (mBassBoost != null) {
153                     mStrength.setEnabled(false);
154                     putEffect(sSession);
155                 }
156             }
157         }
158     }
159 
160     private class BassBoostParam extends EffectParameter {
161         private BassBoost mBassBoost;
162 
BassBoostParam(BassBoost bassboost, int min, int max, SeekBar seekBar, TextView textView)163         public BassBoostParam(BassBoost bassboost, int min, int max, SeekBar seekBar, TextView textView) {
164             super (min, max, seekBar, textView, "o/oo");
165 
166             mBassBoost = bassboost;
167             updateDisplay();
168         }
169 
170         @Override
setParameter(Integer value)171         public void setParameter(Integer value) {
172             if (mBassBoost != null) {
173                 mBassBoost.setStrength(value.shortValue());
174             }
175         }
176 
177         @Override
getParameter()178         public Integer getParameter() {
179             if (mBassBoost != null) {
180                 return new Integer(mBassBoost.getRoundedStrength());
181             }
182             return new Integer(0);
183         }
184 
185         @Override
setEffect(Object effect)186         public void setEffect(Object effect) {
187             mBassBoost = (BassBoost)effect;
188         }
189     }
190 
191     public class EffectListner implements AudioEffect.OnEnableStatusChangeListener,
192         AudioEffect.OnControlStatusChangeListener, AudioEffect.OnParameterChangeListener
193    {
EffectListner()194         public EffectListner() {
195         }
onEnableStatusChange(AudioEffect effect, boolean enabled)196         public void onEnableStatusChange(AudioEffect effect, boolean enabled) {
197             Log.d(TAG,"onEnableStatusChange: "+ enabled);
198         }
onControlStatusChange(AudioEffect effect, boolean controlGranted)199         public void onControlStatusChange(AudioEffect effect, boolean controlGranted) {
200             Log.d(TAG,"onControlStatusChange: "+ controlGranted);
201         }
onParameterChange(AudioEffect effect, int status, byte[] param, byte[] value)202         public void onParameterChange(AudioEffect effect, int status, byte[] param, byte[] value) {
203             int p = byteArrayToInt(param, 0);
204             short v = byteArrayToShort(value, 0);
205 
206             Log.d(TAG,"onParameterChange, status: "+status+" p: "+p+" v: "+v);
207         }
208 
byteArrayToInt(byte[] valueBuf, int offset)209         private int byteArrayToInt(byte[] valueBuf, int offset) {
210             ByteBuffer converter = ByteBuffer.wrap(valueBuf);
211             converter.order(ByteOrder.nativeOrder());
212             return converter.getInt(offset);
213 
214         }
byteArrayToShort(byte[] valueBuf, int offset)215         private short byteArrayToShort(byte[] valueBuf, int offset) {
216             ByteBuffer converter = ByteBuffer.wrap(valueBuf);
217             converter.order(ByteOrder.nativeOrder());
218             return converter.getShort(offset);
219 
220         }
221 
222     }
223 
getEffect(int session)224     private void getEffect(int session) {
225         synchronized (sInstances) {
226             if (sInstances.containsKey(session)) {
227                 mBassBoost = sInstances.get(session);
228             } else {
229                 try{
230                     mBassBoost = new BassBoost(0, session);
231                 } catch (IllegalArgumentException e) {
232                     Log.e(TAG,"BassBoost effect not supported");
233                 } catch (IllegalStateException e) {
234                     Log.e(TAG,"BassBoost cannot get strength supported");
235                 } catch (UnsupportedOperationException e) {
236                     Log.e(TAG,"BassBoost library not loaded");
237                 } catch (RuntimeException e) {
238                     Log.e(TAG,"BassBoost effect not found");
239                 }
240                 sInstances.put(session, mBassBoost);
241             }
242             mReleaseButton.setEnabled(false);
243             mOnOffButton.setEnabled(false);
244 
245             if (mBassBoost != null) {
246                 if (mSettings != "") {
247                     mBassBoost.setProperties(new BassBoost.Settings(mSettings));
248                 }
249                 mBassBoost.setEnableStatusListener(mEffectListener);
250                 mBassBoost.setControlStatusListener(mEffectListener);
251                 mBassBoost.setParameterListener(mEffectListener);
252 
253                 mReleaseButton.setChecked(true);
254                 mReleaseButton.setEnabled(true);
255 
256                 mOnOffButton.setChecked(mBassBoost.getEnabled());
257                 mOnOffButton.setEnabled(true);
258             }
259         }
260     }
261 
putEffect(int session)262     private void putEffect(int session) {
263         mOnOffButton.setChecked(false);
264         mOnOffButton.setEnabled(false);
265         synchronized (sInstances) {
266             if (mBassBoost != null) {
267                 mSettings = mBassBoost.getProperties().toString();
268                 mBassBoost.release();
269                 Log.d(TAG,"BassBoost released");
270                 mBassBoost = null;
271                 sInstances.remove(session);
272             }
273         }
274     }
275 
276 }
277