MidiRemote Quirks

I’ve been deep diving into the midi-remote api the last few weeks, and I’ve found couple of quirks/issues - they MAY be bugs, perhaps stuff that’s not implemented yet, or just me misunderstanding how things are supposed to work…

OnColorChange for Input channels:
It appears that input channels always have a colour of 0,0,0 and are marked as inActive. I appreciate that input channels don’t have tracks so don’t have a colour, but if they sent the default colour instead then they’d “just work”. Otherwise they need special treatment to make the text readable.

OnCololorChange isn’t sent when you change the colour!!! It gets sent on the next track refresh. This is pretty minor but slightly annoying.

OnTitleChanged activeMapping holds the track name for (normally bound)faders and buttons, but for PushEncoders it just holds “Panner”. This is annoying as the encode assignment is something MCU style mappings change around, so it makes sense to take the assignment name from the EncodeKnob

What is Maxerbanks setFollowVisibility() supposed to do… I assumed that it meant that the included tracks were the same ones that were filtered in the onscreen mixer but that doesn’t seem to be the case. Having an option to use the users onscreen preferences would be great.

There were also a few places where its possible t map to key commands (toggle global automation settings) but then there’s no way to provided the feedback to the desk, so the button led can’t track the onscreen button… I’m assuming stuff like this is somewhere on the todo list and will get added as a HostAccess object someday…

I’m throwing this all out there, more as a record of my experience rather than bug reporting, as I’ve probably missed a few things, or done something stupid. Also I’m still on 12.50 so maybe some stuff has changed in 12.51, but I’ve not updated yet.

Overall the API works really well - When I figured out subpages a whole loads of cool stuff opened up!

Please update straight to 12.0.52 (it’s a hotfix for 12.0.51)

“.setFollowVisibility()” is a teaser for future updates (aka no impl bug :wink: )

The “colors not updating when being changed”-thing is a known issue.

yes, key commands do not provide a feedback channel, and it’s unlikely to be changed.

2 Likes

Couple of more quirks:

Sends and similar are accessed by Index, but the 4 eq bands are accessed by different accessors. I get it makes sense that there are a fixed number of bands, but it means the code has to be written out by hand to access each band. Adding bandAtIndex() to channelEQ would avoid copy pasting code (and future proofs for more than 4 bands).

Is it OK to add/remove channels from the hostBankZone after it’s been mapped? or is it better to create multiple hostBankZones, with different sets of tracks in? Multiple Zones seems to work, but makes some other stuff harder. Adding removing seems OK too, but doesn’t seem to update objects bound to channels in the bank until they’re refreshed for some other reason.

Is either approach preferable?

Hi @dctsys, please have a look at the API’s SubPage feature.

Here is an example:

var subPageAreaEQBands = page.makeSubPageArea('EQ Bands')
var subPageEQBand1 = subPageAreaEQBands.makeSubPage('Band 1')
var subPageEQBand2 = subPageAreaEQBands.makeSubPage('Band 2')
var subPageEQBand3 = subPageAreaEQBands.makeSubPage('Band 3')
var subPageEQBand4 = subPageAreaEQBands.makeSubPage('Band 4')

var hostSelTrkEQ = page.mHostAccess.mTrackSelection.mMixerChannel.mChannelEQ
page.makeValueBinding(knob.mSurfaceValue, hostSelTrkEQ.mBand1.mGain).setSubPage(subPageEQBand1)
page.makeValueBinding(knob.mSurfaceValue, hostSelTrkEQ.mBand2.mGain).setSubPage(subPageEQBand2)
page.makeValueBinding(knob.mSurfaceValue, hostSelTrkEQ.mBand3.mGain).setSubPage(subPageEQBand3)
page.makeValueBinding(knob.mSurfaceValue, hostSelTrkEQ.mBand4.mGain).setSubPage(subPageEQBand4)

// step through sub pages
page.makeActionBinding(buttonA.mSurfaceValue, subPageAreaEQBands.mAction.mNext)
page.makeActionBinding(buttonB.mSurfaceValue, subPageAreaEQBands.mAction.mPrev)

// direct activation of sub page
page.makeActionBinding(button1.mSurfaceValue, subPageEQBand1.mAction.mActivate)
page.makeActionBinding(button2.mSurfaceValue, subPageEQBand2.mAction.mActivate)
page.makeActionBinding(button3.mSurfaceValue, subPageEQBand3.mAction.mActivate)
page.makeActionBinding(button4.mSurfaceValue, subPageEQBand4.mAction.mActivate)

That’s basically what I ended up doing, but it’s way more code than it needs to be,especially when you add Freq, Q, type and on/off -each of which has to be copy-sated 4 times, which creates a maintenance and debug issue.

Being able to access the bands by index (as a future addition) would mean 1/4 as many lines of code to set them up:

var subPageAreaEQBands = page.makeSubPageArea('EQ Bands')
var subPageEQBand={}
for(var i=0;i<4;i++)
    {
    subPageEQBand[I] = subPageAreaEQBands.makeSubPage('Band '.concat((I+1).toString())
    page.makeValueBinding(knob.mSurfaceValue,hostSelTrkEQ.getBand(i).mGain).setSubPage(subPageEQBand[I])
    page.makeActionBinding(button[I].mSurfaceValue, subPageEQBand[I].mAction.Activate)
    }

You can do that already as JavaScript allows accessing members using strings.

But anyway, you’re trading amount of code for complexity. If you compare the stripped examples below, you’ll see it only reduces less than 50%.

Short version (9 lines):

var subPageAreaEQBands = page.makeSubPageArea('EQ Bands')
var hostSelTrkEQ = page.mHostAccess.mTrackSelection.mMixerChannel.mChannelEQ
for (var i = 0; i < 4; ++i) {
	var subPageEQBand = subPageAreaEQBands.makeSubPage('Band ' + i)
	page.makeValueBinding(knob.mSurfaceValue, hostSelTrkEQ["mBand" + (i + 1)].mGain).setSubPage(subPageEQBand)
	page.makeActionBinding(button[i].mSurfaceValue, subPageEQBand.mAction.mActivate)
}
page.makeActionBinding(buttonA.mSurfaceValue, subPageAreaEQBands.mAction.mNext)
page.makeActionBinding(buttonB.mSurfaceValue, subPageAreaEQBands.mAction.mPrev)

Long version (16 lines):

var subPageAreaEQBands = page.makeSubPageArea('EQ Bands')
var subPageEQBand1 = subPageAreaEQBands.makeSubPage('Band 1')
var subPageEQBand2 = subPageAreaEQBands.makeSubPage('Band 2')
var subPageEQBand3 = subPageAreaEQBands.makeSubPage('Band 3')
var subPageEQBand4 = subPageAreaEQBands.makeSubPage('Band 4')
var hostSelTrkEQ = page.mHostAccess.mTrackSelection.mMixerChannel.mChannelEQ
page.makeValueBinding(knob.mSurfaceValue, hostSelTrkEQ.mBand1.mGain).setSubPage(subPageEQBand1)
page.makeValueBinding(knob.mSurfaceValue, hostSelTrkEQ.mBand2.mGain).setSubPage(subPageEQBand2)
page.makeValueBinding(knob.mSurfaceValue, hostSelTrkEQ.mBand3.mGain).setSubPage(subPageEQBand3)
page.makeValueBinding(knob.mSurfaceValue, hostSelTrkEQ.mBand4.mGain).setSubPage(subPageEQBand4)
page.makeActionBinding(buttonA.mSurfaceValue, subPageAreaEQBands.mAction.mNext)
page.makeActionBinding(buttonB.mSurfaceValue, subPageAreaEQBands.mAction.mPrev)
page.makeActionBinding(button1.mSurfaceValue, subPageEQBand1.mAction.mActivate)
page.makeActionBinding(button2.mSurfaceValue, subPageEQBand2.mAction.mActivate)
page.makeActionBinding(button3.mSurfaceValue, subPageEQBand3.mAction.mActivate)
page.makeActionBinding(button4.mSurfaceValue, subPageEQBand4.mAction.mActivate)