decode method

Int16List decode(
  1. Uint8List input, {
  2. bool fec = false,
})

解码 Opus 音频数据包为 PCM 样本(16 位整数)

input Opus 编码数据包 fec 前向纠错标志,如果为 true,解码器将尝试使用前一个数据包来恢复丢失的数据

返回解码后的 PCM 样本(16 位有符号整数) 抛出 OpusException 如果解码失败

Implementation

Int16List decode(Uint8List input, {bool fec = false}) {
  final decoder = _decoder;
  if (decoder == null) {
    throw StateError('Decoder has been disposed');
  }

  // 估算输出缓冲区大小:对于 16kHz 采样率,20ms 的帧需要至少 320 个样本
  // 使用更大的缓冲区以确保足够
  final maxSamples = (sampleRate * channels.value * 0.12).ceil(); // 120ms 的样本
  final output = calloc<Int16>(maxSamples);
  final decodedSize = calloc<UintPtr>();
  final error = calloc<OpusError>();

  try {
    final inputPtr = calloc<Uint8>(input.length);
    inputPtr.asTypedList(input.length).setAll(0, input);

    final res = bindings.decode(
      decoder,
      inputPtr,
      input.length,
      output,
      maxSamples,
      fec,
      decodedSize,
      error,
    );

    calloc.free(inputPtr);

    if (res != 0) {
      final errorMsg = extractErrorMessage(error);
      throw OpusException(error.ref.code, errorMsg);
    }

    final size = decodedSize.value;
    final result = Int16List(size);
    final outputList = output.asTypedList(size);
    result.setAll(0, outputList);

    return result;
  } finally {
    freeError(error);
    calloc.free(output);
    calloc.free(decodedSize);
  }
}