aboutsummaryrefslogtreecommitdiff
path: root/backends/platform/android/org/inodes/gus/scummvm
diff options
context:
space:
mode:
authordhewg2011-02-26 14:53:02 +0100
committerdhewg2011-02-27 09:04:36 +0100
commit25d895b859af0df8ea6daa85ba6ec5a0acb81f9d (patch)
tree3ef520562d76f45753c26c53a4995f42658c326d /backends/platform/android/org/inodes/gus/scummvm
parent983e16b36a68292021833aa9b69305a37ffe2f91 (diff)
downloadscummvm-rg350-25d895b859af0df8ea6daa85ba6ec5a0acb81f9d.tar.gz
scummvm-rg350-25d895b859af0df8ea6daa85ba6ec5a0acb81f9d.tar.bz2
scummvm-rg350-25d895b859af0df8ea6daa85ba6ec5a0acb81f9d.zip
ANDROID: Rework audio system
Move the audio thread to the bright side
Diffstat (limited to 'backends/platform/android/org/inodes/gus/scummvm')
-rw-r--r--backends/platform/android/org/inodes/gus/scummvm/ScummVM.java168
-rw-r--r--backends/platform/android/org/inodes/gus/scummvm/ScummVMActivity.java12
2 files changed, 50 insertions, 130 deletions
diff --git a/backends/platform/android/org/inodes/gus/scummvm/ScummVM.java b/backends/platform/android/org/inodes/gus/scummvm/ScummVM.java
index 698e508605..7a326454d9 100644
--- a/backends/platform/android/org/inodes/gus/scummvm/ScummVM.java
+++ b/backends/platform/android/org/inodes/gus/scummvm/ScummVM.java
@@ -35,19 +35,48 @@ import java.util.LinkedHashMap;
public class ScummVM implements SurfaceHolder.Callback {
protected final static String LOG_TAG = "ScummVM";
- // bytes. 16bit audio * stereo
- private final int AUDIO_FRAME_SIZE = 2 * 2;
- public static class AudioSetupException extends Exception {}
-
// native code hangs itself here
private long nativeScummVM;
boolean scummVMRunning = false;
- private native void create(AssetManager am);
+ private native void create(AssetManager am, AudioTrack audio_track,
+ int sample_rate, int buffer_size);
+
+ public ScummVM(Context context) throws Exception {
+ int sample_rate = AudioTrack.getNativeOutputSampleRate(
+ AudioManager.STREAM_MUSIC);
+ int buffer_size = AudioTrack.getMinBufferSize(sample_rate,
+ AudioFormat.CHANNEL_CONFIGURATION_STEREO,
+ AudioFormat.ENCODING_PCM_16BIT);
+
+ // ~100ms
+ int buffer_size_want = (sample_rate * 2 * 2 / 10) & ~1023;
+
+ if (buffer_size < buffer_size_want) {
+ Log.w(LOG_TAG, String.format(
+ "adjusting audio buffer size (was: %d)", buffer_size));
+
+ buffer_size = buffer_size_want;
+ }
+
+ Log.i(LOG_TAG, String.format("Using %d bytes buffer for %dHz audio",
+ buffer_size, sample_rate));
+
+ AudioTrack audio_track =
+ new AudioTrack(AudioManager.STREAM_MUSIC,
+ sample_rate,
+ AudioFormat.CHANNEL_CONFIGURATION_STEREO,
+ AudioFormat.ENCODING_PCM_16BIT,
+ buffer_size,
+ AudioTrack.MODE_STREAM);
+
+ if (audio_track.getState() != AudioTrack.STATE_INITIALIZED)
+ throw new Exception(
+ String.format("Error initialising AudioTrack: %d",
+ audio_track.getState()));
- public ScummVM(Context context) {
// Init C++ code, set nativeScummVM
- create(context.getAssets());
+ create(context.getAssets(), audio_track, sample_rate, buffer_size);
}
private native void nativeDestroy();
@@ -345,8 +374,6 @@ public class ScummVM implements SurfaceHolder.Callback {
// Feed an event to ScummVM. Safe to call from other threads.
final public native void pushEvent(Event e);
- final private native void audioMixCallback(byte[] buf);
-
// Runs the actual ScummVM program and returns when it does.
// This should not be called from multiple threads simultaneously...
final public native int scummVMMain(String[] argv);
@@ -359,131 +386,18 @@ public class ScummVM implements SurfaceHolder.Callback {
protected String[] getSysArchives() { return new String[0]; }
protected String[] getPluginDirectories() { return new String[0]; }
- protected void initBackend() throws AudioSetupException {
+ protected void initBackend() {
createScummVMGLContext();
- initAudio();
- }
-
- private static class AudioThread extends Thread {
- final private int buf_size;
- private boolean is_paused = false;
- final private ScummVM scummvm;
- final private AudioTrack audio_track;
-
- AudioThread(ScummVM scummvm, AudioTrack audio_track, int buf_size) {
- super("AudioThread");
- this.scummvm = scummvm;
- this.audio_track = audio_track;
- this.buf_size = buf_size;
- setPriority(Thread.MAX_PRIORITY);
- setDaemon(true);
- }
-
- public void pauseAudio() {
- synchronized (this) {
- is_paused = true;
- }
- audio_track.pause();
- }
-
- public void resumeAudio() {
- synchronized (this) {
- is_paused = false;
- notifyAll();
- }
- audio_track.play();
- }
-
- public void run() {
- byte[] buf = new byte[buf_size];
- audio_track.play();
- int offset = 0;
- try {
- while (true) {
- synchronized (this) {
- while (is_paused)
- wait();
- }
-
- if (offset == buf.length) {
- // Grab new audio data
- scummvm.audioMixCallback(buf);
- offset = 0;
- }
-
- int len = buf.length - offset;
- int ret = audio_track.write(buf, offset, len);
- if (ret < 0) {
- Log.w(LOG_TAG, String.format(
- "AudioTrack.write(%dB) returned error %d",
- buf.length, ret));
- break;
- } else if (ret != len) {
- Log.w(LOG_TAG, String.format(
- "Short audio write. Wrote %dB, not %dB",
- ret, buf.length));
-
- // Buffer is full, so yield cpu for a while
- Thread.sleep(100);
- }
- offset += ret;
- }
- } catch (InterruptedException e) {
- Log.e(LOG_TAG, "Audio thread interrupted", e);
- }
- }
- }
- private AudioThread audio_thread;
-
- final public int audioSampleRate() {
- return AudioTrack.getNativeOutputSampleRate(AudioManager.STREAM_MUSIC);
- }
-
- private void initAudio() throws AudioSetupException {
- int sample_rate = audioSampleRate();
- int buf_size =
- AudioTrack.getMinBufferSize(sample_rate,
- AudioFormat.CHANNEL_CONFIGURATION_STEREO,
- AudioFormat.ENCODING_PCM_16BIT);
- if (buf_size < 0) {
- // 10ms of audio
- int guess = AUDIO_FRAME_SIZE * sample_rate / 100;
-
- Log.w(LOG_TAG, String.format(
- "Unable to get min audio buffer size (error %d). Guessing %dB.",
- buf_size, guess));
-
- buf_size = guess;
- }
-
- Log.d(LOG_TAG, String.format("Using %dB buffer for %dHZ audio",
- buf_size, sample_rate));
-
- AudioTrack audio_track =
- new AudioTrack(AudioManager.STREAM_MUSIC,
- sample_rate,
- AudioFormat.CHANNEL_CONFIGURATION_STEREO,
- AudioFormat.ENCODING_PCM_16BIT,
- buf_size,
- AudioTrack.MODE_STREAM);
-
- if (audio_track.getState() != AudioTrack.STATE_INITIALIZED) {
- Log.e(LOG_TAG, "Error initialising Android audio system.");
- throw new AudioSetupException();
- }
-
- audio_thread = new AudioThread(this, audio_track, buf_size);
- audio_thread.start();
}
public void pause() {
- audio_thread.pauseAudio();
- // TODO: need to pause engine too
+ // TODO: need to pause audio
+ // TODO: need to pause engine
}
public void resume() {
- // TODO: need to resume engine too
- audio_thread.resumeAudio();
+ // TODO: need to resume audio
+ // TODO: need to resume engine
}
static {
diff --git a/backends/platform/android/org/inodes/gus/scummvm/ScummVMActivity.java b/backends/platform/android/org/inodes/gus/scummvm/ScummVMActivity.java
index 0dd110942b..fb6020cf1c 100644
--- a/backends/platform/android/org/inodes/gus/scummvm/ScummVMActivity.java
+++ b/backends/platform/android/org/inodes/gus/scummvm/ScummVMActivity.java
@@ -49,7 +49,7 @@ public class ScummVMActivity extends Activity {
}
}
- public MyScummVM() {
+ public MyScummVM() throws Exception {
super(ScummVMActivity.this);
// Enable ScummVM zoning on 'small' screens.
@@ -59,7 +59,7 @@ public class ScummVMActivity extends Activity {
}
@Override
- protected void initBackend() throws ScummVM.AudioSetupException {
+ protected void initBackend() {
synchronized (this) {
scummvmRunning = true;
notifyAll();
@@ -153,7 +153,13 @@ public class ScummVMActivity extends Activity {
main_surface.requestFocus();
// Start ScummVM
- scummvm = new MyScummVM();
+ try {
+ scummvm = new MyScummVM();
+ } catch (Exception e) {
+ Log.e(ScummVM.LOG_TAG, "Fatal error", e);
+ finish();
+ return;
+ }
scummvm_thread = new Thread(new Runnable() {
public void run() {