Initialize a frame of PCM audio data using AudioData for encoding into Opus format with AudioEncoder

I use WebAssembly to implement the libopus encode method in the browser, encoding PCM audio data into Opus format frame by frame in real-time, and it works very well. However, when I set the same encoder parameters of libopus to AudioEncoder, the encoded Opus playback quality is very poor, with all noise and sharp sounds. I don’t know what went wrong. Can someone help solve this problem?

PCM audio data’s params is

  • sampleRate:16kHz
  • channels: 1
  • bitrate:32000
  • frameDuration:40ms
  • depth:16

This’s use libopus encode code

// init encoder
opus_encoder_init(
   this.#ptr,
   16_000,
   1,
   'voip',
)

// encode part
// pcm arraybuffer data,byteLength=1280
const pcm = new Uint8Array(PCM buffer data)
opus_encode(
  this.#ptr,
  pcm,
  640,
  output,
  4000,
)

// set encoder params
opus_ctl_params= {
  vbr: false,
  vbr_constraint: true,
  // 1280bit*(1000/40ms)
  bitrate: 32000,
  complexity: 10,
  signal: 'voice',
  lsb_depth: 16,
  dtx: false,
  inband_fec: false,
}

This’s use webcodecs apis encode code

// init AudioEncoder
const encoder = new AudioEncoder({
  error(e: any) {
     console.error('AudioEncoder', e);
  },
  output: (chunk: EncodedAudioChunk) => {
    const { byteLength } = chunk;
    const data = new ArrayBuffer(byteLength);
    chunk.copyTo(data);
  }
)
// set AudioEncoder config
encoder.configure({
  numberOfChannels: 1,
  sampleRate: 16000,
  codec: 'opus',
  bitrate: 32000,
  bitrateMode: 'constant',
  opus: {
    application: 'voip',
    complexity: 10,
    signal: 'voice',
    // frame-size
    frameDuration: 40000,
    packetlossperc: 0,
    usedtx: false,
    useinbandfec: false,
  },
})

// encode part
// pcm arraybuffer data,byteLength=1280
const data = new Int16Array(pcm );
const audioData = new AudioData({
  format: 's16-planar',
  sampleRate: 16000,
  numberOfFrames: 640,
  numberOfChannels: 1,
  timestamp: (voiceDataIndex.value - 1) * 40 * 1000,
  data: data,
});
encoder.encode(audioData);