decodeSample method

  1. @override
IMessage<IMessageType>? decodeSample(
  1. Uint8List frame
)
override

Builds a message from a binary sample frame. Null for streams that do not carry samples.

Implementation

@override
IMessage? decodeSample(Uint8List frame) {
  final channels = WsSampleFrame.decodeChannels(frame, config.channels);
  final timestamp = DateTime.now();
  // The frame carries the sender's clock at offset 6. Turning that into a
  // transit time needs the sender's identity, which is why the subscription
  // map keeps slot -> nodeUId: the offset is estimated per peer on the
  // coordination stream, and this is where a data sample claims its share.
  final peerUId = _slotOwners[WsSampleFrame.sourceSlotOf(frame)];
  final offsets = clockOffsets;
  final timing = MessageTiming(
    sourceClock: WsSampleFrame.senderMicrosOf(frame) / 1e6,
    // Null until the estimator has accepted a burst for this peer, which
    // keeps transitSeconds null rather than reporting the difference of two
    // unrelated monotonic clocks.
    clockOffset: offsets?.offsetFor(peerUId),
    uncertainty: offsets?.uncertaintyFor(peerUId),
    receivedClock: PeerClock.now(),
    sourceId: peerUId,
  );
  switch (config.dataType) {
    case StreamDataType.float32:
    case StreamDataType.double64:
      return MessageFactory.double64Message(
        data: IList(channels.map((v) => (v! as num).toDouble())),
        channels: config.channels,
        timestamp: timestamp,
        timing: timing,
      );
    case StreamDataType.int8:
    case StreamDataType.int16:
    case StreamDataType.int32:
    case StreamDataType.int64:
      return MessageFactory.int64Message(
        data: IList(channels.cast<int>()),
        channels: config.channels,
        timestamp: timestamp,
        timing: timing,
      );
    case StreamDataType.string:
      return MessageFactory.stringMessage(
        data: IList(channels.cast<String>()),
        channels: config.channels,
        timestamp: timestamp,
        timing: timing,
      );
  }
}