对于我的一个音乐项目,我正在播放周期性音频信号(通过循环单个周期)。不幸的是,我的一个波形听起来太安静了(即使在最大音量下)。
我正在尝试使用 FFT 来获得谐波强度,然后对每个谐波进行相移以最小化峰峰值幅度,然后放大信号。
是否有任何算法可以找到最佳相移,或者我应该使用scipy.optimize.basinhopping(或生成数千个随机相位)以获得近似结果?
对于我的一个音乐项目,我正在播放周期性音频信号(通过循环单个周期)。不幸的是,我的一个波形听起来太安静了(即使在最大音量下)。
我正在尝试使用 FFT 来获得谐波强度,然后对每个谐波进行相移以最小化峰峰值幅度,然后放大信号。
是否有任何算法可以找到最佳相移,或者我应该使用scipy.optimize.basinhopping(或生成数千个随机相位)以获得近似结果?
有用于确定低峰值因子信号的算法,例如:
“低自相关 (Corresp.) 的低峰值因子信号和二进制序列的合成”,M. Schroeder,1970
我已将其用于平谱信号以最小化峰峰值幅度。
但是我认为这可能是一个 XY 问题。您对可以给信号引入多少失真有限制吗?您是否尝试过使用动态范围压缩算法?有一些限制算法可以显着增加 RMS 幅度,而不会引入明显的音频伪影。
我认为 FFT 不是解决此问题的合适工具。如果您知道波形中谐波的幅度,我认为最好的方法是粗略搜索具有最小最大值的组合。一旦找到,您可以进行梯度搜索以获得最佳值,或者可能更容易,在最佳粗略搜索结果附近进行另一次蛮力精细搜索。当您找到具有最低最大值的组合(也不要忘记包括波谷)时,您可以将所有幅度相乘以使峰值达到削波极限。
希望这可以帮助,
赛德
================================================
跟进:
我很好奇用 Python 编写代码。干得好:
从数组导入数组
将 numpy 导入为 np
将 matplotlib.pyplot 导入为 plt
#=================================================
定义主():
# - - 设置
N = 200
RPS = 2 * np.pi / N # 每个样本的弧度
P = array( 'd', [0,0,0,0,0] ) # 阶段
A = array( 'd', [0,1,1,1,1] ) # 幅度
#---- 粗略搜索
步长 = 2 * np.pi / 20
MP = FindSmallestPeakPhases(RPS, N, A, P, Step)
#---- 精细搜索
步长 /= 20
MP = FindSmallestPeakPhases(RPS, N, A, MP, Step)
#---- 更精细的搜索
步长 /= 20
MP = FindSmallestPeakPhases(RPS, N, A, MP, Step)
#---- 打印结果
打印“1:”,MP[1]
打印“2:”,MP[2]
打印“3:”,MP[3]
打印“4:”,MP[4]
#---- 从结果构建波
x = np.arange(N)
Tone1 = A[1] * np.sin( x*RPS + MP[1] )
Tone2 = A[2] * np.sin( 2*x*RPS + MP[2] )
Tone3 = A[3] * np.sin( 3*x*RPS + MP[3] )
Tone4 = A[4] * np.sin( 4*x*RPS + MP[4] )
Wave = Tone1 + Tone2 + Tone3 + Tone4
#---- 从结果中显示波形
plt.plot(x, Wave, c='g')
plt.show()
# - - 出口
打印“完成”
返回
#=================================================
def FindSmallestPeakPhases(RPS, N, A, P, Step):
MinPhases = 数组('d',[0,0,0,0,0])
x = np.arange(N)
峰值 = 1000
Wave1 = A[1] * np.sin( x*RPS + P[1] )
阶段 1 = P[1]
MinPhases[1] = 阶段 1
对于范围内的 p2 ( 1, 22 ):
Phase2 = P[2] + ( p2 - 11 ) * 步长
Tone2 = A[2] * np.sin(2*x*RPS + Phase2)
Wave2 = Wave1 + Tone2
对于范围内的 p3 ( 1, 22 ):
Phase3 = P[3] + ( p3 - 11 ) * 步长
Tone3 = A[3] * np.sin( 3*x*RPS + Phase3 )
Wave3 = Wave2 + Tone3
对于范围内的 p4 ( 1, 22 ):
Phase4 = P[4] + ( p4 - 11 ) * 步长
Tone4 = A[4] * np.sin( 4*x*RPS + Phase4 )
Wave4 = Wave3 + Tone4
最小值 = min( Wave4 )
最大值 = 最大值(Wave4)
如果 Max > -Min:
AbsMax = 最大值
别的:
AbsMax = -Min
如果 AbsMax < 峰值:
峰值 = AbsMax
MinPhases[2] = Phase2
MinPhases[3] = Phase3
MinPhases[4] = Phase4
打印“峰值=”,峰值
返回最小阶段
#=================================================
主要的()