python编写简易信号发生器可以生成正弦波、三角波、方波,可以显示这三类波形型号的时域波形和频域波形(上下排列),并能通过按钮添加不同噪声并更新波形。
时间: 2024-02-17 13:04:12 浏览: 197
可以使用Python中的NumPy和Matplotlib库来实现简易信号发生器,以下是一个示例代码:
```python
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.widgets import Button
# 生成正弦波
def generate_sine_wave(freq, amp, dur, sr):
t = np.linspace(0, dur, int(dur*sr), endpoint=False)
y = amp * np.sin(2 * np.pi * freq * t)
return t, y
# 生成三角波
def generate_triangle_wave(freq, amp, dur, sr):
t = np.linspace(0, dur, int(dur*sr), endpoint=False)
y = np.zeros_like(t)
for i, ti in enumerate(t):
y[i] = 2*amp/np.pi * np.arcsin(np.sin(2*np.pi*freq*ti))
return t, y
# 生成方波
def generate_square_wave(freq, amp, dur, sr):
t = np.linspace(0, dur, int(dur*sr), endpoint=False)
y = amp * np.sign(np.sin(2*np.pi*freq*t))
return t, y
# 绘制波形
def plot_waveform(ax, t, y, title):
ax.clear()
ax.plot(t, y)
ax.set_xlabel('Time (s)')
ax.set_ylabel('Amplitude')
ax.set_title(title)
# 绘制频谱
def plot_spectrum(ax, t, y, title):
ax.clear()
freqs = np.fft.rfftfreq(len(y), 1.0/sr)
fft = np.abs(np.fft.rfft(y))
ax.plot(freqs, fft)
ax.set_xlabel('Frequency (Hz)')
ax.set_ylabel('Magnitude')
ax.set_title(title)
# 添加噪声
def add_noise(y, noise_type, noise_level):
if noise_type == 'white':
noise = np.random.randn(len(y))
elif noise_type == 'pink':
noise = np.random.randn(len(y))
b, a = signal.butter(1, 1/np.sqrt(len(y)), 'highpass')
noise = signal.filtfilt(b, a, noise)
else:
noise = np.random.randn(len(y))
b, a = signal.butter(1, 1/np.sqrt(len(y)), 'highpass')
noise = signal.filtfilt(b, a, noise)
b, a = signal.butter(1, 1/10, 'lowpass')
noise = signal.filtfilt(b, a, noise)
return y + noise_level * noise
# 初始化参数
freq = 10
amp = 1
dur = 1
sr = 44100
noise_type = 'white'
noise_level = 0
# 生成波形
t, y_sin = generate_sine_wave(freq, amp, dur, sr)
t, y_tri = generate_triangle_wave(freq, amp, dur, sr)
t, y_squ = generate_square_wave(freq, amp, dur, sr)
# 创建图形界面
fig, axs = plt.subplots(nrows=2, ncols=2)
plt.subplots_adjust(left=0.1, bottom=0.2)
axs[0, 0].set_ylim(-1.2, 1.2)
axs[0, 1].set_ylim(-1.2, 1.2)
axs[1, 0].set_ylim(0, 100)
axs[1, 1].set_ylim(0, 100)
# 绘制初始波形和频谱
plot_waveform(axs[0, 0], t, y_sin, 'Sine Wave')
plot_waveform(axs[0, 1], t, y_tri, 'Triangle Wave')
plot_waveform(axs[1, 0], t, y_squ, 'Square Wave')
plot_spectrum(axs[1, 1], t, y_sin, 'Spectrum')
# 创建按钮
ax_noise_type = plt.axes([0.1, 0.05, 0.15, 0.075])
ax_noise_level = plt.axes([0.3, 0.05, 0.15, 0.075])
btn_white_noise = Button(ax_noise_type, 'White Noise')
btn_pink_noise = Button(ax_noise_type, 'Pink Noise')
btn_brown_noise = Button(ax_noise_type, 'Brown Noise')
btn_noise_level_up = Button(ax_noise_level, 'Noise Level Up')
btn_noise_level_down = Button(ax_noise_level, 'Noise Level Down')
# 按钮回调函数
def white_noise_callback(event):
global noise_type
noise_type = 'white'
btn_white_noise.on_clicked(white_noise_callback)
def pink_noise_callback(event):
global noise_type
noise_type = 'pink'
btn_pink_noise.on_clicked(pink_noise_callback)
def brown_noise_callback(event):
global noise_type
noise_type = 'brown'
btn_brown_noise.on_clicked(brown_noise_callback)
def noise_level_up_callback(event):
global noise_level
noise_level = min(1, noise_level+0.1)
btn_noise_level_up.on_clicked(noise_level_up_callback)
def noise_level_down_callback(event):
global noise_level
noise_level = max(0, noise_level-0.1)
btn_noise_level_down.on_clicked(noise_level_down_callback)
# 更新波形和频谱
def update_plot():
global y_sin, y_tri, y_squ
y_sin = add_noise(generate_sine_wave(freq, amp, dur, sr)[1], noise_type, noise_level)
y_tri = add_noise(generate_triangle_wave(freq, amp, dur, sr)[1], noise_type, noise_level)
y_squ = add_noise(generate_square_wave(freq, amp, dur, sr)[1], noise_type, noise_level)
plot_waveform(axs[0, 0], t, y_sin, 'Sine Wave')
plot_waveform(axs[0, 1], t, y_tri, 'Triangle Wave')
plot_waveform(axs[1, 0], t, y_squ, 'Square Wave')
plot_spectrum(axs[1, 1], t, y_sin, 'Spectrum')
plt.draw()
# 显示图形界面
plt.show()
```
这个代码会生成三种不同类型的波形:正弦波、三角波、方波,并将它们的时域波形和频域波形绘制在同一张图上。代码还添加了四个按钮,可以通过点击按钮来添加不同类型和强度的噪声,并更新波形和频域波形。
阅读全文