Audio Compression tool-Use of speex

Source: Internet
Author: User

In Android development, recordings must be recorded and sent to the other device. The problem is that mobile phones often access the Internet through GPRS, 3G, and other methods. Therefore, it is critical to save traffic. Using speex to compress audio files can reduce the audio pressure file by decimal times.

1. Go to the official speex website to download the latest speex source code.

2. Create a new application (my application name is audio) and create a JNI directory ($ Project/JNI ).

3. Copy the libspeex and include directories and Their subdirectories under the speex source code directory to the $ project/JNI directory ($ Project/JNI/libspeex
And $ Project/JNI/include ).

4. Add the Android. mk file in the JNI directory. The edit content is as follows:

LOCAL_PATH := $(call my-dir)include $(CLEAR_VARS) LOCAL_MODULE    := libspeexLOCAL_CFLAGS = -DFIXED_POINT -DUSE_KISS_FFT -DEXPORT="" -UHAVE_CONFIG_HLOCAL_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 in the JNI directory. The edit content is as follows:

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:

#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 packaging class speex_jni.cpp to call the C code function in speex. The editing content is as follows:

#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 on the Java layer. The content is as follows:

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(short lin[], 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), and enter $ ndk/ndk-build

For installation and configuration of cygwin tool, refer to this article-using ndk and Environment Building


The libs directory and libspeex are generated in the project. so file, which is the system in the speex class. loadlibrary ("speex"); if the code is referenced, the system will find the corresponding dynamic library libspeex according to the operating system. so, in windows, yes. DLL file, which is in Linux. so file.

Currently, my project structure is as follows:



You can download the code from Android-recorder for reference.


Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.