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



在录制麦克风时,录制的块是原始的PCM8格式,我能够通过改变bitDepthInBytes = 2而没有任何噪音来发送它并播放它,但是当我通过网络发送编码的opus帧并将其解码为PCM16时,除非我将它们转换为PCM8,否则我无法播放它们,但它是嘈杂的。下面是我的代码:

const sampleRate = 48000
const 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)

通过阅读这篇文章,我能够知道如何将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)
}

最新更新