python - 如何消除频率之间的“点击”?
问题描述
我编写了一个脚本来生成频率并将它们写入波形文件。我的问题是每个频率前后都有“咔哒”声。
我知道这个点击出现然后是正弦波被打破。但是我怎样才能避免这种情况呢?我想创建一个这样的欧洲信号发生器: 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();
解决方案
您希望确保您的正弦波在 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 秒。
推荐阅读
- powerbi - 使用重复数据创建 idex
- angular - 角度单元测试 NullInjectorError: R3InjectorError(DynamicTestModule)[MatSnackBarComponent -> MatSnackBarComponent]:
- google-ads-api - 了解“keyword_view”报告
- python - 使现有函数可从类中访问
- css - 如何纠正由 transform:translateY() 导致的页面中断流?
- c++ - 如何在flutter中调用C++类方法
- node.js - 浏览 mongoose 中的每条记录,查看特定列与数组中的项目匹配的次数
- python - 以日期时间为索引绘制数据框,仅在 python 的 x 轴上显示小时、分钟和秒
- numpy - 集成中无法将表达式转换为浮点错误
- firebase - 默认情况下,Firestore 函数有哪些安全措施来防止 API 调用泛滥?