Skip to content

feat(sdk): audio play-window (start/duration) on Pattern.sound - #195

Merged
piaskowyk merged 4 commits into
mainfrom
feat/media-haptics-sdk
Aug 11, 2026
Merged

feat(sdk): audio play-window (start/duration) on Pattern.sound#195
piaskowyk merged 4 commits into
mainfrom
feat/media-haptics-sdk

Conversation

@piaskowyk

Copy link
Copy Markdown
Member

Part of the media-synced-haptics feature (SDK slice).

Adds an optional play-window to Pattern.sound so the whole audio file can be shipped once and a trimmed window played from it, in sync with the haptics — there's no runtime seek on the audio, so the native side slices to the window.

  • RN binding: Sound.start/Sound.duration (ms), threaded through usePatternComposer and the PatternComposer_parsePatternWithSound TurboModule spec + iOS/Android bridges.
  • iOS: slice the decoded buffer to a temp .caf and register it with Core Haptics (keeps sample-accurate coupling); temp cleaned up on next parse/dispose.
  • Android: windowed (non-coupled) clips play via MediaPlayer (seekTo + delayed stop); SoundPool still handles whole-file / coupled .ogg.

Verification: iOS Swift core BUILD SUCCEEDED; Android core + RN module BUILD SUCCESSFUL (codegen regenerated the 6-arg signature and the Kotlin bridge matches).

Backward-compatible: start/duration default to 0 (whole file), so existing sound usage is unchanged. No dependency on the other PRs.

Adds optional start/duration (ms) to Sound so the whole audio file can be
shipped once and a trimmed window played from it, in sync with the haptics —
there is no runtime seek on the audio, so the native side slices to the window.

- RN: Sound.start/duration, threaded through usePatternComposer and the
  PatternComposer_parsePatternWithSound TurboModule spec + both bridges.
- iOS: slice the decoded buffer to a temp .caf and register it with Core
  Haptics (keeps sample-accurate coupling); cleaned up on next parse/dispose.
- Android: windowed (non-coupled) clips play via MediaPlayer (seekTo + delayed
  stop); SoundPool still handles whole-file / coupled .ogg playback.
Threads Sound.start/duration through the remaining bindings so Flutter and KMP
honor the same trim window as RN.

- Flutter: Dart Sound gains start/duration + toMap; the iOS and Android plugins
  read them and pass to the (already-capable) native cores.
- KMP: commonMain SoundData gains startMs/durationMs; the Android side threads
  them to the core; the iOS side — which reimplements Core Haptics in Kotlin/
  Native rather than using the Swift core — gets the buffer-slice ported into its
  own makeAudioEvent (AVAudioFile read → slice → temp .caf → register).

Verified: KMP compileKotlinIosSimulatorArm64 + androidMain compile; flutter analyze.
@piaskowyk
piaskowyk merged commit 5ef86b2 into main Aug 11, 2026
2 checks passed
@piaskowyk
piaskowyk deleted the feat/media-haptics-sdk branch August 11, 2026 15:06
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