为了账号安全,请及时绑定邮箱和手机立即绑定

如何播放 opus 解码帧,或将 1 字节 pcm16 拆分为 2 字节 pcm?

如何播放 opus 解码帧,或将 1 字节 pcm16 拆分为 2 字节 pcm?

Go
汪汪一只猫 2022-08-09 20:09:17
在录制麦克风时,录制的块是原始的PCM8格式,我能够通过更改bitDepthInBytes = 2来发送它并播放它而没有任何噪音,但是当我通过网络发送编码的opus帧并将它们解码为PCM16时,除非我将它们转换为PCM8,否则我无法播放它们,但它很嘈杂。这是我的代码:const sampleRate = 48000const channels = 1........    dec, err := opus.NewDecoder(sampleRate, channels)    if err != nil {        fmt.Println(err)        return    }    var frameSizeMs float32 = 20    frameSize := int(channels * frameSizeMs * sampleRate / 1000)    pcm := make([]int16, frameSize)    // (sampleRate int, channelNum int, bitDepthInBytes int, bufferSizeInBytes int)    context, err := oto.NewContext(sampleRate, channels, 1, frameSize*2)    if err != nil {        log.Fatal(err)    }    player := context.NewPlayer()    ...    ...    _, err := dec.Decode(data, pcm)    if err != nil {        fmt.Println(err)    }    var mask uint16 = 0x8000    pcm8 := make([]byte, frameSize)    for i := 0; i < frameSize; i++ {        // using this work and play sound but it has noise        pcm8[i] = byte((uint16(pcm[i]) ^ mask) >> 8)    }        _, _ = player.Write(pcm8)
查看完整描述

1 回答

?
三国纷争

TA贡献1804条经验 获得超7个赞

通过阅读本文,我能够知道如何将PCM缓冲区格式化为可播放的音频字节 https://github.com/philfrei/AudioCue/blob/master/src/main/java/com/adonax/audiocue/AudioCue.java,这是我使用的片段:


public static byte[] fromBufferToAudioBytes(byte[] audioBytes, float[] buffer)

{

    for (int i = 0, n = buffer.length; i < n; i++)

    {

        buffer[i] *= 32767;

        

        audioBytes[i*2] = (byte) buffer[i];

        audioBytes[i*2 + 1] = (byte)((int)buffer[i] >> 8 );

    }

    

    return audioBytes;

}

这是我在代码中更新的内容


    pcm8 := make([]byte, frameSize * 2)

    for i := 0; i < frameSize; i++ {

        //pcm[i] *= 32767 // uncomment when pcm array is float insteand of int16

        pcm8[i*2] =  byte(uint16(pcm[i]))

        pcm8[i*2 + 1] = byte(uint16(pcm[i]) >> 8)

    }


查看完整回答
反对 回复 2022-08-09
  • 1 回答
  • 0 关注
  • 155 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信