c语言实现语音分帧加窗降噪例子
时间: 2023-06-03 08:07:55 浏览: 161
C语言实现kmp算法的C语言实现源码.zip
很高兴能为您解答问题。以下是一个基于C语言实现语音分帧加窗降噪的例子:
```
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define FRAME_SIZE 256 //每帧大小
#define FRAME_SHIFT 128 //帧移
#define WINDOW_SIZE 256 //加窗长度
#define PRE_EMPHASIS_FACTOR 0.95 //预加重系数
#define NOISE_FLOOR 1e-80 //噪音门限
double hamming( int n, int N ) //计算汉明窗系数
{
return 0.54 - 0.46 * cos( 2 * M_PI * n / (N-1) );
}
double pre_emphasis_filter( double x, double prev_x ) //预加重滤波器
{
return x - PRE_EMPHASIS_FACTOR * prev_x;
}
void fft( double *x, int N ) //快速傅里叶变换
{
//省略部分实现代码
}
double magnitude( double real, double imag ) //计算每一点的振幅
{
return sqrt( real * real + imag * imag );
}
int main()
{
int i, j, k, N, n, num_frames, frame_start;
double x, prev_x, hamming_win[WINDOW_SIZE], frame_energy;
double frame[FRAME_SIZE], fft_result[FRAME_SIZE], fft_mag[FRAME_SIZE/2+1];
double noise_floor, noise_spectrum[FRAME_SIZE/2+1], noise_energy[FRAME_SIZE/2+1];
//初始化汉明窗
for ( i=0; i<WINDOW_SIZE; i++ )
hamming_win[i] = hamming( i, WINDOW_SIZE );
//读入音频数据并预加重滤波
//省略部分实现代码
//x表示读入的音频数据,prev_x表示上一帧的最后一个样本点
//计算帧数
N = num_samples - FRAME_SIZE;
num_frames = N / FRAME_SHIFT;
//初始化噪声能量谱
for ( i=0; i<FRAME_SIZE/2+1; i++ )
noise_spectrum[i] = 0;
//分帧并加窗、快速傅里叶变换
for ( i=0; i<num_frames; i++ )
{
frame_start = i * FRAME_SHIFT;
//按照帧长分帧
for ( j=0, n=frame_start; j<FRAME_SIZE; j++, n++ )
{
frame[j] = pre_emphasis_filter( x[n], prev_x );
prev_x = x[n];
}
//加窗
for ( j=0; j<FRAME_SIZE; j++ )
frame[j] *= hamming_win[j];
//快速傅里叶变换
fft( frame, FRAME_SIZE );
for ( j=0; j<FRAME_SIZE; j+=2 )
fft_result[j/2] = magnitude( frame[j], frame[j+1] );
//计算每帧的总能量
frame_energy = 0;
for ( j=0; j<FRAME_SIZE; j++ )
frame_energy += frame[j] * frame[j];
//计算每个频带的噪声能量和噪声能量谱
for ( j=0; j<FRAME_SIZE/2+1; j++ )
{
fft_mag[j] = fft_result[j];
if ( fft_mag[j] > noise_floor )
{
noise_energy[j] = (1-0.95) * noise_energy[j] + 0.95 * fft_mag[j] * fft_mag[j];
noise_spectrum[j] += fft_mag[j] * fft_mag[j];
}
}
//更新噪声门限
noise_floor = 0;
for ( j=0; j<FRAME_SIZE/2+1; j++ )
noise_floor += noise_energy[j] / ( noise_spectrum[j] / num_frames );
noise_floor *= NOISE_FLOOR;
//降噪处理
for ( j=0; j<FRAME_SIZE/2+1; j++ )
{
if ( fft_mag[j] < noise_floor )
fft_mag[j] = 0;
}
//输出该帧音频的处理结果
//省略部分实现代码,例如写入文件或播放
}
return 0;
}
```
希望能够帮助您实现语音处理。
阅读全文