java amr wav_AMR编解码库的实现

基于opencore-amr实现amr-nb编码和解码,在Android上完成wav文件与amr文件格式的相互转换。wav和amr文件读写部分主要参考了opencore中的test文件夹下的例子,以及IOS音频格式之AMR和WAV互转(更新支持amrv7s)。1、opencore-amr的下载和编译编译之后我们可以得到interf_enc.h、interf_dec.h、wrapper.cpp这...
摘要由CSDN通过智能技术生成

基于opencore-amr实现amr-nb编码和解码,在Android上完成wav文件与amr文件格式的相互转换。wav和amr文件读写部分主要参考了opencore中的test文件夹下的例子,以及  IOS音频格式之AMR和WAV互转(更新支持amrv7s)。

1、opencore-amr的下载和编译

编译之后我们可以得到interf_enc.h、interf_dec.h、wrapper.cpp这些与接口有关的文件,通过这些文件相对容易写出JNI接口函数。

在linux下的编译可以得到so文件,但是是基于X86的,想要得到Arm 架构下的 so文件,需要用到ndk编译。

test文件夹下的编解码例子可以自己尝试一下,对后面编写java代码很有帮助。

2、Eclipse下Android工程建立

主要有两点:一是JAVA本地函数通过JNI调用opencore的代码(so封装、调用),二是转码相关的代码。首先需要将opencore编解码的cpp文件放在工程jni目录下,或者其他地方,然后需要编写Android.mk文件,将需要的代码包含进来.

A. JNI 接口cpp文件编写

解码和编码部分分开写,也可以合在一起写,重点是在JNI cpp文件中完成了数据类型的映射和接口函数的重写。写完之后也要包含到Android.mk文件中去。执行ndk-build就可以在lib文件夹下生成so文件。

解码部分JNI cpp代码:

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

1 #include

2 #include

3

4 #ifndef _Included_com_example_amrcodec_decode_AmrDecInterface5 #define _Included_com_example_amrcodec_decode_AmrDecInterface

6 #ifdef __cplusplus7 extern "C"{8 #endif

9 /*

10 * Class: com_example_amr_dec_decode_AmrDecInterface11 * Method: initamr12 * Signature: ()V13 */

14 JNIEXPORT intJNICALL Java_com_example_amrcodec_decode_AmrDecInterface_initDecamr15 (JNIEnv *env, jobject ccc) {16

17 return(jint) Decoder_Interface_init();18 }19

20 /*

21 * Class: com_example_amr_dec_decode_AmrDecInterface22 * Method: exitamr23 * Signature: ()V24 */

25 JNIEXPORT intJNICALL Java_com_example_amrcodec_decode_AmrDecInterface_exitDecamr26 (JNIEnv *env, jobject lll,jint*nativePointer) {27

28 Decoder_Interface_exit(nativePointer);29

30 }31

32 /*

33 * Class: com_example_amr_dec_decode_AmrDecInterface34 * Method: Decodeamr35 * Signature: ([B[B)V36 */

37 JNIEXPORT voidJNICALL Java_com_example_amrcodec_decode_AmrDecInterface_Decodeamr38 (JNIEnv *env, jobject obj, jint* nativePointer,jbyteArray in, jshortArray out, jint bfi)39 {40 jsize inLen = env->GetArrayLength(in); //这里主要就是数据类型的映射

41 jbyte inBuf[inLen];42 env->GetByteArrayRegion(in, 0, inLen, inBuf);43

44 jsize outLen = env->GetArrayLength(out);45 shortoutBuf[outLen];46

47 Decoder_Interface_Decode(nativePointer, (const unsigned char*) inBuf, (short*) outBuf, bfi);48

49 //env->ReleaseByteArrayElements(in, inBuf, JNI_ABORT);//no need - GetByteArrayRegion handles this

50 env->SetShortArrayRegion(out, 0, outLen, outBuf); //释放

51

52 }53

54 #ifdef __cplusplus55 }56 #endif

57 #endif

View Code

编码部分JNI cpp代码:(多出来的枚举型很讨厌)

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

1 /*DO NOT EDIT THIS FILE - it is machine generated*/

2 #include

3 #include

4 #include

5 /*Header for class com_example_amr_dec_encode_AmrEncInterface*/

6

7 #ifndef _Included_com_example_amrcodec_encode_AmrEncInterface8 #define _Included_com_example_amrcodec_encode_AmrEncInterface

9 #ifdef __cplusplus10 extern "C"{11 #endif

12 /*

13 * Class: com_example_amr_dec_encode_AmrEncInterface14 * Method: initEncamr15 * Signature: (I)I16 */

17 JNIEXPORT jint JNICALL Java_com_example_amrcodec_encode_AmrEncInterface_initEncamr(18 JNIEnv *env, jobject job, jint dtxState) {19

20 return(jint) Encoder_Interface_init(dtxState);21 }22 /*

23 * Class: com_example_amr_dec_encode_AmrEncInterface24 * Method: exitEncamr25 * Signature: (I)V26 */

27 JNIEXPORT voidJNICALL Java_com_example_amrcodec_encode_AmrEncInterface_exitEncamr28 (JNIEnv *env, jobject job1, jint*nativePointer) {29

30 Encoder_Interface_exit(nativePointer);31

32 }33

34 /*

35 * Class: com_example_amr_dec_encode_AmrEncInterface36 * Method: Encodeamr37 * Signature: (ILcom/example/amr_dec/encode/AmrEncInterface/Mode;[S[BI)I38 */

39 JNIEXPORT jint JNICALL Java_com_example_amrcodec_encode_AmrEncInterface_Encodeamr(40 JNIEnv *env, jobject job2, jint*nativePointer, jobject mode,41 jshortArray speech, jbyteArray out, jint forceSpeech) {42

43 jsize inLen = env->GetArrayLength(speech);44 jshort inBuf[inLen];45 env->GetShortArrayRegion(speech, 0, inLen, inBuf);46 jclass jcz = env->GetObjectClass(mode);47 jmethodID getNameMethod = env->GetMethodID(jcz, "name",48 "()Ljava/lang/String;");49 jstring modevalue = (jstring) env->CallObjectMethod(mode, getNameMethod);50 const char * valueNative = env->GetStringUTFChars(modevalue, 0);51 /*为了使用C++中定义的模式,需要做以下的映射*/

52 Mode cmode ;53 if(((strcmp(valueNative, "MR475") == 0)))54 cmode =MR475;55 if(((strcmp(valueNative, "MR515") == 0)))56 cmode =MR515;57 if(((strcmp(valueNative, "MR59") == 0)))58 cmode =MR59;59 if(((strcmp(valueNative, "MR67") == 0)))60 cmode =MR67;61 if(((strcmp(valueNative, "MR74") == 0)))62 cmode =MR74;63 if(((strcmp(valueNative, "MR795") == 0)))64 cmode =MR795;65 if(((strcmp(valueNative, "MR102") == 0)))66 cmode =MR102;67 if(((strcmp(valueNative, "MR122") == 0)))68 cmode =MR122;69

70 jsize outLen = env->GetArrayLength(out);71 jbyte outBuf[outLen];72 intencodeLength;73

74 encodeLength = Encoder_Interface_Encode(nativePointer, cmode, (const short*) inBuf,75 (unsigned char*) outBuf, forceSpeech);76

77 //env->ReleaseByteArrayElements(in, inBuf, JNI_ABORT);//no need - GetByteArrayRegion handles this

78 env->SetByteArrayRegion(out, 0, outLen, outBuf);79 returnencodeLength;80

81 }82

83 #ifdef __cplusplus84 }85 #endif

86 #endif

View Code

JAVA 本地函数部分代码(可以合在一起写,也可以放到其他文件里面去,不一定要单独写一个类)

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

1 package com.example.amrcodec.encode;2

3

4 public classAmrEncInterface {5 //本地函数的声明

6

7 public enumMode{8 MR475 ,/*4.75 kbps*/

9 MR515, /*5.15 kbps*/

10 MR59, /*5.90 kbps*/

11 MR67, /*6.70 kbps*/

12 MR74, /*7.40 kbps*/

13 MR795, /*7.95 kbps*/

14 MR102, /*10.2 kbps*/

15 MR122, /*12.2 kbps*/

16 MRDTX, /*DTX*/

17 N_MODES /*Not Used*/

18 }19

20

21 public static native int initEncamr(intini);22 public static native void exitEncamr(intencode);23 public static native int Encodeamr(int gae, Mode mode, short[] in, byte[] outbuffer, intfroceSpeech);24 static{25

26 System.loadLibrary("amr_dec");27

28 }29

30

31 }

View Code

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

1 package com.example.amrcodec.decode;2

3 //本地函数的声明

4 public classAmrDecInterface{5

6 public static native intinitDecamr();7 public static native void exitDecamr(intdecode);8 public static native int Decodeamr(int gae, byte[] in, short[] outbuffer, intunused);9 static{10

11 System.loadLibrary("amr_dec");12

13 }14

15

16 }

View Code

B.Wav文件的读写

关于wav和amr文件转换的c或者c++的代码有很多,别人做的java的相关函数也有一些,通过参考这些文件同时搞清楚amr文件和wav文件的存储结构,就可

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值