1313
1414from matchmaker .base import OnlineAlignment
1515from matchmaker .dp .dtw_loop import oltw_arzt_loop
16- from matchmaker .features .audio import FRAME_RATE , QUEUE_TIMEOUT
16+ from matchmaker .features .audio import FRAME_RATE
17+ from matchmaker .io .audio import QUEUE_TIMEOUT
1718from matchmaker .utils import (
1819 CYTHONIZED_METRICS_W_ARGUMENTS ,
1920 CYTHONIZED_METRICS_WO_ARGUMENTS ,
2627 RECVQueue ,
2728 set_latency_stats ,
2829)
30+ from matchmaker .utils .stream import STREAM_END
2931
30- STEP_SIZE : int = 5
31- WINDOW_SIZE : int = 5
32- START_WINDOW_SIZE : Union [float , int ] = 0.25
32+ STEP_SIZE : int = 3
33+ WINDOW_SIZE : int = 10
34+ START_WINDOW_SIZE : Union [float , int ] = 0.1
3335
3436
3537class OnlineTimeWarpingArzt (OnlineAlignment ):
@@ -98,9 +100,9 @@ def __init__(
98100 current_position : int = 0 ,
99101 frame_rate : int = FRAME_RATE ,
100102 queue : Optional [RECVQueue ] = None ,
101- state_to_ref_time_map = None ,
102- ref_to_state_time_map = None ,
103- state_space = None ,
103+ state_to_ref_time_map = None ,
104+ ref_to_state_time_map = None ,
105+ state_space = None ,
104106 ** kwargs ,
105107 ) -> None :
106108 super ().__init__ (reference_features = reference_features )
@@ -178,12 +180,22 @@ def __init__(
178180 }
179181 self .state_to_ref_time_map = state_to_ref_time_map
180182 self .ref_to_state_time_map = ref_to_state_time_map
181- self .state_space = state_space #if state_space != None else np.unique(self.reference_features.note_array()["onset_beat"])
183+ self .state_space = state_space
184+ self ._ref_frame_to_beat : Optional [NDArray [np .float32 ]] = kwargs .get (
185+ "ref_frame_to_beat" , None
186+ )
187+
188+ @property
189+ def current_beat (self ) -> float :
190+ """Current score position in beats."""
191+ if self ._ref_frame_to_beat is not None :
192+ idx = min (self .current_position , len (self ._ref_frame_to_beat ) - 1 )
193+ return float (self ._ref_frame_to_beat [idx ])
194+ return float (self .current_position )
182195
183196 @property
184- def warping_path (self ) -> NDArray [np .int32 ]:
185- wp = (np .array (self ._warping_path ).T ).astype (np .int32 )
186- return wp
197+ def warping_path (self ) -> NDArray [np .float32 ]:
198+ return np .array (self ._warping_path ).T
187199
188200 def __call__ (self , input : NDArray [np .float32 ]) -> int :
189201 self .step (input )
@@ -211,10 +223,18 @@ def run(self, verbose: bool = True) -> Generator[int, None, NDArray[np.float32]]
211223 self .reset ()
212224
213225 if verbose :
214- pbar = progressbar .ProgressBar (max_value = self .N_ref , redirect_stdout = True )
226+ pbar = progressbar .ProgressBar (
227+ max_value = len (self .state_space ),
228+ redirect_stdout = True ,
229+ redirect_stderr = True ,
230+ )
231+ pbar .start ()
215232
216233 while self .is_still_following ():
217- features , f_time = self .queue .get (timeout = QUEUE_TIMEOUT )
234+ item = self .queue .get (timeout = QUEUE_TIMEOUT )
235+ if item is STREAM_END :
236+ break
237+ features , f_time = item
218238 self .last_queue_update = time .time ()
219239 self .input_features = (
220240 np .concatenate ((self .input_features , features ))
@@ -224,13 +244,13 @@ def run(self, verbose: bool = True) -> Generator[int, None, NDArray[np.float32]]
224244 self .step (features )
225245
226246 if verbose :
227- pbar .update (int (self .current_position ))
247+ pbar .update (int (np . searchsorted ( self .state_space , self . current_beat ) ))
228248
229249 latency = time .time () - self .last_queue_update
230250 self .latency_stats = set_latency_stats (
231251 latency , self .latency_stats , self .input_index
232252 )
233- yield self .current_position
253+ yield self .current_beat
234254
235255 if verbose :
236256 pbar .finish ()
@@ -289,23 +309,17 @@ def step(self, input_features: NDArray[np.float32]) -> None:
289309 min_index = min_index ,
290310 )
291311
292- # adapt current_position: do not go backwards,
293- # but also go a maximum of N steps forward
294-
295- if self .input_index == 0 :
296- # enforce the first time step to stay at the
297- # initial position
298- self .current_position = min ( # TODO: Is this necessary?
299- max (self .current_position , min_index ),
300- self .current_position ,
301- )
302- else :
303- self .current_position = min (
304- max (self .current_position , min_index ),
305- self .current_position + self .step_size ,
312+ # Clamp new position: no backwards, max step_size forward per frame
313+ if self .input_index > 0 :
314+ self .current_position = int (
315+ np .clip (
316+ min_index ,
317+ self .current_position ,
318+ self .current_position + self .step_size ,
319+ )
306320 )
307321
308- self ._warping_path .append ((self .current_position , self .input_index ))
322+ self ._warping_path .append ((self .current_beat , self .input_index ))
309323 # update input index
310324 self .input_index += 1
311325
0 commit comments