Skip to content

Commit

Permalink
New MIDI parameter syntax for --ctrlmidich arg
Browse files Browse the repository at this point in the history
As part of issue jamulussoftware#95, this implements a new way of specifying various
controllers.  The previous possibilities are retained.  This leaves

--ctrlmidich <n> receives on channel n (if 0, on all channels), offset
   to first fader is 70 (Behringer X-Touch)

--ctrlmidich <n>;<off> for specifying a different offset

--ctrlmidich <n>;f<off>*<channels>;p<off>*<channels> specified offsets
for fader controllers and pan controllers, respectively.

There are also s<off> and m<off> specs for Solo and Mute buttons,
respectively.

This only concerns the command line parsing: the actual implementation
is only there for the volume faders.
  • Loading branch information
dakhubgit committed Feb 10, 2021
1 parent f440a8b commit fed6713
Showing 1 changed file with 76 additions and 8 deletions.
84 changes: 76 additions & 8 deletions src/soundbase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,16 @@

#include "soundbase.h"

char const sMidiCtlChar[] =
{
// Has to follow order of EMidiCtlType
/* [EMidiCtlType::Fader] = */ 'f',
/* [EMidiCtlType::Pan] = */ 'p',
/* [EMidiCtlType::Solo] = */ 's',
/* [EMidiCtlType::Mute] = */ 'm',
/* [EMidiCtlType::None] = */ '\0'
};


/* Implementation *************************************************************/
CSoundBase::CSoundBase ( const QString& strNewSystemDriverTechniqueName,
Expand Down Expand Up @@ -241,6 +251,20 @@ void CSoundBase::ParseCommandLineArgument ( const QString& strMIDISetup )
// provides a definition for the controller offset of the level
// controllers (default 70 for the sake of Behringer X-Touch)
// [MIDI channel];[offset for level]
//
// The more verbose new form is a sequence of offsets for various
// controllers: at the current point, 'f', 'p', 's', and 'm' are
// parsed for fader, pan, solo, mute controllers respectively.
// However, at the current point of time only 'f' and 'p'
// controllers are actually implemented. The syntax for a Korg
// nanoKONTROL2 with 8 fader controllers starting at offset 0 and
// 8 pan controllers starting at offset 16 would be
//
// [MIDI channel];f0*8;p16*8
//
// Namely a sequence of letters indicating the kind of controller,
// followed by the offset of the first such controller, followed
// by * and a count for number of controllers (if more than 1)
if ( !strMIDISetup.isEmpty() )
{
// split the different parameter strings
Expand All @@ -252,17 +276,59 @@ void CSoundBase::ParseCommandLineArgument ( const QString& strMIDISetup )
iCtrlMIDIChannel = slMIDIParams[0].toUInt();
}

bool bSimple = true; // Indicates the legacy kind of specifying
// the fader controller offset without an
// indication of the count of controllers


// [offset for level]
if ( slMIDIParams.count() >= 2 )
{
iMIDIOffsetFader = slMIDIParams[1].toUInt();
int i = slMIDIParams[1].toUInt ( &bSimple );
// if the second parameter can be parsed as a number, we
// have the legacy specification of controllers.
if ( bSimple )
iMIDIOffsetFader = i;
}

if ( bSimple )
{
// For the legacy specification, we consider every controller
// up to the maximum number of channels (or the maximum
// controller number) a fader.
for ( int i = 0; i < MAX_NUM_CHANNELS; i++ )
{
if ( i + iMIDIOffsetFader > 127 )
break;
aMidiCtls[i + iMIDIOffsetFader] = { EMidiCtlType::Fader, i };
}
return;
}

for ( int i = 0; i < MAX_NUM_CHANNELS; i++ )
// We have named controllers

for ( int i = 1; i < slMIDIParams.count(); i++ )
{
if ( i + iMIDIOffsetFader > 127 )
break;
aMidiCtls[i + iMIDIOffsetFader] = { EMidiCtlType::Fader, i };
QString sParm = slMIDIParams[i].trimmed();
if ( sParm.isEmpty() )
continue;

int iCtrl = QString ( sMidiCtlChar ).indexOf ( sParm[0] );
if ( iCtrl < 0 )
continue;
EMidiCtlType eTyp = static_cast<EMidiCtlType> ( iCtrl );

const QStringList slP = sParm.mid ( 1 ).split ( '*' );
int iFirst = slP[0].toUInt();
int iNum = ( slP.count() > 1 ) ? slP[1].toUInt() : 1;
for ( int iOff = 0; iOff < iNum; iOff++ )
{
if ( iOff >= MAX_NUM_CHANNELS )
break;
if ( iFirst + iOff >= 128 )
break;
aMidiCtls[iFirst + iOff] = { eTyp, iOff };
}
}
}
}
Expand Down Expand Up @@ -297,10 +363,12 @@ printf ( "\n" );
if ( ( iStatusByte >= 0xB0 ) && ( iStatusByte < 0xC0 ) )
{
// make sure packet is long enough
if ( vMIDIPaketBytes.Size() > 2 )
if ( vMIDIPaketBytes.Size() > 2
&& vMIDIPaketBytes[1] <= uint8_t ( 127 )
&& vMIDIPaketBytes[2] <= uint8_t ( 127 ) )
{
const auto &cCtrl = aMidiCtls[qMin ( vMIDIPaketBytes[1], uint8_t ( 127 ) )];
const int iValue = qMin ( vMIDIPaketBytes[2], uint8_t ( 127 ) );
const CMidiCtlEntry &cCtrl = aMidiCtls[vMIDIPaketBytes[1]];
const int iValue = vMIDIPaketBytes[2];;
switch ( cCtrl.eType )
{
case Fader:
Expand Down

0 comments on commit fed6713

Please sign in to comment.