@@ -2,8 +2,13 @@ import { useCallback, useEffect, useRef } from 'react';
22import { useTransportStore } from '../store/transportStore' ;
33import { useProjectStore } from '../store/projectStore' ;
44import { useUIStore } from '../store/uiStore' ;
5- import { getAudioEngine } from './useAudioEngine' ;
5+ import {
6+ getAudioEngine ,
7+ getTauriPlaybackClockOwner ,
8+ setTauriPlaybackClockOwner ,
9+ } from './useAudioEngine' ;
610import { getAudioBridge } from '../engine/bridge' ;
11+ import type { AudioBridge } from '../engine/bridge/types' ;
712import { loadAudioBlobByKey } from '../services/audioFileManager' ;
813import { synthEngine } from '../engine/SynthEngine' ;
914import { subtractiveEngine } from '../engine/SubtractiveEngine' ;
@@ -117,6 +122,19 @@ function canUseNativeClipPlayback(project: Project, entries: NativePlaybackEntry
117122 return ! project . tracks . some ( trackNeedsWebAudio ) ;
118123}
119124
125+ function getActivePlaybackTime (
126+ engine : ReturnType < typeof getAudioEngine > ,
127+ bridge : AudioBridge ,
128+ ) : number {
129+ if ( ! useTransportStore . getState ( ) . isPlaying ) {
130+ return useTransportStore . getState ( ) . currentTime ;
131+ }
132+ if ( bridge . backend === 'tauri' && getTauriPlaybackClockOwner ( ) === 'native' ) {
133+ return bridge . getCurrentTime ( ) ;
134+ }
135+ return engine . getCurrentTime ( ) ;
136+ }
137+
120138/**
121139 * Trim an AudioBuffer to a specific project-time region.
122140 * The input buffer may cover the full project duration; the output covers only
@@ -453,15 +471,18 @@ export function useTransport() {
453471 && canUseNativeClipPlayback ( nextProject , clipBuffers ) ;
454472
455473 if ( useNativeClipPlayback ) {
474+ setTauriPlaybackClockOwner ( 'native' ) ;
456475 bridge . schedulePlayback ( clipBuffers , startFrom , effectiveEnd ) ;
457476 // The native backend owns audio clip playback, but MIDI, synth,
458477 // sequencer, automation, and Strudel still use AudioEngine's
459478 // RAF clock until the Rust engine reaches full feature parity.
460479 engine . schedulePlayback ( [ ] , startFrom , effectiveEnd ) ;
461480 } else if ( bridge . backend === 'tauri' ) {
481+ setTauriPlaybackClockOwner ( 'web-audio' ) ;
462482 bridge . stopAllSources ( ) ;
463483 engine . schedulePlayback ( clipBuffers , startFrom , effectiveEnd ) ;
464484 } else {
485+ setTauriPlaybackClockOwner ( 'web-audio' ) ;
465486 // Playback reads from stretchedBufferCache (populated on clip stretch mouseup).
466487 // If Signalsmith/Rubber Band already finished → high quality buffer used.
467488 // If neither finished yet → legacy fallback via _getProcessedBuffer.
@@ -835,11 +856,12 @@ export function useTransport() {
835856 }
836857 const engine = getAudioEngine ( ) ;
837858 const bridge = getAudioBridge ( engine ) ;
838- const time = bridge . getCurrentTime ( ) ;
859+ const time = getActivePlaybackTime ( engine , bridge ) ;
839860 finalizeSessionArrangementRecording ( time ) ;
840861 stopStrudelEditorPlayback ( ) ;
841862 stopAllStrudelTracks ( ) ;
842863 engine . stop ( ) ;
864+ setTauriPlaybackClockOwner ( 'web-audio' ) ;
843865 bridge . pauseAllSources ( ) ;
844866 synthEngine . releaseAll ( ) ;
845867 subtractiveEngine . releaseAll ( ) ;
@@ -859,12 +881,11 @@ export function useTransport() {
859881 }
860882 const engine = getAudioEngine ( ) ;
861883 const bridge = getAudioBridge ( engine ) ;
862- const time = engine . playing || bridge . backend === 'tauri'
863- ? bridge . getCurrentTime ( )
864- : useTransportStore . getState ( ) . currentTime ;
884+ const time = getActivePlaybackTime ( engine , bridge ) ;
865885 finalizeSessionArrangementRecording ( time ) ;
866886 stopStrudelEditorPlayback ( ) ;
867887 engine . stop ( ) ;
888+ setTauriPlaybackClockOwner ( 'web-audio' ) ;
868889 bridge . stopAllSources ( ) ;
869890 synthEngine . releaseAll ( ) ;
870891 subtractiveEngine . releaseAll ( ) ;
@@ -884,6 +905,7 @@ export function useTransport() {
884905 stopAllStrudelTracks ( ) ;
885906 if ( engine . playing || ( bridge . backend === 'tauri' && useTransportStore . getState ( ) . isPlaying ) ) {
886907 engine . stop ( ) ;
908+ setTauriPlaybackClockOwner ( 'web-audio' ) ;
887909 bridge . stopAllSources ( ) ;
888910 synthEngine . releaseAll ( ) ;
889911 subtractiveEngine . releaseAll ( ) ;
0 commit comments