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

xytpbqjk  于 11个月前  发布在  Go
关注(0)|答案(1)|浏览(203)

我的程序使用Vosk语音识别库的Go绑定,它将音频作为WAV单声道音频的字节片。我的程序目前使用外部命令arecord从麦克风获取WAV音频,但我更喜欢在Go中正确地完成,最好没有任何共享库依赖。
我试着使用malgo包,但在如何将麦克风的原始音频转换为WAV上卡住了。我发现的WAV编码包只能写入文件(io.WriteSeeker),但我需要转换麦克风的连续流以进行实时语音识别。
至少Linux

lqfhib0f

lqfhib0f1#

最后我也用了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再次创建了内存中的FileSystem 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)


我开发了这些片段,同时试图把你想要的东西放在一起-一个流媒体语音助手https://github.com/Petrzlen/vocode-golang

相关问题