Overview
--------
 	Well, this is a small program I wrote to allow me to make even 
more noise with my MIDI keyboard through my GUS and also to 
play around a little with Window's MIDI capability.  It should work
with any midi device that uses the MidiMapper. Basically 
it allows you to create "regions" on your keyboard that you can 
then play particular sounds with, along with some additional 
effects, i.e. transpose, velocity, pan, and delay.  
Splitmidi.exe, which is on epas, does some of this, but I could 
never get it to work on my machine for more than a few minutes, 
but I liked the noise I could make when it did work, so I got 
inspired.  Be warned, however, that I wrote this in one 
marathon sitting, so I make very few claims about its 
robustness, utility, compatibility with other setups, etc.  It 
works for me and I like it, so I thought I'd let others give it 
a try.  I'd appreciate any feedback if it happens to work on 
other machines. On to the limited documentation...

Doc
---
	Anyway, the basic function of this program is to remap 
MIDI in events to different channels, applying various effects 
to them in the process and playing with different patches.  The 
main (and only) window consists of a list box containing the 
currently setup regions, and a series of edit controls to allow 
addition of new regions and updating of existing regions.

	A "region" consists of the following parameters:

channel: the output channel to which notes from this region 
		will be sent- this is not under user control

lo note, hi note: the note range that defines a particular 
		region, i.e. incoming notes from the MIDI 
		keyboard that fall within these values are 
		considered part of this region. 

patch:  the number of the patch to play for notes in this region
		NOTE: supports Patch Caching with the GUS

transpose: a value to transpose every note by before playing 
		(12 steps is an octave, so to transpose down an 
		octave, you'd enter -12)

velocity: an amount to add to the velocity of every outgoing 
		note; again this can be negative

pan: an amount to indicate the panning (i.e. left to right 
   		balance) for this region (0 is full left,127 right)

delay: this is the funky one, the number of milliseconds to 
		delay before sending a note (or really any 
		event) to this region

bend: not currently implemented, see below

	Once you have defined the parameters for a region, 
press add to add to the list of current regions.  You can also 
select a current region, change the values, and hit update to 
update the region.  Obviously, you can remove a region by 
selecting it and pressing remove.

	Save and load do pretty much what you'd expect - they 
save or load the current list of regions to a file with a .rgn 
extension.  Note than you can launch midiregn with a filename 
as a parameter, i.e. midiregn bgstrngs.rgn, and set up program 
manager groups for different setups, etc. 	


Installation Notes
------------------
	There are three settable parameters to midiregn. They 
are set in the midiregn.ini file.  This should be in the SAME 
DIRECTORY (not the Windows directory) as the executable.  They 
reside under the "[Settings]" section (pretty original, huh?)

They are all integer values, listed here with their default values:

MidiInDevice=0
	-the number of your midi in device

TimerInterval=1
	-the resolution that should be used for the delay timer.  
	This is the number of milliseconds between each call to 
	check the delay buffer.  On a slow machine, a setting 
	of 1 may cause a grisly death.  On my 486-66, it works 
	just dandy, but who knows.  Settings like 5 or 10 
	should work OK, unless you are trying to use very small delay 
	times, which don't work that great, anyway

EventBufferSize=200
	-the size (in number of events) of the delay buffer. 200
	should be fine, unless you have a controller that 
	generates a bunch of events, like wind or guitar.  Also,
	if you are using a 10 second delay or something, you 
	might want a bigger one.  WARNING: setting this over 
	8000 will cause also cause your machine to die an awful 
	death. So don't.

Implementation Notes
--------------------
	The delay effect works by putting any events for a 
given region into a circular queue (stolen shamelessly from 
Micorsoft's Midimon application), along with a timestamp of when 
the event should be sent .  A timer callback that runs 
every millisecond (by default, see above) checks the queue and 
sends any event whose time has come out the proper channel.  
The timer interval directly affects how faithful the delay is. 
Try various values for it if you want to see.

	Note that all events besides note events are simply 
routed to all the channels for the various regions, along with 
the proper delay.  This means that if you have a region 
with a 1 second delay, and you hit the sustain pedal, that 
controller event will be sent a second later to that channel.

Silly things to try
-------------------
	Map the bass part of the keyboard to acoustic bass, 
transpose it down an octave or two, and play any piano stuff 
with an interesting bass line.

	Layer different instruments on top of each other.

	Chorus, reverb type effects, as in some of the 
chris*.mid's.  Add a couple (or more?!?) regions that are of 
the same patch, but delayed by 15 and 30 milliseconds, with the
velocity scaled down, and one panned left and one right.

Known Limitations
-----------------
	The interface is abysmal. Oh well.

	Couldn't figure out how to get pitch bend to work.  I 
tried constructing the event just like the pan and program 
change events and sending, but that didn't work, as so:

void TRgnDlg::sendPitchBend(int chan,int val)
{
	long l=0;
	l |= chan;
	l |= PITCHBEND; //type of event
	if (val > 0)
		l |= (long)((long)pan) << 8;
	midiOutShortMsg(midiMap,l);
}

 If anyone knows who to do this, please let me know.

	Only uses MidiMapper as output device.



Distribution
------------
	This is use-at-your-own-risk-ware.  Hopefully, it won't 
screw anything up, but I make no promises.  Otherwise, do whatever you 
want to with it.  If anyone is interested, I'll give them 
source code, since most of it was pilfered from Microsoft and 
Borland sample code anyway.

	I'd appreciate it if people would send me any interesting .rgn
files they create (or post them, I guess).

Have fun.
John Lynch
johner@trilogy.com


