Python 串联频率变化的正弦信号

Python 串联频率变化的正弦信号,python,audio,concatenation,trigonometry,Python,Audio,Concatenation,Trigonometry,这是我第一次使用音频,我试图连接任意(数据驱动)频率的正弦波,但无法消除因sins之间的不连续性而产生的咔哒噪音 我在读关于使频率成为相位的函数以线性增加波的频率的书,但我不知道如何使其适应任意频率的变化 我在计算前一个正弦信号的相移,然后尝试相应地移动下一个正弦信号,但这似乎只是使声音更高音,并没有消除咔嗒声 def audio_map(data): p=[] phase = 0 for point in data: if point[0]<0: f=100

这是我第一次使用音频,我试图连接任意(数据驱动)频率的正弦波,但无法消除因sins之间的不连续性而产生的咔哒噪音

我在读关于使频率成为相位的函数以线性增加波的频率的书,但我不知道如何使其适应任意频率的变化

我在计算前一个正弦信号的相移,然后尝试相应地移动下一个正弦信号,但这似乎只是使声音更高音,并没有消除咔嗒声

def audio_map(data):
p=[]
phase = 0 
for point in data: 
    if point[0]<0: 
        f=100*np.abs(point[0])
    else:
        f=100*point[0]
#Do something with the phase to shift the sinusoid below??? 
p=np.concatenate((p,np.sin((4*np.pi*f/sampling_rate)*np.arange(sampling_rate*np.pi/(16)))))
    phase=f*np.pi/16

return p
def音频映射(数据):
p=[]
相位=0
对于点输入数据:
如果点[0]编辑

我对你选择的正弦函数也有点困惑,它看起来不像系数或持续时间与真实世界的值有关,我希望看到这样的情况:

p = np.concatenate((p, np.sin((2 * np.pi * f / sampling_rate) * np.arange(total_tone_time * sampling_rate) + phase)))
phase += 2 * np.pi * f * total_tone_time
phase %= 2 * np.pi  # strip off full cycles to avoid overflow
在哪里

  • total_tone_time是当前播放音调的持续时间
  • 采样率以hz为单位(每秒采样数)
在每个项之间添加相位的目的是保持合成曲线的连续性,这可能有助于避免波形中出现任何POP。如果听不到任何声音,请确保输出的频率在可听见的范围内:

我会先尝试上面的建议,然后再尝试下面所说的内容,这些内容会深入到兔子洞的深处

/EDIT

不是专家,但我认为你所说的导致点击的不连续性可能是正确的。如果是,您可以在接合处快速淡出/淡入振幅,以避免咔嗒声

以下是我能想到的一些其他可能性

型号和尺寸

你是如何采样频率的?它们是在特定的时间采样的,所以你可以得到频率作为时间的函数吗?如果是这样,您可以尝试将曲线拟合到点(这是一个非常重要的问题),然后取计算曲线积分的正弦:

Sin[2*PI*积分[freq(time),time,0,current_time]]

数值积分

作为拟合曲线的替代方法,如果频率采样率足够快,可以近似平滑曲线,则可以直接在数值积分中使用这些值。对于下面的示例,我假设您的数据格式为[[freq0,time0],[freq1,time1],…],并且频率采样随时间均匀分布,与您希望采样输出波形的速率相同

PI = 3.14159
waveform = [0] * len(data)
phase = 0
time_delta = data[1][1] - data[0][1]
for i, (f, t) in enumerate(data):
    if i != 0:
        phase += 0.5 * (f + last_f) * time_delta
        waveform[i] = sin(2 * PI * phase)
    last_f = f
    phase %= 2 * PI
请注意,对于以上内容,我使用梯形方法,如下所述:

关于这种方法,我关心的一件事是,你要取的是频率的绝对值,这向我表明,你的频率可能不是从产生良好行为的连续函数的数据源中采样的

添加渐变

最后,如果您是从一个没有直接时间依赖性的随机样本连接频率,那么您可以添加一个频率渐变来弥补这一差距

您可以尝试线性:

sin(PI * [(f2 - f1) / time_frame * t ** 2 + 2 * f1 * t])
或指数:

sin(2 * PI * time_frame * f1 * exp(log(f2 / f1) * t / time_frame) / log(f2 / f1))
在哪里

  • time_frame是希望渐变持续的持续时间
  • 选择t从零开始,在时间帧结束
  • f1是剩余的频率
  • f2是输入的频率

非常感谢您的详尽回答!!我从你的帖子中学到了很多。对于阅读本文的任何其他人来说,在玩了一天之后,我终于意识到我可以确保我的连接发生在零交叉点(即,每个西诺索伊德都连接一个整数倍的周期),但梅里迪厄斯的上述一切将在我工作的后续迭代中证明是有用的。[例如,我使用了类似于p=np.concatenate((p,np.sin((4*np.pi*f/采样率))*np.arange(50*采样率/(4*f')))]