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

使用PyAudio生成波形音频时程序启停/静音阶段爆音问题排查求助

使用PyAudio生成波形音频时程序启停/静音阶段爆音问题排查求助

我正在写一个Python脚本,用来生成指定频率的各种波形音频。我用了PyAudio库(C语言PortAudio的Python封装)来输出基于8位整数的音频,目前音频播放本身效果还不错,只有几个小问题不是我现在关注的重点。

但程序启动或者结束的时候会出现很刺耳的爆音/噼啪声。我知道这种问题可能是音量突变导致的,但我尝试在程序终止前逐步降低音量的操作要么完全没用,甚至还让问题变得更严重了。

我把源代码贴在下面,想请教各位:这个爆音到底是什么原因导致的?是PyAudio本身存在未修复的深层问题?还是我存储音频强度值的方式有问题?会不会是库冲突?或者我是不是漏掉了某个关键步骤?

import pyaudio
import random
import pygame
import copy
pygame.init()

framerate = 60
frequency = 440 #Hertz (Oscillations per Second)
samplerate = 16000 #Samples Per Second
volume = 4 #out of 256

SPU = samplerate//framerate #Samples Per Update
SPO = samplerate//frequency #Samples Per Oscillation

#0: Pulse Wave
#1: Triangle Wave
#2: Sawtooth Wave
#3: Noise
mode = 0

lastvalue = 0
gentimer = 0
pulseswitch = 1
tritone = 0
noisemode = False
noisetimer = 0

timer = pygame.time.Clock()
window = pygame.display.set_mode((100,200))
speaker = pyaudio.PyAudio()
channel = speaker.open(format=pyaudio.paUInt8,frames_per_buffer=SPU,channels=1,rate=samplerate,output=True)
data = bytearray()
lastdata = bytearray()

killtimer = -1
while True:
    events = pygame.event.get()
    for event in events:
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_1:
                mode = 1
            elif event.key == pygame.K_2:
                mode = 2
            elif event.key == pygame.K_3:
                mode = 3
            elif event.key == pygame.K_0:
                mode = 0
            elif event.key == pygame.K_m:
                if noisemode:
                    noisemode = False
                else:
                    noisemode = True
            elif event.key == pygame.K_SPACE:
                frequency = 261.6256
                SPO = samplerate//frequency
            gentimer = 0
        elif event.type == pygame.KEYUP:
            if event.key == pygame.K_SPACE:
                frequency = 440
                SPO = samplerate//frequency
                gentimer = 0
        elif event.type == pygame.QUIT:
            killtimer = 20
    if mode == 0:
        for frame in range(SPU):
            gentimer += 1
            if gentimer >= (samplerate/frequency)/2:
                gentimer = gentimer - ((samplerate/frequency)/2)
                if pulseswitch == 1:
                    pulseswitch = 0
                else:
                    pulseswitch = 1
            data.append(int(volume*pulseswitch/2))
    elif mode == 1:
        for frame in range(SPU):
            gentimer += (1-2*pulseswitch)
            if gentimer >= (samplerate/frequency)/2:
                gentimer = ((samplerate/frequency))-gentimer
                pulseswitch = 1
            elif gentimer < 0:
                gentimer = -gentimer
                pulseswitch = 0
            tritone = gentimer/((samplerate/frequency)/2)
            data.append(int(volume*tritone))
    elif mode == 2:
        for frame in range(SPU):
            gentimer += 1
            if gentimer >= (samplerate/frequency):
                gentimer = gentimer-(samplerate/frequency)
                #print(gentimer)
            tritone = gentimer/(samplerate/frequency)
            data.append(int(volume*tritone))
    elif mode == 3:
        for frame in range(SPU):
            gentimer += 1
            if gentimer >= (samplerate/frequency):
                gentimer = 0
                if noisemode:
                    noisetimer += 1
                if noisetimer >= 31:
                    noisetimer = 0
                    random.seed(0)
                tritone = random.randint(0,255)/255
            data.append(int(volume*tritone))    
    channel.write(bytes(data))
    data = bytearray()
    timer.tick(framerate)
    if killtimer != -1:
        volume = volume*0.9
        if volume < 0.1:
            break
channel.stop_stream()
channel.close()
speaker.terminate()

备注:内容来源于stack exchange,提问作者Sad Robot

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.13 18:28:01