首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >写入wav文件会发出滴答声

写入wav文件会发出滴答声
EN

Stack Overflow用户
提问于 2018-05-31 04:08:59
回答 2查看 278关注 0票数 3

我有这个创建wav文件的代码:

代码语言:javascript
复制
class Note:
    def __init__(self,name,octave,duration):
        self.name = name
        self.octave = octave
        self.duration = duration

SAMPLE_RATE = 44100

wav = wave.open("starw.wav", mode="w")
wav.setparams((1, 2, SAMPLE_RATE , SAMPLE_RATE*4, 'NONE', 'noncompressed'))

def generate_sample(note,volume):
    freq = FREQUENCIES[note.octave][note.name]
    duration = note.duration
    total_samples = int(SAMPLE_RATE * duration)
    for i in range(0,total_samples):
        s = np.clip(int((volume)*math.sin(freq*math.pi*float(i)/float(SAMPLE_RATE))),-32768,32768)    
        data = struct.pack('<h',s)
        wav.writeframes(data)

    return data

for i,m in enumerate(melody):

    if i<len(melody)/5:
        generate_sample(m, 100+i*500)
    elif len(melody)/5<=i<=4*len(melody)/5:
        generate_sample(m, 8800)
    else:
        generate_sample(m, 8800-i*20)

这里的FREQUENCIES是一个描述音符及其频率的字典。melodyNote对象的数组。除了在暂停时会发出奇怪的滴答声之外,一切都很正常。据我所知,这与采样率有关。但我不知道如何更改代码以避免停顿。旋律是这样的:https://drive.google.com/open?id=1e03VC90w5WF4QdU-VxrV906dl_c3UvSQ

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-05-31 04:26:09

如果你指的是音符之间令人不快的滴答声:那是完全正常的。

即使在专门为生成音乐而设计的编程语言中,如果您简单地将块与在整个持续时间内具有固定振幅的(正弦)波并列,也会出现这种效果。

下面是一个音符结束,下一个音符开始时的草图:

除非第一个节点意外地恰好在零结束,否则您将听到在2处绘制的这个“跳转”。

为了避免这种情况,你必须实现更好的音符合成。

一个简单的解决方案是平滑地增加每个音符的振幅,然后让它在结束时平滑地衰减。如果这样做,两个音符之间的转换将如下所示:

此图由以下公式生成:

代码语言:javascript
复制
  if x > 2:
    return sin((x-2) * 60) * (1 - exp(-(x-2)**2 / 0.5))
  else:
    return sin(x * 30) * (1- exp(-(x-2)**2 / 0.5))

希望你能认识到(1 - exp(-(x - tClick) ** 2 / smoothness))的“安慰剂”因素,这些因素导致了坡度上升/下降。

但是,您再次看到音符之间的间隔似乎变得更大,如果您随后尝试使不同音符的间隔相交,这一切都变得相当混乱和复杂,您可能更好地选择已经知道如何正确操作的编程语言或库。我认为Chuck manual包含了关于如何获得更好的音符的相当详细的解释。

票数 5
EN

Stack Overflow用户

发布于 2018-05-31 04:21:57

如果我猜的话,我会认为这可能与音符长度有时甚至不是音符频率的倍数有关。因此,注释的sin(end_time)有时可能会产生一个相对较大的值:在最坏的情况下为32768。在这个频率下音量的突然下降可能是你听到的滴答声/咯咯声的原因。

只有当int((volume)*math.sin(freq*math.pi*float(i)/float(SAMPLE_RATE)))的值接近0时才终止音符,这将消除大部分噪声,如果是这样的话。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50612658

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档