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

如何用Python实现信号频谱畸变:将尖锐频率峰展宽?

实现信号频率峰的模糊畸变并导出音频文件

要把带有尖锐频率峰的信号处理成频谱宽泛模糊的效果,用Python可以通过几种不同的方法实现,下面是具体的实操方案,都能最终导出WAV音频文件:

方法1:随机频率调制(模拟自然频率波动)

这种方法通过缓慢改变信号的瞬时频率,让原本固定的单频率峰变成一个波动的频带,适合模拟类似乐器颤音的自然模糊效果。

代码实现

import numpy as np
import soundfile as sf
from scipy.signal import butter, filtfilt

# 1. 生成/读取原始信号(这里以1kHz正弦波为例,带尖锐频率峰)
sample_rate = 44100
duration = 2.0
t = np.linspace(0, duration, int(sample_rate * duration), endpoint=False)
original_freq = 1000.0
original_signal = np.sin(2 * np.pi * original_freq * t)

# 2. 实现频率调制模糊
freq_dev = 50.0  # 最大频率偏移,控制模糊宽度(值越大模糊越宽)
noise = np.random.normal(0, 1, len(t))

# 低通滤波平滑噪声,让频率变化更平缓
def butter_lowpass_filter(data, cutoff, fs, order=5):
    nyq = 0.5 * fs
    normal_cutoff = cutoff / nyq
    b, a = butter(order, normal_cutoff, btype='low', analog=False)
    return filtfilt(b, a, data)

smoothed_noise = butter_lowpass_filter(noise, 5, sample_rate)
freq_offset = freq_dev * smoothed_noise

# 计算累积相位,生成调制后的信号
instantaneous_freq = original_freq + freq_offset
phase = np.cumsum(2 * np.pi * instantaneous_freq / sample_rate)
distorted_signal = np.sin(phase)

# 3. 归一化并保存音频
distorted_signal = distorted_signal / np.max(np.abs(distorted_signal))
sf.write('distorted_fm.wav', distorted_signal, sample_rate)

关键参数说明

  • freq_dev:控制频率波动的最大范围,比如设为50表示频率在950-1050Hz之间波动
  • 低通滤波的截止频率设为5Hz,确保频率变化足够缓慢,避免信号出现刺耳的突变

方法2:频域频谱平滑(精准控制模糊程度)

直接对信号的频谱进行傅里叶变换,用高斯核卷积平滑尖锐的频率峰,再逆变换回时域,这种方法不会引入额外噪声,效果更干净。

代码实现

import numpy as np
import soundfile as sf
from scipy.fft import rfft, irfft, rfftfreq

# 1. 生成/读取原始信号
sample_rate = 44100
duration = 2.0
t = np.linspace(0, duration, int(sample_rate * duration), endpoint=False)
original_freq = 1000.0
original_signal = np.sin(2 * np.pi * original_freq * t)

# 2. 频域平滑处理
freqs = rfftfreq(len(original_signal), 1/sample_rate)
signal_fft = rfft(original_signal)

# 生成高斯平滑核,控制模糊宽度
sigma = 20.0  # 高斯核标准差,值越大平滑效果越强(模糊越宽)
# 针对特定频率峰的高斯核,若要平滑所有峰可改为全局高斯核
gaussian_kernel = np.exp(-(freqs - original_freq)**2 / (2 * sigma**2))

# 频域相乘等价于时域卷积,实现频谱平滑
smoothed_fft = signal_fft * gaussian_kernel
distorted_signal = irfft(smoothed_fft)

# 3. 归一化保存
distorted_signal = distorted_signal / np.max(np.abs(distorted_signal))
sf.write('distorted_spectrum_smooth.wav', distorted_signal, sample_rate)

关键参数说明

  • sigma:控制频谱平滑的程度,值越大,尖锐峰被抹开的范围越宽
  • 如果原始信号有多个尖锐频率峰,可以叠加多个对应不同频率的高斯核来处理

方法3:叠加窄带噪声(带噪感的模糊效果)

给原始信号叠加目标频率附近的窄带噪声,让尖锐的频率峰被噪声覆盖成宽峰,适合需要带有“嘈杂感”的模糊效果。

代码实现

import numpy as np
import soundfile as sf
from scipy.signal import butter, filtfilt

# 1. 生成/读取原始信号
sample_rate = 44100
duration = 2.0
t = np.linspace(0, duration, int(sample_rate * duration), endpoint=False)
original_freq = 1000.0
original_signal = np.sin(2 * np.pi * original_freq * t)

# 2. 生成并叠加窄带噪声
noise_amplitude = 0.3  # 噪声幅度,控制模糊的强度
noise = np.random.normal(0, noise_amplitude, len(t))

# 带通滤波保留目标频率附近的噪声
def butter_bandpass_filter(data, lowcut, highcut, fs, order=5):
    nyq = 0.5 * fs
    low = lowcut / nyq
    high = highcut / nyq
    b, a = butter(order, [low, high], btype='band')
    return filtfilt(b, a, data)

# 保留950-1050Hz的噪声,带宽控制模糊宽度
band_noise = butter_bandpass_filter(noise, original_freq-50, original_freq+50, sample_rate)
distorted_signal = original_signal + band_noise

# 3. 归一化保存
distorted_signal = distorted_signal / np.max(np.abs(distorted_signal))
sf.write('distorted_noise.wav', distorted_signal, sample_rate)

关键参数说明

  • noise_amplitude:控制噪声的强度,值越大噪声越明显,模糊效果越强
  • 带通滤波的上下限决定了噪声的带宽,也就是频谱峰被模糊的宽度

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 23:12:50