private long interpolateTimeFromUpdate ( TrackPositionUpdate lastTrackUpdate , CdjStatus newDeviceUpdate , BeatGrid beatGrid ) { final int beatNumber = newDeviceUpdate . getBeatNumber ( ) ; final boolean noLongerPlaying = ! newDeviceUpdate . isPlaying ( ) ; // If we have just stopped, see if we are near a cue (assuming that information is available), and if so, // the best assumption is that the DJ jumped to that cue. if ( lastTrackUpdate . playing && noLongerPlaying ) { final CueList . Entry jumpedTo = findAdjacentCue ( newDeviceUpdate , beatGrid ) ; if ( jumpedTo != null ) return jumpedTo . cueTime ; } // Handle the special case where we were not playing either in the previous or current update, but the DJ // might have jumped to a different place in the track. if ( ! lastTrackUpdate . playing ) { if ( lastTrackUpdate . beatNumber == beatNumber && noLongerPlaying ) { // Haven't moved return lastTrackUpdate . milliseconds ; } else { if ( noLongerPlaying ) { // Have jumped without playing. if ( beatNumber < 0 ) { return - 1 ; // We don't know the position any more; weird to get into this state and still have a grid? } // As a heuristic, assume we are right before the beat? return timeOfBeat ( beatGrid , beatNumber , newDeviceUpdate ) ; } } } // One way or another, we are now playing. long elapsedMillis = ( newDeviceUpdate . getTimestamp ( ) - lastTrackUpdate . timestamp ) / 1000000 ; long moved = Math . round ( lastTrackUpdate . pitch * elapsedMillis ) ; long interpolated = ( lastTrackUpdate . reverse ) ? ( lastTrackUpdate . milliseconds - moved ) : lastTrackUpdate . milliseconds + moved ; if ( Math . abs ( beatGrid . findBeatAtTime ( interpolated ) - beatNumber ) < 2 ) { return interpolated ; // Our calculations still look plausible } // The player has jumped or drifted somewhere unexpected, correct. if ( newDeviceUpdate . isPlayingForwards ( ) ) { return timeOfBeat ( beatGrid , beatNumber , newDeviceUpdate ) ; } else { return beatGrid . getTimeWithinTrack ( Math . min ( beatNumber + 1 , beatGrid . beatCount ) ) ; } }
Sanity - check a new non - beat update make sure we are still interpolating a sensible position and correct as needed .