如何在 Go 中从麦克风获取 WAV 音频

问题描述 投票:0回答:1

我的程序使用 Vosk 语音识别库的 Go 绑定,它将音频作为 WAV 单声道音频的字节切片接收。我的程序当前使用外部命令

arecord
从麦克风获取 WAV 音频,但我更喜欢在 Go 中正确执行此操作,并且最好没有任何共享库依赖项。

我尝试使用 malgo 包,但在如何将麦克风中的原始音频转换为 WAV 上遇到了困难。我发现 WAV 编码包只能写入文件(io.WriteSeeker),但我需要转换来自麦克风的连续流以进行实时语音识别。

至少Linux

go wav microphone audio-capture vosk
1个回答
0
投票

我最终也使用了

malgo
,与
malgo.FormatS16

在这个回调中产生字节:

    // https://github.com/gen2brain/malgo/blob/master/_examples/capture/capture.go
    onRecvFrames := func(pSample2, pSample []byte, framecount uint32) {
        // Empirically, len(pSample) is 480, so for sample rate 44100 it's triggered about every 10ms.
        // sampleCount := framecount * deviceConfig.Capture.Channels * sizeInBytes
        pSampleData = append(pSampleData, pSample...)
    }

我可以将其转换为

int
(为此使用 GPT-4):

func twoByteDataToIntSlice(audioData []byte) []int {
    intData := make([]int, len(audioData)/2)
    for i := 0; i < len(audioData); i += 2 {
        // Convert the pCapturedSamples byte slice to int16 slice for FormatS16 as we go
        value := int(binary.LittleEndian.Uint16(audioData[i : i+2]))
        intData[i/2] = value
    }
    return intData
}

然后使用

"github.com/go-audio/wav"
生成内存中的 wav 字节(GPT-4 再次创建了内存中文件系统 hack 来克服
io.WriteSeeker
要求)

// Create an in-memory file to support io.WriteSeeker needed for NewEncoder which is needed for finalizing headers.
    inMemoryFilename := "in-memory-output.wav"
    inMemoryFile, err := fs.Create(inMemoryFilename)
    dbg(err)
    // We will call Close ourselves.

    // Convert audio data to IntBuffer
    inputBuffer := &audio.IntBuffer{Data: intData, Format: &audio.Format{SampleRate: iSampleRate, NumChannels: iNumChannels}}

    // Create a new WAV wavEncoder
    bitDepth := 16
    audioFormat := 1
    wavEncoder := wav.NewEncoder(inMemoryFile, iSampleRate, bitDepth, iNumChannels, audioFormat)

我在尝试将您想要的东西组合在一起时开发了这些片段 - 流式语音助手 [WIP] https://github.com/Petrzlen/vocode-golang

© www.soinside.com 2019 - 2024. All rights reserved.