Previously, we used speex encoding and decoding in applications. Recently, we have summarized the implementation of speex on Android. Speex is an open-source, free, and patent-free audio compression format. The speex project strives to reduce the input threshold of speech applications by providing an alternative high-performance speech codec. In addition, compared with other codec, speex is also suitable for network applications and has its own unique advantages in network applications. In addition, speex is part of the GNU project and has been well supported in the revised BSD Protocol. Speex is based on CELP and is specially designed for speech compression at a bit rate of 2-kbps. Speex source code is implemented based on C speech (Java implementation is also available, and the efficiency is relatively low ).
1. Go to the official speex website to download the latest speex source code.
2. Create a new Android project and a JNI folder.
3. Copy all the libspeex and include directories and Their subdirectories under the speex source code directory to the $ project/JNI directory.
4. Add the Android. mk file in the JNI directory and edit the file as follows:
[Plain]
View plaincopyprint?
- Local_path: = $ (call my-DIR)
- Include $ (clear_vars)
- Local_module: = libspeex
- Local_cflags =-dfixed_point-duse_kiss_fft-dexport = ""-uhave_config_h
- Local_c_includes: = $ (local_path)/include
- Local_src_files: = \
- Libspeex/bits. c \
- Libspeex/buffer. c \
- Libspeex/cb_search.c \
- Libspeex/exc_10_16_table.c \
- Libspeex/exc_10_32_table.c \
- Libspeex/exc_20_32_table.c \
- Libspeex/exc_5_256_table.c \
- Libspeex/exc_5_64_table.c \
- Libspeex/exc_8_128_table.c \
- Libspeex/fftwrap. c \
- Libspeex/filterbank. c \
- Libspeex/filters. c \
- Libspeex/gain_table.c \
- Libspeex/gain_table_lbr.c \
- Libspeex/hexc_10_32_table.c \
- Libspeex/hexc_table.c \
- Libspeex/high_lsp_tables.c \
- Libspeex/jitter. c \
- Libspeex/kiss_fft.c \
- Libspeex/kiss_fftr.c \
- Libspeex/LPC. c \
- Libspeex/LSP. c \
- Libspeex/lsp_tables_nb.c \
- Libspeex/LTP. c \
- Libspeex/MDF. c \
- Libspeex/modes. c \
- Libspeex/modes_wb.c \
- Libspeex/nb_celp.c \
- Libspeex/preprocess. c \
- Libspeex/quant_lsp.c \
- Libspeex/resample. c \
- Libspeex/sb_celp.c \
- Libspeex/Scal. c \
- Libspeex/smallft. c \
- Libspeex/speex. c \
- Libspeex/speex_callbacks.c \
- Libspeex/speex_header.c \
- Libspeex/stereo. c \
- Libspeex/VBR. c \
- Libspeex/VQ. c \
- Libspeex/window. c \
- Speex_jni.cpp \
- Include $ (build_shared_library)
5. Add the application. mk file in the JNI directory. The edit content is as follows:
[Plain]
View plaincopyprint?
- App_abi: = armeabi armeabi-v7a
6. Add the speex_config_types.h file in the $ Project/JNI/include/speex/directory. The edited content is as follows:
[HTML]
View plaincopyprint?
- 01. # ifndef _ speex_types_h __
- 02. # DEFINE _ speex_types_h __
- 03. typedef short spx_int16_t;
- 04. typedef unsigned short spx_uint16_t;
- 05. typedef int spx_int32_t;
- 06. typedef unsigned int spx_uint32_t;
- 07. # endif
7. Create the JNI packaging class speex_jni.cpp to call the C code function in speex. The editing content is as follows:
[CPP]
View plaincopyprint?
- # Include <JNI. h>
- # Include <string. h>
- # Include <unistd. h>
- # Include <speex/speex. h>
- Static int codec_open = 0;
- Static int dec_frame_size;
- Static int enc_frame_size;
- Static speexbits ebits, dBits;
- Void * enc_state;
- Void * dec_state;
- Static JavaVM * gjavavm;
- Extern "C"
- Jniexport jint jnicall java_com_trunkbow_speextest_speex_open
- (Jnienv * ENV, jobject OBJ, jint compression ){
- Int TMP;
- If (codec_open ++! = 0)
- Return (jint) 0;
- Speex_bits_init (& ebits );
- Speex_bits_init (& dBits );
- Enc_state = speex_encoder_init (& speex_nb_mode );
- Dec_state = speex_decoder_init (& speex_nb_mode );
- TMP = compression;
- Speex_encoder_ctl (enc_state, speex_set_quality, & TMP );
- Speex_encoder_ctl (enc_state, speex_get_frame_size, & enc_frame_size );
- Speex_decoder_ctl (dec_state, speex_get_frame_size, & dec_frame_size );
- Return (jint) 0;
- }
- Extern "C"
- Jniexport jint java_com_trunkbow_speextest_speex_encode
- (Jnienv * ENV, jobject OBJ, jshortarray Lin, jint offset, jbytearray encoded, jint size ){
- Jshort buffer [enc_frame_size];
- Jbyte output_buffer [enc_frame_size];
- Int nsamples = (size-1)/enc_frame_size + 1;
- Int I, tot_bytes = 0;
- If (! Codec_open)
- Return 0;
- Speex_bits_reset (& ebits );
- For (I = 0; I <nsamples; I ++ ){
- Env-> getshortarrayregion (Lin, offset + I * enc_frame_size, enc_frame_size, buffer );
- Speex_encode_int (enc_state, buffer, & ebits );
- }
- // Env-> getshortarrayregion (Lin, offset, enc_frame_size, buffer );
- // Speex_encode_int (enc_state, buffer, & ebits );
- Tot_bytes = speex_bits_write (& ebits, (char *) output_buffer,
- Enc_frame_size );
- Env-> setbytearrayregion (encoded, 0, tot_bytes,
- Output_buffer );
- Return (jint) tot_bytes;
- }
- Extern "C"
- Jniexport jint jnicall java_com_trunkbow_speextest_speex_decode
- (Jnienv * ENV, jobject OBJ, jbytearray encoded, jshortarray Lin, jint size ){
- Jbyte buffer [dec_frame_size];
- Jshort output_buffer [dec_frame_size];
- Jsize encoded_length = size;
- If (! Codec_open)
- Return 0;
- Env-> getbytearrayregion (encoded, 0, encoded_length, buffer );
- Speex_bits_read_from (& dBits, (char *) buffer, encoded_length );
- Speex_decode_int (dec_state, & dBits, output_buffer );
- Env-> setshortarrayregion (Lin, 0, dec_frame_size,
- Output_buffer );
- Return (jint) dec_frame_size;
- }
- Extern "C"
- Jniexport jint jnicall java_com_trunkbow_speextest_speex_getframesize
- (Jnienv * ENV, jobject OBJ ){
- If (! Codec_open)
- Return 0;
- Return (jint) enc_frame_size;
- }
- Extern "C"
- Jniexport void jnicall java_com_trunkbow_speextest_speex_close
- (Jnienv * ENV, jobject OBJ ){
- If (-- codec_open! = 0)
- Return;
- Speex_bits_destroy (& ebits );
- Speex_bits_destroy (& dBits );
- Speex_decoder_destroy (dec_state );
- Speex_encoder_destroy (enc_state );
- }
8. Create the speex tool class on the Java layer. The content is as follows:
[Java]
View plaincopyprint?
- Package com. trunkbow. speextest;
- Public class speex {
- /* Quality
- * 1: 4 kbps (very noticeable artifacts, usually intelligible)
- * 2: 6 kbps (very noticeable artifacts, good intelligibility)
- * 4: 8 kbps (noticeable artifacts sometimes)
- * 6: 11 Kpbs (artifacts usually only noticeable with headphones)
- * 8: 15 kbps (artifacts not usually noticeable)
- */
- Private Static final int default_compression = 8;
- Speex (){
- }
- Public void Init (){
- Load ();
- Open (default_compression );
- }
- Private void load (){
- Try {
- System. loadlibrary ("speex ");
- } Catch (throwable e ){
- E. printstacktrace ();
- }
- }
- Public native int open (INT compression );
- Public native int getframesize ();
- Public native int decode (byte encoded [], short LiN [], int size );
- Public native int encode (short LiN [], int offset, byte encoded [], int size );
- Public native void close ();
- }
9. Use cygwin to compile and generate the so file.
**************************************** *******************************
* Reproduced in: http://blog.csdn.net/xyz_lmn
* Author: Zhang xingye
* Email: xy-zhang@163.com
**************************************** *******************************
Refer:
Http://code.google.com/p/android-recorder/downloads/list this is an android recorder that uses speex encoding,