You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python生成《小星星》音频存在背景杂音,求解决方法

解决Python生成《小星星》音频的背景杂音问题

你的代码产生杂音主要有三个原因,对应修改方案如下:

1. 静默音符错误使用低频正弦波

原代码里把静默音符设为1.0Hz的频率,这会生成极低频率的嗡嗡声。正确的做法是直接生成全零信号。

2. 音符切换时无过渡导致咔哒声

不同音符的波形在衔接处没有淡入淡出,波形突变会产生刺耳的咔哒杂音,需要给每个音符添加淡入淡出效果。

3. 频率舍入导致的波形不连续

原代码中对频率的舍入操作可能导致单个音符的波形周期不完整,衔接时出现微小突变,可通过调整波形生成逻辑避免不必要的舍入。

修改后的完整代码

import numpy as np
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
        self.sample_rate = 44100
        
    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(val, 2) for key, val in note_freqs.items()}
        note_freqs[''] = 0.0  # 静默音符设为0频率
        return note_freqs
    
    def generate_wave(self, freq):
        time = 60 / self.tempo
        t = np.linspace(0, time, int(self.sample_rate * time), endpoint=False)
        
        if freq == 0.0:
            # 生成全零静默信号
            wave = np.zeros_like(t)
        else:
            # 直接使用计算的频率,避免不必要的舍入
            wave = np.sin(2 * np.pi * freq * t)
        
        # 添加淡入淡出效果,消除切换时的咔哒声
        fade_samples = int(self.sample_rate * 0.01)  # 10ms淡入淡出
        if len(wave) > fade_samples * 2:
            wave[:fade_samples] *= np.linspace(0, 1, fade_samples)
            wave[-fade_samples:] *= np.linspace(1, 0, fade_samples)
        
        # 调整振幅到int16范围
        wave *= 32767
        return wave.astype(np.int16)
    
    def generate_digital_note(self):
        note_freqs = self.generate_freq()
        all_notes = []
        for note in self.notes:
            freq = note_freqs[note]
            all_notes.append(self.generate_wave(freq))
        return np.concatenate(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_clean.wav', 44100, twinkle_normal_wave)

修改说明

  • 静默音符处理:将note_freqs['']设为0.0,生成全零信号替代低频正弦波,彻底消除嗡嗡声。
  • 淡入淡出效果:给每个音符前后添加10ms的线性淡入淡出,平滑波形衔接,去除咔哒杂音。
  • 频率计算优化:移除了原代码中对频率的舍入调整,直接使用精确计算的频率值,减少波形不连续的可能。
  • 类型提前转换:在生成波形时直接转为np.int16,避免最后转换时的潜在精度问题。

内容的提问来源于stack exchange,提问作者prasadav

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 19:25:28