BASS.NET API for the Un4seen BASS Audio LibraryMidiInputDeviceColtrollerPairMatrix Property BASS.NET API for the Un4seen BASS Audio Library
Sets the controller pair matrix to automatic combine any ShortMessage with a StatusType of ControlChange.

Namespace: radio42.Multimedia.Midi
Assembly: Bass.Net (in Bass.Net.dll) Version: 2.4.12.0
Syntax

public byte[,] ColtrollerPairMatrix { get; set; }

Property Value

Type: Byte
Remarks

Some controllers are continuous controllers, which simply means that their value can be set to any value within the range from 0 to 16383 (for 14-bit coarse/fine resolution) or 0 to 127 (for 7-bit, coarse resolution). Some Midi data messages might actually use two sub-sequent short messages to construct a paired message representing a single value range (e.g. the ControlChange with a BankSelect). This to support paired values with a higher resolution (16384 instead of 128 values).

This matrix defines how sub-sequent short-messages with a StatusType of ControlChange are detected and which controller number defines the MSB (coarse) value and which defines the LSB (fine) value. Furthermore the matrix defines which controller number is used in the single combined and paired short-message used in the resulting MessageReceived event.

When a continuous controller pair is detected (see IsSetAsContinuousController) by default only the last received short-message of the pair will be used when raising the MessageReceived event. If the Midi input device follows the general rule and first sends the MSB (coarse) controller message and right after the LSB (fine) controller message this would mean, that in the MessageReceived event handle you would only see the last LSB (fine) message (the previous message with the MSB, coarse value will always be suppressed). However, when accessing the ControllerValue of the fired message you will receive the combined and paired 14-bit conroller value between 0 and 16383.

Sometimes Midi devices do not send the paired messages in a particular order. This would mean that controller pairs can still be detected and combined, but that in such case still the last received short-message of the pair will be used when the MessageReceived event is raised. This would result in the fact, that your application would sometimes receive the LSB short-message and sometimes the MSB short-message (see ControllerType). To handle this circumstance the ColtrollerPairMatrix keeps a value allowing you to swap or redefine the ControllerType value being used with the ShortMessage fired with the MessageReceived event.

NOTE: This property is only evaluated, if the AutoPairController property is set to and the ControlChannel messages are send exactly subsequently (with no other short-message in between)!

So how is the ColtrollerPairMatrix defined:

The matrix is defined as a two dimentional byte array meaning each element of the first dimention consists of 3 elements. Whereas the first dimention is simply the list of all defined controller pairs.

The matrix layout:

VerticalThe list of defined controller pairs (each entry represents a controller pair to be combined).
HorizontalThe definition of each controller pair:

First value : the MSB (coarse) controller number (see Controller).

Second value: the LSB (fine) controller number (see Controller).

Third value : the swap flag for the ControllerType of the forwarded message:

  • 255 - Leave current and previous message as is.
  • 254 - Use the LSB message value, swap previous message if needed.
  • 253 - Use the MSB message value, swap previous message if needed.
  • 252 - Use the LSB message value, leave previous message as is.
  • 251 - Use the MSB message value, leave previous message as is.
  • <128 - Overwrite and use this value, leave previous message as is.

      --MSB-LSB--SWAP-> (definition)
     |   0,  32, 255
     |   1,  33, 255
     |   2,  34, 255
     | ...  ...  ...
     |  99,  98, 254
     | 101, 100, 254
     v                  
(Pairs)

Here is the default definition of this property:

byte[,] ColtrollerPairMatrix = new byte[34,3] 
{ 
        {  0,  32, 255},
        {  1,  33, 255},
        {  2,  34, 255},
        {  3,  35, 255},
        {  4,  36, 255},
        {  5,  37, 255},
        {  6,  38, 255},
        {  7,  39, 255},
        {  8,  40, 255},
        {  9,  41, 255},
        { 10,  42, 255},
        { 11,  43, 255},
        { 12,  44, 255},
        { 13,  45, 255},
        { 14,  46, 255},
        { 15,  47, 255},
        { 16,  48, 255},
        { 17,  49, 255},
        { 18,  50, 255},
        { 19,  51, 255},
        { 20,  52, 255},
        { 21,  53, 255},
        { 22,  54, 255},
        { 23,  55, 255},
        { 24,  56, 255},
        { 25,  57, 255},
        { 26,  58, 255},
        { 27,  59, 255},
        { 28,  60, 255},
        { 29,  61, 255},
        { 30,  62, 255},
        { 31,  63, 255},
        { 99,  98, 255},
        {101, 100, 255}
};

You might use the ThisIsMSB and PreviousIsMSB properties to identify which message contains the coarse (MSB) or fine (LSB) controller value. A access the paired short-message use the PreviousShortMessage member.

Examples

VB
Private _inDevice As MidiInputDevice = Nothing
...
_inDevice = New MidiInputDevice(0)
_inDevice.AutoPairController = True
AddHandler _inDevice.MessageReceived, AddressOf InDevice_MessageReceived
If _inDevice.Open() Then
  _inDevice.Start()
End If
...
Private Sub InDevice_MessageReceived(sender As Object, e As MidiMessageEventArgs)
  If e.IsShortMessage Then
    If e.ShortMessage.IsSetAsContinuousController Then
      Console.WriteLine("Continuous Controller {0}: Value={1}", 
                        e.ShortMessage.Controller, 
                        e.ShortMessage.ControllerValue)
      If e.ShortMessage.ThisIsMSB Then
        Console.WriteLine("MSB ControllerType={0}", e.ShortMessage.ControllerType)
      Else
        Console.WriteLine("MSB ControllerType={0}", e.ShortMessage.PreviousShortMessage.ControllerType)
      End If
      If e.ShortMessage.PreviousIsMSB Then
        Console.WriteLine("LSB ControllerType={0}", e.ShortMessage.ControllerType)
      Else
        Console.WriteLine("LSB ControllerType={0}", e.ShortMessage.PreviousShortMessage.ControllerType)
      End If
    Else
      Console.WriteLine(e.ShortMessage.ToString())
    End If
  End If
End Sub
private MidiInputDevice _inDevice = null;
...
_inDevice = new MidiInputDevice(0);
_inDevice.AutoPairController = true;
_inDevice.MessageReceived += new MidiMessageEventHandler(InDevice_MessageReceived);
if ( _inDevice.Open() )
  _inDevice.Start();
...
private void InDevice_MessageReceived(object sender, MidiMessageEventArgs e)
{
  if (e.IsShortMessage)
  {
    if (e.ShortMessage.IsSetAsContinuousController)
    {
      Console.WriteLine("Continuous Controller {0}: Value={1}", 
                        e.ShortMessage.Controller, 
                        e.ShortMessage.ControllerValue);
      Console.WriteLine("MSB ControllerType={0}, LSB ControllerType={1}", 
                        e.ShortMessage.ThisIsMSB ? e.ShortMessage.ControllerType : 
                                                   e.ShortMessage.PreviousShortMessage.ControllerType,
                        e.ShortMessage.PreviousIsMSB ? e.ShortMessage.ControllerType : 
                                                       e.ShortMessage.PreviousShortMessage.ControllerType);
    }
    else
      Console.WriteLine(e.ShortMessage.ToString());
  }
  ...
}
See Also

Reference