http://blog.csdn.net/chenfeng0104/article/details/7088138
In Android development, recording is required and sent to the other device. At this point, the mobile phone is often GPRS, 3G and other ways to surf the internet, so it is very important to save traffic, using Speex to compress audio files, you can press the audio file for a small number of times.
1. Go to Speex official website to download the latest Speex source code.
2. Create a new app (I created the app named audio) and create a JNI directory ($project/jni).
3. Copy the Libspeex and include directories and their subdirectory files under the Speex source directory to the $project/jni directory ($project/jni/libspeex and $project/jni/include).
4. Add the Android.mk file to the JNI directory and edit the content as follows
[Plain]View Plaincopy
- 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: = \
- ./speex_jni.cpp \
- ./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
- Include $ (build_shared_library)
5. Add the Application.mk file to the JNI directory and edit the content as follows
[Plain]View Plaincopy
- App_abi: = Armeabi armeabi-v7a
6. Add the Speex_config_types.h file in the $project/jni/include/speex/directory and edit the contents as follows
[CPP]View Plaincopy
- #ifndef __speex_types_h__
- #define __speex_types_h__
- typedef short spx_int16_t;
- typedef unsigned short spx_uint16_t;
- typedef INT spx_int32_t;
- typedef unsigned int spx_uint32_t;
- #endif
7. Create the Jni wrapper class Speex_jni.cpp, which is used to call the C code function in Speex, and edit the contents as follows
[CPP]View Plaincopy
- #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_audio_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_audio_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_audio_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_audio_getframesize
- (jnienv *env, Jobject obj) {
- if (!codec_open)
- return 0;
- return (jint) enc_frame_size;
- }
- extern "C"
- Jniexport void Jnicall java_com_audio_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 in the Java layer with the following content
[Java]View Plaincopy
- Package Com.audio;
- Class Speex {
- / * Quality
- * 1:4KBPS (very noticeable artifacts, usually intelligible)
- * 2:6KBPS (very noticeable artifacts, good intelligibility)
- * 4:8KBPS (noticeable artifacts sometimes)
- * 6:11KPBS (artifacts usually only noticeable with headphones)
- * 8:15KBPS (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 (shortlin[], int offset, byte encoded[], int size);
- public native void Close ();
- }
9. Open the Cygwin tool, switch to the project directory (my project is in F:\workspace\Audio), enter $ndk/ndk-build
Cygwin tool installation and configuration, you can read this article-using the NDK and the environment to build
The Libs directory and the libspeex.so file are generated in the project, which is System.loadlibrary ("Speex") in the Speex class, and the system is referenced by the "Speex" according to the operating system Find the corresponding dynamic library libspeex.so,windows is the. dll file under Linux, which is the. so file.
Currently, my project structure is as follows
Speex for Android