Skip to content
This repository was archived by the owner on Dec 9, 2025. It is now read-only.
This repository was archived by the owner on Dec 9, 2025. It is now read-only.

Improve lost frame recovery with partial reconstruction #14

Description

@unforced

Problem

Currently, when packet loss is detected, the entire frame is discarded. This is wasteful since partial frames could be recovered.

Location: lib/utils/audio/wav_bytes_util.dart:68-77

if (packetIndex != _lastPacketIndex + 1 ||
    (frameId != 0 && frameId != _lastFrameId + 1)) {
  debugPrint('[WavBytesUtil] Lost frame detected');
  _lastPacketIndex = -1;
  _pending.clear();  // Discards entire frame
  _lostFrameCount++;
  return;
}

Suggested Solution

Implement partial frame recovery:

bool _isRecoverablePacketLoss(int packetIndex, int frameId) {
  // Allow recovery if we're still within the same frame
  return frameId == _lastFrameId && packetIndex > _lastPacketIndex;
}

void storeFramePacket(List<int> packet) {
  // ... existing code ...
  
  if (packetIndex != _lastPacketIndex + 1 ||
      (frameId != 0 && frameId != _lastFrameId + 1)) {
    
    // Try partial recovery
    if (_isRecoverablePacketLoss(packetIndex, frameId)) {
      debugPrint('[WavBytesUtil] Packet loss detected, attempting recovery');
      
      // Fill gap with silence/interpolation
      final missedPackets = packetIndex - _lastPacketIndex - 1;
      for (int i = 0; i < missedPackets; i++) {
        _pending.addAll(List.filled(content.length, 0)); // Silence
      }
      
      _pending.addAll(content);
      _lastPacketIndex = packetIndex;
      _lastFrameId = frameId;
      return;
    }
    
    // Unrecoverable loss - discard frame
    debugPrint('[WavBytesUtil] Unrecoverable frame loss');
    _lastPacketIndex = -1;
    _pending.clear();
    _lostFrameCount++;
    return;
  }
  
  // ... continue normal processing ...
}

Benefits

  • Reduces audio data loss
  • Better audio quality with gaps instead of complete frame loss
  • More resilient to poor BLE connection quality

Trade-offs

  • More complex logic
  • Requires silence padding or interpolation
  • Could introduce artifacts if not done carefully

Priority

Low-Medium - Nice to have, not critical

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions