编译依赖speex库的可执行文件测试speex性能
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := speextest
LOCAL_CFLAGS = -DFIXED_POINT -DUSE_KISS_FFT -DEXPORT="" -UHAVE_CONFIG_H
LOCAL_C_INCLUDES := $(LOCAL_PATH)/include
LOCAL_SRC_FILES := speex_test.cpp \
./libspeexdsp/buffer.c \
./libspeexdsp/fftwrap.c \
./libspeexdsp/filterbank.c \
./libspeexdsp/jitter.c \
./libspeexdsp/kiss_fft.c \
./libspeexdsp/kiss_fftr.c \
./libspeexdsp/mdf.c \
./libspeexdsp/preprocess.c \
./libspeexdsp/resample.c \
./libspeexdsp/scal.c \
./libspeexdsp/smallft.c \
./libspeex/bits.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/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/lpc.c \
./libspeex/lsp_tables_nb.c \
./libspeex/lsp.c \
./libspeex/ltp.c \
./libspeex/modes_wb.c \
./libspeex/modes.c \
./libspeex/nb_celp.c \
./libspeex/quant_lsp.c \
./libspeex/sb_celp.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_EXECUTABLE)
以下是对应的实现
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "speex/speex_echo.h"
#include "speex/speex_preprocess.h"
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <utils/Log.h>
#define NN 160
#define TAIL 160*8
#define DENOISE_DB (-90)
struct WAV_Format {
uint32_t ChunkID; /* "RIFF" */
uint32_t ChunkSize; /* 36 + Subchunk2Size */
uint32_t Format; /* "WAVE" */
/* sub-chunk "fmt" */
uint32_t Subchunk1ID; /* "fmt " */
uint32_t Subchunk1Size; /* 16 for PCM */
uint16_t AudioFormat; /* PCM = 1*/
uint16_t NumChannels; /* Mono = 1, Stereo = 2, etc. */
uint32_t SampleRate; /* 8000, 44100, etc. */
uint32_t ByteRate; /* = SampleRate * NumChannels * BitsPerSample/8 */
uint16_t BlockAlign; /* = NumChannels * BitsPerSample/8 */
uint16_t BitsPerSample; /* 8bits, 16bits, etc. */
/* sub-chunk "data" */
uint32_t Subchunk2ID; /* "data" */
uint32_t Subchunk2Size; /* data size */
};
int checkPath(const char *path)
{
char tmp[256];
int i = 0;
while (*path) {
tmp[i] = *path;
if (*path == '/' && i) {
tmp[i] = '\0';
if (access(tmp, F_OK) != 0) {
if (mkdir(tmp, 0770) == -1) {
return -1;
}
}
tmp[i] = '/';
}
i++;
path++;
}
return 0;
}
FILE* openFile(const char *filepath, char *mode)
{
int ret;
FILE *fp;
ret = checkPath(filepath);
if (ret < 0) {
printf("check patch %s fail\n", filepath);
} else {
fp = fopen(filepath, mode);
if (fp != NULL) {
printf("find %s \n", filepath);
return fp;
} else {
printf("open %s fail\n", filepath);
}
}
return NULL;
}
void wav2pcm(FILE *fp)
{
struct WAV_Format wav;
if (!fp) {
printf("can't open audio file\n");
exit(1);
}
fread(&wav, 1, sizeof(struct WAV_Format), fp);
printf("ChunkID \t%s\n", (char*)&wav.ChunkID);
printf("ChunkSize \t%d\n", wav.ChunkSize);
printf("Format \t\t%s\n", (char*)&wav.Format);
printf("Subchunk1ID \t%s\n", (char*)&wav.Subchunk1ID);
printf("Subchunk1Size \t%d\n", wav.Subchunk1Size);
printf("AudioFormat \t%d\n", wav.AudioFormat);
printf("NumChannels \t%d\n", wav.NumChannels);
printf("SampleRate \t%d\n", wav.SampleRate);
printf("ByteRate \t%d\n", wav.ByteRate);
printf("BlockAlign \t%d\n", wav.BlockAlign);
printf("BitsPerSample \t%d\n", wav.BitsPerSample);
printf("Subchunk2ID \t%x\n", wav.Subchunk2ID);
printf("Subchunk2Size \t%x\n", wav.Subchunk2Size);
fclose(fp);
printf("format check end\n");
}
int main(int argc, char **argv)
{
printf("set\n");
FILE *echo_fd, *ref_fd, *e_fd;
short echo_buf[NN], ref_buf[NN], e_buf[NN];
SpeexEchoState *st;
SpeexPreprocessState *process1;
SpeexPreprocessState *process2;
int sampleRate = 8000;
long length;
int i;
float f;
printf("open source file\n");
echo_fd = openFile("/sdcard/echo.wav", "rb");//参考信号
ref_fd = openFile("/sdcard/ref.wav", "rb");//需要消除噪音和回音的信号
e_fd = openFile("/sdcard/out.pcm", "wb");//处理之后的信号
fseek(echo_fd,44L,SEEK_SET);
fseek(ref_fd,44L,SEEK_SET);
printf("初始化消除噪音的对象\n");
process1 = speex_preprocess_state_init(NN, sampleRate);
i=1;
speex_preprocess_ctl(process1, SPEEX_PREPROCESS_SET_DENOISE, &i);
printf("get is noise %d\n", i);
int noiseSuppress = DENOISE_DB;
speex_preprocess_ctl(process1, SPEEX_PREPROCESS_SET_NOISE_SUPPRESS, &noiseSuppress); //设置噪声的dB
speex_preprocess_ctl(process1, SPEEX_PREPROCESS_GET_NOISE_SUPPRESS, &noiseSuppress);
printf("get noise DB %d\n", noiseSuppress);
i=0;
speex_preprocess_ctl(process1, SPEEX_PREPROCESS_SET_AGC, &i);
i=8000;
speex_preprocess_ctl(process1, SPEEX_PREPROCESS_SET_AGC_LEVEL, &i);
i=0;
speex_preprocess_ctl(process1, SPEEX_PREPROCESS_SET_DEREVERB, &i);
f=.0;
speex_preprocess_ctl(process1, SPEEX_PREPROCESS_SET_DEREVERB_DECAY, &f);
f=.0;
speex_preprocess_ctl(process1, SPEEX_PREPROCESS_SET_DEREVERB_LEVEL, &f);
printf("初始化消除回音的对象\n");
st = speex_echo_state_init(NN, TAIL);
process2 = speex_preprocess_state_init(NN, sampleRate);
speex_echo_ctl(st, SPEEX_ECHO_SET_SAMPLING_RATE, &sampleRate);
speex_preprocess_ctl(process2, SPEEX_PREPROCESS_SET_ECHO_STATE, st);
printf("process start\n");
while (!feof(ref_fd) && !feof(echo_fd))
{
//读取源数据
fread(ref_buf, sizeof(short), NN, ref_fd);
//消除噪音
speex_preprocess_run(process1, ref_buf);
//消除回音
fread(echo_buf, sizeof(short), NN, echo_fd);
speex_echo_cancellation(st, ref_buf, echo_buf, e_buf);
speex_preprocess_run(process2, e_buf);
//写入已处理数据,消除回音和噪音
fwrite(ref_buf, sizeof(short), NN, e_fd);
}
printf("process end\n");
speex_echo_state_destroy(st);
speex_preprocess_state_destroy(process1);
speex_preprocess_state_destroy(process2);
fclose(e_fd);
fclose(echo_fd);
fclose(ref_fd);
return 0;
}
该博客主要涉及使用编译后的Speex库执行性能测试,以评估其在音频处理中的效率和效果。内容涵盖了如何构建依赖Speex的可执行文件,并进行了详细的操作流程描述。
1万+

被折叠的 条评论
为什么被折叠?



