首页 > 解决方案 > 如何消除频率之间的“点击”?

问题描述

我编写了一个脚本来生成频率并将它们写入波形文件。我的问题是每个频率前后都有“咔哒”声。

我知道这个点击出现然后是正弦波被打破。但是我怎样才能避免这种情况呢?我想创建一个这样的欧洲信号发生器: https ://wellen.uber.space/doku.php/user:vicuni:amateurfunk:software:eurosignal

链接文件的问题是它已有 10 多年的历史,我无法让它在我的 Python 上运行。我正在使用 Python 3.8

这是我的 Python 脚本:

import structimport numpy as np
from scipy import signal as sg
import wave

# Parameters
sampleRate = 44100
frequency = 400
duration = 1


# define wave file
file = wave.open('test.wav', 'w')
file.setnchannels(1)
file.setsampwidth(2)
file.setframerate(sampleRate)



def generate(output, freq, dur):
    # create sine wave
    samples = dur*sampleRate
    x = np.arange(samples)
    sineWave = (32767.0*np.sin(2 * np.pi * freq * x / sampleRate))

for i in sineWave:
    value = i
    data = struct.pack('<h', int(value))
    output.writeframesraw(data);


for x in range(1):
    generate(file, 1153.1, 1.0)
    generate(file, 1062.9, 0.1)
    generate(file, 1153.1, 1.0)
    generate(file, 1062.9, 0.1)
    generate(file, 1153.1, 1.0)
    generate(file, 1062.9, 0.1)

    generate(file, 510.7, 0.1)
    generate(file, 832.5, 0.1)
    generate(file, 652.0, 0.1)
    generate(file, 554.0, 0.1)
    generate(file, 470.8, 0.1)
    generate(file, 510.7, 0.1)
    generate(file, 0.0, 0.22)

    generate(file, 1153.1, 0.22)

    generate(file, 510.7, 0.1)
    generate(file, 832.5, 0.1)
    generate(file, 652.0, 0.1)
    generate(file, 554.0, 0.1)
    generate(file, 470.8, 0.1)
    generate(file, 510.7, 0.1)
    generate(file, 0.0, 0.22)

    generate(file, 1153.1, 0.22)

    generate(file, 510.7, 0.1)
    generate(file, 832.5, 0.1)
    generate(file, 652.0, 0.1)
    generate(file, 554.0, 0.1)
    generate(file, 470.8, 0.1)
    generate(file, 510.7, 0.1)
    generate(file, 0.0, 0.22)

    generate(file, 1153.1, 0.22)

    generate(file, 510.7, 0.1)
    generate(file, 832.5, 0.1)
    generate(file, 652.0, 0.1)
    generate(file, 554.0, 0.1)
    generate(file, 470.8, 0.1)
    generate(file, 510.7, 0.1)





file.close();

标签: pythonmathaudio

解决方案


您希望确保您的正弦波在 sin(x)=0 的点处结束。所以表达式2 * np.pi * freq * x / sampleRate必须是 pi 的倍数。这反过来意味着freq * samples / sampleRate必须是整数,所以freq * dur必须是整数。

实现这一目标的最简单方法是首先找到周期数并调整持续时间,以便获得整数个周期

def generate(output, freq, dur):
    # create sine wave
    n_cycles = math.floor(freq*dur)  # number of cycle
    dur2 = n_cycles /freq            # adjusted duration
    samples = dur2*sampleRate
    x = np.arange(samples+1)         # want inclusive range
    sineWave = (32767.0*np.sin(2 * np.pi * freq * x / sampleRate))

所以对于你的第一个例子

generate(file, 1153.1, 1.0)

调整后的持续时间为 0.999913277 秒。


推荐阅读