Jump to content
  • entries
    9
  • comments
    4
  • views
    31,770

MIOS32: Velocity crossfaded keyboard zones (code included)


Duggle

1,655 views

 Share

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

 Share

0 Comments


Recommended Comments

There are no comments to display.

Guest
Add a comment...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
×
×
  • Create New...