Python中将合成正弦波转换为WAV音频报错的解决咨询
合成正弦信号转WAV格式报错解决
问题背景
生成两个不同频率的正弦信号并求和,尝试转换为WAV音频时触发error: required argument is not an integer错误,原代码及报错如下:
原信号生成代码
import numpy as np import matplotlib.pyplot as plt samples = 50 f = 160 x = np.arange(samples) y1 = np.sin(2*np.pi*f * (x/samples)) plt.figure() plt.stem(x,y1, 'r') plt.plot(x,y1) plt.xlabel('Time -->') plt.ylabel('<-- Amplitude -->') plt.show() samples = 50 f = 188.6 x = np.arange(samples) y2 = np.sin(2*np.pi*f * (x/samples)) plt.figure() plt.stem(x,y2, 'r') plt.plot(x,y2) plt.xlabel('Time -->') plt.ylabel('<-- Amplitude -->') plt.show() y3 = y1 + y2 plt.plot(x,y3) plt.xlabel('Time -->') plt.ylabel('<-- Amplitude -->') plt.show()
原转换代码及报错
import wave import struct def signal_to_wav(signal, fname, Fs): """Convert a numpy array into a wav file. Args ---- signal : 1-D numpy array An array containing the audio signal. fname : str Name of the audio file where the signal will be saved. Fs: int Sampling rate of the signal. """ data = struct.pack('>' + ('Bdd'*len(signal)), *signal) wav_file = wave.open(fname, 'wb') wav_file.setnchannels(1) wav_file.setsampwidth(2) wav_file.setframerate(Fs) wav_file.writeframes(data) wav_file.close()
报错信息:
error: required argument is not an integer
错误原因
- struct格式字符串不匹配:原代码用
Bdd作为格式符,B是无符号字节(0-255),d是双精度浮点数,但信号是[-2,2]范围的浮点数,且setsampwidth(2)指定了2字节(16位)采样宽度,对应格式应该是16位有符号整数h。 - 信号未转换为整数:WAV文件要求音频数据为整数类型,原信号是浮点数,直接打包会触发类型错误。
- 采样点过少:原信号仅50个采样点,即使转换成功播放时间也不足0.1秒,无实际意义。
修正后的完整代码
import numpy as np import matplotlib.pyplot as plt import wave import struct # 生成合理的音频信号:采样率44100Hz(标准音频采样率),时长1秒 Fs = 44100 duration = 1 samples = Fs * duration t = np.linspace(0, duration, samples, endpoint=False) # 生成两个正弦信号并求和 y1 = np.sin(2 * np.pi * 160 * t) y2 = np.sin(2 * np.pi * 188.6 * t) y3 = y1 + y2 # 可视化前1000个采样点(避免全量绘制过于密集) plt.figure() plt.plot(t[:1000], y3[:1000]) plt.xlabel('Time -->') plt.ylabel('<-- Amplitude -->') plt.show() def signal_to_wav(signal, fname, Fs): """将numpy数组转换为WAV音频文件""" # 归一化信号到16位整数有效范围:-32768 到 32767 signal_normalized = np.int16(signal / np.max(np.abs(signal)) * 32767) # 打包为16位有符号大端整数,匹配setsampwidth(2)的设置 data = struct.pack('>' + ('h' * len(signal_normalized)), *signal_normalized) # 用上下文管理器自动关闭文件,避免资源泄漏 with wave.open(fname, 'wb') as wav_file: wav_file.setnchannels(1) # 单声道 wav_file.setsampwidth(2) # 2字节采样宽度(16位) wav_file.setframerate(Fs) wav_file.writeframes(data) # 转换并保存为WAV文件 signal_to_wav(y3, 'sine_mix.wav', Fs)
关键修改说明
- 信号生成优化:使用标准音频采样率44100Hz,生成1秒时长的信号,保证播放可闻。
- 信号归一化:将浮点数信号缩放到16位整数的有效范围,避免音频失真或溢出。
- 格式符修正:用
h(16位有符号整数)匹配setsampwidth(2)的设置,解决类型错误。 - 上下文管理器:用
with语句自动关闭WAV文件,避免资源泄漏。
内容的提问来源于stack exchange,提问作者yasinsulhan
相关产品推荐
相关产品推荐

