• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.media.audiofx.Visualizer;
23 import android.os.Bundle;
24 import android.os.Handler;
25 import android.os.Looper;
26 import android.os.Message;
27 import android.util.Log;
28 import android.view.KeyEvent;
29 import android.view.Menu;
30 import android.view.View;
31 import android.view.View.OnClickListener;
32 import android.view.ViewGroup;
33 import android.widget.Button;
34 import android.widget.CompoundButton;
35 import android.widget.CompoundButton.OnCheckedChangeListener;
36 import android.widget.EditText;
37 import android.widget.TextView;
38 import android.widget.ToggleButton;
39 import android.widget.SeekBar;
40 
41 import java.nio.ByteOrder;
42 import java.nio.ByteBuffer;
43 import java.util.HashMap;
44 import java.util.Map;
45 
46 public class VisualizerTest extends Activity implements OnCheckedChangeListener {
47 
48     private final static String TAG = "Visualizer Test";
49 
50     private Visualizer mVisualizer;
51     ToggleButton mOnOffButton;
52     ToggleButton mReleaseButton;
53     boolean mEnabled;
54     EditText mSessionText;
55     static int sSession = 0;
56     int mCaptureSize;
57     ToggleButton mCallbackButton;
58     boolean mCallbackOn;
59     VisualizerListener mVisualizerListener;
60     private static HashMap<Integer, Visualizer> sInstances = new HashMap<Integer, Visualizer>(10);
61     private VisualizerTestHandler mVisualizerTestHandler = null;
62 
VisualizerTest()63     public VisualizerTest() {
64         Log.d(TAG, "contructor");
65     }
66 
67     @Override
onCreate(Bundle icicle)68     public void onCreate(Bundle icicle) {
69         super.onCreate(icicle);
70 
71         TextView textView;
72 
73         setContentView(R.layout.visualizertest);
74 
75         mSessionText = (EditText) findViewById(R.id.sessionEdit);
76         mSessionText.setOnKeyListener(mSessionKeyListener);
77         mSessionText.setText(Integer.toString(sSession));
78 
79         mReleaseButton = (ToggleButton)findViewById(R.id.visuReleaseButton);
80         mOnOffButton = (ToggleButton)findViewById(R.id.visualizerOnOff);
81         mCallbackButton = (ToggleButton)findViewById(R.id.visuCallbackOnOff);
82         mCallbackOn = false;
83         mCallbackButton.setChecked(mCallbackOn);
84 
85         mVisualizerTestHandler = new VisualizerTestHandler();
86         mVisualizerListener = new VisualizerListener();
87 
88         getEffect(sSession);
89 
90         if (mVisualizer != null) {
91             mReleaseButton.setOnCheckedChangeListener(this);
92             mOnOffButton.setOnCheckedChangeListener(this);
93             mCallbackButton.setOnCheckedChangeListener(this);
94         }
95     }
96 
97     private static final int MSG_START_CAPTURE = 0;
98     private static final int MSG_STOP_CAPTURE = 1;
99     private static final int MSG_NEW_CAPTURE = 2;
100     private static final int CAPTURE_PERIOD_MS = 100;
101 
102     private class VisualizerTestHandler extends Handler {
103         boolean mActive = false;
104         @Override
handleMessage(Message msg)105         public void handleMessage(Message msg) {
106             switch (msg.what) {
107             case MSG_START_CAPTURE:
108                 if (!mActive) {
109                     Log.d(TAG, "Start capture");
110                     mActive = true;
111                     sendMessageDelayed(obtainMessage(MSG_NEW_CAPTURE, 0, 0, null), CAPTURE_PERIOD_MS);
112                 }
113                 break;
114             case MSG_STOP_CAPTURE:
115                 if (mActive) {
116                     Log.d(TAG, "Stop capture");
117                     mActive = false;
118                 }
119                 break;
120             case MSG_NEW_CAPTURE:
121                 if (mActive && mVisualizer != null) {
122                     if (mCaptureSize > 0) {
123                         byte[] data = new byte[mCaptureSize];
124                         if (mVisualizer.getWaveForm(data) == Visualizer.SUCCESS) {
125                             int len = data.length < mCaptureSize ? data.length : mCaptureSize;
126                             displayVal(R.id.waveformMin, data[0]);
127                             displayVal(R.id.waveformMax, data[len-1]);
128                             displayVal(R.id.waveformCenter, data[len/2]);
129                         };
130                         if (mVisualizer.getFft(data) == Visualizer.SUCCESS) {
131                             int len = data.length < mCaptureSize ? data.length : mCaptureSize;
132                             displayVal(R.id.fftMin, data[0]);
133                             displayVal(R.id.fftMax, data[len-1]);
134                             displayVal(R.id.fftCenter, data[len/2]);
135                         };
136                     }
137                     sendMessageDelayed(obtainMessage(MSG_NEW_CAPTURE, 0, 0, null), CAPTURE_PERIOD_MS);
138                 }
139                 break;
140             }
141         }
142     }
143 
144     private class VisualizerListener implements Visualizer.OnDataCaptureListener {
145 
146         public VisualizerListener() {
147         }
148         public void onWaveFormDataCapture(Visualizer visualizer, byte[] waveform, int samplingRate) {
149             if (visualizer == mVisualizer) {
150                 if (waveform.length > 0) {
151                     Log.d(TAG, "onWaveFormDataCapture(): "+waveform[0]+" smp rate: "+samplingRate/1000);
152                     displayVal(R.id.waveformMin, waveform[0]);
153                     displayVal(R.id.waveformMax, waveform[waveform.length - 1]);
154                     displayVal(R.id.waveformCenter, waveform[waveform.length/2]);
155                 }
156             }
157         }
158         public void onFftDataCapture(Visualizer visualizer, byte[] fft, int samplingRate) {
159             if (visualizer == mVisualizer) {
160                 if (fft.length > 0) {
161                     Log.d(TAG, "onFftDataCapture(): "+fft[0]);
162                     displayVal(R.id.fftMin, fft[0]);
163                     displayVal(R.id.fftMax, fft[fft.length - 1]);
164                     displayVal(R.id.fftCenter, fft[fft.length/2]);
165                 }
166             }
167         }
168     }
169 
170     @Override
171     public void onResume() {
172         super.onResume();
173     }
174 
175     @Override
176     public void onPause() {
177         super.onPause();
178     }
179 
180     private View.OnKeyListener mSessionKeyListener
181     = new View.OnKeyListener() {
182         public boolean onKey(View v, int keyCode, KeyEvent event) {
183             if (event.getAction() == KeyEvent.ACTION_DOWN) {
184                 switch (keyCode) {
185                     case KeyEvent.KEYCODE_DPAD_CENTER:
186                     case KeyEvent.KEYCODE_ENTER:
187                         try {
188                             sSession = Integer.parseInt(mSessionText.getText().toString());
189                             getEffect(sSession);
190                         } catch (NumberFormatException e) {
191                             Log.d(TAG, "Invalid session #: "+mSessionText.getText().toString());
192                         }
193 
194                         return true;
195                 }
196             }
197             return false;
198         }
199     };
200 
201     // OnCheckedChangeListener
onCheckedChanged(CompoundButton buttonView, boolean isChecked)202     public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
203         if (buttonView.getId() == R.id.visualizerOnOff) {
204             if (mVisualizer != null) {
205                 mEnabled = isChecked;
206                 mCallbackButton.setEnabled(!mEnabled);
207                 if (mCallbackOn && mEnabled) {
208                     mVisualizer.setDataCaptureListener(mVisualizerListener,
209                             10000,
210                             true,
211                             true);
212                 }
213                 mVisualizer.setEnabled(mEnabled);
214                 if (mCallbackOn) {
215                     if (!mEnabled) {
216                         mVisualizer.setDataCaptureListener(null,
217                                 10000,
218                                 false,
219                                 false);
220                     }
221                 } else {
222                     int msg = isChecked ? MSG_START_CAPTURE : MSG_STOP_CAPTURE;
223                     mVisualizerTestHandler.sendMessage(
224                             mVisualizerTestHandler.obtainMessage(msg, 0, 0, null));
225                 }
226             }
227         }
228         if (buttonView.getId() == R.id.visuReleaseButton) {
229             if (isChecked) {
230                 if (mVisualizer == null) {
231                     getEffect(sSession);
232                 }
233             } else {
234                 if (mVisualizer != null) {
235                     putEffect(sSession);
236                 }
237             }
238         }
239         if (buttonView.getId() == R.id.visuCallbackOnOff) {
240             mCallbackOn = isChecked;
241         }
242     }
243 
displayVal(int viewId, int val)244     private void displayVal(int viewId, int val) {
245         TextView textView = (TextView)findViewById(viewId);
246         String text = Integer.toString(val);
247         textView.setText(text);
248     }
249 
250 
getEffect(int session)251     private void getEffect(int session) {
252         synchronized (sInstances) {
253             if (sInstances.containsKey(session)) {
254                 mVisualizer = sInstances.get(session);
255             } else {
256                 try{
257                     mVisualizer = new Visualizer(session);
258                 } catch (UnsupportedOperationException e) {
259                     Log.e(TAG,"Visualizer library not loaded");
260                     throw (new RuntimeException("Cannot initialize effect"));
261                 } catch (RuntimeException e) {
262                     throw e;
263                 }
264                 sInstances.put(session, mVisualizer);
265             }
266         }
267         mReleaseButton.setEnabled(false);
268         mOnOffButton.setEnabled(false);
269         if (mVisualizer != null) {
270             mCaptureSize = mVisualizer.getCaptureSize();
271 
272             mReleaseButton.setChecked(true);
273             mReleaseButton.setEnabled(true);
274 
275             mEnabled = mVisualizer.getEnabled();
276             mOnOffButton.setChecked(mEnabled);
277             mOnOffButton.setEnabled(true);
278 
279             mCallbackButton.setEnabled(!mEnabled);
280         }
281     }
282 
putEffect(int session)283     private void putEffect(int session) {
284         mOnOffButton.setChecked(false);
285         mOnOffButton.setEnabled(false);
286         synchronized (sInstances) {
287             if (mVisualizer != null) {
288                 mVisualizer.release();
289                 Log.d(TAG,"Visualizer released");
290                 mVisualizer = null;
291                 sInstances.remove(session);
292             }
293         }
294     }
295 
296 }
297