Working audio implementation contributed by Joseph Lunderville
This commit is contained in:
parent
a409f9858f
commit
4f9db82a4c
5 changed files with 291 additions and 148 deletions
|
@ -29,11 +29,15 @@ public class SDLActivity extends Activity {
|
|||
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 @@ public class SDLActivity extends Activity {
|
|||
// 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 @@ public class SDLActivity extends Activity {
|
|||
mSurface.flipEGL();
|
||||
}
|
||||
|
||||
public static void updateAudio(byte [] buf) {
|
||||
// Audio
|
||||
private static Object 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 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;
|
||||
}
|
||||
|
||||
mAudioTrack.write(buf, 0, buf.length);
|
||||
public static void audioStartThread() {
|
||||
mAudioThread = new Thread(new Runnable() {
|
||||
public void run() {
|
||||
mAudioTrack.play();
|
||||
nativeRunAudioThread();
|
||||
}
|
||||
});
|
||||
|
||||
Log.v("SDL", "Played some audio");
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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 @@ class SDLSurface extends SurfaceView implements SurfaceHolder.Callback,
|
|||
|
||||
} 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 @@ class SDLSurface extends SurfaceView implements SurfaceHolder.Callback,
|
|||
|
||||
} catch(Exception e) {
|
||||
Log.v("SDL", "flipEGL(): " + e);
|
||||
for(StackTraceElement s : e.getStackTrace()) {
|
||||
for (StackTraceElement s : e.getStackTrace()) {
|
||||
Log.v("SDL", s.toString());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,7 +27,10 @@ extern "C" {
|
|||
#include "events/SDL_events_c.h"
|
||||
#include "video/android/SDL_androidkeyboard.h"
|
||||
#include "video/android/SDL_androidvideo.h"
|
||||
}
|
||||
|
||||
/* Impelemented in audio/android/SDL_androidaudio.c */
|
||||
extern void Android_RunAudioThread();
|
||||
} // C
|
||||
|
||||
/*******************************************************************************
|
||||
This file links the Java side of Android with libsdl
|
||||
|
@ -39,23 +42,21 @@ extern "C" {
|
|||
/*******************************************************************************
|
||||
Globals
|
||||
*******************************************************************************/
|
||||
JavaVM* mVM = NULL;
|
||||
JNIEnv* mEnv = NULL;
|
||||
JNIEnv* mAudioThreadEnv = NULL; //See the note below for why this is necessary
|
||||
static JavaVM* mVM = NULL;
|
||||
static JNIEnv* mEnv = NULL;
|
||||
static JNIEnv* mAudioEnv = NULL;
|
||||
|
||||
//Main activity
|
||||
jclass mActivityInstance;
|
||||
// Main activity
|
||||
static jclass mActivityInstance;
|
||||
|
||||
//method signatures
|
||||
jmethodID midCreateGLContext;
|
||||
jmethodID midFlipBuffers;
|
||||
jmethodID midUpdateAudio;
|
||||
// method signatures
|
||||
static jmethodID midCreateGLContext;
|
||||
static jmethodID midFlipBuffers;
|
||||
static jmethodID midAudioInit;
|
||||
static jmethodID midAudioWriteShortBuffer;
|
||||
static jmethodID midAudioWriteByteBuffer;
|
||||
|
||||
//Feature IDs
|
||||
static const int FEATURE_AUDIO = 1;
|
||||
static const int FEATURE_ACCEL = 2;
|
||||
|
||||
//Accelerometer data storage
|
||||
// Accelerometer data storage
|
||||
float fLastAccelerometer[3];
|
||||
|
||||
|
||||
|
@ -82,42 +83,42 @@ extern "C" void SDL_Android_Init(JNIEnv* env)
|
|||
mActivityInstance = cls;
|
||||
midCreateGLContext = mEnv->GetStaticMethodID(cls,"createGLContext","()V");
|
||||
midFlipBuffers = mEnv->GetStaticMethodID(cls,"flipBuffers","()V");
|
||||
midUpdateAudio = mEnv->GetStaticMethodID(cls,"updateAudio","([B)V");
|
||||
midAudioInit = mEnv->GetStaticMethodID(cls, "audioInit", "(IZZI)Ljava/lang/Object;");
|
||||
midAudioWriteShortBuffer = mEnv->GetStaticMethodID(cls, "audioWriteShortBuffer", "([S)V");
|
||||
midAudioWriteByteBuffer = mEnv->GetStaticMethodID(cls, "audioWriteByteBuffer", "([B)V");
|
||||
|
||||
if(!midCreateGLContext || !midFlipBuffers || !midUpdateAudio) {
|
||||
__android_log_print(ANDROID_LOG_INFO, "SDL", "SDL: Bad mids\n");
|
||||
} else {
|
||||
#ifdef DEBUG
|
||||
__android_log_print(ANDROID_LOG_INFO, "SDL", "SDL: Good mids\n");
|
||||
#endif
|
||||
if(!midCreateGLContext || !midFlipBuffers || !midAudioInit ||
|
||||
!midAudioWriteShortBuffer || !midAudioWriteByteBuffer) {
|
||||
__android_log_print(ANDROID_LOG_WARN, "SDL", "SDL: Couldn't locate Java callbacks, check that they're named and typed correctly");
|
||||
}
|
||||
}
|
||||
|
||||
// Keydown
|
||||
extern "C" void Java_org_libsdl_app_SDLActivity_onNativeKeyDown(JNIEnv* env,
|
||||
jobject obj, jint keycode)
|
||||
// Resize
|
||||
extern "C" void Java_org_libsdl_app_SDLActivity_onNativeResize(
|
||||
JNIEnv* env, jobject obj,
|
||||
jint width, jint height, jint format)
|
||||
{
|
||||
Android_SetScreenResolution(width, height, format);
|
||||
}
|
||||
|
||||
// Keydown
|
||||
extern "C" void Java_org_libsdl_app_SDLActivity_onNativeKeyDown(
|
||||
JNIEnv* env, jobject obj, jint keycode)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
__android_log_print(ANDROID_LOG_INFO, "SDL",
|
||||
"SDL: native key down %d\n", keycode);
|
||||
#endif
|
||||
Android_OnKeyDown(keycode);
|
||||
}
|
||||
|
||||
// Keyup
|
||||
extern "C" void Java_org_libsdl_app_SDLActivity_onNativeKeyUp(JNIEnv* env,
|
||||
jobject obj, jint keycode)
|
||||
extern "C" void Java_org_libsdl_app_SDLActivity_onNativeKeyUp(
|
||||
JNIEnv* env, jobject obj, jint keycode)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
__android_log_print(ANDROID_LOG_INFO, "SDL",
|
||||
"SDL: native key up %d\n", keycode);
|
||||
#endif
|
||||
Android_OnKeyUp(keycode);
|
||||
}
|
||||
|
||||
// Touch
|
||||
extern "C" void Java_org_libsdl_app_SDLActivity_onNativeTouch(JNIEnv* env,
|
||||
jobject obj, jint action, jfloat x, jfloat y, jfloat p)
|
||||
extern "C" void Java_org_libsdl_app_SDLActivity_onNativeTouch(
|
||||
JNIEnv* env, jobject obj,
|
||||
jint action, jfloat x, jfloat y, jfloat p)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
__android_log_print(ANDROID_LOG_INFO, "SDL",
|
||||
|
@ -128,22 +129,7 @@ extern "C" void Java_org_libsdl_app_SDLActivity_onNativeTouch(JNIEnv* env,
|
|||
//TODO: Pass this off to the SDL multitouch stuff
|
||||
}
|
||||
|
||||
// Quit
|
||||
extern "C" void Java_org_libsdl_app_SDLActivity_nativeQuit( JNIEnv* env,
|
||||
jobject obj )
|
||||
{
|
||||
// Inject a SDL_QUIT event
|
||||
SDL_SendQuit();
|
||||
}
|
||||
|
||||
// Resize
|
||||
extern "C" void Java_org_libsdl_app_SDLActivity_onNativeResize(
|
||||
JNIEnv* env, jobject obj, jint width,
|
||||
jint height, jint format)
|
||||
{
|
||||
Android_SetScreenResolution(width, height, format);
|
||||
}
|
||||
|
||||
// Accelerometer
|
||||
extern "C" void Java_org_libsdl_app_SDLActivity_onNativeAccel(
|
||||
JNIEnv* env, jobject obj,
|
||||
jfloat x, jfloat y, jfloat z)
|
||||
|
@ -153,6 +139,20 @@ extern "C" void Java_org_libsdl_app_SDLActivity_onNativeAccel(
|
|||
fLastAccelerometer[2] = z;
|
||||
}
|
||||
|
||||
// Quit
|
||||
extern "C" void Java_org_libsdl_app_SDLActivity_nativeQuit(
|
||||
JNIEnv* env, jobject obj)
|
||||
{
|
||||
// Inject a SDL_QUIT event
|
||||
SDL_SendQuit();
|
||||
}
|
||||
|
||||
extern "C" void Java_org_libsdl_app_SDLActivity_nativeRunAudioThread(
|
||||
JNIEnv* env)
|
||||
{
|
||||
mVM->AttachCurrentThread(&mAudioEnv, NULL);
|
||||
Android_RunAudioThread();
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
|
@ -168,33 +168,81 @@ extern "C" void Android_JNI_SwapWindow()
|
|||
mEnv->CallStaticVoidMethod(mActivityInstance, midFlipBuffers);
|
||||
}
|
||||
|
||||
extern "C" void Android_JNI_UpdateAudioBuffer(unsigned char *buf, int len)
|
||||
//
|
||||
// Audio support
|
||||
//
|
||||
static jint audioBufferFrames = 0;
|
||||
static bool audioBuffer16Bit = false;
|
||||
static bool audioBufferStereo = false;
|
||||
|
||||
static jobject audioBuffer;
|
||||
static void * audioPinnedBuffer;
|
||||
|
||||
extern "C" int Android_JNI_OpenAudioDevice(int sampleRate, int is16Bit, int channelCount, int desiredBufferFrames)
|
||||
{
|
||||
//Annoyingly we can't just call into Java from any thread. Because the audio
|
||||
//callback is dispatched from the SDL audio thread (that wasn't made from
|
||||
//java, we have to do some magic here to let the JVM know about the thread.
|
||||
//Because everything it touches on the Java side is static anyway, it's
|
||||
//not a big deal, just annoying.
|
||||
if(!mAudioThreadEnv) {
|
||||
__android_log_print(ANDROID_LOG_INFO, "SDL", "SDL: Need to set up audio thread env\n");
|
||||
__android_log_print(ANDROID_LOG_VERBOSE, "SDL", "SDL audio: opening device");
|
||||
audioBuffer16Bit = is16Bit;
|
||||
audioBufferStereo = channelCount > 1;
|
||||
|
||||
mVM->AttachCurrentThread(&mAudioThreadEnv, NULL);
|
||||
audioBuffer = mEnv->CallStaticObjectMethod(mActivityInstance, midAudioInit, sampleRate, audioBuffer16Bit, audioBufferStereo, desiredBufferFrames);
|
||||
audioBuffer = mEnv->NewGlobalRef(audioBuffer);
|
||||
|
||||
__android_log_print(ANDROID_LOG_INFO, "SDL", "SDL: ok\n");
|
||||
if (audioBuffer == NULL) {
|
||||
__android_log_print(ANDROID_LOG_WARN, "SDL", "SDL audio: didn't get back a good audio buffer!");
|
||||
return 0;
|
||||
}
|
||||
|
||||
jbyteArray arr = mAudioThreadEnv->NewByteArray(len);
|
||||
if (audioBufferStereo) {
|
||||
audioBufferFrames = mEnv->GetArrayLength((jshortArray)audioBuffer) / 2;
|
||||
} else {
|
||||
audioBufferFrames = mEnv->GetArrayLength((jbyteArray)audioBuffer);
|
||||
}
|
||||
|
||||
//blah. We probably should rework this so we avoid the copy.
|
||||
mAudioThreadEnv->SetByteArrayRegion(arr, 0, len, (jbyte *)buf);
|
||||
return audioBufferFrames;
|
||||
}
|
||||
|
||||
__android_log_print(ANDROID_LOG_INFO, "SDL", "SDL: copied\n");
|
||||
extern "C" void * Android_JNI_PinAudioBuffer()
|
||||
{
|
||||
jboolean isCopy = JNI_FALSE;
|
||||
|
||||
mAudioThreadEnv->CallStaticVoidMethod( mActivityInstance,
|
||||
midUpdateAudio, arr );
|
||||
if (audioPinnedBuffer != NULL) {
|
||||
return audioPinnedBuffer;
|
||||
}
|
||||
|
||||
__android_log_print(ANDROID_LOG_INFO, "SDL", "SDL: invoked\n");
|
||||
if (audioBuffer16Bit) {
|
||||
audioPinnedBuffer = mAudioEnv->GetShortArrayElements((jshortArray)audioBuffer, &isCopy);
|
||||
} else {
|
||||
audioPinnedBuffer = mAudioEnv->GetByteArrayElements((jbyteArray)audioBuffer, &isCopy);
|
||||
}
|
||||
|
||||
return audioPinnedBuffer;
|
||||
}
|
||||
|
||||
extern "C" void Android_JNI_WriteAudioBufferAndUnpin()
|
||||
{
|
||||
if (audioPinnedBuffer == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (audioBuffer16Bit) {
|
||||
mAudioEnv->ReleaseShortArrayElements((jshortArray)audioBuffer, (jshort *)audioPinnedBuffer, JNI_COMMIT);
|
||||
mAudioEnv->CallStaticVoidMethod(mActivityInstance, midAudioWriteShortBuffer, (jshortArray)audioBuffer);
|
||||
} else {
|
||||
mAudioEnv->ReleaseByteArrayElements((jbyteArray)audioBuffer, (jbyte *)audioPinnedBuffer, JNI_COMMIT);
|
||||
mAudioEnv->CallStaticVoidMethod(mActivityInstance, midAudioWriteByteBuffer, (jbyteArray)audioBuffer);
|
||||
}
|
||||
|
||||
audioPinnedBuffer = NULL;
|
||||
}
|
||||
|
||||
extern "C" void Android_JNI_CloseAudioDevice()
|
||||
{
|
||||
if (audioBuffer) {
|
||||
mEnv->DeleteGlobalRef(audioBuffer);
|
||||
audioBuffer = NULL;
|
||||
}
|
||||
|
||||
// TODO: Implement
|
||||
}
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
|
|
|
@ -31,7 +31,12 @@ extern "C" {
|
|||
/* Interface from the SDL library into the Android Java activity */
|
||||
void Android_JNI_CreateContext();
|
||||
void Android_JNI_SwapWindow();
|
||||
void Android_JNI_UpdateAudioBuffer(unsigned char *buf, int len);
|
||||
|
||||
// Audio support
|
||||
int Android_JNI_OpenAudioDevice(int sampleRate, int is16Bit, int channelCount, int desiredBufferFrames);
|
||||
void* Android_JNI_PinAudioBuffer();
|
||||
void Android_JNI_WriteAudioBufferAndUnpin();
|
||||
void Android_JNI_CloseAudioDevice();
|
||||
|
||||
/* Ends C function definitions when using C++ */
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -18,8 +18,6 @@
|
|||
|
||||
Sam Lantinga
|
||||
slouken@libsdl.org
|
||||
|
||||
This file written by Ryan C. Gordon (icculus@icculus.org)
|
||||
*/
|
||||
#include "SDL_config.h"
|
||||
|
||||
|
@ -28,18 +26,31 @@
|
|||
#include "SDL_audio.h"
|
||||
#include "../SDL_audio_c.h"
|
||||
#include "SDL_androidaudio.h"
|
||||
|
||||
#include "../../SDL_android.h"
|
||||
|
||||
#include <android/log.h>
|
||||
|
||||
static void * audioDevice;
|
||||
|
||||
static int
|
||||
AndroidAUD_OpenDevice(_THIS, const char *devname, int iscapture)
|
||||
{
|
||||
SDL_AudioFormat test_format = SDL_FirstAudioFormat(this->spec.format);
|
||||
SDL_AudioFormat test_format;
|
||||
int valid_datatype = 0;
|
||||
|
||||
//TODO: Sample rates etc
|
||||
__android_log_print(ANDROID_LOG_INFO, "SDL", "AndroidAudio Open\n");
|
||||
if (iscapture) {
|
||||
//TODO: implement capture
|
||||
SDL_SetError("Capture not supported on Android");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (audioDevice != NULL) {
|
||||
SDL_SetError("Only one audio device at a time please!");
|
||||
return 0;
|
||||
}
|
||||
|
||||
audioDevice = this;
|
||||
|
||||
this->hidden = SDL_malloc(sizeof(*(this->hidden)));
|
||||
if (!this->hidden) {
|
||||
|
@ -48,17 +59,42 @@ AndroidAUD_OpenDevice(_THIS, const char *devname, int iscapture)
|
|||
}
|
||||
SDL_memset(this->hidden, 0, (sizeof *this->hidden));
|
||||
|
||||
while ((!valid_datatype) && (test_format)) {
|
||||
test_format = SDL_FirstAudioFormat(this->spec.format);
|
||||
while (test_format != 0) { // no "UNKNOWN" constant
|
||||
if ((test_format == AUDIO_U8) || (test_format == AUDIO_S16LSB)) {
|
||||
this->spec.format = test_format;
|
||||
switch (test_format) {
|
||||
case AUDIO_S8:
|
||||
/*case AUDIO_S16LSB: */
|
||||
valid_datatype = 1;
|
||||
break;
|
||||
default:
|
||||
test_format = SDL_NextAudioFormat();
|
||||
break;
|
||||
}
|
||||
test_format = SDL_NextAudioFormat();
|
||||
}
|
||||
|
||||
if (test_format == 0) {
|
||||
// Didn't find a compatible format :(
|
||||
SDL_SetError("No compatible audio format!");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (this->spec.channels > 1) {
|
||||
this->spec.channels = 2;
|
||||
} else {
|
||||
this->spec.channels = 1;
|
||||
}
|
||||
|
||||
if (this->spec.freq < 8000) {
|
||||
this->spec.freq = 8000;
|
||||
}
|
||||
if (this->spec.freq > 48000) {
|
||||
this->spec.freq = 48000;
|
||||
}
|
||||
|
||||
// TODO: pass in/return a (Java) device ID, also whether we're opening for input or output
|
||||
this->spec.samples = Android_JNI_OpenAudioDevice(this->spec.freq, this->spec.format == AUDIO_U8 ? 0 : 1, this->spec.channels, this->spec.samples);
|
||||
SDL_CalculateAudioSpec(&this->spec);
|
||||
|
||||
if (this->spec.samples == 0) {
|
||||
// Init failed?
|
||||
SDL_SetError("Java-side initialization failed!");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
@ -67,49 +103,34 @@ AndroidAUD_OpenDevice(_THIS, const char *devname, int iscapture)
|
|||
static void
|
||||
AndroidAUD_PlayDevice(_THIS)
|
||||
{
|
||||
__android_log_print(ANDROID_LOG_INFO, "SDL", "AndroidAudio Play\n");
|
||||
|
||||
|
||||
//playGenericSound(this->hidden->mixbuf, this->hidden->mixlen);
|
||||
|
||||
#if 0
|
||||
|
||||
// sound->rate = 22050; /* sample rate = 22050Hz */
|
||||
// sound->vol = 127; /* volume [0..127] for [min..max] */
|
||||
// sound->pan = 64; /* balance [0..127] for [left..right] */
|
||||
// sound->format = 0; /* 0 for 16-bit, 1 for 8-bit */
|
||||
// playSound(sound);
|
||||
#endif
|
||||
Android_JNI_WriteAudioBufferAndUnpin();
|
||||
this->hidden->mixbuf = NULL;
|
||||
}
|
||||
|
||||
|
||||
static Uint8 *
|
||||
AndroidAUD_GetDeviceBuf(_THIS)
|
||||
{
|
||||
//__android_log_print(ANDROID_LOG_INFO, "SDL", "****** get device buf\n");
|
||||
|
||||
|
||||
// sound->data = this->hidden->mixbuf;/* pointer to raw audio data */
|
||||
// sound->len = this->hidden->mixlen; /* size of raw data pointed to above */
|
||||
|
||||
|
||||
Android_JNI_UpdateAudioBuffer(this->hidden->mixbuf, this->hidden->mixlen);
|
||||
|
||||
return this->hidden->mixbuf; /* is this right? */
|
||||
}
|
||||
|
||||
static void
|
||||
AndroidAUD_WaitDevice(_THIS)
|
||||
{
|
||||
/* stub */
|
||||
__android_log_print(ANDROID_LOG_INFO, "SDL", "****** wait device buf\n");
|
||||
if (this->hidden->mixbuf == NULL) {
|
||||
this->hidden->mixbuf = Android_JNI_PinAudioBuffer();
|
||||
}
|
||||
return this->hidden->mixbuf;
|
||||
}
|
||||
|
||||
static void
|
||||
AndroidAUD_CloseDevice(_THIS)
|
||||
{
|
||||
/* stub */
|
||||
__android_log_print(ANDROID_LOG_INFO, "SDL", "****** close device buf\n");
|
||||
if (this->hidden != NULL) {
|
||||
if (this->hidden->mixbuf != NULL) {
|
||||
Android_JNI_WriteAudioBufferAndUnpin();
|
||||
}
|
||||
SDL_free(this->hidden);
|
||||
this->hidden = NULL;
|
||||
}
|
||||
Android_JNI_CloseAudioDevice();
|
||||
|
||||
if (audioDevice == this) {
|
||||
audioDevice = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -118,17 +139,15 @@ AndroidAUD_Init(SDL_AudioDriverImpl * impl)
|
|||
/* Set the function pointers */
|
||||
impl->OpenDevice = AndroidAUD_OpenDevice;
|
||||
impl->PlayDevice = AndroidAUD_PlayDevice;
|
||||
impl->WaitDevice = AndroidAUD_WaitDevice;
|
||||
impl->GetDeviceBuf = AndroidAUD_GetDeviceBuf;
|
||||
impl->CloseDevice = AndroidAUD_CloseDevice;
|
||||
|
||||
/* and the capabilities */
|
||||
impl->ProvidesOwnCallbackThread = 1;
|
||||
impl->HasCaptureSupport = 0; //TODO
|
||||
impl->OnlyHasDefaultOutputDevice = 1;
|
||||
impl->OnlyHasDefaultInputDevice = 1;
|
||||
|
||||
__android_log_print(ANDROID_LOG_INFO, "SDL","Audio init\n");
|
||||
|
||||
return 1; /* this audio target is available. */
|
||||
}
|
||||
|
||||
|
@ -136,4 +155,11 @@ AudioBootStrap ANDROIDAUD_bootstrap = {
|
|||
"android", "SDL Android audio driver", AndroidAUD_Init, 0 /*1? */
|
||||
};
|
||||
|
||||
/* Called by the Java code to start the audio processing on a thread */
|
||||
void
|
||||
Android_RunAudioThread()
|
||||
{
|
||||
SDL_RunAudio(audioDevice);
|
||||
}
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
|
|
|
@ -34,9 +34,8 @@ struct SDL_PrivateAudioData
|
|||
/* The file descriptor for the audio device */
|
||||
Uint8 *mixbuf;
|
||||
Uint32 mixlen;
|
||||
Uint32 write_delay;
|
||||
Uint32 initial_calls;
|
||||
};
|
||||
|
||||
#endif /* _SDL_androidaudio_h */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue