The recent project used the voice coding opus, searched the Internet, very little information, and no complete tutorial, now simply record the use of opus.
First introduce opus
Opus
O The Pus encoder is a lossy sound coding format, by the Internet Engineering Task Force (IETF) developed for real-time sound transmission on the network, in the standard format RFC 6716. Opus format is an open format that is used without any patents or restrictions.
Characteristics
Opus was formerly known as the Celt encoder. In today's lossy audio format contention, the AAC format with many different encoders defeats the same potential for Musepack, Vorbis and other formats, and it seems different after the Opus format was born. Through a lot of comparative testing, low bit rate under the OPSU victory once the obvious advantage of he aac, the rate of protected has been able to the enemy code rate of about 30% of the AAC format, and high bit rate closer to the original audio.
The above from Baidu Encyclopedia (PS: Baidu Encyclopedia of the introduction of Opus are very few)
In a nutshell, Opus is a high-fidelity, open-source speech encoding format for transmission over the network, and fidelity is better than other encoding formats, but a little larger. Website address: http://www.opus-codec.org/
How to use it?
First you can use the compiled so library to use directly, or you can use the source itself according to demand to generate so library to use, of course, you can also directly use the source code to their own projects, which is the benefits of open source. Okay, here's how to compile.
I compiled it through eclipse, first download the source code in Opus official website, unzip.
The coding work requires NDK programming and therefore requires some knowledge of NDK programming.
Creates a Opustool class in the project that is used to invoke methods of the native layer.
Package Com.ione.opustool;public class Opustool {public native String nativegetstring ();p ublic native int encode_wav_ File (string In_path, String out_path);p ublic native int decode_opus_file (string in_path, String out_path);}
where the Nativegetstring () method is a test method used to test the success of a JNI call, Encode_wav_file (string In_path, String Out_path), and Decode_opus_file ( String In_path, String out_path), respectively, is used to encode and decode. All three of the above methods need to be declared as native to invoke the C function of JNI. Then open the command line under the project root and use the Javah command to generate the. h file, which is:
Javah-classpath. \bin\classes-d JNI Com.ione.opustool.OpusTool
where . \bin\classes is the path to the specified Opustool.class, the-D jni is used to generate the Jni folder in the current directory to hold the native layer code. After the carriage return, the Jni folder and the Com_ione_opustool_opustool.h file are generated under the project's root directory. such as:
/* Don't EDIT this file-it are machine generated */#include <jni.h>/* Header for class Com_ione_opustool_opustool */#ifndef _included_com_ione_opustool_opustool#define _included_com_ione_opustool_opustool#ifdef __ Cplusplusextern "C" {#endif/* * Class:com_ione_opustool_opustool * method:nativegetstring * Signature: () ljava/la ng/string; */jniexport jstring jnicall java_com_ione_opustool_opustool_nativegetstring (jnienv *, jobject);/* * Class:com_ione_ Opustool_opustool * Method:encode_wav_file * Signature: (ljava/lang/string; ljava/lang/string;) I */jniexport jint jnicall java_com_ione_opustool_opustool_encode_1wav_1file (JNIENV *, Jobject, Jstring, jstring);/* * Class:com_ione_opustool_opustool * method:decode_opus_file * Signature: (ljava/lang/string ; ljava/lang/string;) I */jniexport jint jnicall java_com_ione_opustool_opustool_decode_1opus_1file (JNIENV *, Jobject, Jstring, jstring); #ifdef __cplusplus} #endif #endif
Next copycom_ione_opustool_opustool.h file to the JNI directory, modify the name of com_ione_opustool_opustool.c to modify the content as:
#include <com_ione_opustool_opustool.h>jniexport jstring jnicall Java_com_ione_opustool_opustool_ Nativegetstring jnienv * env, Jobject obj) {return (*env)->newstringutf (env, "Hello Opus");} Jniexport jint jnicall java_com_ione_opustool_opustool_encode_1wav_1file (jnienv *env, Jobject obj, jstring wav_path, Jstring opus_path) {return 0;} Jniexport jint jnicall java_com_ione_opustool_opustool_decode_1opus_1file (jnienv *env, Jobject obj, jstring wav_path, Jstring opus_path) {return 0;}
Then create and configure the Makefile and android.mk files, which are given later. Remember to configure Ndk_builder.
At this point you can callthe Nativegetstring () method of the Opustool class looks at whether the returned data is normal, and if it is Hello Opus, the JNI call succeeds. You can continue with the following work.
In the JNI directory to create the Libopus folder, the opus source paste into the folder, that is, Celt, include, silk, src folder and config file, of course, not all files are used, can be copied according to the needs of self-remembering. Configure the Makefile and other configuration files can compile the project, if the compilation is smooth, then the configuration file no problem, continue to operate. The src file is added with the C implementation to create the OPUS_TOOL.C file for the codec of the audio file.
Opus_tool.c
/***************************************************************************** #-*-Coding:utf-8-*-# author:ione # Create date:2014-11-27 *****************************************************************************/#include " Android_log.h "#include" opus.h "#include" opus_types.h "#include" opus_multistream.h "#define Sample_rate 16000#define Channel_num 1#define bit_rate 16000#define bit_per_sample 16#define wb_frame_size 320#define DATA_SIZE 1024x768 * 1024x768 * 4int Encode (char* in, int len, unsigned char* opus, int* opus_len) {int err = 0;opus_int32 Skip = 0;opusencoder *enc = Opus_enc Oder_create (Sample_rate, Channel_num,opus_application_voip, &err), if (err! = OPUS_OK) {fprintf (stderr, "cannnot Create Opus Encoder:%s\n ", Opus_strerror (err)); enc = null;return-1;} Opus_encoder_ctl (Enc, opus_set_bandwidth (Opus_bandwidth_wideband)); Opus_encoder_ctl (Enc, opus_set_bitrate (BIT_ rate); Opus_encoder_ctl (Enc, OPUS_SET_VBR (1)); Opus_encoder_ctl (enc, opus_set_complexity); Opus_encoder_ctl ( Enc OPUS_SET_INBAND_FEC (0)); Opus_encoder_ctl (Enc, opus_set_force_channels (Opus_auto)); Opus_encoder_ctl (ENC, OPUS_SET _DTX (0)); Opus_encoder_ctl (ENC, OPUS_SET_PACKET_LOSS_PERC (0)); Opus_encoder_ctl (Enc, opus_get_lookahead (&SKIP) ); Opus_encoder_ctl (enc, opus_set_lsb_depth); short frame_size = Wb_frame_size;int frame_bytes = (Frame_size < < 1); Opus_int16 *frame = (opus_int16 *) in;unsigned char *cbits = opus;while (Len > frame_bytes) {int nbytes = Opus_ Encode (enc, frame, frame_size, cbits + sizeof (char), 640-sizeof (short)); if (Nbytes > frame_size * 2 | | nbytes < 0) {return-1;} Cbits[0] = Nbytes;frame + = wb_frame_size;cbits + nbytes + sizeof (char); len-= Frame_bytes;*opus_len + nbytes + sizeof (CH AR);} Opus_encoder_destroy (ENC); return 0;} int decode (unsigned char* in, Int. Len, short* out, int* out_len) {int err = 0;opus_int32 Skip = 0;*out_len = 0;opusdecoder *dec = Opus_decoder_create (sample_rate, 1, &err); if (err! = OPUS_OK) {fprintf (stderr, "Cannnot decode Opus:%s\n", Opus_strerror (ERR));d EC = null;return-1;} Short Frame_size = wb_frame_size;opus_int16 *frame = (opus_int16 *) in;while (len > 0) {int nbytes = in[0];if (Nbytes & lt;= 0) {return-1;} int decode_len = Opus_decode (dec, in + sizeof (char), nbytes, out,frame_size, 0); if (Decode_len! = frame_size) {return-1;} In + = sizeof (char) + nbytes;out + = Frame_size;len-= nbytes-sizeof (char); *out_len + = frame_size;} Opus_decoder_destroy (DEC); return 0;} int Encode_wav_file (char *in_file_path, char *out_file_path) {File *fin = fopen (In_file_path, "RB"); if (fin = = NULL | | fin = = 0) {return-1;} Char *in = (char*) malloc (data_size); memset (in, 0, data_size); int len = Fread (in, 1, data_size, Fin); if (len = = 0) {return -1;} FILE *fout = fopen (Out_file_path, "WB"); if (Fout = = NULL | | fout = 0) {return-1;} unsigned char *out = (unsigned char*) malloc (data_size); memset (out, 0, data_size); int out_len = 0;encode (in, Len, out, &am P;out_len); if (Len < 0) {return-1;} Fwrite (out, 1, Out_len * sizeof (unsigned char), fout); free (in); fclose (Fin); fclose (fout); return Len;} int Make_wav_header (FILE *out, int len) {int size = 0;int *sz = &size;int Number;int * nm = &number;//RIFF 4 byt Esfseek (out, 0, Seek_set), fputs ("RIFF", out);//len 4 Byteslen = (len + 44-8); Fwrite (&len, 2, 1, out); number = 0;f Write (nm, 2, 1, out);//WAVE 4 bytes + "FMT" 4 bytesfputs ("Wavefmt", out);//size1 4 Bytesnumber = 16;fwrite (nm, 2, 1, out); number = 0;fwrite (nm, 2, 1, out);//format tag 2 Bytesnumber = 1;fwrite (nm, 2, 1, out);//Channel 2 bytes Number = Channel_num;fwrite (nm, 2, 1, out);//Sample rate 4 Bytesnumber = Sample_rate;fwrite (nm, 2, 1, out); Numbe r = 0;fwrite (nm, 2, 1, out);//byte per seconds 4 Bytesnumber = 22664;fwrite (nm, 2, 1, out); number = 0;fwrite (nm, 2, 1, O UT);//block align 2 bytesnumber = Channel_num * Bit_per_sample/8;fwrite (NM, 2, 1, out);//Bitpersample 2 Bytesnumbe r = 16;fwrite (nm, 2, 1, out);//"Data" 4 bytesfputs ("Data", out);//Size24 bytessize = (size-36); Fwrite (SZ, 2, 1, out); number = 0;fwrite (nm, 2, 1, out); return 0;} int Decode_opus_file (char *in_file_path, char *out_file_path) {printf ("%s\n", In_file_path); FILE *fin = fopen (In_file_path, "RB"); if (fin = = NULL | | fin = = 0) {return-1;} unsigned char *in = (unsigned char *) malloc (data_size); memset (in, 0, data_size); int len = Fread (in, 1, data_size, Fin); FILE *fout = fopen (Out_file_path, "WB"); if (Fout = = NULL | | fout = 0) {return-1;} Short *out = (short *) malloc (data_size); memset (out, 0, data_size); int Out_len = 0;out + = 44;decode (in, Len, (short *) out , &out_len); if (Len < 0) {return-1;} Fwrite (out, 1, Out_len * sizeof (short), fout), Int. err = Make_wav_header (Fout, Out_len); free (in); free; fclose (FIN); Fclose (Fout); return Out_len;}
Configure the Makefile file to add the opus_tool.c file and compile it to generate the. So file in the Libs directory
At this point, the native layer operation has been completed and so libraries have been compiled.
The next article will show you how to use the so library.
Opus of audio coding