2017-08-08 87 views
0

我试图使用相位声码器来冻结声音。我通过存储光谱帧(幅度和相位)以及前一帧和当前帧之间的相位差来实现这一点。要播放冻结帧,我只需将频谱帧重复插入相位声码器的反相功能中,每次使用相位差值递增(并缠绕)相位。将2个相位声码器帧混合在一起

这里是我现在正在做的一些伪码(为了简洁),其中frameA和frameB是相位声码器的fft表示的幅度/相位表示。

void analyze(inputSignal) { 
    // convert time domain "inputSignal" to frequency domain 
    frameA = vocoder.forward(inputSignal); 

    // calculate the inter-frame phase delta 
    phaseDeltaA = frameA.phase - lastPhases; 
    lastPhases = frameA.phase; 
} 

void playback(outputSignal) { 
    frameA.phase += phaseDeltaA; 
    outputSignal = vocoder.reverse(frameA); 
} 

它很好用。但我想要做的是将这个冻结的光谱帧与其他“冻结”帧(积累它们)结合起来。

我试过把帧加在一起,也尝试过把相位差加在一起,但它只是产生讨厌的噪音。

void analyze(inputSignal) { 

    ... 

    // naively sum the magnitudes and phases of both frames 
    combinedFrame.magnitude = frameA.magnitude + frameB.magnitude; 
    combinedFrame.phase = frameA.phase + frameB.phase; 

    // sum the phase deltas 
    combinedPhaseDelta = phaseDeltaA + phaseDeltaB; 

} 
void playback(outputSignal) { 
    combinedFrame.phase += combinedPhaseDelta; 
    outputSignal = vocoder.reverse(combinedFrame); 
} 

回答

0

将delta相位加在一起会改变频率,因此破坏了使合成声音“良好”所需的任何谐波关系。

另一个可能的解决方案是组合不是帧,而是完整的合成音轨。例如确保每个相位声码器合成的声音轨道本身听起来不错,然后使用混合器来合成结果。

+0

我同意在将它们移回到时域后将它们相加可以起作用(我实际上有这个工作,以便听到它应该听起来像什么),但是我想在频域中这样做,所以我不用没有必要做更多的IFFT比我需要。我以为因为FFT是线性的,你应该能够以某种方式添加这两个信号。只是无法摆脱它。 – mazbox