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

使用Go语言beep包播放底鼓音频出现失真问题求助

问题:使用beep包播放底鼓音频时出现失真杂音

我使用Go语言的beep包开发节奏生成器,实现单次音频播放功能。通过Logic Pro导出了多种鼓组音效(击边鼓、侧击鼓、踩镲、底鼓、铃鼓),其他音效在程序中播放均正常,唯独底鼓出现失真,音频开头和结尾存在明显杂音。

已做排查与尝试

  • 所有音频文件参数为44.1KHz 24位,在程序外播放完全正常;
  • 导出时已调整增益并添加淡入淡出效果,底鼓额外应用了线性EQ低切和高切滤波器;
  • 尝试为所有音频设置恒定缓冲区长度,播放底鼓的代码逻辑与其他音效一致:speaker.Play(buf.kick.Streamer(0, buf.kick.Len())

相关代码片段

导入语句

"github.com/gopxl/beep"
"github.com/gopxl/beep/speaker"
"github.com/gopxl/beep/wav"

缓冲区创建代码

type Buffer struct {
    snr           *beep.Buffer
    side          *beep.Buffer
    hh            *beep.Buffer
    clickDownBeat *beep.Buffer
    click         *beep.Buffer
    kick          *beep.Buffer
}

func Ui() {
    w := &Widgets{}
    p := &Parameters{}
    p.pattern = new(string)
    buf := &Buffer{
        kick:          makeBuffer("./wav/kick.wav"),
        snr:           makeBuffer("./wav/rim.wav"),
        side:          makeBuffer("./wav/side.wav"),
        hh:            makeBuffer("./wav/hh.wav"),
        clickDownBeat: makeBuffer("./wav/ride_bell.wav"),
        click:         makeBuffer("./wav/tambourine.wav"),
    }
    
    // 剩余UI函数代码
}

func makeBuffer(file string) *beep.Buffer {
    f, err := os.Open(file)
    if err != nil {
        log.Fatal(err)
    }

    streamer, format, err := wav.Decode(f)
    if err != nil {
        log.Fatal(err)
    }

    speaker.Init(format.SampleRate, format.SampleRate.N(time.Second/35))

    buffer := beep.NewBuffer(format)
    buffer.Append(streamer)
    streamer.Close()
    return buffer
}

音频播放逻辑

func playSpeaker(char rune, w *Widgets, buf *Buffer) {
    switch {
    case char == 'O': // 存在问题的底鼓音效
        kick := buf.kick.Streamer(0, buf.kick.Len())
        speaker.Play(kick)
    case char == 'X':
        speaker.Play(buf.snr.Streamer(0, buf.snr.Len()))
    case char == 'x':
        if !w.muteFillsCheck.Checked {
            speaker.Play(buf.side.Streamer(0, buf.side.Len()))
        } else {
            return
        }
    case char == 'o':
        if !w.muteOffsetsCheck.Checked {
            speaker.Play(buf.hh.Streamer(0, buf.hh.Len()))
        } else {
            return
        }
    }
}

播放函数调用方式

// 循环前已处理时钟、BPM变更和UI更新

for i, char := range *p.pattern {
    select {
        // click是由时钟函数定期发送的结构体通道信号
    case <-click: 
        go playSpeaker(char, w, buf)
    case <-stopPlayChan:
        return
        }   
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 13:16:16