2017-08-08 62 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