| /* |
| * Copyright (C) 2009 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package com.android.effectstest; |
| |
| import android.app.Activity; |
| import android.content.Context; |
| import android.content.Intent; |
| import android.media.audiofx.Visualizer; |
| import android.os.Bundle; |
| import android.os.Handler; |
| import android.os.Looper; |
| import android.os.Message; |
| import android.util.Log; |
| import android.view.KeyEvent; |
| import android.view.Menu; |
| import android.view.View; |
| import android.view.View.OnClickListener; |
| import android.view.ViewGroup; |
| import android.widget.Button; |
| import android.widget.CompoundButton; |
| import android.widget.CompoundButton.OnCheckedChangeListener; |
| import android.widget.EditText; |
| import android.widget.TextView; |
| import android.widget.ToggleButton; |
| import android.widget.SeekBar; |
| |
| import java.nio.ByteOrder; |
| import java.nio.ByteBuffer; |
| import java.util.HashMap; |
| import java.util.Map; |
| |
| public class VisualizerTest extends Activity implements OnCheckedChangeListener { |
| |
| private final static String TAG = "Visualizer Test"; |
| |
| private Visualizer mVisualizer; |
| ToggleButton mOnOffButton; |
| ToggleButton mReleaseButton; |
| boolean mEnabled; |
| EditText mSessionText; |
| static int sSession = 0; |
| int mCaptureSize; |
| ToggleButton mCallbackButton; |
| boolean mCallbackOn; |
| VisualizerListener mVisualizerListener; |
| private static HashMap<Integer, Visualizer> sInstances = new HashMap<Integer, Visualizer>(10); |
| private VisualizerTestHandler mVisualizerTestHandler = null; |
| |
| public VisualizerTest() { |
| Log.d(TAG, "contructor"); |
| } |
| |
| @Override |
| public void onCreate(Bundle icicle) { |
| super.onCreate(icicle); |
| |
| TextView textView; |
| |
| setContentView(R.layout.visualizertest); |
| |
| mSessionText = (EditText) findViewById(R.id.sessionEdit); |
| mSessionText.setOnKeyListener(mSessionKeyListener); |
| mSessionText.setText(Integer.toString(sSession)); |
| |
| mReleaseButton = (ToggleButton)findViewById(R.id.visuReleaseButton); |
| mOnOffButton = (ToggleButton)findViewById(R.id.visualizerOnOff); |
| mCallbackButton = (ToggleButton)findViewById(R.id.visuCallbackOnOff); |
| mCallbackOn = false; |
| mCallbackButton.setChecked(mCallbackOn); |
| |
| mVisualizerTestHandler = new VisualizerTestHandler(); |
| mVisualizerListener = new VisualizerListener(); |
| |
| getEffect(sSession); |
| |
| if (mVisualizer != null) { |
| mReleaseButton.setOnCheckedChangeListener(this); |
| mOnOffButton.setOnCheckedChangeListener(this); |
| mCallbackButton.setOnCheckedChangeListener(this); |
| } |
| } |
| |
| private static final int MSG_START_CAPTURE = 0; |
| private static final int MSG_STOP_CAPTURE = 1; |
| private static final int MSG_NEW_CAPTURE = 2; |
| private static final int CAPTURE_PERIOD_MS = 100; |
| |
| private class VisualizerTestHandler extends Handler { |
| boolean mActive = false; |
| @Override |
| public void handleMessage(Message msg) { |
| switch (msg.what) { |
| case MSG_START_CAPTURE: |
| if (!mActive) { |
| Log.d(TAG, "Start capture"); |
| mActive = true; |
| sendMessageDelayed(obtainMessage(MSG_NEW_CAPTURE, 0, 0, null), CAPTURE_PERIOD_MS); |
| } |
| break; |
| case MSG_STOP_CAPTURE: |
| if (mActive) { |
| Log.d(TAG, "Stop capture"); |
| mActive = false; |
| } |
| break; |
| case MSG_NEW_CAPTURE: |
| if (mActive && mVisualizer != null) { |
| if (mCaptureSize > 0) { |
| byte[] data = new byte[mCaptureSize]; |
| if (mVisualizer.getWaveForm(data) == Visualizer.SUCCESS) { |
| int len = data.length < mCaptureSize ? data.length : mCaptureSize; |
| displayVal(R.id.waveformMin, data[0]); |
| displayVal(R.id.waveformMax, data[len-1]); |
| displayVal(R.id.waveformCenter, data[len/2]); |
| }; |
| if (mVisualizer.getFft(data) == Visualizer.SUCCESS) { |
| int len = data.length < mCaptureSize ? data.length : mCaptureSize; |
| displayVal(R.id.fftMin, data[0]); |
| displayVal(R.id.fftMax, data[len-1]); |
| displayVal(R.id.fftCenter, data[len/2]); |
| }; |
| } |
| sendMessageDelayed(obtainMessage(MSG_NEW_CAPTURE, 0, 0, null), CAPTURE_PERIOD_MS); |
| } |
| break; |
| } |
| } |
| } |
| |
| private class VisualizerListener implements Visualizer.OnDataCaptureListener { |
| |
| public VisualizerListener() { |
| } |
| public void onWaveFormDataCapture(Visualizer visualizer, byte[] waveform, int samplingRate) { |
| if (visualizer == mVisualizer) { |
| if (waveform.length > 0) { |
| Log.d(TAG, "onWaveFormDataCapture(): "+waveform[0]+" smp rate: "+samplingRate/1000); |
| displayVal(R.id.waveformMin, waveform[0]); |
| displayVal(R.id.waveformMax, waveform[waveform.length - 1]); |
| displayVal(R.id.waveformCenter, waveform[waveform.length/2]); |
| } |
| } |
| } |
| public void onFftDataCapture(Visualizer visualizer, byte[] fft, int samplingRate) { |
| if (visualizer == mVisualizer) { |
| if (fft.length > 0) { |
| Log.d(TAG, "onFftDataCapture(): "+fft[0]); |
| displayVal(R.id.fftMin, fft[0]); |
| displayVal(R.id.fftMax, fft[fft.length - 1]); |
| displayVal(R.id.fftCenter, fft[fft.length/2]); |
| } |
| } |
| } |
| } |
| |
| @Override |
| public void onResume() { |
| super.onResume(); |
| } |
| |
| @Override |
| public void onPause() { |
| super.onPause(); |
| } |
| |
| private View.OnKeyListener mSessionKeyListener |
| = new View.OnKeyListener() { |
| public boolean onKey(View v, int keyCode, KeyEvent event) { |
| if (event.getAction() == KeyEvent.ACTION_DOWN) { |
| switch (keyCode) { |
| case KeyEvent.KEYCODE_DPAD_CENTER: |
| case KeyEvent.KEYCODE_ENTER: |
| try { |
| sSession = Integer.parseInt(mSessionText.getText().toString()); |
| getEffect(sSession); |
| } catch (NumberFormatException e) { |
| Log.d(TAG, "Invalid session #: "+mSessionText.getText().toString()); |
| } |
| |
| return true; |
| } |
| } |
| return false; |
| } |
| }; |
| |
| // OnCheckedChangeListener |
| public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { |
| if (buttonView.getId() == R.id.visualizerOnOff) { |
| if (mVisualizer != null) { |
| mEnabled = isChecked; |
| mCallbackButton.setEnabled(!mEnabled); |
| if (mCallbackOn && mEnabled) { |
| mVisualizer.setDataCaptureListener(mVisualizerListener, |
| 10000, |
| true, |
| true); |
| } |
| mVisualizer.setEnabled(mEnabled); |
| if (mCallbackOn) { |
| if (!mEnabled) { |
| mVisualizer.setDataCaptureListener(null, |
| 10000, |
| false, |
| false); |
| } |
| } else { |
| int msg = isChecked ? MSG_START_CAPTURE : MSG_STOP_CAPTURE; |
| mVisualizerTestHandler.sendMessage( |
| mVisualizerTestHandler.obtainMessage(msg, 0, 0, null)); |
| } |
| } |
| } |
| if (buttonView.getId() == R.id.visuReleaseButton) { |
| if (isChecked) { |
| if (mVisualizer == null) { |
| getEffect(sSession); |
| } |
| } else { |
| if (mVisualizer != null) { |
| putEffect(sSession); |
| } |
| } |
| } |
| if (buttonView.getId() == R.id.visuCallbackOnOff) { |
| mCallbackOn = isChecked; |
| } |
| } |
| |
| private void displayVal(int viewId, int val) { |
| TextView textView = (TextView)findViewById(viewId); |
| String text = Integer.toString(val); |
| textView.setText(text); |
| } |
| |
| |
| private void getEffect(int session) { |
| synchronized (sInstances) { |
| if (sInstances.containsKey(session)) { |
| mVisualizer = sInstances.get(session); |
| } else { |
| try{ |
| mVisualizer = new Visualizer(session); |
| } catch (UnsupportedOperationException e) { |
| Log.e(TAG,"Visualizer library not loaded"); |
| throw (new RuntimeException("Cannot initialize effect")); |
| } catch (RuntimeException e) { |
| throw e; |
| } |
| sInstances.put(session, mVisualizer); |
| } |
| } |
| mReleaseButton.setEnabled(false); |
| mOnOffButton.setEnabled(false); |
| if (mVisualizer != null) { |
| mCaptureSize = mVisualizer.getCaptureSize(); |
| |
| mReleaseButton.setChecked(true); |
| mReleaseButton.setEnabled(true); |
| |
| mEnabled = mVisualizer.getEnabled(); |
| mOnOffButton.setChecked(mEnabled); |
| mOnOffButton.setEnabled(true); |
| |
| mCallbackButton.setEnabled(!mEnabled); |
| } |
| } |
| |
| private void putEffect(int session) { |
| mOnOffButton.setChecked(false); |
| mOnOffButton.setEnabled(false); |
| synchronized (sInstances) { |
| if (mVisualizer != null) { |
| mVisualizer.release(); |
| Log.d(TAG,"Visualizer released"); |
| mVisualizer = null; |
| sInstances.remove(session); |
| } |
| } |
| } |
| |
| } |