MIDIbox Forum: MIOS32: Velocity crossfaded keyboard zones (code included) - MIDIbox Forum

Jump to content

-----
Simple keyboard zones
Rather than have the whole keyboard output the same midi channel (hence same sound) we may want to have "left hand ->Bass" and "right hand -> Treble" parts. This is accomplished by having a "zones" in this case upper and lower parts of the keyboard separated at a certain note on the keyboard ("split point").
A simple keyboard zone split is simple to define: for example output note numbers above a the split point on a different channel.
Posted Image

Velocity crossfaded zones
Rather than a sudden boundary dividing keys into one channel or another, crossfaded zones have an overlap. The incoming notes have their velocities scaled according to a curve best shown in a diagram:
Posted Image

Implementation
A simple split my be accomplished with a call to the following function with received midi package before sinding it on:
//*********************Simple split*************************************************************
mios32_midi_package_t split(mios32_midi_package_t m_p, u8 splitpoint)
{
 if ((m_p.type == NoteOn || m_p.type == NoteOff)&& m_p.note>splitpoint) 
    m_p.chn++;                                //output on next channel
 return m_p;	  
}
//**********************************************************************************************

The lower zone is output on the same channel as the input. The upper zone is output on the next channel.


Velocity crossfade zones are done with calls to two functions: upper and lower.
//********************Upper keyboard zone*******************************************************
mios32_midi_package_t VelocityCrossfadeUpper(mios32_midi_package_t m_p,u8 sp,u8 size,u8 chan){
	m_p.chn=chan;					      //route to new channel regardless	
	if (m_p.type==NoteOn){                //other event types are passed through 
		 if (m_p.velocity==0) return m_p; //note offs (vel==0) get passed through
		 if (m_p.note>(sp+size/2))return m_p;	//above split region so return unmodified
		 if (m_p.note<(sp-size/2)){		  //below split region so return velocity 0
			m_p.velocity=0; 	          
			return m_p;
		 }else{							  //within sp + or - size/2 so scale
			m_p.velocity=(m_p.velocity*(m_p.note-(sp-size/2)))/size;	//scale the velocity
			return m_p;
		 }
	} else return m_p;					//NoteOffs (or other events types) get passed through
}
//**********************************************************************************************
//*******************Lower Keyboard zone********************************************************
mios32_midi_package_t VelocityCrossfadeLower(mios32_midi_package_t m_p,u8 sp,u8 size,u8 chan){
	m_p.chn=chan;					  			//route to new channel	
	if (m_p.type==NoteOn){
		 if (m_p.velocity==0) return m_p; 		//note offs (vel==0) get passed through
		 if (m_p.note<(sp-size/2)) return m_p;	//below split region so return unmodified
		 if (m_p.note>(sp+size/2)){
			m_p.velocity=0; 					//above split region so return velocity 0
			return m_p;
		 }else{							 		//within sp + or - size/2 so scale
			m_p.velocity=m_p.velocity-(m_p.velocity*(m_p.note-(sp-size/2)))/size;//scale the velocity
			return m_p;
		 }
	} else return m_p;					//NoteOffs (or other events types) get passed through
}
//**********************************************************************************************

Application
The following application applies the crossfade split to note events on any channel of any (or all) ports. Midi packages on USB0 are not processed to keep the port available to MIOS Studio as a development convenience.
Usage
Inputs
notes on any channel
CC#110: Splitpoint location (note number)
CC#111: Split size (distance in midi notes)
Outputs
ch1: Lower zone output
ch2: Upper zone output

//***********Velocity crossfade zones app example******************************
void APP_MIDI_NotifyPackage(mios32_midi_port_t port, mios32_midi_package_t m_p)
{
static u8 splitpoint=60;    //defaults 
static u8 splitsize=12;     //defaults

  if (port!=USB0){ //reserve USB0 for MIOS Studio comms
    //send lower split
	MIOS32_MIDI_SendPackage(port,VelocityCrossfadeLower(m_p,splitpoint,splitsize,0));
	//send upper split
	MIOS32_MIDI_SendPackage(port,VelocityCrossfadeUpper(m_p,splitpoint,splitsize,1));
	
	if (m_p.type==CC){			//update split params
	    switch(m_p.cc_number){
			case 110: splitpoint=m_p.value;break;
			case 111: splitsize=m_p.value;break;
		}
	}	
  }		
}

Pictures and code © Duggle 2010
  Like

0 Comments On This Entry

Trackbacks for this entry [ Trackback URL ]

There are no Trackbacks for this entry

February 2012

M T W T F S S
  12345
678 9 101112
13141516171819
20212223242526
272829    

Categories

testblock

Ok this is a test blog block