duckstation

duckstation, but archived from the revision just before upstream changed it to a proprietary software project, this version is the libre one
git clone https://git.neptards.moe/u3shit/duckstation.git
Log | Files | Refs | README | LICENSE

cubeb-jni.cpp (2703B)


      1 /* clang-format off */
      2 #include "jni.h"
      3 #include <assert.h>
      4 #include "cubeb-jni-instances.h"
      5 /* clang-format on */
      6 
      7 #define AUDIO_STREAM_TYPE_MUSIC 3
      8 
      9 struct cubeb_jni {
     10   jobject s_audio_manager_obj = nullptr;
     11   jclass s_audio_manager_class = nullptr;
     12   jmethodID s_get_output_latency_id = nullptr;
     13 };
     14 
     15 extern "C" cubeb_jni *
     16 cubeb_jni_init()
     17 {
     18   jobject ctx_obj = cubeb_jni_get_context_instance();
     19   JNIEnv * jni_env = cubeb_get_jni_env_for_thread();
     20   if (!jni_env || !ctx_obj) {
     21     return nullptr;
     22   }
     23 
     24   cubeb_jni * cubeb_jni_ptr = new cubeb_jni;
     25   assert(cubeb_jni_ptr);
     26 
     27   // Find the audio manager object and make it global to call it from another
     28   // method
     29   jclass context_class = jni_env->FindClass("android/content/Context");
     30   jfieldID audio_service_field = jni_env->GetStaticFieldID(
     31       context_class, "AUDIO_SERVICE", "Ljava/lang/String;");
     32   jstring jstr = (jstring)jni_env->GetStaticObjectField(context_class,
     33                                                         audio_service_field);
     34   jmethodID get_system_service_id =
     35       jni_env->GetMethodID(context_class, "getSystemService",
     36                            "(Ljava/lang/String;)Ljava/lang/Object;");
     37   jobject audio_manager_obj =
     38       jni_env->CallObjectMethod(ctx_obj, get_system_service_id, jstr);
     39   cubeb_jni_ptr->s_audio_manager_obj =
     40       reinterpret_cast<jobject>(jni_env->NewGlobalRef(audio_manager_obj));
     41 
     42   // Make the audio manager class a global reference in order to preserve method
     43   // id
     44   jclass audio_manager_class = jni_env->FindClass("android/media/AudioManager");
     45   cubeb_jni_ptr->s_audio_manager_class =
     46       reinterpret_cast<jclass>(jni_env->NewGlobalRef(audio_manager_class));
     47   cubeb_jni_ptr->s_get_output_latency_id =
     48       jni_env->GetMethodID(audio_manager_class, "getOutputLatency", "(I)I");
     49 
     50   jni_env->DeleteLocalRef(ctx_obj);
     51   jni_env->DeleteLocalRef(context_class);
     52   jni_env->DeleteLocalRef(jstr);
     53   jni_env->DeleteLocalRef(audio_manager_obj);
     54   jni_env->DeleteLocalRef(audio_manager_class);
     55 
     56   return cubeb_jni_ptr;
     57 }
     58 
     59 extern "C" int
     60 cubeb_get_output_latency_from_jni(cubeb_jni * cubeb_jni_ptr)
     61 {
     62   assert(cubeb_jni_ptr);
     63   JNIEnv * jni_env = cubeb_get_jni_env_for_thread();
     64   return jni_env->CallIntMethod(
     65       cubeb_jni_ptr->s_audio_manager_obj,
     66       cubeb_jni_ptr->s_get_output_latency_id,
     67       AUDIO_STREAM_TYPE_MUSIC); // param: AudioManager.STREAM_MUSIC
     68 }
     69 
     70 extern "C" void
     71 cubeb_jni_destroy(cubeb_jni * cubeb_jni_ptr)
     72 {
     73   assert(cubeb_jni_ptr);
     74 
     75   JNIEnv * jni_env = cubeb_get_jni_env_for_thread();
     76   assert(jni_env);
     77 
     78   jni_env->DeleteGlobalRef(cubeb_jni_ptr->s_audio_manager_obj);
     79   jni_env->DeleteGlobalRef(cubeb_jni_ptr->s_audio_manager_class);
     80 
     81   delete cubeb_jni_ptr;
     82 }