// JNINativeMethod 是一个结构体
//typedef struct {
// const char* name; // 1. Java 中 native 方法的名字
// const char* signature; // 2. 方法的签名(参数类型和返回值类型)
// void* fnPtr; // 3. C++ 中对应实现函数的指针
//} JNINativeMethod;
// 例子
// 简单的
// {"native_start", "()V", (void *)android_media_AudioTrack_start},
// native_start:在AudioTrack.java中,你会看到 private native void native_start();
// ()V:()表示该方法没有参数。 V表示返回值是void
// android_media_AudioTrack_start:对应C++文件中名为这个的函数
// 复杂的
// {"native_setup", "(Ljava/lang/Object;Ljava/lang/Object;[IIIIII[IJZILjava/lang/Object;Ljava/lang/String;)I", (void *)android_media_AudioTrack_setup},
// 这是 AudioTrack 最核心的初始化方法。
// 签名解析:这一串乱码一样的 (Ljava/lang... 其实是类型缩写:
// Ljava/lang/Object;:传入一个对象
// [I:传入一个整数数组(int[])
// I: 传入一个整数(int)
// J: 传入一个长整型(long)。
// Z: 传入一个布尔值(boolean)。
// )I: 最后括号外的 I 表示返回一个整数(int)。
// 作用:当你 new AudioTrack(...) 时,Java 构造函数最终会调用这个 native_setup 来在 C++ 层创建真正的音频对象
// 数据写入
// {"native_write_byte", "([BIIIZ)I", (void *)android_media_AudioTrack_writeArray<jbyteArray>},
// [B: 表示 byte[] 数组。
// android_media_AudioTrack_writeArray<jbyteArray>: 这是一个 C++ 模板函数,用于处理不同类型(byte, short, float)的音频数据写入
static const JNINativeMethod gMethods[] = {
// name, signature, funcPtr
{"native_is_direct_output_supported", "(IIIIIII)Z",
(void *)android_media_AudioTrack_is_direct_output_supported},
{"native_start", "()V", (void *)android_media_AudioTrack_start},
{"native_stop", "()V", (void *)android_media_AudioTrack_stop},
{"native_pause", "()V", (void *)android_media_AudioTrack_pause},
{"native_flush", "()V", (void *)android_media_AudioTrack_flush},
{"native_setup",
"(Ljava/lang/Object;Ljava/lang/Object;[IIIIII[IJZILjava/lang/Object;Ljava/lang/String;)I",
(void *)android_media_AudioTrack_setup},
{"native_finalize", "()V", (void *)android_media_AudioTrack_finalize},
{"native_release", "()V", (void *)android_media_AudioTrack_release},
{"native_write_byte", "([BIIIZ)I", (void *)android_media_AudioTrack_writeArray<jbyteArray>},
{"native_write_native_bytes", "(Ljava/nio/ByteBuffer;IIIZ)I",
(void *)android_media_AudioTrack_write_native_bytes},
{"native_write_short", "([SIIIZ)I",
(void *)android_media_AudioTrack_writeArray<jshortArray>},
{"native_write_float", "([FIIIZ)I",
(void *)android_media_AudioTrack_writeArray<jfloatArray>},
{"native_setVolume", "(FF)V", (void *)android_media_AudioTrack_set_volume},
{"native_get_buffer_size_frames", "()I",
(void *)android_media_AudioTrack_get_buffer_size_frames},
{"native_set_buffer_size_frames", "(I)I",
(void *)android_media_AudioTrack_set_buffer_size_frames},
{"native_get_buffer_capacity_frames", "()I",
(void *)android_media_AudioTrack_get_buffer_capacity_frames},
{"native_set_playback_rate", "(I)I", (void *)android_media_AudioTrack_set_playback_rate},
{"native_get_playback_rate", "()I", (void *)android_media_AudioTrack_get_playback_rate},
{"native_set_playback_params", "(Landroid/media/PlaybackParams;)V",
(void *)android_media_AudioTrack_set_playback_params},
{"native_get_playback_params", "()Landroid/media/PlaybackParams;",
(void *)android_media_AudioTrack_get_playback_params},
{"native_set_marker_pos", "(I)I", (void *)android_media_AudioTrack_set_marker_pos},
{"native_get_marker_pos", "()I", (void *)android_media_AudioTrack_get_marker_pos},
{"native_set_pos_update_period", "(I)I",
(void *)android_media_AudioTrack_set_pos_update_period},
{"native_get_pos_update_period", "()I",
(void *)android_media_AudioTrack_get_pos_update_period},
{"native_set_position", "(I)I", (void *)android_media_AudioTrack_set_position},
{"native_get_position", "()I", (void *)android_media_AudioTrack_get_position},
{"native_get_latency", "()I", (void *)android_media_AudioTrack_get_latency},
{"native_get_underrun_count", "()I", (void *)android_media_AudioTrack_get_underrun_count},
{"native_get_flags", "()I", (void *)android_media_AudioTrack_get_flags},
{"native_get_timestamp", "([J)I", (void *)android_media_AudioTrack_get_timestamp},
{"native_getMetrics", "()Landroid/os/PersistableBundle;",
(void *)android_media_AudioTrack_native_getMetrics},
{"native_set_loop", "(III)I", (void *)android_media_AudioTrack_set_loop},
{"native_reload_static", "()I", (void *)android_media_AudioTrack_reload},
{"native_get_output_sample_rate", "(I)I",
(void *)android_media_AudioTrack_get_output_sample_rate},
{"native_get_min_buff_size", "(III)I", (void *)android_media_AudioTrack_get_min_buff_size},
{"native_setAuxEffectSendLevel", "(F)I",
(void *)android_media_AudioTrack_setAuxEffectSendLevel},
{"native_attachAuxEffect", "(I)I", (void *)android_media_AudioTrack_attachAuxEffect},
{"native_setOutputDevice", "(I)Z", (void *)android_media_AudioTrack_setOutputDevice},
{"native_getRoutedDeviceId", "()I", (void *)android_media_AudioTrack_getRoutedDeviceId},
{"native_enableDeviceCallback", "()V",
(void *)android_media_AudioTrack_enableDeviceCallback},
{"native_disableDeviceCallback", "()V",
(void *)android_media_AudioTrack_disableDeviceCallback},
{"native_applyVolumeShaper",
"(Landroid/media/VolumeShaper$Configuration;Landroid/media/VolumeShaper$Operation;)I",
(void *)android_media_AudioTrack_apply_volume_shaper},
{"native_getVolumeShaperState", "(I)Landroid/media/VolumeShaper$State;",
(void *)android_media_AudioTrack_get_volume_shaper_state},
{"native_setPresentation", "(II)I", (void *)android_media_AudioTrack_setPresentation},
{"native_getPortId", "()I", (void *)android_media_AudioTrack_get_port_id},
{"native_set_delay_padding", "(II)V", (void *)android_media_AudioTrack_set_delay_padding},
{"native_set_audio_description_mix_level_db", "(F)I",
(void *)android_media_AudioTrack_setAudioDescriptionMixLeveldB},
{"native_get_audio_description_mix_level_db", "([F)I",
(void *)android_media_AudioTrack_getAudioDescriptionMixLeveldB},
{"native_set_dual_mono_mode", "(I)I", (void *)android_media_AudioTrack_setDualMonoMode},
{"native_get_dual_mono_mode", "([I)I", (void *)android_media_AudioTrack_getDualMonoMode},
{"native_setLogSessionId", "(Ljava/lang/String;)V",
(void *)android_media_AudioTrack_setLogSessionId},
{"native_setPlayerIId", "(I)V", (void *)android_media_AudioTrack_setPlayerIId},
{"native_setStartThresholdInFrames", "(I)I",
(void *)android_media_AudioTrack_setStartThresholdInFrames},
{"native_getStartThresholdInFrames", "()I",
(void *)android_media_AudioTrack_getStartThresholdInFrames},
};