convert method

  1. @override
Future<Uint8List> convert(
  1. Float32List pcmData, {
  2. required int channels,
  3. required int sampleRate,
  4. double quality = 0.4,
})

Implementation

@override
Future<Uint8List> convert(
  Float32List pcmData, {
  required int channels,
  required int sampleRate,
  double quality = 0.4,
}) async {
  await initialize();

  if (_wasmExports == null || _wasmModule == null) {
    // Thêm kiểm tra này để đảm bảo initialize() đã chạy đúng
    if (!_isInitialized) {
      throw Exception('Wasm module initialization failed or never ran.');
    }
    throw Exception(
      'Wasm module references are null despite initialization.',
    );
  }

  final pcmDataSize = pcmData.length * pcmData.elementSizeInBytes;
  final pcmPtr = _wasmExports!.malloc(pcmDataSize.toJS).toDartInt;

  if (pcmPtr == 0) {
    throw Exception('Wasm _malloc failed to allocate memory for PCM data.');
  }

  try {
    // --- BƯỚC 1: GHI DỮ LIỆU VÀO WASM ---
    try {
      // Lấy view HEAPF32 trực tiếp từ module
      final JSFloat32Array wasmHeapF32View = _wasmExports!.HEAPF32;

      // Ghi dữ liệu vào heap bằng phương thức .set() từ extension
      // pcmPtr là một byte offset. HEAPF32 là một Float32Array
      // nên chỉ số (offset) của nó là (byteOffset / 4) hoặc (byteOffset >> 2)
      wasmHeapF32View.set(
        pcmData.toJS,
        pcmPtr >> 2,
      ); // set(source, targetOffset)
    } catch (e) {
      throw Exception('Failed to write PCM data to Wasm heap.');
    }

    // --- BƯỚC 2: GỌI HÀM WASM ---
    final resultPtr = _wasmExports!
        .encode_pcm_to_ogg(
          pcmPtr.toJS,
          pcmData.length.toJS,
          channels.toJS,
          sampleRate.toJS,
          quality.toJS,
        )
        .toDartInt;

    if (resultPtr == 0) {
      throw Exception(
        'Wasm function \'encode_pcm_to_ogg\' returned a null pointer.',
      );
    }

    try {
      // --- BƯỚC 3: ĐỌC KẾT QUẢ TỪ WASM ---
      final dataPtr = _wasmExports!
          .get_ogg_output_data(resultPtr.toJS)
          .toDartInt;
      final size = _wasmExports!
          .get_ogg_output_size(resultPtr.toJS)
          .toDartInt;

      if (dataPtr == 0) {
        throw Exception(
          'Wasm function returned a null data pointer inside the result struct.',
        );
      }
      if (size == 0) {
        return Uint8List(0);
      }

      // Lấy view HEAPU8 trực tiếp.
      final JSUint8Array heapU8View = _wasmExports!.HEAPU8;

      // Gọi phương thức .slice() từ extension
      final oggData = heapU8View.slice(dataPtr, dataPtr + size).toDart;
      return oggData;
    } finally {
      // Giải phóng con trỏ kết quả (struct)
      _wasmExports!.free_ogg_output(resultPtr.toJS);
    }
  } catch (e) {
    throw Exception('Caught a general exception in convert: $e');
    // return Uint8List(0);
  } finally {
    // Luôn giải phóng bộ đệm PCM đã cấp phát
    _wasmExports!.free(pcmPtr.toJS);
  }
}