1. <span id="petwi"><output id="petwi"></output></span>
      <ruby id="petwi"></ruby>

      <span id="petwi"></span>
      <span id="petwi"><video id="petwi"></video></span>
        <ol id="petwi"></ol>

        <track id="petwi"><i id="petwi"></i></track>

      1. <span id="petwi"><sup id="petwi"></sup></span>
        <optgroup id="petwi"><em id="petwi"><del id="petwi"></del></em></optgroup>

            <legend id="petwi"><i id="petwi"></i></legend>

            1. <span id="petwi"></span>
              新聞內容

              音頻編碼之opus(一)

              信息來源:雙贊工控|時間:2017-03-19 19:38|瀏覽量:

              ?

              首先介紹一下opus

               

              Opus

              Opus編碼器 是一個有損聲音編碼的格式,由互聯網工程任務組(IETF)進來開發,適用于網絡上的實時聲音傳輸,標準格式為RFC 6716。Opus 格式是一個開放格式,使用上沒有任何專利或限制。

              特性

              Opus的前身是celt編碼器。在當今的有損音頻格式爭奪上,擁有眾多不同編碼器的AAC格式打敗了同樣頗有潛力的Musepack、Vorbis等格式,而在Opus格式誕生后,情況似乎不同了。通過諸多的對比測試,低碼率下Opsu完勝曾經優勢明顯的HE AAC,中碼率就已經可以媲敵碼率高出30%左右的AAC格式,而高碼率下更接近原始音頻。

              以上來自百度百科(PS:百度百科對opus的介紹都很少)

               

              簡單來說,opus是一個高保真的適合在網絡中傳輸的開源的語音編碼格式,相對于其他編碼格式來講,保真性更好,但體積會稍微大一些。官網地址:http://www.opus-codec.org/

               

              怎么用呢?

              首先你可以使用編譯好的so庫直接使用,或者也可以使用源碼自己根據需求生成so庫來使用,當然,你也可以直接將源碼使用到自己工程各中,這就是開源的好處。好了下面介紹如何編譯。

              我是通過Eclipse來編譯的,首先在opus官網下載源代碼,解壓。

              編碼工作需要ndk編程所以需要一些NDK編程的知識。

              在工程中創建OpusTool類,該類用于調用native層的方法。

               

              [java] view plain copy
               
               在CODE上查看代碼片派生到我的代碼片
              1. package com.ione.opustool;  
              2.   
              3. public class OpusTool {  
              4.   
              5.     public native String nativeGetString();  
              6.   
              7.     public native int encode_wav_file(String in_path, String out_path);  
              8.   
              9.     public native int decode_opus_file(String in_path, String out_path);  
              10. }  

              其中nativeGetString()方法是用來測試jni調用是否成功的測試方法,encode_wav_file(String in_path, String out_path);和 decode_opus_file(String in_path, String out_path);分別是用來編解碼。以上三個方法均需聲明為native,用來調用jni的c函數。然后在項目根目錄下打開命令行,使用javah命令生成.h文件,即:

               

              javah -classpath .\bin\classes -d jni com.ione.opustool.OpusTool

              其中.\bin\classes為指定OpusTool.class的路徑,-d jni為在當前目錄下生成jni文件夾,用來存放native層代碼?;剀囍蟊阍诠こ痰母夸浵律闪薺ni文件夾以及com_ione_opustool_OpusTool.h文件。如:

               

               

               

              [cpp] view plain copy
               
               在CODE上查看代碼片派生到我的代碼片
              1. /* DO NOT EDIT THIS FILE - it is machine generated */  
              2. #include <jni.h>  
              3. /* Header for class com_ione_opustool_OpusTool */  
              4.   
              5. #ifndef _Included_com_ione_opustool_OpusTool  
              6. #define _Included_com_ione_opustool_OpusTool  
              7. #ifdef __cplusplus  
              8. extern "C" {  
              9. #endif  
              10. /* 
              11.  * Class:     com_ione_opustool_OpusTool 
              12.  * Method:    nativeGetString 
              13.  * Signature: ()Ljava/lang/String; 
              14.  */  
              15. JNIEXPORT jstring JNICALL Java_com_ione_opustool_OpusTool_nativeGetString  
              16.   (JNIEnv *, jobject);  
              17.   
              18. /* 
              19.  * Class:     com_ione_opustool_OpusTool 
              20.  * Method:    encode_wav_file 
              21.  * Signature: (Ljava/lang/String;Ljava/lang/String;)I 
              22.  */  
              23. JNIEXPORT jint JNICALL Java_com_ione_opustool_OpusTool_encode_1wav_1file  
              24.   (JNIEnv *, jobject, jstring, jstring);  
              25.   
              26. /* 
              27.  * Class:     com_ione_opustool_OpusTool 
              28.  * Method:    decode_opus_file 
              29.  * Signature: (Ljava/lang/String;Ljava/lang/String;)I 
              30.  */  
              31. JNIEXPORT jint JNICALL Java_com_ione_opustool_OpusTool_decode_1opus_1file  
              32.   (JNIEnv *, jobject, jstring, jstring);  
              33.   
              34. #ifdef __cplusplus  
              35. }  
              36. #endif  
              37. #endif  

              接下來復制一份com_ione_opustool_OpusTool.h文件到jni目錄,修改名稱為com_ione_opustool_OpusTool.c修改內容為:

               

               

              [cpp] view plain copy
               
               在CODE上查看代碼片派生到我的代碼片
              1. #include <com_ione_opustool_OpusTool.h>  
              2.   
              3. JNIEXPORT jstring JNICALL Java_com_ione_opustool_OpusTool_nativeGetString  
              4.                    JNIEnv * env, jobject obj) {  
              5.     return (*env)->NewStringUTF(env, "Hello Opus");  
              6. }  
              7.   
              8. JNIEXPORT jint JNICALL Java_com_ione_opustool_OpusTool_encode_1wav_1file(  
              9.         JNIEnv *env, jobject obj, jstring wav_path, jstring opus_path) {  
              10.     return 0;  
              11. }  
              12.   
              13. JNIEXPORT jint JNICALL Java_com_ione_opustool_OpusTool_decode_1opus_1file(  
              14.         JNIEnv *env, jobject obj, jstring wav_path, jstring opus_path) {  
              15.     return 0;  
              16. }  
              然后創建并配置makefile和android.mk文件,后面會給出。記得配置NDK_Builder。
              此時可以調用OpusTool類的nativeGetString()方法查看返回數據是否正常,若為Hello Opus 則jni調用成功??梢岳^續下面的工作。

               

              在jni目錄下創建libopus文件夾,將Opus源碼粘貼到該文件夾下,即celt、include、silk、src文件夾以及config文件,當然不是所有的文件都用的上,可以根據自記得需求進行拷貝。配置好makefile等配置文件后即可編譯工程,如果編譯順利,則說明配置文件沒有問題,繼續操作。在src文件加下創建opus_tool.c文件用來進行音頻文件的編解碼的c實現。

              opus_tool.c

               

              [cpp] view plain copy
               
               在CODE上查看代碼片派生到我的代碼片
              1. /***************************************************************************** 
              2.  # -*- coding:utf-8 -*- 
              3.  # author: ione 
              4.  # create date: 2014-11-27 
              5.  *****************************************************************************/  
              6. #include "android_log.h"  
              7. #include "opus.h"  
              8. #include "opus_types.h"  
              9. #include "opus_multistream.h"  
              10.   
              11. #define SAMPLE_RATE 16000  
              12. #define CHANNEL_NUM 1  
              13. #define BIT_RATE 16000  
              14. #define BIT_PER_SAMPLE 16  
              15. #define WB_FRAME_SIZE 320  
              16. #define DATA_SIZE 1024 * 1024 * 4  
              17.   
              18. int encode(char* in, int len, unsigned char* opus, int* opus_len) {  
              19.     int err = 0;  
              20.     opus_int32 skip = 0;  
              21.   
              22.     OpusEncoder *enc = opus_encoder_create(SAMPLE_RATE, CHANNEL_NUM,  
              23.             OPUS_APPLICATION_VOIP, &err);  
              24.     if (err != OPUS_OK) {  
              25.         fprintf(stderr, "cannnot create opus encoder: %s\n",  
              26.                 opus_strerror(err));  
              27.         enc = NULL;  
              28.         return -1;  
              29.     }  
              30.   
              31.     opus_encoder_ctl(enc, OPUS_SET_BANDWIDTH(OPUS_BANDWIDTH_WIDEBAND));  
              32.     opus_encoder_ctl(enc, OPUS_SET_BITRATE(BIT_RATE));  
              33.     opus_encoder_ctl(enc, OPUS_SET_VBR(1));  
              34.     opus_encoder_ctl(enc, OPUS_SET_COMPLEXITY(10));  
              35.     opus_encoder_ctl(enc, OPUS_SET_INBAND_FEC(0));  
              36.     opus_encoder_ctl(enc, OPUS_SET_FORCE_CHANNELS(OPUS_AUTO));  
              37.     opus_encoder_ctl(enc, OPUS_SET_DTX(0));  
              38.     opus_encoder_ctl(enc, OPUS_SET_PACKET_LOSS_PERC(0));  
              39.     opus_encoder_ctl(enc, OPUS_GET_LOOKAHEAD(&skip));  
              40.     opus_encoder_ctl(enc, OPUS_SET_LSB_DEPTH(16));  
              41.   
              42.     short frame_size = WB_FRAME_SIZE;  
              43.     int frame_bytes = (frame_size << 1);  
              44.   
              45.     opus_int16 *frame = (opus_int16 *) in;  
              46.     unsigned char *cbits = opus;  
              47.   
              48.     while (len > frame_bytes) {  
              49.         int nbytes = opus_encode(enc, frame, frame_size, cbits + sizeof(char),  
              50.                 640 - sizeof(short));  
              51.         if (nbytes > frame_size * 2 || nbytes < 0) {  
              52.             return -1;  
              53.         }  
              54.         cbits[0] = nbytes;  
              55.         frame += WB_FRAME_SIZE;  
              56.         cbits += nbytes + sizeof(char);  
              57.         len -= frame_bytes;  
              58.         *opus_len += nbytes + sizeof(char);  
              59.     }  
              60.     opus_encoder_destroy(enc);  
              61.     return 0;  
              62. }  
              63.   
              64. int decode(unsigned char* in, int len, short* out, int* out_len) {  
              65.     int err = 0;  
              66.     opus_int32 skip = 0;  
              67.     *out_len = 0;  
              68.   
              69.     OpusDecoder *dec = opus_decoder_create(SAMPLE_RATE, 1, &err);  
              70.     if (err != OPUS_OK) {  
              71.         fprintf(stderr, "cannnot decode opus: %s\n", opus_strerror(err));  
              72.         dec = NULL;  
              73.         return -1;  
              74.     }  
              75.   
              76.     short frame_size = WB_FRAME_SIZE;  
              77.   
              78.     opus_int16 *frame = (opus_int16 *) in;  
              79.   
              80.     while (len > 0) {  
              81.         int nbytes = in[0];  
              82.         if (nbytes <= 0) {  
              83.             return -1;  
              84.         }  
              85.         int decode_len = opus_decode(dec, in + sizeof(char), nbytes, out,  
              86.                 frame_size, 0);  
              87.         if (decode_len != frame_size) {  
              88.             return -1;  
              89.         }  
              90.   
              91.         in += sizeof(char) + nbytes;  
              92.         out += frame_size;  
              93.         len -= nbytes - sizeof(char);  
              94.         *out_len += frame_size;  
              95.     }  
              96.     opus_decoder_destroy(dec);  
              97.     return 0;  
              98. }  
              99.   
              100. int encode_wav_file(char *in_file_path, char *out_file_path) {  
              101.     FILE *fin = fopen(in_file_path, "rb");  
              102.   
              103.     if (fin == NULL || fin == 0) {  
              104.         return -1;  
              105.     }  
              106.     char *in = (char*) malloc(DATA_SIZE);  
              107.     memset(in, 0, DATA_SIZE);  
              108.     int len = fread(in, 1, DATA_SIZE, fin);  
              109.     if (len == 0) {  
              110.         return -1;  
              111.     }  
              112.     FILE *fout = fopen(out_file_path, "wb");  
              113.   
              114.     if (fout == NULL || fout == 0) {  
              115.         return -1;  
              116.     }  
              117.   
              118.     unsigned char *out = (unsigned char*) malloc(DATA_SIZE);  
              119.     memset(out, 0, DATA_SIZE);  
              120.     int out_len = 0;  
              121.     encode(in, len, out, &out_len);  
              122.     if (len < 0) {  
              123.         return -1;  
              124.     }  
              125.     fwrite(out, 1, out_len * sizeof(unsigned char), fout);  
              126.   
              127.     free(in);  
              128.     free(out);  
              129.     fclose(fin);  
              130.     fclose(fout);  
              131.     return len;  
              132. }  
              133.   
              134. int make_wav_header(FILE *out, int len) {  
              135.     int size = 0;  
              136.     int *sz = &size;  
              137.     int number;  
              138.     int * nm = &number;  
              139.   
              140.     // RIFF  4 bytes  
              141.     fseek(out, 0, SEEK_SET);  
              142.     fputs("RIFF", out);  
              143.   
              144.     // len   4 bytes  
              145.     len = (len + 44 - 8);  
              146.     fwrite(&len, 2, 1, out);  
              147.     number = 0;  
              148.     fwrite(nm, 2, 1, out);  
              149.   
              150.     // WAVE  4 bytes  + "fmt " 4 bytes  
              151.     fputs("WAVEfmt ", out);  
              152.   
              153.     // size1   4 bytes  
              154.     number = 16;  
              155.     fwrite(nm, 2, 1, out);  
              156.     number = 0;  
              157.     fwrite(nm, 2, 1, out);  
              158.   
              159.     // format tag       2 bytes  
              160.     number = 1;  
              161.     fwrite(nm, 2, 1, out);  
              162.   
              163.     // channel    2 bytes  
              164.     number = CHANNEL_NUM;  
              165.     fwrite(nm, 2, 1, out);  
              166.   
              167.     // sample rate          4 bytes  
              168.     number = SAMPLE_RATE;  
              169.     fwrite(nm, 2, 1, out);  
              170.     number = 0;  
              171.     fwrite(nm, 2, 1, out);  
              172.   
              173.     //byte per seconds   4 bytes  
              174.     number = 22664;  
              175.     fwrite(nm, 2, 1, out);  
              176.     number = 0;  
              177.     fwrite(nm, 2, 1, out);  
              178.   
              179.     // block align   2 bytes  
              180.     number = CHANNEL_NUM * BIT_PER_SAMPLE / 8;  
              181.     fwrite(nm, 2, 1, out);  
              182.   
              183.     // bitPerSample   2 bytes  
              184.     number = 16;  
              185.     fwrite(nm, 2, 1, out);  
              186.   
              187.     // "data"      4 bytes  
              188.     fputs("data", out);  
              189.   
              190.     // size2    4 bytes  
              191.     size = (size - 36);  
              192.     fwrite(sz, 2, 1, out);  
              193.     number = 0;  
              194.     fwrite(nm, 2, 1, out);  
              195.   
              196.     return 0;  
              197. }  
              198.   
              199. int decode_opus_file(char *in_file_path, char *out_file_path) {  
              200.     printf("%s\n", in_file_path);  
              201.     FILE *fin = fopen(in_file_path, "rb");  
              202.     if (fin == NULL || fin == 0) {  
              203.         return -1;  
              204.     }  
              205.     unsigned char *in = (unsigned char *) malloc(DATA_SIZE);  
              206.     memset(in, 0, DATA_SIZE);  
              207.     int len = fread(in, 1, DATA_SIZE, fin);  
              208.   
              209.     FILE *fout = fopen(out_file_path, "wb");  
              210.     if (fout == NULL || fout == 0) {  
              211.         return -1;  
              212.     }  
              213.     short *out = (short *) malloc(DATA_SIZE);  
              214.     memset(out, 0, DATA_SIZE);  
              215.   
              216.     int out_len = 0;  
              217.     out += 44;  
              218.     decode(in, len, (short *) out, &out_len);  
              219.     if (len < 0) {  
              220.         return -1;  
              221.     }  
              222.     fwrite(out, 1, out_len * sizeof(short), fout);  
              223.     int err = make_wav_header(fout, out_len);  
              224.   
              225.     free(in);  
              226.     free(out);  
              227.     fclose(fin);  
              228.     fclose(fout);  
              229.     return out_len;  
              230. }  
              配置makefile文件添加opus_tool.c文件,然后編譯,即可在libs目錄下生成.so文件

               


              至此,native層操作已經完成,so庫也已經通過編譯得到。

              下一篇將會介紹如何使用該so庫。

              音頻編碼之opus(二)

              久久这里只有热精品18_毛片免费看_免费毛片高清完整版_午夜一级成年大片在线无码