desc: MaAr  <Mallet_Articulator>  v.1.1

slider1:47<0,127,1{c-2,c#-2,d-2,d#-2,e-2,f-2,f#-2,g-2,g#-2,a-2,a#-2,h-2,c-1,c#-1,d-1,d#-1,e-1,f-1,f#-1,g-1,g#-1,a-1,a#-1,h-1,c0,c#0,d0,d#0,e0,f0,f#0,g0,g#0,a0,a#0,h0,c1,c#1,d1,d#1,e1,f1,f#1,g1,g#1,a1,a#1,h1,c2,c#2,d2,d#2,e2,f2,f#2,g2,g#2,a2,a#2,h2,c3,c#3,d3,d#3,e3,f3,f#3,g3,g#3,a3,a#3,h3,c4,c#4,d4,d#4,e4,f4,f#4,g4,g#4,a4,a#4,h4,c5,c#5,d5,d#5,e5,f5,f#5,g5,g#5,a5,a#5,h5,c6,c#6,d6,d#6,e6,f6,f#6,g6,g#6,a6,a#6,h6,c7,c#7,d7,d#7,e7,f7,f#7,g7,g#7,a7,a#7,h7,c8,c#8,d8,d#8,e8,f8,f#8,g8}>damper

slider2:48<0,127,1{c-2,c#-2,d-2,d#-2,e-2,f-2,f#-2,g-2,g#-2,a-2,a#-2,h-2,c-1,c#-1,d-1,d#-1,e-1,f-1,f#-1,g-1,g#-1,a-1,a#-1,h-1,c0,c#0,d0,d#0,e0,f0,f#0,g0,g#0,a0,a#0,h0,c1,c#1,d1,d#1,e1,f1,f#1,g1,g#1,a1,a#1,h1,c2,c#2,d2,d#2,e2,f2,f#2,g2,g#2,a2,a#2,h2,c3,c#3,d3,d#3,e3,f3,f#3,g3,g#3,a3,a#3,h3,c4,c#4,d4,d#4,e4,f4,f#4,g4,g#4,a4,a#4,h4,c5,c#5,d5,d#5,e5,f5,f#5,g5,g#5,a5,a#5,h5,c6,c#6,d6,d#6,e6,f6,f#6,g6,g#6,a6,a#6,h6,c7,c#7,d7,d#7,e7,f7,f#7,g7,g#7,a7,a#7,h7,c8,c#8,d8,d#8,e8,f8,f#8,g8}>silent

slider3:50<0,127,1{c-2,c#-2,d-2,d#-2,e-2,f-2,f#-2,g-2,g#-2,a-2,a#-2,h-2,c-1,c#-1,d-1,d#-1,e-1,f-1,f#-1,g-1,g#-1,a-1,a#-1,h-1,c0,c#0,d0,d#0,e0,f0,f#0,g0,g#0,a0,a#0,h0,c1,c#1,d1,d#1,e1,f1,f#1,g1,g#1,a1,a#1,h1,c2,c#2,d2,d#2,e2,f2,f#2,g2,g#2,a2,a#2,h2,c3,c#3,d3,d#3,e3,f3,f#3,g3,g#3,a3,a#3,h3,c4,c#4,d4,d#4,e4,f4,f#4,g4,g#4,a4,a#4,h4,c5,c#5,d5,d#5,e5,f5,f#5,g5,g#5,a5,a#5,h5,c6,c#6,d6,d#6,e6,f6,f#6,g6,g#6,a6,a#6,h6,c7,c#7,d7,d#7,e7,f7,f#7,g7,g#7,a7,a#7,h7,c8,c#8,d8,d#8,e8,f8,f#8,g8}>tremolo low 

slider4:52<0,127,1{c-2,c#-2,d-2,d#-2,e-2,f-2,f#-2,g-2,g#-2,a-2,a#-2,h-2,c-1,c#-1,d-1,d#-1,e-1,f-1,f#-1,g-1,g#-1,a-1,a#-1,h-1,c0,c#0,d0,d#0,e0,f0,f#0,g0,g#0,a0,a#0,h0,c1,c#1,d1,d#1,e1,f1,f#1,g1,g#1,a1,a#1,h1,c2,c#2,d2,d#2,e2,f2,f#2,g2,g#2,a2,a#2,h2,c3,c#3,d3,d#3,e3,f3,f#3,g3,g#3,a3,a#3,h3,c4,c#4,d4,d#4,e4,f4,f#4,g4,g#4,a4,a#4,h4,c5,c#5,d5,d#5,e5,f5,f#5,g5,g#5,a5,a#5,h5,c6,c#6,d6,d#6,e6,f6,f#6,g6,g#6,a6,a#6,h6,c7,c#7,d7,d#7,e7,f7,f#7,g7,g#7,a7,a#7,h7,c8,c#8,d8,d#8,e8,f8,f#8,g8}>tremolo high

slider5:0<0,3,1{no_sustain,legato_to_sustain,key_to_sustain_norm,key_to_sustain_inv}>damping mode

@init //===================================================================================================================================

KEYBVELO = 0;   // KEYBVELO[N] - keyboard velocity matrix; 
KEYBOFFS = 512; // KEYBOFFS[N] - keyboard NOTEOFF-s state;
//                                                  
//                                                                         
//                                                            
i1=0;loop
(128,
  KEYBVELO[i1] = 0; KEYBOFFS[i1] = 0; //no notes pressed on a keyboard; no "unclosed" NOTEOFFS
  i1=i1+1;
);

NOTE_LO=-1;
NOTE_HI=-1;
SUST=0;
SLNT=0; // silebt tremolo note flag
POLY=2; // same note polyphony (fpr manual setup!!)



@slider // ================================================================================================================================

DAMP_KY = slider1;   // damp note number
SLNT_KY = slider2;   // silent note number
TREM_LO = slider3;   // left tremolo note number
TREM_HI = slider4;   // right tremolo note number
DAMP_MD = slider5;   // damp mode
SUST = DAMP_MD-2;    // init_sust_mode


@sample //=================================================================================================================================

while
(
  midirecv(offset,MD1,MD2,MD3)? // receive note
  (
		
		
		type=(MD1&$xF0)/$x10;
		type==9 && MD3==0 ? type=8; 
		type!=8 && type!=9 ?
		(
			midisend(offset,MD1,MD2,MD3); //through if not NOTE
		):( 
			
			MDnote=MD2;
			MDvelo=MD3;
			MDchan=MD1&$x0F;
			MDtype=type;
		
			MDnote == DAMP_KY ?  
			(                                         //-----------------------------------------------------------------------------is DAMP NOTE ?----|
				MDtype == 8 ? SUST=DAMP_MD-2;
				MDtype == 9 ? SUST=3-DAMP_MD;
				SUST == 0?
				(
					i04=0;                                                             //
					while (i04 <= 127)                                                 //
					(                                                                  //   OFF отложенные notes
						KEYBOFFS[i04] > 0 && KEYBVELO[i04]==0 ?                          //
						(                                                                //
							loop                           																 //
							(KEYBOFFS[i04],                                             	 //
								midisend(offset,8*16+MDchan,i04,MDvelo); //OFF               //  OFF velocity = DAMP_KY ON!!
								KEYBOFFS[i04]-=1; // decrease KEYBOFFS parameter          	 //
							);                                                             //
						);                                                               //  
						i04+=1;                        
					);
				);
				
				FLAG=0;
					 
			):( MDnote == SLNT_KY ? (                  //----------------------------------------------------------------------------is SLNT NOTE ?----|
				MDtype == 8 ? SLNT=0;
				MDtype == 9 ? SLNT=1;
				FLAG=1;

			):( MDnote==TREM_LO ? (                 //-------------------------------------------------------------------------is TREMOLO LO NOTE ?----|
				
				MDtype == 9 && NOTE_LO != -1?
				(
					KEYBVELO[NOTE_LO]=KEYBVELO[NOTE_HI]=MDvelo;
				
					KEYBOFFS[NOTE_LO] >= POLY ? 
						(
							loop
							(KEYBOFFS[NOTE_LO]-POLY,
								midisend(offset,8*16+MDchan,NOTE_LO,00); //OFF same previous if max poly reached
								KEYBOFFS[NOTE_LO]-=1; // decrease KEYBOFFS parameter
							);
						);
					midisend(offset,9*16+MDchan,NOTE_LO,KEYBVELO[NOTE_LO]); //send MIDI ON	
					KEYBOFFS[NOTE_LO]+=1;     // set OFFS parameter
				);
				MDtype == 8 && NOTE_LO != -1?
				(
					KEYBOFFS[NOTE_HI] >= POLY ? 
						(
							loop
							(KEYBOFFS[NOTE_HI]-POLY,
								midisend(offset,8*16+MDchan,NOTE_HI,00); //OFF same previous if max poly reached
								KEYBOFFS[NOTE_HI]-=1; // decrease KEYBOFFS parameter
							);
						);
					midisend(offset,9*16+MDchan,NOTE_HI,KEYBVELO[NOTE_HI]); //send MIDI ON	
					KEYBOFFS[NOTE_HI]+=1;     // set OFFS parameter
				);

			
			FLAG=2;
			
			):( MDnote==TREM_HI ? (                 //-------------------------------------------------------------------------is TREMOLO HI NOTE ?----|
				
				MDtype == 9 && NOTE_HI != -1 ?
				(
					KEYBVELO[NOTE_LO]=KEYBVELO[NOTE_HI]=MDvelo;
				
					KEYBOFFS[NOTE_HI] >= POLY ? 
						(
							loop
							(KEYBOFFS[NOTE_HI]-POLY,
								midisend(offset,8*16+MDchan,NOTE_HI,00); //OFF same previous if max poly reached
								KEYBOFFS[NOTE_HI]-=1; // decrease KEYBOFFS parameter
							);
						);
					midisend(offset,9*16+MDchan,NOTE_HI,KEYBVELO[NOTE_HI]); //send MIDI ON	
					KEYBOFFS[NOTE_HI]+=1;     // set OFFS parameter
				);
				MDtype == 8 && NOTE_LO != -1 ?
				(
					KEYBOFFS[NOTE_LO] >= POLY ? 
						(
							loop
							(KEYBOFFS[NOTE_LO]-POLY,
								midisend(offset,8*16+MDchan,NOTE_LO,00); //OFF same previous if max poly reached
								KEYBOFFS[NOTE_LO]-=1; // decrease KEYBOFFS parameter
							);
						);
					midisend(offset,9*16+MDchan,NOTE_LO,KEYBVELO[NOTE_LO]); //send MIDI ON	
					KEYBOFFS[NOTE_LO]+=1;     // set OFFS parameter
				);

			
			FLAG=3;
		
			):(                                        //--------------------------------------------------------------------------is NORMAL NOTE ?----|
			
				MDtype == 9 ? //----------------------------------------------------------------------------------------------NOTE_ON?---|
				(
					KEYBOFFS[MDnote] >= POLY ? 
					(
						loop
						(KEYBOFFS[MDnote]-POLY,
							midisend(offset,8*16+MDchan,MDnote,00); //OFF same previous if max poly reached
							KEYBOFFS[MDnote]-=1; // decrease KEYBOFFS parameter
						);
					);
					
					KEYBVELO[MDnote] = MDvelo; KEYBOFFS[MDnote]+=1;     // set new KEYBVELO and OFFS parameter
					MDnote < NOTE_LO || NOTE_LO == -1 ? NOTE_LO=MDnote; //
					MDnote > NOTE_HI ? NOTE_HI=MDnote;                  // set LO/HI note
					SLNT == 0 ?                                         // send MIDI if SILENT NOTE not pressed
					(
						midisend(offset,MD1,MDnote,MDvelo);  
					);	
				);
				
				MDtype == 8 ? //----------------------------------------------------------------------------------------------NOTE_OFF?--|
				(
					KEYBVELO[MDnote] = 0; 
					NOTE_LO=NOTE_HI=-1;                           //
					i01=0;                                        // 
						while (i01 <= 127)                          //
						(                                           //
							KEYBVELO[i01]>0?                          //   update LO HI note after NOTE OFF
							(                                         //
								NOTE_LO == -1 ? NOTE_LO=i01;            //
								NOTE_HI=i01;                            //
							);                                        //
							i01+=1;                                   //
						);                                          //
					
					DAMP_MD == 0? //--------------------------------------------------------------------DAMP_MODE_0?-|
					(
						loop
						(KEYBOFFS[MDnote],
							midisend(offset,8*16+MDchan,MDnote,00); //OFF 
							KEYBOFFS[MDnote]-=1; // decrease KEYBOFFS parameter
						);
					);
					DAMP_MD == 1? //--------------------------------------------------------------------DAMP_MODE_1?-|
					(
						NOTE_LO == -1 ? 
						(                                                                    // 
							i02=0;                                                             //
							while (i02 <= 127)                                                 //
							(                                                                  //   OFF отложенные notes
								KEYBOFFS[i02] > 0 ?                                              //
								(                                                                //
									loop                           																 //
									(KEYBOFFS[i02],                                             	 //
                  	midisend(offset,8*16+MDchan,i02,00); //OFF                	 //
                  	KEYBOFFS[i02]-=1; // decrease KEYBOFFS parameter          	 //
                  );                                                             //
								);                                                               //  
								i02+=1;                                   
							);        
						);
					
					
					);
       
					DAMP_MD == 2 || DAMP_MD == 3?//-------------------------------------------------DAMP_MODE_2_or_3?-|  
					(
						SUST == 0 ? 
						(                                                                    // 
							loop
							(KEYBOFFS[MDnote],
								midisend(offset,8*16+MDchan,MDnote,00); //OFF 
								KEYBOFFS[MDnote]-=1; // decrease KEYBOFFS parameter
							); 
						);
					
					
					);	

					FLAG=4;
				);
					
			))));                                        //---------------------------------------------------------------------------------------END----|
		);
	);
);
