|
@@ -221,8 +221,18 @@ static JNINativeMethod SDLInputConnection_tab[] = {
|
|
|
JNIEXPORT void JNICALL SDL_JAVA_AUDIO_INTERFACE(nativeSetupJNI)(
|
|
|
JNIEnv *env, jclass jcls);
|
|
|
|
|
|
+JNIEXPORT void JNICALL
|
|
|
+SDL_JAVA_AUDIO_INTERFACE(addAudioDevice)(JNIEnv *env, jclass jcls, jboolean is_capture,
|
|
|
+ jint device_id);
|
|
|
+
|
|
|
+JNIEXPORT void JNICALL
|
|
|
+SDL_JAVA_AUDIO_INTERFACE(removeAudioDevice)(JNIEnv *env, jclass jcls, jboolean is_capture,
|
|
|
+ jint device_id);
|
|
|
+
|
|
|
static JNINativeMethod SDLAudioManager_tab[] = {
|
|
|
- { "nativeSetupJNI", "()I", SDL_JAVA_AUDIO_INTERFACE(nativeSetupJNI) }
|
|
|
+ { "nativeSetupJNI", "()I", SDL_JAVA_AUDIO_INTERFACE(nativeSetupJNI) },
|
|
|
+ { "addAudioDevice", "(ZI)V", SDL_JAVA_AUDIO_INTERFACE(addAudioDevice) },
|
|
|
+ { "removeAudioDevice", "(ZI)V", SDL_JAVA_AUDIO_INTERFACE(removeAudioDevice) }
|
|
|
};
|
|
|
|
|
|
/* Java class SDLControllerManager */
|
|
@@ -330,6 +340,8 @@ static jmethodID midSupportsRelativeMouse;
|
|
|
static jclass mAudioManagerClass;
|
|
|
|
|
|
/* method signatures */
|
|
|
+static jmethodID midGetAudioOutputDevices;
|
|
|
+static jmethodID midGetAudioInputDevices;
|
|
|
static jmethodID midAudioOpen;
|
|
|
static jmethodID midAudioWriteByteBuffer;
|
|
|
static jmethodID midAudioWriteShortBuffer;
|
|
@@ -655,8 +667,14 @@ JNIEXPORT void JNICALL SDL_JAVA_AUDIO_INTERFACE(nativeSetupJNI)(JNIEnv *env, jcl
|
|
|
|
|
|
mAudioManagerClass = (jclass)((*env)->NewGlobalRef(env, cls));
|
|
|
|
|
|
+ midGetAudioOutputDevices = (*env)->GetStaticMethodID(env, mAudioManagerClass,
|
|
|
+ "getAudioOutputDevices",
|
|
|
+ "()[I");
|
|
|
+ midGetAudioInputDevices = (*env)->GetStaticMethodID(env, mAudioManagerClass,
|
|
|
+ "getAudioInputDevices",
|
|
|
+ "()[I");
|
|
|
midAudioOpen = (*env)->GetStaticMethodID(env, mAudioManagerClass,
|
|
|
- "audioOpen", "(IIII)[I");
|
|
|
+ "audioOpen", "(IIIII)[I");
|
|
|
midAudioWriteByteBuffer = (*env)->GetStaticMethodID(env, mAudioManagerClass,
|
|
|
"audioWriteByteBuffer", "([B)V");
|
|
|
midAudioWriteShortBuffer = (*env)->GetStaticMethodID(env, mAudioManagerClass,
|
|
@@ -666,7 +684,7 @@ JNIEXPORT void JNICALL SDL_JAVA_AUDIO_INTERFACE(nativeSetupJNI)(JNIEnv *env, jcl
|
|
|
midAudioClose = (*env)->GetStaticMethodID(env, mAudioManagerClass,
|
|
|
"audioClose", "()V");
|
|
|
midCaptureOpen = (*env)->GetStaticMethodID(env, mAudioManagerClass,
|
|
|
- "captureOpen", "(IIII)[I");
|
|
|
+ "captureOpen", "(IIIII)[I");
|
|
|
midCaptureReadByteBuffer = (*env)->GetStaticMethodID(env, mAudioManagerClass,
|
|
|
"captureReadByteBuffer", "([BZ)I");
|
|
|
midCaptureReadShortBuffer = (*env)->GetStaticMethodID(env, mAudioManagerClass,
|
|
@@ -678,9 +696,13 @@ JNIEXPORT void JNICALL SDL_JAVA_AUDIO_INTERFACE(nativeSetupJNI)(JNIEnv *env, jcl
|
|
|
midAudioSetThreadPriority = (*env)->GetStaticMethodID(env, mAudioManagerClass,
|
|
|
"audioSetThreadPriority", "(ZI)V");
|
|
|
|
|
|
- if (!midAudioOpen || !midAudioWriteByteBuffer || !midAudioWriteShortBuffer || !midAudioWriteFloatBuffer || !midAudioClose ||
|
|
|
- !midCaptureOpen || !midCaptureReadByteBuffer || !midCaptureReadShortBuffer || !midCaptureReadFloatBuffer || !midCaptureClose || !midAudioSetThreadPriority) {
|
|
|
- __android_log_print(ANDROID_LOG_WARN, "SDL", "Missing some Java callbacks, do you have the latest version of SDLAudioManager.java?");
|
|
|
+ if (!midGetAudioOutputDevices || !midGetAudioInputDevices || !midAudioOpen ||
|
|
|
+ !midAudioWriteByteBuffer || !midAudioWriteShortBuffer || !midAudioWriteFloatBuffer ||
|
|
|
+ !midAudioClose ||
|
|
|
+ !midCaptureOpen || !midCaptureReadByteBuffer || !midCaptureReadShortBuffer ||
|
|
|
+ !midCaptureReadFloatBuffer || !midCaptureClose || !midAudioSetThreadPriority) {
|
|
|
+ __android_log_print(ANDROID_LOG_WARN, "SDL",
|
|
|
+ "Missing some Java callbacks, do you have the latest version of SDLAudioManager.java?");
|
|
|
}
|
|
|
|
|
|
checkJNIReady();
|
|
@@ -911,6 +933,26 @@ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativePermissionResult)(
|
|
|
SDL_AtomicSet(&bPermissionRequestPending, SDL_FALSE);
|
|
|
}
|
|
|
|
|
|
+extern void SDL_AddAudioDevice(const SDL_bool iscapture, const char *name, SDL_AudioSpec *spec, void *handle);
|
|
|
+extern void SDL_RemoveAudioDevice(const SDL_bool iscapture, void *handle);
|
|
|
+
|
|
|
+JNIEXPORT void JNICALL
|
|
|
+SDL_JAVA_AUDIO_INTERFACE(addAudioDevice)(JNIEnv *env, jclass jcls, jboolean is_capture,
|
|
|
+ jint device_id) {
|
|
|
+ int n = (int) (log10(device_id) + 1);
|
|
|
+ char device_name[n];
|
|
|
+ SDL_itoa(device_id, device_name, 10);
|
|
|
+ SDL_Log("Adding device with name %s, capture %d", device_name, is_capture);
|
|
|
+ SDL_AddAudioDevice(is_capture, SDL_strdup(device_name), NULL, (void *) ((size_t) device_id + 1));
|
|
|
+}
|
|
|
+
|
|
|
+JNIEXPORT void JNICALL
|
|
|
+SDL_JAVA_AUDIO_INTERFACE(removeAudioDevice)(JNIEnv *env, jclass jcls, jboolean is_capture,
|
|
|
+ jint device_id) {
|
|
|
+ SDL_Log("Removing device with handle %d, capture %d", device_id + 1, is_capture);
|
|
|
+ SDL_RemoveAudioDevice(is_capture, (void *) ((size_t) device_id + 1));
|
|
|
+}
|
|
|
+
|
|
|
/* Paddown */
|
|
|
JNIEXPORT jint JNICALL SDL_JAVA_CONTROLLER_INTERFACE(onNativePadDown)(
|
|
|
JNIEnv *env, jclass jcls,
|
|
@@ -1429,7 +1471,29 @@ static void *audioBufferPinned = NULL;
|
|
|
static int captureBufferFormat = 0;
|
|
|
static jobject captureBuffer = NULL;
|
|
|
|
|
|
-int Android_JNI_OpenAudioDevice(int iscapture, SDL_AudioSpec *spec)
|
|
|
+void Android_JNI_GetAudioOutputDevices(int *devices, int *length) {
|
|
|
+ JNIEnv *env = Android_JNI_GetEnv();
|
|
|
+ jintArray result;
|
|
|
+
|
|
|
+ result = (*env)->CallStaticObjectMethod(env, mAudioManagerClass, midGetAudioOutputDevices);
|
|
|
+
|
|
|
+ *length = (*env)->GetArrayLength(env, result);
|
|
|
+
|
|
|
+ (*env)->GetIntArrayRegion(env, result, 0, *length, devices);
|
|
|
+}
|
|
|
+
|
|
|
+void Android_JNI_GetAudioInputDevices(int * devices, int *length) {
|
|
|
+ JNIEnv *env = Android_JNI_GetEnv();
|
|
|
+ jintArray result;
|
|
|
+
|
|
|
+ result = (*env)->CallStaticObjectMethod(env, mAudioManagerClass, midGetAudioInputDevices);
|
|
|
+
|
|
|
+ *length = (*env)->GetArrayLength(env, result);
|
|
|
+
|
|
|
+ (*env)->GetIntArrayRegion(env, result, 0, *length, devices);
|
|
|
+}
|
|
|
+
|
|
|
+int Android_JNI_OpenAudioDevice(int iscapture, int device_id, SDL_AudioSpec *spec)
|
|
|
{
|
|
|
int audioformat;
|
|
|
jobject jbufobj = NULL;
|
|
@@ -1455,10 +1519,10 @@ int Android_JNI_OpenAudioDevice(int iscapture, SDL_AudioSpec *spec)
|
|
|
|
|
|
if (iscapture) {
|
|
|
__android_log_print(ANDROID_LOG_VERBOSE, "SDL", "SDL audio: opening device for capture");
|
|
|
- result = (*env)->CallStaticObjectMethod(env, mAudioManagerClass, midCaptureOpen, spec->freq, audioformat, spec->channels, spec->samples);
|
|
|
+ result = (*env)->CallStaticObjectMethod(env, mAudioManagerClass, midCaptureOpen, spec->freq, audioformat, spec->channels, spec->samples, device_id);
|
|
|
} else {
|
|
|
__android_log_print(ANDROID_LOG_VERBOSE, "SDL", "SDL audio: opening device for output");
|
|
|
- result = (*env)->CallStaticObjectMethod(env, mAudioManagerClass, midAudioOpen, spec->freq, audioformat, spec->channels, spec->samples);
|
|
|
+ result = (*env)->CallStaticObjectMethod(env, mAudioManagerClass, midAudioOpen, spec->freq, audioformat, spec->channels, spec->samples, device_id);
|
|
|
}
|
|
|
if (result == NULL) {
|
|
|
/* Error during audio initialization, error printed from Java */
|