-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
matthew-compton
committed
Jul 28, 2014
1 parent
f410a2d
commit 52a817e
Showing
14 changed files
with
269 additions
and
86 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
62 changes: 62 additions & 0 deletions
62
app/src/main/java/com/ambergleam/visualizer/AudioPlayer.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
package com.ambergleam.visualizer; | ||
|
||
import android.content.Context; | ||
import android.media.MediaPlayer; | ||
|
||
public class AudioPlayer extends MediaPlayer { | ||
|
||
private MediaPlayer mPlayer; | ||
|
||
public enum STATE { | ||
PLAYING, | ||
PAUSED, | ||
STOPPED | ||
} | ||
|
||
private int mLength; | ||
private STATE mState; | ||
|
||
public AudioPlayer() { | ||
mState = STATE.STOPPED; | ||
} | ||
|
||
public void play(Context c, int id) { | ||
stop(); | ||
|
||
mState = STATE.PLAYING; | ||
mPlayer = MediaPlayer.create(c, id); | ||
mPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() { | ||
@Override | ||
public void onCompletion(MediaPlayer mp) { | ||
stop(); | ||
} | ||
}); | ||
|
||
mPlayer.start(); | ||
} | ||
|
||
public void pause() { | ||
mState = STATE.PAUSED; | ||
mPlayer.pause(); | ||
mLength = mPlayer.getCurrentPosition(); | ||
} | ||
|
||
public void stop() { | ||
mState = STATE.STOPPED; | ||
if (mPlayer != null) { | ||
mPlayer.release(); | ||
mPlayer = null; | ||
} | ||
} | ||
|
||
public void resume() { | ||
mState = STATE.PLAYING; | ||
mPlayer.seekTo(mLength); | ||
mPlayer.start(); | ||
} | ||
|
||
public STATE getState() { | ||
return mState; | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -26,4 +26,4 @@ protected void onCreate(Bundle savedInstanceState) { | |
} | ||
} | ||
|
||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -9,4 +9,4 @@ protected Fragment createFragment() { | |
return new VisualizerFragment(); | ||
} | ||
|
||
} | ||
} |
109 changes: 81 additions & 28 deletions
109
app/src/main/java/com/ambergleam/visualizer/VisualizerFragment.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,60 +1,113 @@ | ||
package com.ambergleam.visualizer; | ||
|
||
import android.animation.AnimatorSet; | ||
import android.animation.ObjectAnimator; | ||
import android.annotation.TargetApi; | ||
import android.os.Build; | ||
import android.media.AudioManager; | ||
import android.media.audiofx.Visualizer; | ||
import android.os.Bundle; | ||
import android.support.v4.app.Fragment; | ||
import android.view.LayoutInflater; | ||
import android.view.View; | ||
import android.view.ViewGroup; | ||
import android.view.animation.AccelerateInterpolator; | ||
import android.widget.ImageButton; | ||
import android.widget.LinearLayout; | ||
|
||
import java.util.Random; | ||
import com.ambergleam.visualizer.AudioPlayer.STATE; | ||
|
||
public class VisualizerFragment extends Fragment { | ||
|
||
private static Random sRandom = new Random(); | ||
private AnimatorSet mAnimatorSet; | ||
private static final float VISUALIZER_HEIGHT_DIP = 50f; | ||
|
||
private View mOrbView; | ||
private int orb_x; | ||
private int orb_y; | ||
private AudioPlayer mAudioPlayer; | ||
private Visualizer mVisualizer; | ||
|
||
private LinearLayout mFrame; | ||
private VisualizerView mVisualizerView; | ||
private ImageButton mPlayButton; | ||
private ImageButton mPauseButton; | ||
|
||
@Override | ||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { | ||
View view = inflater.inflate(R.layout.fragment_sunset, container, false); | ||
View view = inflater.inflate(R.layout.fragment_visualizer, container, false); | ||
|
||
mOrbView = view.findViewById(R.id.orb); | ||
getActivity().setVolumeControlStream(AudioManager.STREAM_MUSIC); | ||
mAudioPlayer = new AudioPlayer(); | ||
|
||
view.setOnClickListener(new View.OnClickListener() { | ||
@TargetApi(Build.VERSION_CODES.KITKAT) | ||
mPlayButton = (ImageButton) view.findViewById(R.id.play); | ||
mPlayButton.setOnClickListener(new View.OnClickListener() { | ||
@Override | ||
public void onClick(View v) { | ||
startVisualizer(); | ||
if (mAudioPlayer.getState() == STATE.PAUSED) { | ||
mAudioPlayer.resume(); | ||
} else { | ||
mAudioPlayer.play(getActivity(), R.raw.test_audio); | ||
mVisualizer = new Visualizer(mAudioPlayer.getAudioSessionId()); | ||
mVisualizer.setCaptureSize(Visualizer.getCaptureSizeRange()[1]); | ||
mVisualizer.setDataCaptureListener(new Visualizer.OnDataCaptureListener() { | ||
|
||
public void onWaveFormDataCapture(Visualizer visualizer, byte[] bytes, int samplingRate) { | ||
mVisualizerView.updateVisualizer(bytes); | ||
} | ||
|
||
public void onFftDataCapture(Visualizer visualizer, byte[] bytes, int samplingRate) { | ||
} | ||
|
||
}, Visualizer.getMaxCaptureRate() / 2, true, false); | ||
} | ||
updateUI(); | ||
} | ||
}); | ||
|
||
orb_x = view.getWidth() / 2; | ||
orb_y = view.getHeight() / 2; | ||
mPauseButton = (ImageButton) view.findViewById(R.id.pause); | ||
mPauseButton.setOnClickListener(new View.OnClickListener() { | ||
@Override | ||
public void onClick(View v) { | ||
mAudioPlayer.pause(); | ||
updateUI(); | ||
} | ||
}); | ||
|
||
mOrbView.setX(orb_x); | ||
mOrbView.setX(orb_y); | ||
mFrame = (LinearLayout) view.findViewById(R.id.frame); | ||
mVisualizerView = new VisualizerView(getActivity()); | ||
mVisualizerView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, (int) (VISUALIZER_HEIGHT_DIP * getResources().getDisplayMetrics().density))); | ||
mFrame.addView(mVisualizerView); | ||
|
||
return view; | ||
} | ||
|
||
private void startVisualizer() { | ||
ObjectAnimator orbAnimatorX = ObjectAnimator.ofFloat(mOrbView, "x", orb_x, orb_x + sRandom.nextInt(400)).setDuration(1000); | ||
orbAnimatorX.setInterpolator(new AccelerateInterpolator()); | ||
@Override | ||
public void onResume() { | ||
super.onResume(); | ||
updateUI(); | ||
} | ||
|
||
ObjectAnimator orbAnimatorY = ObjectAnimator.ofFloat(mOrbView, "y", orb_y, orb_y + sRandom.nextInt(400)).setDuration(1000); | ||
orbAnimatorY.setInterpolator(new AccelerateInterpolator()); | ||
@Override | ||
public void onPause() { | ||
super.onPause(); | ||
if (mVisualizer != null) { | ||
mVisualizer.release(); | ||
} | ||
mAudioPlayer.stop(); | ||
} | ||
|
||
mAnimatorSet = new AnimatorSet(); | ||
mAnimatorSet.play(orbAnimatorX).with(orbAnimatorY); | ||
mAnimatorSet.start(); | ||
private void updateUI() { | ||
switch (mAudioPlayer.getState()) { | ||
case PAUSED: | ||
case STOPPED: | ||
if (mVisualizer != null) { | ||
mVisualizerView.setEnabled(false); | ||
} | ||
mPauseButton.setEnabled(false); | ||
mPlayButton.setEnabled(true); | ||
break; | ||
case PLAYING: | ||
if (mVisualizer != null) { | ||
mVisualizerView.setEnabled(true); | ||
} | ||
mPauseButton.setEnabled(true); | ||
mPlayButton.setEnabled(false); | ||
break; | ||
default: | ||
break; | ||
} | ||
} | ||
|
||
} |
77 changes: 77 additions & 0 deletions
77
app/src/main/java/com/ambergleam/visualizer/VisualizerView.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
package com.ambergleam.visualizer; | ||
|
||
import android.content.Context; | ||
import android.graphics.Canvas; | ||
import android.graphics.Color; | ||
import android.graphics.Paint; | ||
import android.graphics.Rect; | ||
import android.util.AttributeSet; | ||
import android.view.View; | ||
|
||
/** | ||
* A simple class that draws waveform data received from a | ||
* {@link android.media.audiofx.Visualizer.OnDataCaptureListener#onWaveFormDataCapture } | ||
*/ | ||
public class VisualizerView extends View { | ||
|
||
private byte[] mBytes; | ||
private float[] mPoints; | ||
private Rect mRect = new Rect(); | ||
|
||
private Paint mForePaint = new Paint(); | ||
|
||
public VisualizerView(Context context) { | ||
super(context); | ||
init(); | ||
} | ||
|
||
public VisualizerView(Context context, AttributeSet attrs) { | ||
super(context, attrs); | ||
init(); | ||
} | ||
|
||
public VisualizerView(Context context, AttributeSet attrs, int defStyle) { | ||
super(context, attrs, defStyle); | ||
init(); | ||
} | ||
|
||
private void init() { | ||
mBytes = null; | ||
|
||
mForePaint.setStrokeWidth(1f); | ||
mForePaint.setAntiAlias(true); | ||
mForePaint.setColor(Color.rgb(0, 128, 255)); | ||
} | ||
|
||
public void updateVisualizer(byte[] bytes) { | ||
mBytes = bytes; | ||
invalidate(); | ||
} | ||
|
||
@Override | ||
protected void onDraw(Canvas canvas) { | ||
super.onDraw(canvas); | ||
|
||
if (mBytes == null) { | ||
return; | ||
} | ||
|
||
if (mPoints == null || mPoints.length < mBytes.length * 4) { | ||
mPoints = new float[mBytes.length * 4]; | ||
} | ||
|
||
mRect.set(0, 0, getWidth(), getHeight()); | ||
|
||
for (int i = 0; i < mBytes.length - 1; i++) { | ||
mPoints[i * 4] = mRect.width() * i / (mBytes.length - 1); | ||
mPoints[i * 4 + 1] = mRect.height() / 2 | ||
+ ((byte) (mBytes[i] + 128)) * (mRect.height() / 2) / 128; | ||
mPoints[i * 4 + 2] = mRect.width() * (i + 1) / (mBytes.length - 1); | ||
mPoints[i * 4 + 3] = mRect.height() / 2 | ||
+ ((byte) (mBytes[i + 1] + 128)) * (mRect.height() / 2) / 128; | ||
} | ||
|
||
canvas.drawLines(mPoints, mForePaint); | ||
} | ||
|
||
} |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,8 @@ | ||
<?xml version="1.0" encoding="utf-8"?> | ||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" | ||
xmlns:tools="http://schemas.android.com/tools" | ||
android:id="@+id/fragmentContainer" | ||
android:layout_width="match_parent" | ||
android:layout_height="match_parent" > | ||
xmlns:tools="http://schemas.android.com/tools" | ||
android:id="@+id/fragmentContainer" | ||
android:layout_width="match_parent" | ||
android:layout_height="match_parent"> | ||
|
||
</FrameLayout> | ||
</FrameLayout> |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
<?xml version="1.0" encoding="utf-8"?> | ||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" | ||
android:id="@+id/frame" | ||
android:orientation="vertical" | ||
android:layout_width="match_parent" | ||
android:layout_height="match_parent" | ||
android:layout_margin="@dimen/activity_horizontal_margin"> | ||
|
||
<LinearLayout | ||
android:layout_width="match_parent" | ||
android:layout_height="wrap_content" | ||
android:layout_gravity="center|bottom"> | ||
|
||
<ImageButton | ||
android:id="@+id/play" | ||
android:layout_width="wrap_content" | ||
android:layout_height="wrap_content" | ||
android:layout_weight="1" | ||
android:src="@android:drawable/ic_media_play" | ||
/> | ||
|
||
<ImageButton | ||
android:id="@+id/pause" | ||
android:layout_width="wrap_content" | ||
android:layout_height="wrap_content" | ||
android:layout_weight="1" | ||
android:src="@android:drawable/ic_media_pause" | ||
/> | ||
|
||
</LinearLayout> | ||
|
||
</LinearLayout> |
Oops, something went wrong.