convert method
Future<Uint8List>
convert(
- Float32List pcmData, {
- required int channels,
- required int sampleRate,
- 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);
}
}