StudioMixMap Version 1.1 (Beta 4)

[See version notes at the end of this file for info on new features!]

What is StudioMixMap?  

StudioMixMap is an application that allows you to use the faders, buttons, knobs, and transport controls on the StudioMix to send just about any MIDI controller messages that you want.  Now you can twiddle the knobs on your soft-synth with your StudioMix, or use it to control StudioWare devices, or use it as a transport controller for programs other than Cakewalk and SONAR, like Sound Forge.  In addition, StudioMixMap supports reverse mapping: if you have mapped a fader to controller 1 and you are playing back MIDI that changes controller 1, the fader will follow the changes.  StudioMixMap was designed to work well with Cakewalk/SONAR, but it also lets you use your StudioMix without running them at all.  You could even be using another sequencer entirely.

StudioMixMap also has fixes for two problems that apparently afflict many StudioMix users: the problem of fader "jitter," and the bug in SONAR 1 that prevents StudioMix faders from moving on playback of MIDI tracks.

Why Is StudioMixMap Useful?
This program was born out of my frustration at not being able to use my StudioMix to control programs and devices other than Cakewalk/SONAR.  I discovered that I could use the (excellent, by the way) utility MidiOx (that's www.midiox.com, folks) to map the output from the StudioMix faders to MIDI controller messages, but I couldn't do much about the buttons and knobs.  The problem is that the StudioMix knobs just send out messages that say "one click right" or "one click left."  The knobs don't store state (i.e. current value), so mapping isn't enough.  StudioMixMap stores the state of each of the knobs and buttons, and this allows it to translate two consecutive "one click right" messages into a "Controller n to 119" message, and then a "Controller n to 120" message.  This also allows the buttons to behave like toggle switches, if desired.

I, and probably most StudioMix users, have a variety of devices and programs I want to control, so I've worked hard to make it fairly painless to switch back and forth. The StudioMixMap takes care of moving the faders and restoring the knob and button values to the place where you left them for each device or program.

The program also provides a work-around for the SONAR 1 MIDI track automation non-playback bug and attempts to address (or mitigate) the problem of fader jitter.

Caveats:
I've only worked with my own StudioMix; so I can't promise my fixes will work for everyone.  I hope to get feedback so that future versions of the program will solve problems for more people.  This applies particularly to "fader creep," which I haven't experienced on my own system.  My hope is that the "jitter" fix will solve people's problems with fader creep, but I don't know.

Installation
Just put the program somewhere and be sure the included .dll files (MxMidi16.dll, MxMidi95.dll and MxMidi32.dll) are with it in the same directory.  If you prefer, you can put the .dll's into the Windows System folder.  I use an .ini file in the program's directory (instead of writing to the registry) to store some program settings; it will show up after you’ve run the program for the first time.

StudioMixMap Setup
StudioMixMap has to interpose itself into the MIDI data stream between the StudioMix and the rest of your MIDI world.  If you're running Cakewalk or SONAR, StudioMixMap will be quite useful to you, but you don't need to be running either program at all to use your StudioMix (and your computer running StudioMixMap) as a MIDI controller for hardware instruments or effects or stand-alone software synths.  When I talk about a "sequencer" below, keep in mind that I really mean "sequencer or any other MIDI controllable program or instrument," but that's pretty unwieldy.

You can insert StudioMixMap into the MIDI stream in a variety of ways: you could do it physically if you have hardware ports to spare, or you could use a patch bay, but it's probably easiest to acquire and install some type of MIDI loopback software for your system.  I use MidiYoke, available from the people who brought you MidiOx at, once again,  www.midiox.com.

The StudioMixMap application sits between the StudioMix and your sequencer, and either passes MIDI data through or transforms it.  The chain looks like this:

[StudioMix MIDI out] -->
[Computer MIDI In] --> 
[StudioMixMap App] --> 
[Loopback Device X] --> 
[SONAR input]

The StudioMixMap application also sits between data going out of SONAR and into data going into the StudioMix.  The chain looks like this:

[SONAR output] -->  
[Loopback Device Y] --> 
[StudioMixMap App] --> 
[Computer MIDI Out] -->
[StudioMix MIDI in]

You set these connections up under the MIDI menu in StudioMixMap.  The application will store your setup and attempt to restore it when you run the program again.

So, to step through it:

The StudioMix Input should be set to the input port on which the StudioMix is connected to the computer, and the StudioMix Output should be set to the output port on which the computer is connected to the StudioMix.

The Sequencer Input should be set to the input of whichever loopback device the user has designated as carrying data from the StudioMixMap application to the sequencer (or whatever else happens to be taking input from the loopback device).  The Sequencer Output should be set to the output of whichever loopback device the user has designated as carrying data from the sequencer to the StudioMixMap application.  Notice that you must use two loopback devices.

In the example of the signal chains above, StudioMix Input would be set to "Computer MIDI In" and StudioMix Output would be set to "Computer MIDI Out."  Sequencer MIDI In would be set to "Loopback Device X", and Sequencer MIDI Out would be set to "Loopback Device Y."

SONAR Setup
After you've made these changes, you'll need to set up SONAR as well.  First, make sure that the MIDI input port to which the StudioMix is connected (Computer MIDI In in the above example) is disabled as an input to SONAR.  Then, make sure that the loopback device to which the program is writing (Loopback Device X in the above example) is enabled as a MIDI input in SONAR.  Finally, in the StudioMix view, set the StudioMix output to be the other loopback device (Loopback Device Y in the above example).

Start StudioMixMap before you start SONAR if it is convenient to do so.  Doing this will allow StudioMixMap to see the fader changes SONAR sends out when it starts, and then the two will be synchronized right away.

Jitter Eater
My StudioMix has an intermittent and irritating problem.  Sometimes a fader suddenly starts sending out MIDI messages even though it isn't being moved.  My faders seem to "jitter" rapidly, either around a single value or back and forth between two ranges of values.  This sends out lots of MIDI messages and causes a variety of problems.  The Jitter Eater causes the application to "eat" (i.e. not echo) any messages for which the Jitter Delta value (as calculated by its Magical Jitter Processor -- see later section for details) is under a user-specified threshold.  You can tune this feature by opening the I/O window (View...Show I/O Window or F4) when your StudioMix is "dancing the jitterbug" and watching the Jitter Delta values displayed.  Set the Jitter Delta in the main view to the lowest value that still catches your particular brand of jitter.

MIDI Track Automation Playback Problem in SONAR 1
As most StudioMix/SONAR users probably know, there is a bug in SONAR 1(through 1.31) which causes messages intended for the StudioMix to be sent out on the wrong channel, if the track in question is a MIDI track.  StudioMix only listens to MIDI channel 16, so StudioMixMap re-channelizes all NRPN data from SONAR to the StudioMix to channel 16 -- well, as long as mapping isn't turned on, anyway.  When mapping is on, StudioMixMap blocks NRPN messages from SONAR to the StudioMix so that fader automation playback doesn't happen when the faders on the StudioMix are being mapped to send out controller messages.

What Is A Map?
The central idea in this program is that of a "map."  A map is a collection of settings for each control on the StudioMix; these settings determine how data corresponding to a control will be transformed (or not).  In other words, a map tells us what StudioMixMap will transmit when we move any knob, button, or fader on the StudioMix.

A StudioMixMap document is a collection of maps.  Maps are usually specialized for a specific device or program, so we want to have several on hand.  One might be a "No Mapping" map, which just passes data from the StudioMix unmodified.  This is the map that would work when using the StudioMix in its original context -- working with Cakewalk/SONAR in the usual way.  Next, we might have a map where the faders and knobs are set up to control parameters on a soft synth, but that passes the transport controls unchanged -- this way, we can be fooling around with the controls on a soft synth while still being able to control SONAR's transport.  Then, we might have a map to control the transport of Sound Forge, so we can use the jog and shuttle wheels to navigate in that application.

The Main View
The main view shows the contents of the currently selected map; it also shows the list of maps in the current document and has a few controls to allow moving data between the display and document.  For most maps (except the one for use with SONAR directly), the "Mapping On" box in the lower left will be checked.  For the knobs and faders, there is a field to set the MIDI controller message sent by the knob or fader, and a box that displays the value of the knob or fader.  New in version 1.1 is the "Rel" checkbox, which allows the knobs to be set, in banks,  to "relative" mode, where they send 1 when turned clockwise and 127 when turned counterclockwise.  For buttons there is likewise a field to set the controller number, but instead of a value field there is an on-screen button which displays the button's state.  The "Toggle" checkbox will cause the button to act like a toggle switch -- press to turn on, press again to turn off.  Without the "Toggle" setting, the on-screen button simply reflects the position of the corresponding button on the StudioMix, staying down only as long as the button is actually held down.  The value 128 in a controller field is a magic value that means that the control is unmapped.  I know this is kind of lame; but it works for the time being.

There is also a field to specify which MIDI channel a map should transmit on; selecting a map will redirect MIDI output to that map's channel.  This makes it easy to work with several devices set up to receive on different channels -- selecting the map for a device will direct MIDI to that device's channel.

StudioMixMap maps data going to the sequencer, but it can also map data coming back from the sequencer -- you control this with the "Reverse On" checkbox.  So, if you have fader 1 mapped to send controller 7, the program will map a controller 7 message from the sequencer to the MIDI message that will move the StudioMix fader.  For knobs and buttons, the program updates the state and value display of the virtual knobs and buttons.  I added some code that screens out "reflected" MIDI messages to the faders: this happens if you map a fader to a virtual control that transmits the same MIDI messages it is receiving. These messages make the faders nearly unusable because they mechanically resist every change you try to make.  I also do this for button messages if the buttons are in toggle mode, since seeing the reflected "button down" message would toggle the button back to its original value.  Anyway, this reverse mapping makes it much easier to punch in changes in recorded controller data, for instance, because if the sequencer has, in playing back automation, changed a virtual knob from a value of 0 to a value of 64 (and transmitted the change via MIDI), then when you turn the knob on the StudioMix to the right it will send 65, not 1.

I decided to exclude controllers 99, 98, 6, and 38 from reverse mapping.  These are the controller messages that make up NRPN messages, and if you are using StudioMix and SONAR, SONAR will be sending fader change messages to StudioMixMap even when you are using the program to send controller messages,  so your values for these controllers would be getting stomped on anyway.  I had to do this on all channels because the SONAR bug means that the fader change NRPN messages could be coming on any channel, not just 16.

In addition to reverse mapping, StudioMixMap has a feature that I call "background tracking".  If you have two maps, a "No Mapping" map and a synth map, say, and you are using the synth map while SONAR is running, background tracking means that StudioMixMap is following the fader changes sent out by SONAR so that when you switch to your "No Mapping" map, the faders will move -- not to where you left them, but to where SONAR has moved them in the meantime.  Any maps in your document that have mapping turned off will be updated in this way.  Unfortunately, this won’t keep the knobs in sync, since SONAR doesn't transmit these changes.

The transport buttons have a separate on/off control for mapping.  They also allow the option of sending note values instead of controller values, since some sequencers are set up for this kind of MIDI control.  The setting of "Controller" or "Note" will determine whether the value for a control is transmitted as a note number or a controller number.

The "Shuttle Multi-send" option causes the shuttle wheel to send out controller messages at regular intervals while it is being held in a "turned" position.  This option is necessary to use the shuttle wheel with Sound Forge and may be useful for other programs.

New in version 1.1 is the option of having the Jog and Shuttle wheels send different controller messages for forward and reverse.  Note that this is optional; to use the same controller in both directions, just put that controller number twice.

The "document management" section of the main view is centered around the list of maps.  Selecting a map from the list makes it the current map and loads its controller settings and values into the display.   You can change the current map's position in the list using the up and down arrow buttons.  You can delete the current map with the button that has an "X" on it.  You can create a new map (with the current settings and values) and add it to the list with the "New" button -- it's the one with the ghostly rectangle.  If you want to make the current values of a map the initial values, use the "Store Values".  If you want to restore the values for a map to its initial values, use the "Load Values" button.  One other piece of document management is the "File...Append..." menu item, which allows the application to append a document on disk to the current document.  This makes it easy to share maps -- a user could download a document containing only the map for a particular device, and then append it to the document that contains the maps for all his gear.

You can edit the map names by double-clicking on them in the list.

Finally, the "Send Snapshot" button causes the program to send out the current value of each knob, button, and fader.  This is only available when mapping is on.

Documents are loaded and saved in the usual way via the "File..." menu.

Compact View
When you're sick of staring at the control-laden mess that is StudioMixMap, you can switch to the Compact view (View...Compact View or F3) which only displays the values of the controls.  You can't change anything is this view, so when you want to edit your maps, you can switch back to the big view with View...Full View or F2.

I/O Window
Pop this up (View...Show I/O Window or F4) to see the gory details of what the StudioMix is sending in and what StudioMixMap is sending out.  There isn't a display for the information going the other way (from the sequencer into the StudioMix) -- hey, it's a free program.

Edit...Set Knobs...
This might save you a little time...it lets you set either row of knobs to 0, 127, or 0 and 127 alternating (think pan settings).  When you do this, StudioMixMap sends out MIDI messages to communicate the new values of the knobs that were changed (if mapping is on, of course).  This doesn't affect the knobs on the master channel of the StudioMix.  

Edit...Set Knob Resolution...
How much should the value change when you turn the StudioMix knob one click?  You decide.  At an increase of 1 per one click, the knobs are pretty "slow" -- meaning you risk wrist damage if you're trying to turn something from full-off to full-on; on the other hand, for fine gradations, one-to-one is the way to go.  Knob resolution is a property of the program, not of any particular map or document.

Edit...Set Button Preferences...
If you want, you can dedicate the bottom two buttons in the vertical row (next to the jog/shuttle control) to switch maps in StudioMixMap.  The upper button moves up through the list, the lower down.  If you enable this, StudioMixMap won't pass the messages from these buttons even to SONAR, so if you have them set up to do something that you can' t live without in SONAR, don't enable this. 

MIDI Behavior In Detail
Let me begin with a warning: I've tried to handle MIDI in such a way that you can have other devices on the same port as StudioMixMap, but I don't think this is a very good idea, as I haven't tested it much.

Forward MIDI Behavior
Forward, meaning MIDI from the StudioMix to the sequencer via StudioMixMap.

Any event not on channel 16 is echoed, since the StudioMix sends on channel 16.  Any event on channel 16 that isn't an NRPN is echoed.

If the event is an NRPN from a fader, it is checked to see if it qualifies as jitter; if it does, then the program will eat the NRPN.  Also, if the NRPN is a message from a fader that appears to be the result of the fader's value being set by MIDI (as opposed to by hand), the NRPN will get eaten.  The reason for this is that when you send a message to the StudioMix to position a fader, the fader doesn't actually go where you told it to go; it just goes somewhere close.  There are two ways a program can handle this -- break the bad news right away or wait for it to be discovered when the user moves a fader.  I followed SONAR's lead on this one, so I lie about where the fader is and wait until it gets moved to tell where it really is.  For instance, in SONAR, if you move an on-screen fader to, say, 64, the physical fader jumps to the middle of its range, and you might assume all is right with the world, since the fader's ToolTip tells you that the value is 64.  However, if you nudge the fader up a little, you might well see the on-screen fader move down to 63, since the StudioMix fader was really at 62, even though SONAR told it to go to 64.

If transport mapping is on, transport button presses will be mapped to the appropriate controller or note (and transport button releases will be eaten), and the jog wheel and shuttle control will be mapped.  If transport mapping isn't on, the transport button and jog and shuttle messages will be passed unmodified.

If the program is set to use the bottom two buttons in the vertical row to switch maps, then the NRPN's they send will be eaten by the program.  Otherwise, they are echoed.

If mapping is off, the NRPN's from the knobs, buttons, and faders will be echoed.  If mapping is on, all recognized NRPN's will be mapped, and any unrecognized NRPN's will get eaten.  The shuttle control has more gradations than I thought it was practical to map (seven forward and seven backward); the in-between messages will get thrown away.

Reverse MIDI Behavior
Reverse, meaning MIDI from the sequencer to the StudioMix via StudioMixMap.

If mapping is off, StudioMixMap will change the channel of any NRPN to be 16 and echo it.  This is a work-around for the SONAR bug that sends NRPN's on the wrong channel for MIDI tracks.  Any other MIDI data on any channel is passed unmodified.

If mapping is on, all NRPN's will get eaten by the program (although they will be "background tracked").  

If reverse mapping is off, any non-NRPN events will be echoed.

If reverse mapping is on, any non-controller messages will be echoed.  Any controller messages that aren't on the channel of the current map will be echoed.  All controller messages on the current map's channel will get eaten unless a fader is mapped to that controller, in which case the controller message will be mapped to an NRPN to move the fader. If a knob or button is mapped to the controller number, its value will be updated.

Magical Jitter Processor
As I said above, when one of my faders is "jittering," it is usually sending out a series of values that either centers around a single value (for example: 100, 98, 99, 101, 100, 102), or alternates between two ranges (for example:  100, 180, 98, 178, 181, 102, 105, 183).  In an effort to cover these bases, I store two values for each fader on the StudioMix: previousValue1 and previousValue2.  When a message arrives from the StudioMix indicating fader movement, the Jitter Processor does roughly the following:

delta1 = abs(newValue - previousValue1)
delta2 = abs(newValue - previousValue2)

// if neither delta is within jitterDelta, cycle the values through
if ((delta1 < jitterDelta) && (delta2 < jitterDelta))
{
   previousValue1 = previousValue2;
   previousValue2 = newValue;
   // Send the newValue raw or mapped as appropriate
}
// if the new value is within jitterDelta of previousValue1
// eat the new value and store it in previousValue1
else if (delta2 <= jitterDelta)
{
   previousValue1 = newValue;
   // Don't send anything
}
// if the new value is within jitterDelta of previousValue2
// eat the new value and store it in previousValue2
else // if (delta1 <= jitterDelta)
{
   previousValue2 = newValue;
   // Don't send anything
}

In general, the Jitter Eater will eat fewer messages the smaller you make Jitter Delta; you need to find a value that works for you and your particular hardware.

StudioMix NRPN Messages
StudioMix sends out NRPN messages.  These consist of four separate MIDI messages on controllers 99, 98, 6, and 38 respectively.  These are combined to provide an NRPN Number and a value.  While normal MIDI messages are restricted to a range of 0..127, NRPN messages have a range 0..16383.  

Here is what your StudioMix sends out.

Control			NRPN Number(s)
Knobs (1 - 8), Row 1:		500-507
Knobs (1 - 8), Row 2:		1500-1507
Master Knob 1:		4500
Master Knob 2:		4501

Knobs send a value of 1 when turned clockwise and 16383 when turned counter-clockwise.

Buttons (1 - 8):			2500-2507
Master Button:			4502
Vertical Buttons (top down):	5000-5004

Buttons send a value of 1 when depressed and 16383 when released.

Faders (1 - 8):			3500-3507
Master Fader:			4503

Faders theoretically send values between 0 and 16383; mine don't seem to get within 500 or so of either extreme.

Transport Buttons:
Rew				6000
Ff				6001
Play				6003  <--|
Stop				6002  <--| Notice this transposition! This doesn't match the layout on StudioMix.
Rec				6004
Int/MMC			6005

The transport buttons send a value of 1 when depressed and 16383 when released.

Jog				7000
Shuttle				7001

The jog wheel acts like a knob; it sends a value of 1 for each "click" clockwise and 16383 for each "click" counter-clockwise.

The shuttle wheel sends out a value of 1 when it is turned a little bit clockwise; as it is turned more in that direction, it sends out values of 2 through 7.  Similarly, as it is turned counter-clockwise, it sends values that progress from 16383 to 16377 at the counter-clockwise extreme.

Contact
Please let me know if you find bugs or have suggestions for enhancements.

Wayne Legro
wlegro@earthlink.net

Credits
My application is based on the Maximum MIDI Programmer's Toolkit Copyright © 1993-1997 by Paul Messick.

I recommend his book, Maximum MIDI: Music Applications in C++, which includes the toolkit.

Version Notes

StudioMixMap 1.1 Beta4

I accidentally trashed the minimize and close program buttons in Beta3; this version restores them.

StudioMixMap 1.1 Beta3

I think this on actually works -- how's that for a feature!  Also, the current map's name will be the name displayed in the Taskbar, so if you have your taskbar visible, you will be able to verify which map you're using without having to bring up the program window.

StudioMixMap 1.1 Beta2

Well, I just got on a roll, so I made a few other changes that were pretty easy.  I added the ability to have the buttons in the vertical row send notes instead of controller messages.  Currently, they use the note off convention of sending a Note On message with velocity 0; future versions should probably be more flexible about this (optionally sending real Note Off messages -- or does anything use those?).

I also added the ability to switch knobs into "relative" mode, where they always send 1 when turned clockwise and 127 when turned counterclockwise.  That's the good news; the bad news is that you can only do it in banks of 9 (ie the horizontal rows).  I know this isn't as flexible as it should be, but I figured better that than not doing it at all because I don't have time to do it "right".

StudioMixMap 1.1 Beta1

This is a small release.  You can now assign different controllers numbers to the forward and backward direction of the shuttle and jog wheels, and you can adjust the shuttle multi-send time more flexibly.

I also added support the infamous missing two buttons.