Android Speex编译及使用

@Author:明明不说话
@Statement:博客内容纯属个人观点,欢迎转载,转载请注明,谢谢

Speex是一套主要针对语音的开源免费,无专利保护的音频压缩格式。Speex工程着力于通过提供一个可以替代高性能语音编解码来降低语音应用输入门槛 。另外,相对于其它编解码器,Speex也很适合网络应用,在网络应用上有着自己独特的优势。同时,Speex还是GNU工程的一部分,在改版的BSD协议中得到了很好的支持。它完全是C语言实现的,所以它具有很好的移植性。所以在Android当中具有很好的使用性。可以在它的官网上下载需要的源码来操作。

Android当中移植Speex需要以下几个步骤:

1.NDK配置

NDK怎么配置和操作可以网上搜索,一大堆资料来告诉大家怎么操作的。现在越来越多的Android应用项目需要JNI代码操作,所以懂得NDK操作还是非常必要的。(最后能够在命令行执行出ndk-build,就说明NDK基本配置成功了)

2.Speex编译

Speex编译生成连接库给Android有很多种方法,可以通过MinGW编译,也可以通过在linux下编译,这些方法可以网上搜索吧。我这里采用的是将Speex在Android工程中编译成静态库.a的方式,这样该Speex可以很方便的在不同项目当中使用,而且方便其他项目管理,如果Speex有更改,则重新将Speex编译程静态库,然后替换到相应项目中就行了。

下面是libSpeex.a库的编译生成过程:
环境

windows + Android studio + NDK10

a. 去Speex官网下载最新Speex

b. 随便找一个android工程,新建一个也可以,在它的工程下创建jni目录

c.把speex源码目录下的libspeex和include目录及其子目录文件全部拷贝到jni目录下

d. 在jni中创建Android.mk

Android.mk的写法如下:

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 \

#创建static静态库,动态库为BUILD_SHARED_LIBRARY
include $(BUILD_STATIC_LIBRARY)    

e. 在jni目录下新增Application.mk文件

Application.mk的编写如下,可以根据需要的硬件平台来配置,如arm,arm-v7,x86,mips等。

APP_ABI := armeabi armeabi-v7a    

f. 在jni/include/speex/目录下speex_config_types.h.xx文件的xx后缀去掉,编辑内容如下

#ifndef __SPEEX_TYPES_H__    
#define __SPEEX_TYPES_H__    
pedef short spx_int16_t;    
typedef unsigned short spx_uint16_t;    
typedef int spx_int32_t;    
typedef unsigned int spx_uint32_t;    
#endif   

g. 然后打开cmd命令行,定位到前面创建的jni目录,执行ndk-build,则会生成相应的libSpeex.a(这里面不仅仅包含encode和decode,同时还包含降噪等操作,因为这里是整个项目全部编译了)

3.libSpeex.a的使用

将libSpeex.a拷贝到需要的工程目录中,然后将libSpeex下的.h文件和include中的.h文件全部拷贝到jni目录中,然后编写自己的Speex Native文件,可以是C或者C++的

Speex初始化

**ps:示例代码,仅供参考**
 preprocessState = speex_preprocess_state_init(RECORDER_FRAMES, SL_SAMPLINGRATE_16/1000);
    int denoise = 1, noiseSuppress = -25;
    speex_preprocess_ctl(preprocessState, SPEEX_PREPROCESS_SET_DENOISE, &denoise); //降噪
    speex_preprocess_ctl(preprocessState, SPEEX_PREPROCESS_SET_NOISE_SUPPRESS, &noiseSuppress); //设置噪声的
    //        int agc = 1, q=15000;
    ////        //actually default is 8000(0,32768),here make it louder for voice is not loudy enough by default. 8000
    //        speex_preprocess_ctl(preprocessState, SPEEX_PREPROCESS_SET_AGC, &agc);//增益
    //        speex_preprocess_ctl(preprocessState, SPEEX_PREPROCESS_SET_AGC_LEVEL,&q);

   int vad = 1;
   int vadProbStart = 99;
   int vadProbContinue = 99;
   speex_preprocess_ctl(preprocessState, SPEEX_PREPROCESS_SET_VAD, &vad); //静音检测
   speex_preprocess_ctl(preprocessState, SPEEX_PREPROCESS_SET_PROB_START , &vadProbStart); //Set probability required for the VAD to go from silence to voice
   speex_preprocess_ctl(preprocessState, SPEEX_PREPROCESS_SET_PROB_CONTINUE, &vadProbContinue); //Set probability

   //init speex encoder
   speex_bits_init(&ebits);
   enc_state = speex_encoder_init(&speex_wb_mode);
   speex_encoder_ctl(enc_state, SPEEX_SET_QUALITY, &compression);
   speex_encoder_ctl(enc_state, SPEEX_GET_FRAME_SIZE, &enc_frame_size);
   speex_encoder_ctl(enc_state, SPEEX_GET_SAMPLING_RATE, &sample_rate);
   pcm_buffer = malloc(enc_frame_size * sizeof(short));
   output_buffer = malloc(enc_frame_size * sizeof(char));

Speex编码

speex_encode_int(enc_state, pcm_buffer, &ebits);

Speex解码

speex_bits_read_from(&dbits, rtmp_pakt.m_body + 1, rtmp_pakt.m_nBodySize - 1);
speex_decode_int(dec_state, &dbits, output_buffer);

ps:使用speex_preprocess注意
在arch.h当中需要定义是否浮点运算,还是定点运算,这取决于cpu,这里是我选择定点运算FIXED_POINT

#define FIXED_POINT  //需要自己定义一个FIXED_POINT   or  FLOATING_POINT
/* A couple test to catch stupid option combinations */
#ifdef FIXED_POINT
#ifdef FLOATING_POINT

基本上Speex在Android上的使用就是这样。可以下载demo查看。Q&A,Thanks!

### 回答1: Android Speech Enhancement Library(也称为Speex降噪)是为Android平台开发的一个开源的语音增强库。该库使用Speex算法实现降低噪声、消除回声等功能,以提高语音通话和语音识别的质量。 Speex降噪算法主要通过对音频信号进行滤波处理来实现噪声的降低。它使用了自适应滤波器来减少来自噪声信号的干扰,同时保留语音信号的清晰度。它还可以通过自适应的谱减法进行扩频噪声抑制,从而降低背景噪声对语音信号的影响。 在Android平台上使用Speex降噪功能,首先需要导入Speech Enhancement Library的库文件,并进行初始化设置。其次,在需要增强语音的地方调用相关的API实现音频增强功能。最后,在通话或识别结束后,应释放资源。 使用Speex降噪模块可以提升语音通话和语音识别的准确性和可靠性。特别是在嘈杂的环境使用Speex降噪可以有效减少噪声对语音信号的干扰,提升语音的清晰度和可辨识度。 总而言之,Android Speex降噪是一种有效的语音增强技术,可以应用于Android平台的语音通话和语音识别应用,提升用户体验,增强声音质量。 ### 回答2: Android Speex是一种用于语音编解码的开源库,它主要用于实现语音通话的音频编解码。降噪是Android Speex的一个重要功能,用于减少噪音对语音质量的影响。 Android Speex的降噪功能采用幅度域噪音抑制(Noise Suppression,简称NS)技术。具体来说,它使用一种噪音噪声估计算法来分析音频信号的噪音成分,并根据噪音估计值对语音信号进行处理,从而在保持语音清晰度的前提下抑制噪音的干扰。 Android Speex的降噪功能通过对语音信号的频谱进行分析和处理来实现。在音频编解码时,它会对语音信号进行预处理,先对信号进行快速傅里叶变换(FFT),将时域的语音信号转换为频域的信号。然后对得到的频谱进行噪音估计和噪音补偿,将噪音的估计减去,以减少噪音对语音的干扰。最后将处理后的频域信号进行逆变换(IFFT),将频域的信号转换为时域的信号,再进行音频编解码。 Android Speex的降噪功能可以提供较好的语音质量和噪音抑制效果。在降低噪音干扰的同时,也能有效保留语音信号的清晰度和完整性。这对于语音通话和语音识别等应用场景都非常重要。同时,Android Speex的降噪功能也可以根据具体需求进行灵活配置,以适应不同环境和噪音条件下的语音处理需求。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值