连接不同频率的正弦曲线

时间:2015-01-23 03:57:16

标签: python audio concatenation sin

这是我第一次使用音频而且我试图连接任意(数据驱动)频率的正弦曲线,并且无法消除由于两者之间的不连续性而导致的咔嗒声。罪孽。

我正在阅读this thread关于使频率成为相位函数以便线性增加波的频率,但无法弄清楚如何使其适应任意频移。

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

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

感谢您的帮助!!

1 个答案:

答案 0 :(得分:3)

修改

我也对你选择的正弦函数感到有些困惑,它看起来不像系数或持续时间与现实世界的价值观有关,我希望看到这样的东西:

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是当前正在播放的音调的持续时间
  • sampling_rate以hz(每秒样本数)计算

在每个术语之间添加相位的目的是使得到的复合曲线保持连续,这可能有助于避免波形中的任何弹出。如果您听不到任何声音,请确保输出的频率在可听范围内:http://en.wikipedia.org/wiki/Audio_frequency

我会先尝试上面的建议,然后再尝试我下面谈到的内容,这会更深入地挖掘兔子洞。

<强> /修改

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

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

模型和适合

您如何对频率进行采样?它们是在特定时间采样的,因此您可以将频率作为时间的函数吗?如果是这样,您可以尝试将曲线拟合到点(这是一个非平凡的问题),然后取计算曲线的积分的正弦值:

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

请注意,对于上面我使用的是梯形方法,如下所述:http://www.mathworks.com/help/matlab/ref/trapz.html#bua4lsr

关于这种方法我关注的一点是你正在考虑频率的绝对值,这表明你的频率可能无法从数据源中采样,从而产生良好的连续函数。

添加斜坡

最后,如果您从随机样本中连接没有直接时间依赖性的频率,您可以添加频率斜坡来弥补差距。

您可以尝试线性:

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选择从零开始并在time_frame结束
  • f1是留下的频率
  • f2是输入的频率