首先配置Android Studio NDK以及下載Speex原始碼放入main/cpp/speex目錄
在cpp目錄下更改根CMakeList.tet檔案:
一下是包含子目錄得形式,
#指定需要CMAKE的最小版本
cmake_minimum_required(VERSION 3.4.1)
#C 的編譯選項是 CMAKE_C_FLAGS
# 指定編譯引數,可選
SET(CMAKE_CXX_FLAGS "-Wno-error=format-security -Wno-error=pointer-sign")
#設定生成的so動態庫最后輸出的路徑
#set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/../jniLibs/${ANDROID_ABI})
#設定頭檔案搜索路徑(和此txt同個路徑的頭檔案無需設定),可選
#INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/common)
#指定用到的系統庫或者NDK庫或者第三方庫的搜索路徑,可選,
#LINK_DIRECTORIES(/usr/local/lib)
#添加子目錄,將會呼叫子目錄中的CMakeLists.txt
ADD_SUBDIRECTORY(speex)
在cpp/speex增加子檔案:
# For more information about using CMake with Android Studio, read the
# documentation: https://d.android.com/studio/projects/add-native-code.html
# Sets the minimum version of CMake required to build the native library.
cmake_minimum_required(VERSION 3.4.1)
# Creates and names a library, sets it as either STATIC
# or SHARED, and provides the relative paths to its source code.
# You can define multiple libraries, and CMake builds them for you.
# Gradle automatically packages shared libraries with your APK.
set(CMAKE_C_FLAGS "-DFIXED_POINT -DUSE_KISS_FFT -DEXPORT="" -UHAVE_CONFIG_H")
add_library( # Sets the name of the library.
speex-lib
# Sets the library as a shared library.
SHARED
# Provides a relative path to your source file(s).
speex_jni.cpp
./libspeex/bits.c
./libspeex/cb_search.c
./libspeex/buffer.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_lbr.c
./libspeex/gain_table.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_tables_nb.c
./libspeex/lsp.c
./libspeex/ltp.c
./libspeex/mdf.c
./libspeex/modes_wb.c
./libspeex/modes.c
./libspeex/nb_celp.c
./libspeex/preprocess.c
./libspeex/quant_lsp.c
./libspeex/sb_celp.c
./libspeex/scal.c
./libspeex/smallft.c
./libspeex/speex_callbacks.c
./libspeex/speex_header.c
./libspeex/speex.c
./libspeex/stereo.c
./libspeex/vbr.c
./libspeex/vorbis_psy.c
./libspeex/vq.c
./libspeex/window.c)
#target_include_directories(speex-lib
# PRIVATE
# /include)
include_directories(include)
# Searches for a specified prebuilt library and stores the path as a
# variable. Because CMake includes system libraries in the search path by
# default, you only need to specify the name of the public NDK library
# you want to add. CMake verifies that the library exists before
# completing its build.
find_library( # Sets the name of the path variable.
log-lib
# Specifies the name of the NDK library that
# you want CMake to locate.
log)
# Specifies libraries CMake should link to your target library. You
# can link multiple libraries, such as libraries you define in this
# build script, prebuilt third-party libraries, or system libraries.
target_link_libraries( # Specifies the target library.
speex-lib
# Links the target library to the log library
# included in the NDK.
${log-lib})
在gradle下:
defaultConfig {
...
externalNativeBuild {
cmake {
cppFlags "-std=c++11 -frtti"
abiFilters 'armeabi-v7a', "arm64-v8a", 'x86', 'x86_64'
arguments "-DANDROID_TOOLCHAIN=clang", "-DANDROID_STL=c++_static"
}
}
}
android {
externalNativeBuild {
cmake {
path "src/main/cpp/CMakeLists.txt"
version "3.10.2"
}
}
}
若使用Android.mk:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_LDLIBS :=-llog
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/cb_search.c \
./libspeex/buffer.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_lbr.c \
./libspeex/gain_table.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_tables_nb.c \
./libspeex/lsp.c \
./libspeex/ltp.c \
./libspeex/mdf.c \
./libspeex/modes_wb.c \
./libspeex/modes.c \
./libspeex/nb_celp.c \
./libspeex/preprocess.c \
./libspeex/quant_lsp.c \
./libspeex/sb_celp.c \
./libspeex/scal.c \
./libspeex/smallft.c \
./libspeex/speex_callbacks.c \
./libspeex/speex_header.c \
./libspeex/speex.c \
./libspeex/stereo.c \
./libspeex/vbr.c \
./libspeex/vorbis_psy.c \
./libspeex/vq.c \
./libspeex/window.c \
include $(BUILD_SHARED_LIBRARY)
application.mk
APP_ABI := armeabi
gradle也不一樣:
android{
externalNativeBuild {
ndkBuild {
path 'src/main/cpp/Android.mk'
}
}
}
speex_jni.cpp
#include <jni.h>
#include <string.h>
#include <unistd.h>
#include <speex/speex.h>
#include<Android/log.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;
#define TAG "JNI" // 這個是自定義的LOG的標識
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, TAG ,__VA_ARGS__) // 定義LOGD型別
extern "C"
JNIEXPORT jint JNICALL Java_包名_NativeCodec_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;
}
float encoder_input[160];
extern "C"
JNIEXPORT jint Java_包名_NativeCodec_encode
(JNIEnv *env, jobject obj, jshortArray lin, jint offset, jbyteArray encoded, jint size) {
jshort buffer[enc_frame_size];
jbyte output_buffer[20];
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_包名_NativeCodec_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;
speex_bits_reset(&dbits);
env->GetByteArrayRegion(encoded, 0, encoded_length, buffer);
speex_bits_read_from(&dbits, (char *)buffer, encoded_length);
// speex_decode_int(dec_state, &dbits, output_buffer);
float decoder_output[dec_frame_size];
speex_decode(dec_state, &dbits, decoder_output);
for (int i = 0; i < dec_frame_size; i++)
{
output_buffer[i] = decoder_output[i];
}
env->SetShortArrayRegion(lin, 0, dec_frame_size,
output_buffer);
return (jint)dec_frame_size;
}
extern "C"
JNIEXPORT jint JNICALL Java_包名_NativeCodec_getFrameSize
(JNIEnv *env, jobject obj) {
if (!codec_open)
return 0;
return (jint)enc_frame_size;
}
extern "C"
JNIEXPORT void JNICALL Java_包名_NativeCodec_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);
}
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();
解碼引數 1 encodedData, 編碼資料
2 decodedData, 解碼資料,可通過getFrameSize獲取長度
3 encodedData.length
編碼引數1 audioData,原始引數
2 0
3 encodedData,
4 audioData.length
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/298397.html
標籤:其他
