使用倒谱保留共振峰

信息处理 fft 倒谱分析
2022-02-09 05:21:01

我使用Stefan Bernsee 的代码实现了一个协调器,效果很好。我弄清楚了找到根音的逻辑,以及音阶中的正确和声。

唯一的问题是,我的高音听起来像是吸了太多氦气的人!

经过一番研究,我发现那是因为我没有保留共振峰。问题是我不知道该怎么做!我听说我必须使用倒谱,但仅此而已。

我修改的斯蒂芬的代码是:

/* ***************** PROCESSING ******************* */
        /* this does the actual pitch shifting */
        memset(mSynMagn, 0, mParent.mFftFrameSize * sizeof(float));
        memset(mSynFreq, 0, mParent.mFftFrameSize * sizeof(float));


        for (k = 0; k <= mParent.mFftFrameSize2; k++)
        {
            index = k * pitchShift;
            if (index <= mParent.mFftFrameSize2)
            {
                mSynMagn[index] = mParent.mAnaMagn[k];
                mSynFreq[index] = mParent.mAnaFreq[k] * pitchShift;
            }
        }

我想我必须弄乱 SynMagn 数组,但我不知道该怎么做。我认为计算倒谱,只是通过 manaMag 并记录日志?(哪个基数?)那么当我有那个倒谱时,我该怎么办?那些线应该变成什么?

    mSynMagn[index] = mParent.mAnaMagn[k];
    mSynFreq[index] = mParent.mAnaFreq[k] * pitchShift;
1个回答

您是否需要从原始和音高偏移信号中提取频谱包络,然后扭曲偏移频谱以与原始信号匹配!

您可以使用倒谱LPC或通道声码器来提取包络!

可以使用以下等式计算实际倒谱:

Rcepstrum=real(ifft(log(abs(fft(windowed_signal)))))

现在你需要低通吗Rcepstrum

最后FFT再次申请获得光谱包络,您将获得光谱的平滑版本!

此时您需要从 中获取差异光谱形状(Shifted-Original),这是您的校正因子,现在在偏移光谱中应用校正因子。

编辑

让我尝试展示它是如何完成的:

FFT1 = Original
FFT2 = Pitch shifted

从两个信号中获取真实倒谱:

cepstrum1 = real(ifft(log(abs(FFT1))));
cepstrum2 = real(ifft(log(abs(FFT2))));

倒谱的低通窗口:

选择一些索引值来截取倒谱(50、100、150),只获取第一个索引(例如 0 到 50)并完全置零。

从斜线窗口中提取信封

envelope1 = exp(2*real(fft(cep_cut1))); % spectral shape
envelope2 = exp(2*real(fft(cep_cut2))); % spectral shape

从信封中找出正确的因子:

warp_factor=(envelope1/envelope2)

应用更正:

new=(FFT2.*warp_factor)

再次将信号返回到时域(不要忘记,是否需要重叠和添加)

New_Formant_signal = real(ifft(new))

我的小测试有时给我的结果很差,也许你可以在 FFT 中使用一些峰值选择并插入结果以给出一个很好的包络,我会尝试一天,但我从来没有时间哈哈

当然,如果你是变音单声道信号,你可以使用 PSOLA 来保持共振峰的完整性......