scipy Python创建的声波为戏剧提供了背景节拍沿着音符

rur96b6h  于 2022-11-23  发布在  Python
关注(0)|答案(1)|浏览(114)

我已经创建了一个脚本来播放闪烁闪烁litte明星与参考这篇文章(https://towardsdatascience.com/mathematics-of-music-in-python-b7d838c84f72),并创建了我的一些变化。音乐播放正确,但有一些恼人的节拍在背景中。有人能请帮助如何消除恼人的节拍声音从背景中?
我的代码:

import numpy as np
import pandas as pd
import os
from scipy.io.wavfile import write

class Music:
    
    def __init__(self,notes,tempo,base_freq = 'C4'):
        self.notes = notes
        self.tempo = tempo
        self.base_freq = base_freq
        
    def generate_freq(self):
        octave = ['C', 'c', 'D', 'd', 'E', 'F', 'f', 'G', 'g', 'A', 'a', 'B']

        num = int(self.base_freq[1])
        delta = 4 - num
        bf = 261.63 * 2**(delta)
        note_freqs = {octave[i]: bf * pow(2,(i/12)) for i in range(len(octave))}
        note_freqs = {key : round(note_freqs[key],2) for key in note_freqs}
        note_freqs[''] = 1.0 # silent note
        return note_freqs
    
    def generate_wave(self, freq):
        sample_rate = 44100
        div = int(sample_rate/freq)
        freq = round(sample_rate/div,2)
        amplitude = 4096
        time = 60/self.tempo
        t = np.linspace(0, time, int(sample_rate * time), endpoint=False)
        wave = np.sin(2 * np.pi * freq * t)
        wave *= 32767
        return wave
    
    def generate_digital_note(self):
        note_freqs = self.generate_freq()
        all_notes =[]
        for i in range(len(self.notes)):
            freq = note_freqs[self.notes[i]]
            wave = [self.generate_wave(freq)]
            all_notes = all_notes + wave
        all_notes = np.concatenate(all_notes)
        return all_notes

music_notes = 'C-C-G-G-A-A-G--F-F-E-E-D-D-C--G-G-F-F-E-E-D--G-G-F-F-E-E-D--C-C-G-G-A-A-G--F-F-E-E-D-D-C'
music_notes = music_notes.split('-')

twinkle_normal = Music(music_notes,120)
twinkle_normal_wave = twinkle_normal.generate_digital_note()

write('twinkle-twinkle_normal.wav', 44100, twinkle_normal_wave.astype(np.int16))

谢谢你,

goucqfw6

goucqfw61#

您生成的信号在每个音符过渡处都有中断。每个中断都会导致扬声器发出“砰”的一声。解决此问题的一个简单方法是将与每个音符相关的数组乘以envelope,该值在开始时从0上升到1,在结束时从1下降到0(即为每个音符的声音提供“起音”和“释放”)。
Synth和DSPMaven可能会有更好的建议--可能性是无限的--但是一个快速的方法是使用scipy.signal.windows.tukey提供的Tukey窗口。

  • 在开头添加
from scipy.signal.windows import tukey

  • 在函数generate_wave()中,更改以下行:从
wave = np.sin(2 * np.pi * freq * t)

wave = np.sin(2 * np.pi * freq * t) * tukey(len(t))

相关问题