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

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

错误原因

  1. struct格式字符串不匹配:原代码用Bdd作为格式符,B是无符号字节(0-255),d是双精度浮点数,但信号是[-2,2]范围的浮点数,且setsampwidth(2)指定了2字节(16位)采样宽度,对应格式应该是16位有符号整数h。
  2. 信号未转换为整数:WAV文件要求音频数据为整数类型,原信号是浮点数,直接打包会触发类型错误。
  3. 采样点过少:原信号仅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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 14:10:20