@ -62,7 +62,7 @@ class ArpeggiatorEngine(QObject): 
			
		
	
		
			
				
					    NOTE_SPEEDS  =  {  
			
		
	
		
			
				
					        " 1/32 " :  1 / 32 ,  " 1/32T " :  1 / 48 ,  " 1/16 " :  1 / 16 ,  " 1/16T " :  1 / 24 ,   
			
		
	
		
			
				
					        " 1/8 " :  1 / 8 ,  " 1/8T " :  1 / 12 ,  " 1/4 " :  1 / 4 ,  " 1/4T " :  1 / 6 ,  
			
		
	
		
			
				
					        " 1/2 " :  1 / 2 ,  " 1/2T " :  1 / 3 ,  " 1/1 " :  1 ,  " 2/1 " :  2 ,  " 4/1 " :  4  
			
		
	
		
			
				
					        " 1/2 " :  1 / 2 ,  " 1/2T " :  1 / 3 ,  " 1/1 " :  1 ,  " 2/1 " :  2 ,  " 2/1T " :  4 / 3 ,  " " :  4 ,  " 4/1T " :  8 / 3  
			
		
	
		
			
				
					    }  
			
		
	
		
			
				
					     
			
		
	
		
			
				
					    def  __init__ ( self ,  channel_manager :  MIDIChannelManager ,  synth_router :  SynthRouter ,  
			
		
	
	
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
				
				@ -284,10 +284,20 @@ class ArpeggiatorEngine(QObject): 
			
		
	
		
			
				
					        self . step_duration  =  note_duration  /  beats_per_second  
			
		
	
		
			
				
					     
			
		
	
		
			
				
					    def  calculate_delay_step_duration ( self ) :  
			
		
	
		
			
				
					        """ Calculate time between delay steps based on tempo and delay timing """  
			
		
	
		
			
				
					        """ Calculate time between delay steps based on tempo and delay timing relative to note speed  """  
			
		
	
		
			
				
					        beats_per_second  =  self . tempo  /  60.0  
			
		
	
		
			
				
					        delay_note_duration  =  self . NOTE_SPEEDS [ self . delay_timing ]  
			
		
	
		
			
				
					        self . delay_step_duration  =  delay_note_duration  /  beats_per_second  
			
		
	
		
			
				
					         
			
		
	
		
			
				
					        # Get current note speed duration  
			
		
	
		
			
				
					        current_note_duration  =  self . NOTE_SPEEDS [ self . note_speed ]  
			
		
	
		
			
				
					         
			
		
	
		
			
				
					        # Get delay timing duration  
			
		
	
		
			
				
					        delay_timing_duration  =  self . NOTE_SPEEDS [ self . delay_timing ]  
			
		
	
		
			
				
					         
			
		
	
		
			
				
					        # Calculate delay as multiple of note speed  
			
		
	
		
			
				
					        delay_multiplier  =  delay_timing_duration  /  current_note_duration  
			
		
	
		
			
				
					         
			
		
	
		
			
				
					        # Calculate actual delay step duration  
			
		
	
		
			
				
					        self . delay_step_duration  =  ( current_note_duration  *  delay_multiplier )  /  beats_per_second  
			
		
	
		
			
				
					     
			
		
	
		
			
				
					    def  schedule_delays ( self ,  channel :  int ,  note :  int ,  original_volume :  int ) :  
			
		
	
		
			
				
					        """ Schedule delay/echo repeats for a note """  
			
		
	
	
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
				
				@ -423,17 +433,46 @@ class ArpeggiatorEngine(QObject): 
			
		
	
		
			
				
					        elif  self . pattern_type  ==  " random_chord " :  
			
		
	
		
			
				
					            self . current_pattern  =  self . _generate_random_chord_pattern ( )  
			
		
	
		
			
				
					         
			
		
	
		
			
				
					        # Apply user pattern length by truncating or repeating the pattern   
			
		
	
		
			
				
					        # Apply user pattern length intelligently based on pattern type   
			
		
	
		
			
				
					        if  self . current_pattern :  
			
		
	
		
			
				
					            original_pattern  =  self . current_pattern . copy ( )  
			
		
	
		
			
				
					            if  len ( self . current_pattern )  >  self . user_pattern_length :  
			
		
	
		
			
				
					                # Truncate pattern to user length  
			
		
	
		
			
				
					                self . current_pattern  =  self . current_pattern [ : self . user_pattern_length ]  
			
		
	
		
			
				
					            elif  len ( self . current_pattern )  <  self . user_pattern_length :  
			
		
	
		
			
				
					                # Repeat pattern to fill user length  
			
		
	
		
			
				
					                while  len ( self . current_pattern )  <  self . user_pattern_length :  
			
		
	
		
			
				
					                    remaining_steps  =  self . user_pattern_length  -  len ( self . current_pattern )  
			
		
	
		
			
				
					                    self . current_pattern . extend ( original_pattern [ : remaining_steps ] )  
			
		
	
		
			
				
					             
			
		
	
		
			
				
					            # For directional patterns, adapt the pattern to fit the length  
			
		
	
		
			
				
					            if  self . pattern_type  in  [ " up_down " ,  " down_up " ]  and  self . user_pattern_length  > =  4 :  
			
		
	
		
			
				
					                # For up_down with 4 steps: take first half up, second half down  
			
		
	
		
			
				
					                scale_notes  =  self . _generate_scale_notes ( )  
			
		
	
		
			
				
					                half_length  =  self . user_pattern_length  / /  2  
			
		
	
		
			
				
					                 
			
		
	
		
			
				
					                if  self . pattern_type  ==  " up_down " :  
			
		
	
		
			
				
					                    # First half: up progression  
			
		
	
		
			
				
					                    up_part  =  scale_notes [ : half_length ]  if  len ( scale_notes )  > =  half_length  else  scale_notes  *  ( ( half_length  / /  len ( scale_notes ) )  +  1 )  
			
		
	
		
			
				
					                    up_part  =  up_part [ : half_length ]  
			
		
	
		
			
				
					                     
			
		
	
		
			
				
					                    # Second half: down progression  
			
		
	
		
			
				
					                    down_part  =  list ( reversed ( scale_notes ) ) [ : half_length ]  if  len ( scale_notes )  > =  half_length  else  list ( reversed ( scale_notes ) )  *  ( ( half_length  / /  len ( scale_notes ) )  +  1 )  
			
		
	
		
			
				
					                    down_part  =  down_part [ : half_length ]  
			
		
	
		
			
				
					                     
			
		
	
		
			
				
					                    self . current_pattern  =  up_part  +  down_part  
			
		
	
		
			
				
					                elif  self . pattern_type  ==  " down_up " :  
			
		
	
		
			
				
					                    # First half: down progression  
			
		
	
		
			
				
					                    down_part  =  list ( reversed ( scale_notes ) ) [ : half_length ]  if  len ( scale_notes )  > =  half_length  else  list ( reversed ( scale_notes ) )  *  ( ( half_length  / /  len ( scale_notes ) )  +  1 )  
			
		
	
		
			
				
					                    down_part  =  down_part [ : half_length ]  
			
		
	
		
			
				
					                     
			
		
	
		
			
				
					                    # Second half: up progression  
			
		
	
		
			
				
					                    up_part  =  scale_notes [ : half_length ]  if  len ( scale_notes )  > =  half_length  else  scale_notes  *  ( ( half_length  / /  len ( scale_notes ) )  +  1 )  
			
		
	
		
			
				
					                    up_part  =  up_part [ : half_length ]  
			
		
	
		
			
				
					                     
			
		
	
		
			
				
					                    self . current_pattern  =  down_part  +  up_part  
			
		
	
		
			
				
					            else :  
			
		
	
		
			
				
					                # For other patterns, use the original logic  
			
		
	
		
			
				
					                if  len ( self . current_pattern )  >  self . user_pattern_length :  
			
		
	
		
			
				
					                    # Truncate pattern to user length  
			
		
	
		
			
				
					                    self . current_pattern  =  self . current_pattern [ : self . user_pattern_length ]  
			
		
	
		
			
				
					                elif  len ( self . current_pattern )  <  self . user_pattern_length :  
			
		
	
		
			
				
					                    # Repeat pattern to fill user length  
			
		
	
		
			
				
					                    while  len ( self . current_pattern )  <  self . user_pattern_length :  
			
		
	
		
			
				
					                        remaining_steps  =  self . user_pattern_length  -  len ( self . current_pattern )  
			
		
	
		
			
				
					                        self . current_pattern . extend ( original_pattern [ : remaining_steps ] )  
			
		
	
		
			
				
					         
			
		
	
		
			
				
					        self . pattern_length  =  len ( self . current_pattern )  
			
		
	
		
			
				
					        self . pattern_position  =  0