Tyler Turner
Tyler Turner

Reputation: 43

new Dart ByteBuffer from region of existing ByteBuffer?

I'm loading binary files in a Dart web application that include compressed audio data as a portion of the binary data. When the data is loaded via http request, it comes in as a ByteBuffer, which I understand is Dart's substitute for a JS ArrayBuffer. The AudioContext.decodeAudioData() method requires a ByteBuffer, and I'm trying to figure out how to give it the relevant section of the loaded ByteBuffer. The loaded ByteBuffer contains additional data not related to audio. ArrayBuffers in JS support a slice() method, but I'm missing this in the ByteBuffer class, and I can't see any way to get back to a ByteBuffer after converting to any of the lists that would allow a range selection.

I imagine I could create a hybrid solution with raw JS, but if possible I'd like to keep this in Dart. Ideas appreciated!

Upvotes: 4

Views: 595

Answers (2)

lrn
lrn

Reputation: 71693

The Dart ByteBuffer doesn't have a slice method. You can go thorough the Uint8List, so instead of buffer.slice(a, b) you do buffer.asUint8List().sublist(a, b).buffer. The sublist method on typed data lists returns a list of the same type backed by a new buffer, and the buffer getter returns the underlying buffer for any typed-data list. It's not as pretty as the slice directly on the buffer, but it gets the job done without any alignment issues (the Int32List requires its start-offset to be 4-byte aligned, so for arbitrary cutting, always use an 8-bit list).

Upvotes: 3

Maximilian Riegler
Maximilian Riegler

Reputation: 23506

I can't see any way to get back to a ByteBuffer after converting to any of the lists that would allow a range selection

There are a few ways around that, but since you don't want to modify the original buffer (I guess), you will copy a few bytes around then:

// extract 2 ints (8 bytes) - no copying done yet
var rangeIterable = buffer.asInt32List().getRange(8, 10);

// create new typed list (copies the bytes from the iterable)
var newList = new Int32List.fromList(rangeIterable);
var newBuffer = newList.buffer;

print(buffer.lengthInBytes);
print(newBuffer.lengthInBytes);

Upvotes: 0

Related Questions