Audio系统的JNI代码

来源:互联网 发布:五大臣出洋考察 知乎 编辑:程序博客网 时间:2024/05/22 13:27

Android JNI代码
http://www.eoeandroid.com/forum-viewthread-tid-75140-fromuid-497034.html


       Audio系统的JNI代码

       Android的Audio部分通过JNI向Java层提供接口,在Java层可以通过JNI接口完成Audio系统的大部分操作。
Audio JNI部分的代码路径为:frameworks/base/core/jni。

       其中,主要实现的3个文件为:android_media_AudioSystem.cpp、android_media_Audio Track.cpp和

       android_media_AudioRecord.cpp,它们分别对应了Android Java框架中的3个类的支持:
       android.media.AudioSystem:负责Audio系统的总体控制;
       android.media.AudioTrack:负责Audio系统的输出环节;
       android.media.AudioRecorder:负责Audio系统的输入环节。

       在Android的Java层中,可以对Audio系统进行控制和数据流操作,对于控制操作,和底层的处理基本一致;但是对于数据流操作,由于Java不支持指针,因此接口被封装成了另外的形式。

       例如,对于音频输出,android_media_AudioTrack.cpp提供的是写字节和写短整型的接口类型。

Java代码:
  1. static jint android_media_AudioTrack_native_write(JNIEnv *env, jobject thiz, jbyteArray javaAudioData, jint offsetInBytes, jint sizeInBytes, jint javaAudioFormat) {
  2. jbyte* cAudioData = NULL;
  3. AudioTrack *lpTrack = NULL;
  4. lpTrack = (AudioTrack *)env->GetIntField( thiz, javaAudioTrackFields. Native TrackInJavaObj);
  5. // …… 省略部分内容
  6. ssize_t written = 0;
  7. if (lpTrack->sharedBuffer() == 0) {
  8. //进行写操作
  9. written = lpTrack->write(cAudioData +offsetInBytes, sizeInBytes);
  10. } else {
  11. if (javaAudioFormat == javaAudioTrackFields.PCM16) {
  12. memcpy(lpTrack->sharedBuffer()->pointer(), cAudioData+offsetInBytes, sizeInBytes);
  13. written = sizeInBytes;
  14. }
  15. else if (javaAudioFormat == javaAudioTrackFields.PCM8) {
  16. int count = sizeInBytes;
  17. int16_t *dst = (int16_t *)lpTrack->sharedBuffer()->pointer();
  18. const int8_t *src = (const int8_t *)(cAudioData + offsetInBytes);
  19. while(count--) {
  20. *dst++ = (int16_t)(*src++^0x80) << 8;
  21. }
  22. written = sizeInBytes;
  23. }
  24. }
  25. // …… 省略部分内容
  26. env->ReleasePrimitiveArrayCritical(javaAudioData, cAudioData, 0);
  27. return (int)written;
  28. }
复制代码

        所定义的JNI接口native_write_byte和native_write_short如下所示:

Java代码:
  1. {"native_write_byte", "([BIII]I", (void *)android_media_AudioTrack_native_write), {"native_write_short", "([SIII]I", (void *)android_media_AudioTrack_native_ write_short),
复制代码

       向Java提供native_write_byte和native_write_short接口,它们一般是通过调用AudioTrack的write()函数来完成的,只是在Java的数据类型和C++的指针中做了一步转换。