双麦克风语音去混响算法C代码实现(附github项目链接)

1. 算法依据

算法的依据是论文《Multi-Channel Linear Prediction Speech Dereverberation Algorithm Based on QR-RLS Adaptive Filter》提出的QR-MCLP模型。文中提出的MCLP是目前比较常见的语音去混响模型,使用QR分解是为了避免使用RLS做矩阵逆运算时出现的不稳定问题

2. 代码逻辑

音频的输入和输出都是32kHz的双通道pcm文件。因为wav文件和pcm文件之间数据存在32768的倍数差异,所以若使用wav文件需要进行格式转化成pcm文件

2.1 正交分解

由于语音部分主要存在低频区域,所以算法主要对低16kHz的部分去混响,高16kHz部分不做任何处理,来提升计算的效率

InnoTalkSpl_AnalysisQMF(mic1_s, shInL1, shInH1, ch1filter_state1, ch1filter_state12); //通道一分解
InnoTalkSpl_AnalysisQMF(mic2_s, shInL2, shInH2, ch2filter_state1, ch2filter_state12); //通道二分解
/* 算法主体部分,对 shInL1 和 shInL2 两个通道低频分量进行滤波处理 */
InnoTalkSpl_SynthesisQMF(shInL1, mict1, out_frameN1, ch1Synthesis_state1, ch1Synthesis_state12);  //通道一合成
InnoTalkSpl_SynthesisQMF(shInL2, mict2, out_frameN2, ch2Synthesis_state1, ch2Synthesis_state12); //通道二合成

2.2 STFT

对混响信号做STFT变换,选择1024点(32ms)的汉明窗,帧移半帧长。

SignalDFT(shInL1, sigArray1, FFT_SIZE, NN, 1);
SignalDFT(shInL2, sigArray2, FFT_SIZE, NN, 1);

2.3 重加权系数计算

模型是对每一帧的每个频点进行操作,一共有513个频点。在初始化之后计算源信号、期望信号和后期混响的PSD,并以此计算重加权参数

for (int j = 0; j < nchan; j++)
{
    
    
	x_abs_2[j] = pow(cmod(mcl[j]),2);  //这里是实数
	sigema_x[k][curframe][j] = alfa * sigema_x[k][curframe - 1][j] + alfa_1 * x_abs_2[j];
	sigema_r[k][curframe][j] = coff1 * sigema_x[k][curframe-ND][j];
	sigema_d[k][curframe][j] = alfa * sigema_d[k][curframe-1][j] + alfa_1 * max((x_abs_2[j] - sigema_r[k][curframe][j]), 0);
}
w_2[k][curframe] = pow((pow(sigema_d[k][curframe][0], 2) + pow(sigema_d[k][curframe][1], 2)) / nchan + eps_1, p / 2 - 1);

2. 4 QR分解

qrgv_1(R_qr, D_total, k);

2.5 回代求解滤波器系数

backsolution(G_hat_total, R_qr_MLg, d_qr_M, chan, k);

2.6 获得混响分量并减去

for (int i = 0; i < Lg * nchan; i++)
{
    
    
	u[0] = cplus(u[0], cpro(G_hat_total[i][0][k], x_tau[i]));
	u[1] = cplus(u[1], cpro(G_hat_total[i][1][k], x_tau[i]));
}
d[0] = cminus(mcl[0], u[0]);
d[1] = cminus(mcl[1], u[1]);

3. github工程链接

https://github.com/rickie-mi/Adaptive-Speech-Dereverberation-based-on-QR-MCLP-model

猜你喜欢

转载自blog.csdn.net/qq_40017011/article/details/122292702
今日推荐