@@ -94,14 +94,22 @@ pub fn estimate_with<A: Signal, N: Signal>(audio: &A, note: &N, duration_sec: f6
9494 } ;
9595 }
9696
97- // Build shared sampling grid centered at search_center_sec
97+ // Build absolute-time sampling grid for the audio signal.
9898 let t_min = config. search_center_sec - config. search_range_sec ;
9999 let t_max = config. search_center_sec + duration_sec + config. search_range_sec ;
100100 let ts = build_ts_grid ( t_min, t_max, config. sampling_interval_sec ) ;
101101
102- // Sample both signals
102+ // Sample audio on the absolute-time grid.
103103 let audio_samples = audio. samples ( & ts) ;
104- let note_samples = note. samples ( & ts) ;
104+
105+ // Shift the note signal into absolute time by sampling it at
106+ // ts_note[i] = ts[i] - search_center_sec
107+ // so that a note event at chart time `note.time` appears at absolute
108+ // time `note.time + search_center_sec`. After this shift the two
109+ // signals share a single (absolute) coordinate system and the
110+ // cross-correlation lag is a small residual rather than the full offset.
111+ let note_ts: Vec < f64 > = ts. iter ( ) . map ( |& t| t - config. search_center_sec ) . collect ( ) ;
112+ let note_samples = note. samples ( & note_ts) ;
105113
106114 if audio_samples. is_empty ( ) || note_samples. is_empty ( ) {
107115 return AlignmentResult {
@@ -112,19 +120,15 @@ pub fn estimate_with<A: Signal, N: Signal>(audio: &A, note: &N, duration_sec: f6
112120 } ;
113121 }
114122
115- // Cross-correlation
123+ // Cross-correlation — now the best lag is a small residual around zero
116124 let max_lag_bins = ( config. search_range_sec / config. sampling_interval_sec ) . ceil ( ) as usize ;
117125 let ( corr, best_lag, best_val) = cross_correlation ( & note_samples, & audio_samples, max_lag_bins) ;
118126
119- // Best lag in seconds (relative to search center)
127+ // Residual lag, then add search_center_sec to get absolute offset
120128 let best_lag_sec = ( best_lag as isize - max_lag_bins as isize ) as f64 * config. sampling_interval_sec ;
121- // Absolute offset: search center + measured lag correction
122129 let offset = config. search_center_sec + best_lag_sec;
123130
124- // Build correlation curve with absolute offset on the x-axis.
125- // This makes the curve consistent with chart_offset and info_offset values,
126- // so the orange (chart offset) and green (suggested offset) markers are
127- // positioned correctly on the graph.
131+ // Correlation curve: x = absolute offset (search_center + lag)
128132 let correlation_curve: Vec < ( f64 , f32 ) > = corr
129133 . iter ( )
130134 . enumerate ( )
0 commit comments