Speex的安装使用

感情迁移 提交于 2020-03-01 12:01:41

从链接中https://www.speex.org/downloads/下载Speex 1.2.0、SpeexDSP 1.2rc3。

编译和安装

下载以后解压,然后点击INSTALL,根据其中的命令进行安装,具体的安装方式也可以看解压后doc目录中manual.pdf的第3章。

% ./configure [--prefix=<install-path>]
%make
%make install
其设置支持是通过Speex配置脚本的,这些命令选项跟在 ./configure设置 :
-prefix=<path> 指定Speex安装其本路径(如 /usr)
-enable-shared/-disable-shared  是否编译共享库
-enable-static/-disable-static  是否编译静态库
-disable-wideband 取消Speex的宽带部分(典型的节省空间)
-enable-valgrind  为调试目的启用额外valgrind的命中率
-enable-sse  启用SSE指令(只在 x86/浮点)
-enable-fixed-point 编译Speex为无浮点单位(FPU)处理器
-enable-arm4-asm 启用汇编指定为ARMv4架构(只在gcc
-enable-arm5e-asm 启用汇编指定为ARMv5E架构只在gcc
-enable-fixed-point-debug 只使用调试定点码(非常慢)
-enable-epic-48k 启用一个专门(不兼容)4.8kbps窄带模式(在1.1.x和1.2beta)
-enable-ti-c55x 启用支持TI C5x族
-enable-blackfin-asm 启动汇编指定为Blackfin DSP架构
-enable-vorbis-psycho 使编码器使用Vorbis心理学模型。这是非常实验性,可能在将来会被移除

对于去除音频中的噪声,manual.pdf中第6章有写到语音处理的API,即libspeexdsp。在1.2rc3版本中,speex中和编码无关的部分被分离出来作为单独的库-libspeexdsp,在speexdsp压缩包里面。这个库包含了预处理(去噪在里面),回声消除,jitter buffer和重采样。UNIX系统中可以通过添加-lspeexdsp -lm到编译器命令行链接到一个program。

6.1节中 Preprocessor
要在程序中使用speex preprocessor,需要添加头文件
#include <speex/speex_preprocess.h>

然后创建preprocessor state的方式为:
SpeexPreprocessState*preprocess_state=speex_preprocess_state_init(frme_size,sampling_rate);

frme_size建议设置为和编码器相同的值,对每个输入的帧,应该这样声明:
speex_preprocess_run(preprocess_state, audio_frame); 

这里的audio_frame在输入和输出中都被使用,在输出音频对某一帧没有用处的情况下,可以使用:

speex_preprocess_estimate_update(preprocess_state, audio_frame); 

这将更新所有预处理器内部状态变量,而不用计算输出音频,因此节省CPU计算时间。

预处理器的方式更改为:
speex_preprocess_ctl(preprocess_state, request, ptr); 

这和编码、解码器使用的方式相同,具体选项在6.1.1节中,这个预处理器的状态能被销毁:
speex_preprocess_state_destroy(preprocess_state); 

6.1.1

As with the codec, the preprocessor also has options that can be controlled using an ioctl()-like call. The available options are:

和编解码器相同,预处理器可以使用ioct1()-like声明,选项为:
SPEEX_PREPROCESS_SET_DENOISE Turns denoising on(1) or off(2) (spx_int32_t)
SPEEX_PREPROCESS_GET_DENOISE Get denoising status (spx_int32_t)
SPEEX_PREPROCESS_SET_AGC Turns automatic gain control (AGC) on(1) or off(2) (spx_int32_t)
SPEEX_PREPROCESS_GET_AGC Get AGC status (spx_int32_t)
SPEEX_PREPROCESS_SET_VAD Turns voice activity detector (VAD) on(1) or off(2) (spx_int32_t)
SPEEX_PREPROCESS_GET_VAD Get VAD status (spx_int32_t)
SPEEX_PREPROCESS_SET_AGC_LEVEL
SPEEX_PREPROCESS_GET_AGC_LEVEL
19
6 Speech Processing API (libspeexdsp)
SPEEX_PREPROCESS_SET_DEREVERB Turns reverberation removal on(1) or off(2) (spx_int32_t)
SPEEX_PREPROCESS_GET_DEREVERB Get reverberation removal status (spx_int32_t)
SPEEX_PREPROCESS_SET_DEREVERB_LEVEL Not working yet, do not use
SPEEX_PREPROCESS_GET_DEREVERB_LEVEL Not working yet, do not use
SPEEX_PREPROCESS_SET_DEREVERB_DECAY Not working yet, do not use
SPEEX_PREPROCESS_GET_DEREVERB_DECAY Not working yet, do not use
SPEEX_PREPROCESS_SET_PROB_START
SPEEX_PREPROCESS_GET_PROB_START
SPEEX_PREPROCESS_SET_PROB_CONTINUE
SPEEX_PREPROCESS_GET_PROB_CONTINUE
SPEEX_PREPROCESS_SET_NOISE_SUPPRESS Set maximum attenuation of the noise in dB (negativespx_int32_t
)
SPEEX_PREPROCESS_GET_NOISE_SUPPRESS Get maximum attenuation of the noise in dB (negativespx_int32_t
)
SPEEX_PREPROCESS_SET_ECHO_SUPPRESS Set maximum attenuation of the residual echo in dB (negative spx_int32_t
)
SPEEX_PREPROCESS_GET_ECHO_SUPPRESS Set maximum attenuation of the residual echo in dB (negativespx_int32_t
)
SPEEX_PREPROCESS_SET_ECHO_SUPPRESS_ACTIVE Set maximum attenuation of the echo in dB when near
end is active (negative spx_int32_t)
SPEEX_PREPROCESS_GET_ECHO_SUPPRESS_ACTIVE Set maximum attenuation of the echo in dB when near
end is active (negative spx_int32_t)
SPEEX_PREPROCESS_SET_ECHO_STATE Set the associated echo canceller for residual echo suppression (pointer
or NULL for no residual echo suppression)
SPEEX_PREPROCESS_GET_ECHO_STATE Get the associated echo canceller (pointer)

 

Eclipse库中添加speexdsp的步骤:

添加Include链接:Project->Property->C/C++ Build->Setting->Tool Settings->GCC C Compiler->Includes,将编译好的include/speex目录放进来。
添加静态库:Project->Property->C/C++ Build->Setting->Tool Settings->GCC C Linker->Miscellaneous->other Objects:在文件系统中找到**.a加入。这里添加静态库编译没有通过,动态库才通过。


静态库编译报错以后,就编译的动态库,如果编译的是动态库,就需要添加动态库:Project->Property->C/C++ Build->Setting->Tool Settings->GCC C Linker->Libraries。
其中Libraries是.so的动态库名称,Librarysearch path是包含动态库的路径

编写c文件时,speexdsp_config_types.h增加#include <stdint-gcc.h>头文件

main.c 

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <assert.h>
#include <string.h>
#include <stdbool.h>
#include <speex/speex_preprocess.h>

#define HEADLEN 44
#define SAMPLE_RATE   (16000) #采样率
#define SAMPLES_PER_FRAME  (1024) #每帧的采样数
#define FRAME_SIZE   (SAMPLES_PER_FRAME * 1000/ SAMPLE_RATE) #每帧的时长ms
#define FRAME_BYTES  (SAMPLES_PER_FRAME) 
//typedef enum {false, true} bool;
char *splitword(char *word,char *neword){  
	char *out="out_";
	for(int j=0;j<strlen(word)+4;j++){
		if (j<4)
			neword[j]=out[j];
		else
			neword[j]=word[j-4];
	}
	return neword;
}
int main(int argc,char ** argv){
    size_t n = 0;
    FILE *inFile, *outFile;
    char * copy = malloc(sizeof(char)*(strlen(argv[1]) + 1));
    strcpy(copy, argv[1]);
    char *neword;
    neword=(char *)malloc(strlen(argv[1])+4);
    char *output=splitword(copy,neword);

    inFile=fopen(argv[1], "rb");
    outFile=fopen(output, "wb");
    char *headBuf = (char*)malloc(HEADLEN);
    char *dataBuf = (char*)malloc(FRAME_BYTES * 2 );
    memset(headBuf, 0, HEADLEN);
    memset(dataBuf, 0, FRAME_BYTES);
    assert(headBuf != NULL);
    assert(dataBuf != NULL);

    SpeexPreprocessState *state = speex_preprocess_state_init(1024,SAMPLE_RATE);
    int denoise = 1;
    int noiseSuppress = -25;
    speex_preprocess_ctl(state, SPEEX_PREPROCESS_SET_DENOISE, &denoise);
    speex_preprocess_ctl(state, SPEEX_PREPROCESS_SET_NOISE_SUPPRESS, &noiseSuppress);

    int i;
    i = 0;
    speex_preprocess_ctl(state, SPEEX_PREPROCESS_SET_AGC, &i);
    i = 9000;
    speex_preprocess_ctl(state, SPEEX_PREPROCESS_SET_AGC_LEVEL, &i);
//    i = 10000;
//    speex_preprocess_ctl(state, SPEEX_PREPROCESS_SET_DEREVERB, &i);
    //静音检测的效果一般
    /*
    int vad = 1;
    int vadProbStart = 80;
    int vadProbContinue = 65;
    speex_preprocess_ctl(state, SPEEX_PREPROCESS_SET_VAD, &vad);
    speex_preprocess_ctl(state, SPEEX_PREPROCESS_SET_PROB_START, &vadProbStart);
    speex_preprocess_ctl(state, SPEEX_PREPROCESS_SET_PROB_CONTINUE, &vadProbContinue);
    */
    bool flag=true;
    while (1){
        if (flag == true){
            flag = false;
            n = fread(headBuf, 1, HEADLEN, inFile);
            if (n == 0)
                break;
            fwrite(headBuf, 1, HEADLEN, outFile);
        }
        else{
            n = fread(dataBuf, 1, SAMPLES_PER_FRAME, inFile);
            if (n == 0)
                break;
            speex_preprocess_run(state, (spx_int16_t*)(dataBuf));
            fwrite(dataBuf, 1, SAMPLES_PER_FRAME, outFile);
        }
    }
    free(headBuf);
    free(dataBuf);
    fclose(inFile);
    fclose(outFile);
    speex_preprocess_state_destroy(state);
    return 0;
}

编译以后的使用方法 

./可执行文件 *.wav

Speex文档:https://www.speex.org/docs/api/speex-api-reference/modules.html
参考的内容:
https://blog.csdn.net/zsJum/article/details/7555025

https://blog.csdn.net/fireroll/article/details/83347795

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!