Mercurial > sdl-ios-xcode
diff android-project/src/org/libsdl/app/SDLActivity.java @ 4995:9f9bea41e88f
Working audio implementation contributed by Joseph Lunderville
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Thu, 13 Jan 2011 11:14:20 -0800 |
parents | 3c9058f3ffe7 |
children | 8d7315668e35 |
line wrap: on
line diff
--- a/android-project/src/org/libsdl/app/SDLActivity.java Thu Jan 13 09:15:51 2011 -0800 +++ b/android-project/src/org/libsdl/app/SDLActivity.java Thu Jan 13 11:14:20 2011 -0800 @@ -29,11 +29,15 @@ private static SDLSurface mSurface; // Audio + private static Thread mAudioThread; private static AudioTrack mAudioTrack; // Load the .so static { System.loadLibrary("SDL"); + //System.loadLibrary("SDL_image"); + //System.loadLibrary("SDL_mixer"); + //System.loadLibrary("SDL_ttf"); System.loadLibrary("main"); } @@ -67,12 +71,13 @@ // C functions we call public static native void nativeInit(); public static native void nativeQuit(); + public static native void onNativeResize(int x, int y, int format); public static native void onNativeKeyDown(int keycode); public static native void onNativeKeyUp(int keycode); public static native void onNativeTouch(int action, float x, float y, float p); - public static native void onNativeResize(int x, int y, int format); public static native void onNativeAccel(float x, float y, float z); + public static native void nativeRunAudioThread(); // Java functions called from C @@ -84,23 +89,83 @@ mSurface.flipEGL(); } - public static void updateAudio(byte [] buf) { + // Audio + private static Object buf; + + public static Object audioInit(int sampleRate, boolean is16Bit, boolean isStereo, int desiredFrames) { + int channelConfig = isStereo ? AudioFormat.CHANNEL_CONFIGURATION_STEREO : AudioFormat.CHANNEL_CONFIGURATION_MONO; + int audioFormat = is16Bit ? AudioFormat.ENCODING_PCM_16BIT : AudioFormat.ENCODING_PCM_8BIT; + int frameSize = (isStereo ? 2 : 1) * (is16Bit ? 2 : 1); + + Log.v("SDL", "SDL audio: wanted " + (isStereo ? "stereo" : "mono") + " " + (is16Bit ? "16-bit" : "8-bit") + " " + ((float)sampleRate / 1000f) + "kHz, " + desiredFrames + " frames buffer"); + + // Let the user pick a larger buffer if they really want -- but ye + // gods they probably shouldn't, the minimums are horrifyingly high + // latency already + desiredFrames = Math.max(desiredFrames, (AudioTrack.getMinBufferSize(sampleRate, channelConfig, audioFormat) + frameSize - 1) / frameSize); + + mAudioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, sampleRate, + channelConfig, audioFormat, desiredFrames * frameSize, AudioTrack.MODE_STREAM); + + audioStartThread(); + + Log.v("SDL", "SDL audio: got " + ((mAudioTrack.getChannelCount() >= 2) ? "stereo" : "mono") + " " + ((mAudioTrack.getAudioFormat() == AudioFormat.ENCODING_PCM_16BIT) ? "16-bit" : "8-bit") + " " + ((float)mAudioTrack.getSampleRate() / 1000f) + "kHz, " + desiredFrames + " frames buffer"); + + if (is16Bit) { + buf = new short[desiredFrames * (isStereo ? 2 : 1)]; + } else { + buf = new byte[desiredFrames * (isStereo ? 2 : 1)]; + } + return buf; + } - if(mAudioTrack == null) { - // Hardcoded things are bad. FIXME when we have more sound stuff - // working properly. - mAudioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, - 11025, - AudioFormat.CHANNEL_CONFIGURATION_MONO, - AudioFormat.ENCODING_PCM_8BIT, - 2048, - AudioTrack.MODE_STREAM); + public static void audioStartThread() { + mAudioThread = new Thread(new Runnable() { + public void run() { + mAudioTrack.play(); + nativeRunAudioThread(); + } + }); + + // I'd take REALTIME if I could get it! + mAudioThread.setPriority(Thread.MAX_PRIORITY); + mAudioThread.start(); + } + + public static void audioWriteShortBuffer(short[] buffer) { + for (int i = 0; i < buffer.length; ) { + int result = mAudioTrack.write(buffer, i, buffer.length - i); + if (result > 0) { + i += result; + } else if (result == 0) { + try { + Thread.sleep(10); + } catch(InterruptedException e) { + // Nom nom + } + } else { + Log.w("SDL", "SDL audio: error return from write(short)"); + return; + } } - - mAudioTrack.write(buf, 0, buf.length); - mAudioTrack.play(); - - Log.v("SDL", "Played some audio"); + } + + public static void audioWriteByteBuffer(byte[] buffer) { + for (int i = 0; i < buffer.length; ) { + int result = mAudioTrack.write(buffer, i, buffer.length - i); + if (result > 0) { + i += result; + } else if (result == 0) { + try { + Thread.sleep(10); + } catch(InterruptedException e) { + // Nom nom + } + } else { + Log.w("SDL", "SDL audio: error return from write(short)"); + return; + } + } } } @@ -279,7 +344,7 @@ } catch(Exception e) { Log.v("SDL", e + ""); - for(StackTraceElement s : e.getStackTrace()) { + for (StackTraceElement s : e.getStackTrace()) { Log.v("SDL", s.toString()); } } @@ -303,7 +368,7 @@ } catch(Exception e) { Log.v("SDL", "flipEGL(): " + e); - for(StackTraceElement s : e.getStackTrace()) { + for (StackTraceElement s : e.getStackTrace()) { Log.v("SDL", s.toString()); } }