@@ -636,6 +636,58 @@ export function Player({
636636 ! isPlaying &&
637637 ! isRepeat ;
638638
639+ const lastSyncedFileRef = useRef < string | null > ( null ) ;
640+
641+ const applyPlaybackModeToEngine = useCallback ( ( ) => {
642+ let targetRate : number ;
643+ let targetSemitones : number ;
644+ switch ( playbackMode ) {
645+ case "slowed" :
646+ targetRate = slowedRate ;
647+ targetSemitones = getSemitonesFromRate ( slowedRate ) ;
648+ break ;
649+ case "speedup" :
650+ targetRate = speedupRate ;
651+ targetSemitones = getSemitonesFromRate ( speedupRate ) ;
652+ break ;
653+ case "custom" :
654+ targetRate = customRate ;
655+ targetSemitones = customSemitones ;
656+ break ;
657+ default :
658+ targetRate = normalRate ;
659+ targetSemitones = 0 ;
660+ }
661+ setRate ( targetRate ) ;
662+ setSemitones ( targetSemitones ) ;
663+ } , [
664+ playbackMode ,
665+ slowedRate ,
666+ normalRate ,
667+ speedupRate ,
668+ customRate ,
669+ customSemitones ,
670+ setRate ,
671+ setSemitones ,
672+ ] ) ;
673+
674+ // Re-apply the selected mode after a new track finishes loading — the stretch
675+ // pipeline reinitializes on fileUrl changes and can otherwise keep rate at 1.
676+ useEffect ( ( ) => {
677+ if ( ! media ?. fileUrl ) {
678+ lastSyncedFileRef . current = null ;
679+ return ;
680+ }
681+ if ( ! isReady ) return ;
682+ if ( lastSyncedFileRef . current === media . fileUrl ) return ;
683+ lastSyncedFileRef . current = media . fileUrl ;
684+ applyPlaybackModeToEngine ( ) ;
685+ } , [ media ?. fileUrl , isReady , applyPlaybackModeToEngine ] ) ;
686+
687+ useEffect ( ( ) => {
688+ lastSyncedFileRef . current = null ;
689+ } , [ advancedStretch ] ) ;
690+
639691 const handleAdvancedStretchChange = useCallback ( ( enabled : boolean ) => {
640692 setAdvancedStretch ( enabled ) ;
641693 savePlaybackPrefs ( { advancedStretch : enabled } ) ;
@@ -1055,6 +1107,10 @@ export function Player({
10551107 const handleRateChange = useCallback (
10561108 ( newRate : number ) => {
10571109 setRate ( newRate ) ;
1110+ if ( playbackMode === "custom" ) {
1111+ setCustomRate ( newRate ) ;
1112+ return ;
1113+ }
10581114 // Save rate per current mode
10591115 const mode = getModeFromRate ( newRate , semitones ) ;
10601116 if ( mode === "slowed" ) setSlowedRate ( newRate ) ;
@@ -1063,7 +1119,7 @@ export function Player({
10631119 else setCustomRate ( newRate ) ;
10641120 setPlaybackMode ( mode ) ;
10651121 } ,
1066- [ setRate , semitones ] ,
1122+ [ setRate , semitones , playbackMode ] ,
10671123 ) ;
10681124
10691125 const handleSemitonesChange = useCallback (
0 commit comments