Skip to content

feat: inline timestamp markers for offline audio segments#4851

Closed
mdmohsin7 wants to merge 10 commits intomainfrom
feat/offline-audio-timestamp-markers
Closed

feat: inline timestamp markers for offline audio segments#4851
mdmohsin7 wants to merge 10 commits intomainfrom
feat/offline-audio-timestamp-markers

Conversation

@mdmohsin7
Copy link
Copy Markdown
Member

@mdmohsin7 mdmohsin7 commented Feb 17, 2026

Summary

  • Embeds inline 0xFF timestamp markers in the offline audio data stream so each recording segment (between BLE disconnects or power cycles) has an exact UTC start time
  • Extends info.txt on SD card from 4 to 8 bytes to persist a recording start time alongside the read offset
  • Exposes recording start time via the BLE storage characteristic (3rd uint32 value)
  • Fixes WAL timing bugs: chunk size now uses actual codec FPS, and WAL duration derives from real frame count instead of a hardcoded 60-second assumption
  • Flushes the storage write buffer on device shutdown to prevent data loss

Firmware changes

  • transport.c: write_timestamp_to_storage() injects a 5-byte marker (0xFF + 4-byte LE epoch) before the first offline audio frame of each segment. storage_flush_buffer() flushes pending data on shutdown. needs_timestamp_marker flag resets on each BLE connect.
  • sd_card.c: recording_start_time persisted in info.txt (backward-compatible 8-byte format)
  • storage.c: BLE read characteristic returns [file_size, offset, recording_start_time]
  • button.c: Calls storage_flush_buffer() before app_sd_off() in turnoff_all()

App changes

  • sdcard_wal_sync.dart: Parses 0xFF markers in both BLE and WiFi sync paths, splits audio into correctly-timed WAL segments. Fixes chunk size from sdcardChunkSizeSecs * 100 to sdcardChunkSizeSecs * codec.getFramesPerSecond().

Backward compatibility

  • New firmware + old app: Old parser hits bounds check on 255-byte frame size and skips to next block. Minimal data loss (5 bytes per marker).
  • Old firmware + new app: No markers in stream, new code path never triggers. Works unchanged.
  • info.txt: Old 4-byte format reads correctly (extra bytes default to zero).

Test plan

  • Build firmware via Docker and flash OTA
  • Connect phone → disconnect BLE → record ~1 min offline → reconnect briefly → disconnect → record ~1 min → sync
  • Verify app shows two WAL segments with correct timestamps and a gap between them
  • Test power off during offline recording → power on → record → sync → verify two segments
  • Test with old app version to confirm backward compatibility

Add recording_start_time tracking to the SD card storage layer.
The info.txt file is extended from 4 bytes (offset only) to 8 bytes
(offset + recording start time) with backward-compatible reading.
Extend the storage read characteristic from 2 to 3 uint32 values
to include the recording start time alongside file size and offset.
Add write_timestamp_to_storage() to write a 5-byte marker (0xFF +
4-byte LE epoch) before the first audio frame of each offline
recording segment. Add storage_flush_buffer() to flush pending
data on shutdown. Reset the marker flag on each BLE connect so
subsequent offline sessions get fresh timestamps.
Call storage_flush_buffer() in turnoff_all() to ensure any pending
audio data in the write buffer is persisted before powering off the
SD card.
Parse inline timestamp markers in both BLE and WiFi sync paths to
split audio into properly-timed WAL segments. Also fix chunk size
calculation to use actual codec FPS instead of hardcoded values,
and derive WAL duration from actual frame count rather than a fixed
60-second assumption.
@mdmohsin7
Copy link
Copy Markdown
Member Author

Screenshot 2026-02-17 at 11 46 33 PM

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request successfully implements a valuable feature by embedding inline timestamp markers in offline audio recordings, allowing for accurate segmentation. The firmware and app changes are well-executed, with robust logic for handling the new data format and maintaining backward compatibility. However, the review identified two high-severity issues that should be addressed: unrelated logging configuration changes in omi.conf that appear to be development artifacts, and the removal of a necessary header file in sd_card.c which could compromise build stability. Once these points are resolved, the pull request will be in excellent shape.

Comment thread omi/firmware/omi/omi.conf Outdated
Comment thread omi/firmware/omi/src/sd_card.c
Instead of flushing immediately when a 0xFF timestamp marker is
encountered during BLE streaming, record markers and their frame
indices. Split segments at marker boundaries only during the
normal chunking phase, preventing tiny 5-second WAL fragments.
@mdmohsin7 mdmohsin7 marked this pull request as ready for review February 19, 2026 16:09
@mdmohsin7 mdmohsin7 requested review from TuEmb and beastoin February 19, 2026 17:52
mdmohsin7 added a commit that referenced this pull request Mar 11, 2026
Split from #4851 - app changes only.
Parses 0xFF timestamp markers from the offline audio stream and
fixes WAL segment timing during SD card sync.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
mdmohsin7 added a commit that referenced this pull request Mar 11, 2026
Split from #4851 - firmware changes only.
Adds inline 0xFF timestamp markers in the offline audio stream,
exposes recording start time via BLE, and flushes storage buffer
on shutdown.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@mdmohsin7
Copy link
Copy Markdown
Member Author

Split into two separate PRs: #5571 (firmware) and #5572 (app)

@mdmohsin7 mdmohsin7 closed this Mar 11, 2026
@github-actions
Copy link
Copy Markdown
Contributor

Hey @mdmohsin7 👋

Thank you so much for taking the time to contribute to Omi! We truly appreciate you putting in the effort to submit this pull request.

After careful review, we've decided not to merge this particular PR. Please don't take this personally — we genuinely try to merge as many contributions as possible, but sometimes we have to make tough calls based on:

  • Project standards — Ensuring consistency across the codebase
  • User needs — Making sure changes align with what our users need
  • Code best practices — Maintaining code quality and maintainability
  • Project direction — Keeping aligned with our roadmap and vision

Your contribution is still valuable to us, and we'd love to see you contribute again in the future! If you'd like feedback on how to improve this PR or want to discuss alternative approaches, please don't hesitate to reach out.

Thank you for being part of the Omi community! 💜

mdmohsin7 added a commit that referenced this pull request Mar 12, 2026
#5572)

## Summary

- Parses inline `0xFF` timestamp markers from the offline audio data
stream so each recording segment has an exact UTC start time
- Fixes WAL timing bugs: chunk size now uses actual codec FPS, and WAL
duration derives from real frame count instead of a hardcoded 60-second
assumption
- Splits audio into correctly-timed WAL segments based on timestamp
markers

Split from #4851 — app changes only. See #5571 for the firmware
counterpart.

### App changes
- **sdcard_wal_sync.dart**: Gates all timestamp marker logic on firmware
version `>= 3.0.16` using `_supportsTimestampMarkers()`. Old firmware
uses the original legacy parsing path unchanged. New firmware uses
marker-aware parsing in both BLE and WiFi sync paths, splitting audio
into correctly-timed WAL segments. Also fixes chunk size from
`sdcardChunkSizeSecs * 100` to `sdcardChunkSizeSecs *
codec.getFramesPerSecond()` (new firmware path only).

### Firmware version gating
- **Old firmware (< 3.0.16)**: Takes the
`_readStorageBytesToFileLegacy()` path — identical to current `main`
branch behavior. No marker detection, no new chunking logic.
- **New firmware (>= 3.0.16)**: Takes the
`_readStorageBytesToFileWithMarkers()` path — parses `0xFF` markers,
splits segments by timestamp boundaries, uses device-provided recording
start time.

## Test plan

- [ ] Connect with old firmware (< 3.0.16) → verify BLE sync works
identically to current behavior
- [ ] Connect with new firmware (>= 3.0.16) → disconnect BLE → record ~1
min offline → reconnect → sync
- [ ] Verify app shows WAL segments with correct timestamps from
device-provided epochs
- [ ] Test WiFi sync path with both old and new firmware

🤖 Generated with [Claude Code](https://claude.com/claude-code)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant