/* * 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 sInstances = new HashMap(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); } } } }