基本概念
最小相位脉冲响应[1]可以保证波形在时域上基本不变。
根据频谱包络求出最小相位响应(减弱时域信号的相位失真),然后IFFT还原为语音信号
其中
A
A
A跟频谱包络有关
##合成流程
合成[2]分为三步
- 根据
f
0
f_0
f0确定脉冲的位置
对分帧的频谱插值获得脉冲对应的频谱 s p e c t r u m spectrum spectrum - 时域周期信号
2.1 求出频谱包络中周期部分,然后过最小相位脉冲响应
p e r i o d _ s p e c t r u m = s p e c t r u m [ i ] ⋅ ( 1 − a p e r i o d i c _ r a t i o [ i ] ) period\_spectrum=spectrum[i] \cdot (1-aperiodic\_ratio[i]) period_spectrum=spectrum[i]⋅(1−aperiodic_ratio[i])
2.2 反傅里叶变换得到时域信号,并去除直流分量
R e m o v e D C ( I F F T ( p e r i o d _ s p e c t r u m ) ) RemoveDC(IFFT(period\_spectrum)) RemoveDC(IFFT(period_spectrum)) - 时域非周期信号
3.1 求出频谱包络中非周期部分,然后过最小相位脉冲响应
a p e r i o d _ s p e c t r u m = s p e c t r u m [ i ] ⋅ a p e r i o d i c _ r a t i o [ i ] aperiod\_spectrum=spectrum[i] \cdot aperiodic\_ratio[i] aperiod_spectrum=spectrum[i]⋅aperiodic_ratio[i]
3.2 高斯白噪声的幅度谱
n o i s e _ s p e c t r u m = F F T ( n o i s e ) noise\_spectrum=FFT(noise) noise_spectrum=FFT(noise)
3.3 获取最后的非周期时域信号
I F F T ( a p e r i o d _ s p e c t r u m ⋅ n o i s e _ s p e c t r u m ) IFFT(aperiod\_spectrum\cdot noise\_spectrum) IFFT(aperiod_spectrum⋅noise_spectrum) - 时域周期信号和时域非周期信号相加得到最后的合成信号
代码细节
GetTimeBase()
synth->interpolated_vuv:voice的概率
synth->pulse_locations:脉冲对应的时间
synth->pulse_locations_index:脉冲对应的采样点
1.线性插值的到每个sample对应的f0和vuv
原来5ms对应一帧,有一个f0,扩展到每一个采样点一个f0,直接线性插值
2.获取pulse location,参考wiki
每个采样点对应的
p
h
a
s
e
=
2
π
f
0
f
s
phase=\frac{2\pi f_0}{f_s}
phase=fs2πf0
每个采样点对应的累积相位
每个采样点对应的
w
r
a
p
_
p
h
a
s
e
=
t
o
t
a
l
_
p
h
a
s
e
m
o
d
2
π
wrap\_phase=total\_phase\ mod\ 2\pi
wrap_phase=total_phase mod 2π
每个采样点对应的
w
r
a
p
_
p
h
a
s
e
[
n
]
−
w
r
a
p
_
p
h
a
s
e
[
n
−
1
]
>
π
wrap\_phase[n] - wrap\_phase[n-1]>\pi
wrap_phase[n]−wrap_phase[n−1]>π即为新的pulse的起点
参考文献
[1].speech representation and transformation using adaptive interpolation of weighted spectrum vocoder revisited
[2].https://github.com/mmorise/World