• entries
    9
  • comments
    4
  • views
    26,518

MIOS32: Velocity crossfaded keyboard zones (code included)

Sign in to follow this  
Followers 0
Duggle

619 views

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.

gallery_3440_57_70437.png

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:

gallery_3440_57_115744.png

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


Sign in to follow this  
Followers 0


0 Comments


There are no comments to display.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now