Files
ppsspp/android/src/com/henrikrydgard/libnative/NativeAudioPlayer.java
T

118 lines
3.1 KiB
Java

package com.henrikrydgard.libnative;
import android.media.AudioFormat;
import android.media.AudioManager;
import android.media.AudioTrack;
import android.util.Log;
import com.henrikrydgard.libnative.AudioFocusChangeListener;
public class NativeAudioPlayer {
private String TAG = "NativeAudioPlayer";
private Thread thread;
private boolean playing_;
// Calling stop() is allowed at any time, whether stopped or not.
// If playing, blocks until not.
public synchronized void stop() {
if (thread != null) {
waitUntilDone();
} else {
Log.e(TAG, "Was already stopped");
}
}
// If not playing, make sure we're playing.
public synchronized void play() {
if (thread == null) {
playStreaming();
} else {
Log.e(TAG, "Was already playing");
}
}
//keep this static so we can call this even if we don't
//instantiate NativeAudioPlayer
public static void gainAudioFocus(AudioManager audioManager, AudioFocusChangeListener focusChangeListener) {
if (audioManager != null) {
audioManager.requestAudioFocus(focusChangeListener,
AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN);
}
}
//keep this static so we can call this even if we don't
//instantiate NativeAudioPlayer
public static void loseAudioFocus(AudioManager audioManager,AudioFocusChangeListener focusChangeListener){
if (audioManager != null) {
audioManager.abandonAudioFocus(focusChangeListener);
}
}
private void playStreaming() {
playing_ = true;
thread = new Thread(new Runnable() {
public void run() {
playThread();
}
});
thread.setPriority(Thread.MAX_PRIORITY);
thread.start();
}
private void waitUntilDone() {
if (!playing_) {
Log.i(TAG, "not playing.");
}
try {
playing_ = false;
Log.e(TAG, "waitUntilDone: Joining audio thread.");
thread.join();
} catch (InterruptedException e) {
Log.e(TAG, "INterrupted!");
e.printStackTrace();
}
thread = null;
Log.i(TAG, "Finished waitUntilDone");
}
private void playThread() {
try {
Log.i(TAG, "Thread started.");
// Get the smallest possible buffer size (which is annoyingly huge).
int buffer_size_bytes = AudioTrack.getMinBufferSize(
44100,
AudioFormat.CHANNEL_OUT_STEREO,
AudioFormat.ENCODING_PCM_16BIT);
// Round buffer_size_bytes up to an even multiple of 128 for convenience.
buffer_size_bytes = (buffer_size_bytes + 127) & ~127;
AudioTrack audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC,
44100,
AudioFormat.CHANNEL_OUT_STEREO,
AudioFormat.ENCODING_PCM_16BIT,
buffer_size_bytes,
AudioTrack.MODE_STREAM);
int buffer_size = buffer_size_bytes / 2;
short [] buffer = new short[buffer_size];
audioTrack.play();
Log.i(TAG, "Playing... minBuffersize = " + buffer_size);
while (playing_) {
int validShorts = NativeApp.audioRender(buffer);
if (validShorts != 0) {
audioTrack.write(buffer, 0, validShorts);
}
Thread.yield();
}
audioTrack.stop();
audioTrack.release();
Log.i(TAG, "Stopped playing.");
} catch (Throwable t) {
Log.e(TAG, "Playback Failed");
t.printStackTrace();
Log.e(TAG, t.toString());
}
}
}