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