Mackie C4 Project and Novation A-Station remote panel

Hello everybody :slight_smile: ,

so here is my first version of a Novation V/A-Station remote panel for the Mackie C4 and i would like to share it.


Introduction:
The aim of the project is to truly showcase the power of a C4 and afterwards give Mackie C4 owners the possibility, to create things on their own. This midi controller is not well documented and if your software does not support it, you will be doomed, especially if you are on Mac OS. On release, there was once a software called ‘Total Commander’ that shipped with the Mackie C4, with which you could do remote panels easily, but this software has several downsides:

  1. It does not work anymore on any newer Mac OS (i think pre Intel-Macs where the last ones). No Rosetta-version.
  2. It does not support bi-directional work, so a panel cant react to program or parameter changes of the hardware for example.
  3. It also supports only one-time actions, so you cant use the push and turn function of a Vpot, only one of these per Vpot.
  4. It does not offer other functions like level metering, multiple Midi-Out etc.
  5. and last but not least, it only works with a PC of course.

This midi controller is capable of so much more. With Bome MTP and this project, you will have full control over it, finally understand your midi-controller and are not limited to these restrictions.

In combination with a Bome Box, you dont even need a PC anymore. You can do a Live act, with your hardware only and still use remote panels (yes, plural :wink: ).

The 32 Vpots:
So lets start exploring how the Mackie C4 works and I will start with the Vpots first:

Vpots are endless rotary encoders that send relative ±values (starting from the value/parameter they want to control) and therefore they have not a limited operating value ‘range’. The limit here, is only the parameter range itself.
This has the advantage that they are ‘moving’ accurate in any operating range. Accurate, because the starting point for ‘moving’ is always the current parameter value. In comparison most (cheap) encoders that send absolute values, are only operating in a limited 0-127 value range, because this range is hardcoded into them. Also they are always ‘moving’ from the point you left them.

‘Yah, but is not that the same?’. No, it is not. For example, if there is a program/preset change, then there is mostly likely parameter value changes too. If you now ‘move’ a encoder that send absolute values, then the parameter value will ‘jump’ to the last point where this encoder was. This behaviour is not wanted and can be very annoying, depending what parameter is controlled. This is especially true, while editing/creating a patch or in a live gig scenario, where one track ends and you are using different sounds for the next track. Aaah, i love seeing that stickers and labels on a cheap, tiny midi-controller, leaving you confused and buzzed in a dark environment and all that live on stage :clown_face:. That makes your heart pumping :japanese_ogre: .
There where several attempts in the past, that tried to evade this problem and none of them are accurate. In a nutshell: relative encoders will jump to the parameter value and start moving from there, whereas absolute encoders will ‘force’ the parameter value to jump to them.

‘So we have 32 encoders with relative values sending, is this great then or not?’
Unfortunately in their default state, they are not sending ± 1 values and Mackie did not include a option to do so. If the soft or hardware has no option to support proper scaling of the sended values, you can not really use them in almost all situations, where you want them to use, mainly in the common 0-127 value range. Steinberg Cubase, for example, needed decades to give users a option for that. This is where MTP is needed, but lets get back to the topic.

So the C4 has 32 Vpots, which send values with CC# 0-31 accordingly.

This is a bit awkward, because devs will tend to describe the Vpots in this way (using their CC# numbers). A normal person, does not think this way, as there is no Vpot 0 (in reality even the labeling of the hardware, does not follow this concept.) and so there is no Vpot 32, that he can find in comments of scripts either. I did my best to avoid this in my project, so that users can better follow the description and comments.

The 32 Vpots can also receive values from CC# 32-63 for their LED rings. Probably this was done to avoid infinite midi loops, that can cause hangs, crashes even blue screens. So as a thumb of rule, to adress the LED ring of a Vpot, you simply add 32 to the CC that a Vpot sends, to know the receiving CC number for the LED ring of that Vpot. Example: Vpot 1 will use CC#0 for sending and CC#32 for receiving values. I have attached style-sheets at the end of this post, that describe all CC# and note# numbers, that the Mackie C4 uses.

The LED rings can use four different ‘ring modes’, which i will decribe next. So in the example above we used Vpot 1, which can receives values on CC# 32. Depending on the value, you can use these ring modes described in this table:

*        Vpots 01-32 receiving:
*          CC# 32-63 + value             = ring mode:
*                CC# + value 00          = turns the LED ring Off.
*                CC# + value 01-11       = is used for Single LED ring mode.
*                CC# + value 16          = turns the LED ring Off.
*                CC# + value 17-27       = is used for Boost-Cut ring mode.
*                CC# + value 32          = turns the LED ring Off.
*                CC# + value 33-43       = is used for Wrap ring mode.
*                CC# + value 48          = turns the LED ring Off.
*                CC# + value 49-54       = is used for Spread ring mode.
*                CC# + value 55-63       = turns the LED ring Off
*                CC# + value 64          = turns on the pDot only
*                CC# + value 65-75       = turns on the pDot and is used in whole Single LED ring mode
*                CC# + value 80          = turns on the pDot only
*                CC# + value 81-91       = turns on the pDot and is used in whole Boost-Cut ring mode
*                CC# + value 96          = turns on the pDot only
*                CC# + value 97-107      = turns on the pDot and is used in whole Wrap ring mode.
*                CC# + value 112         = turns on the pDot only
*                CC# + value 113-118     = turns on the pDot and is used in whole Spread ring mode.
*                CC# + value 119-127     = turns on the pDot only

The four Ring Modes:

Single_Dot_no_PBoost_CutWrapped_ModeSpread_Mode

So in short, each ring mode uses eleven different values (or twelve if you add Off to it), to ‘move’ the LED segments (except for Spread that use only six). Each ring mode exists with or without a pDot. So for representing the common 0-127 value range with a LED ring, you will need to divide the range with eleven to have a evenly approximination showed of by the eleven LED segments of a ring (127/11). With Bome MTP you can create even a new ring mode, i.e. like this:
Blinking

Tip: I recommend to use the pDot LED only for Vpots that will also use the push-function. This way a user can clearly see, what Vpot can also be pushed. Probably the reason why Mackie named that pDot. I also recommend to use the Single LED ring mode as much as possible. While it is tempting to use all these ring modes, in practice the Single LED is clearly the most accurate one for showing values and the Vpots will not look like a messed up insanity. The other three ring modes, will often lead to situations, where they look the same and that will lead to confusion and you dont want confusion in a live gig. I prefer using only two different ring modes at most, because of that fact.Just observe the GIF animations above and you will know, what i mean. I would only use a different ring mode for a real special case or pointing to a important parameter, drawing attention to the user.

Poor documentation leads to poor support and poor support leads to poor user experience. The Mackie C4 has no documentation at all :clown_face: . Insanely dumb for that pricing and being a midi-controller. The only documentation that comes close, is the one for the Mackie MCU.
Even that is madness. They explained the MCU Vpot rings like this:

This is not wrong in midi-terms, but in all honesty i will ask you know, what did you understand better. My example or theirs… :rofl: :clown_face: :flushed:

More updates for the documentation of this Mackie C4 project are coming soon in this thread.

Mackie C4 remote panel for Novation A-Station v01…bmtp (60.8 KB)
Mackie C4 remote panel for Novation A-Station v03…bmtp (106.2 KB)



A-Station.pdf (1.6 MB)

Hi, we would need to capture the value of the global variable that contains the current LFO speed and then set a repeating timer at a calculated interval based on that value. Is the LFO speed represented by a 128 (7 bit) or 16383 (14 bit) CC. An example of a given value and associated blink rate would also help to figure the calculations needed.

I don’t see anywhere in your project where you document the global variables that you are using and what they are used for. I guess you are tracking them somewhere else.

Steve Caldwell
Bome Customer Care


Also available for paid consulting services: bome@sniz.biz

Hi Steve :slight_smile: ,

LFO speed is represented by 7bit.

LFO infos i got from the manual:

LFO 1 and LFO 2:
Waveform Sample & Hold / Tri / Saw / Squ
Speed 0 Hz – 1Khz
Delay Fade In 0 – 5 Seconds
LFO Sync Internal – MIDI Clock

Speed is set by CC 80 and range 0-127 for the NON-SYNC LFO1 SPEED, which is the one i want to experiment first. I know this can only be a approximation, but i would like to have it anyways. I will experiment to come close to the hardware :smiley: ;). The original can only blink and has no dimming. Full on or off so to say.

I am sorry, but they are inside the preset ‘Outgoing Values from A-Station’ in a Translator that is the first in the list, called ‘Novation A-Station Global Defs’. Maybe not the best place to be :slight_smile: . Currently there is no global for the LFO speed, but g6, g7 is the desired one. Thanks for looking into this.

OK, so what should the blink rate be at 1Khz? and what note number do you send to turn the LED on and off?

Steve Caldwell
Bome Customer Care


Also available for paid consulting services: bome@sniz.biz

Sequenz 01_1
Sequenz 01_2

Zero is off and 127 is so fast, you cant really tell if it is blinking or just on.
For the smaller gif, i did cut off the ‘turned’ off part, but you can see how long the duration for the ‘on’ part is. The ‘off’ part has the same duration.

For the note number, it would be the best to use aany LED segment of the Vpot Ring. Best would be the pdot of the ring (the one that is on the center bottom 40 in hex).

OK, I’m not going to mess with your project so I attached and example.

This works with the first VPOT of MCU controller.
I calculate the CC value and send the CC 80 in translator 0.0.
I call Perform ‘Blink’ in that translator which is translator 0.1.
I used g6 to store the value

Perform Blink (Translator 0.1) calculated the blink rate and calls a repeating timer. If the blink rate is less than 100 ms or over 1000 ms, then I call Perform Stop (translator 0,2) and otherwise do nothing with the timer. If it within range it starts a repeating timer at the currently calculated rate.

The timer, actually turns on and off the LED toggling it (using global variable g7).

Blink stop (Translator 0.3) kills the timer and calls Perform ‘LED’ with the parameter for either on or off.

Translator 0.4 either turns off or on the LED when the timer stops.

I use aliases instead so that if port names change I just re-assign the alias.

You can learn more about aliases from this tutorial.

Blink-From LED value-example-2025-04-11.bmtp (2.6 KB)

Steve Caldwell
Bome Customer Care


Also available for paid consulting services: bome@sniz.biz
1 Like

Thats great, i will try that out. Thanks to your help, today i did found out how the meter leveling works on the Mackie C4. It was the last and only thing, that i could not setup on the Mackie C4 for years. Your patience with me and explaining the hex>binary>bit thing, helped me to understand the midi-implentation of the MCU and how to activate that meter leveling. Cant tell you, what a relief that find out is to me. This project was a good choice to learn these things and how great MTP is.

I wish you a very nice weekend. Again, many, many thanks for all that help and i will give my best to implement the LFO blinking :smiley: :blush:

1 Like

So i have included your ‘blink’ solution into my project. It is quite a nice gimmick i must say :slight_smile: . Sadly i cant sync it, mainly because the scaling is linear, but the LFO Speed range is not. With a setting of 350ms in your project for the speed range, it is working fairly good at mid to end settings, but anything below the half (range) of the rate is waaay off. It would need to blink once in intervals of several seconds, which is not possible with this setting. We need kind of a exponential curve to come close to the original. The LFOs can be synced to a midiclock. So i think the Rate range can be calculated. I am really not good in this. I mean knowing how long a delay should be i.e. for a triple note with 120bpm, but there are tables for that, from what i have seen.
I need to tweak blink project a little more, it should turn off completely after 5min., if there are no incoming messages, otherwise the displays will not turn off. It counts like a action for the device :smiley: and it should turn on again after incoming messages :wink: . I can configure the screensaver for the displays with:
F0 00 00 66 17 0B and then 00-7F for duration time. Default is 15minutes with 0F. I will try to bind the timeout for the LFO blink to that parameter. The last thing i need to do, is to alternate between lamp and the actual LFO Rate value showing/pointing with a LED ring segment. So the Vpot Ring is never completely off and instead pointing the value, this makes the effect even more ‘stylish’.
Wrap-Manual_1
But then, it will be perfect :smiley: .

We could mess with the scaling but it would probably be hit and miss. The best thing I would suggest is setting some MIDI values and then hardcoding the rate from there.

Like:

if g6==64 then tt=40
if g6 ==90 then tt=50

as crude example.

Even at that, there is no guarantee that LED will go on on the downbeat.

At a tempo of 120 beats per minute (BPM), a quarter note (1/4 note) has a duration of 500 milliseconds (ms). This can be calculated by dividing 60,000 milliseconds (one minute) by the tempo (120 BPM). For other time divisions, you can adjust the duration accordingly. For example, an eighth note (1/8 note) would be 250 ms (half of 500 ms) and a 1/128th note would be 16 ms.

If the MIDI clock is putting out clock pulses then we could use those and divide by 24 to blink the LED to have it blink once per quarter note.

Steve Caldwell
Bome Customer Care


Also available for paid consulting services: bome@sniz.biz

I will keep that in mind. Possibly the best to do this, is when i setup the page, where all these sync functions can be set. I dont know if the A-Station has a own midi clock, will consult the manual again :smiley: . But i know you can sync to a external clock, like DAW etc.

I has mentioned the Level metering and it is really cool to have that. You might think, those levels for output levels are inaccurate and slow and this is true, but to be honest, i think they where there for something different. I can use 16 channels. Four per display or two full rows. What i want to do, is to take the level meters for the matrix, where you choose things like Aftertouch, Velocity, Breath and how much impact they have on a patch/sound. If the metering is active it expects aftertouch values to work with. The Aftertouch message is divided into two single hex digits. The first (left) number tells which channel to use. Channel is such a wrong word, what the manual really meant was, a Vpot cell is counted as a channel and they really mean the hardware, not a midichannel or what so ever.
So i would need to split the hex again, left number is Vpot or channel to use. The right hex number should be the meter values. We can use a range of 0-C, and bind that to any paramter that is desired. If velocity is in question, then of course it needs to be converted, so that the output are aftertouch values from 0-C. This is quite a range. So we have 12 steps of the meter in a 0-128 range. Just like the LED rings, but better :smiley: . Sometimes place is short on the display and you can use metering to show values, instead of using three digits to show them. Often values have no meaning. It is just a number that represents a min.-max. range. You can even use the meter for showing positive and negative values, So you can use metering for these kind of things, which is like i said, really nice to have. Very handy, if you play a note and instantly see, how it affects the sound/patch. The splitting is not the problem, but getting those values together again, is always something i struggle with. For example i have fully working Feedback, whenever i use the A-Station, but sending out the proper values from the C4 to the A-Station again, is a problem for me. The switches are one example of this. I should have done those switches better :smiley: .

Today i will attach some spreadsheets about the C4, so everybody can check, which button sends what etc. Also a ASCII character sheet that represents one display and the offset that is used for showing values at ‘the right channel’ :smiley: and i will do some cleaning of the project, before going to the next page.

At the end i am really excited about MTP, it is so fast and the panel is very responsive. I had two software panels before, but they struggle, have micro stuttering and such. And your blink project is a good example for how fast and responsive MTP delivers. Really cool.

For all the parameters, i will use the levels for sure :smiley: :blush:



In vertical mode, you can use 10 letters at least (top and bottom line of the display), for a parameter name in a Vpot cell. easy :smiley: and for these cases, the levels are pretty accurate and work well. And yeah, the A-Station has a internal midiclock: LFO Sync Internal – MIDI Clock. Pretty much can be synced: LFOs, Arpeggiator, Chorus Phase, Panning, Delay, EQ Filter :smiley: . Ha, and it can be triggered/set. Perfect.



Looks like you are having way too much fun :grinning:

Steve Caldwell
Bome Customer Care


Also available for paid consulting services: bome@sniz.biz
1 Like

Haha … yes, but sadly not enough time :wink: . Ok, so after two weeks, i was able to spend some time again :blush: I updated the picture and project. First page now nearly finished, added buttons to browse banks and presets, added C4 sheets and added the A-Station manual for reference purposes. More documentation will follow :wink: . Everything to be found in first post.

I found out, that the ARP Rate parameter is the one that is used for ALL syncing, if internal sync is selected. It is CC# 9 and the range is from 64BPM to 191BPM (1-127). Explained on page 36 in manual). So your LFO blink example, should be tied to this, to be in sync i guess.

Meanwhile finishing the first page of 32 Vpots, i encountered a problem with this small, innocent looking encoder ‘pulse width’. Let me explain with following picture:

What this encoder does, depends on the three switches the red lines points to. This alone is not enough, because there is a third option for the pwm source: the Mod Env option. On hardware, you can reach that only with using a shift switch, but this switch does not send any midi data. In my case, the C4 does not know, that i selected a Mod Env source for example. It can only detect the change, the moment i turn the pulse width encoder. That would send a midi message, that only this mode can send, indicating the pwm source is a Mod Env. Odd and crazy :clown_face:.

In a nutshell, this encoder can deliver nine different parameters (three for each OSC) at least. I managed to do that with MTP and a single Vpot on the C4 and make proper changes to the decription of the Vpot and the values it shows. This was a lot of work to realize and to get it working, but here really, really, really shines the power of the combo MTP and C4. After going through this hell (did i mention the difference for pulse and any other waveform :smiley: ) i would like to push it just a little further, by storing each value into globals in that way, that a user can ‘return’ to his changes he previously made (to these parameters). Something neither hard or software is offering. This way you can find your optimum values for each of your settings you do for this encoder and can always return to them. This would expand the functionality of this encoder to 36 different values, because you have four waveforms (4x3x3). Once i did this (finished the first OSC already), i would like to add a whole new feature to hard and software. Mainly i want to add Cycling. Cycling through OSCs and cycling these PWM Width settings and both cycle types tied to the mentioned ARP Rate. Outcome would be a performance similar to a Vermona PerFOURmer or Korg Monopoly, which is giving them this typical unique character.

This way the panel will offering new features. I never understand people creating remote panels, but never add new things after going through this (painful) process. They simply ‘lose’ the creativity in this process. Know i know why :innocent:

Anyways, first comes first and that is the LFO Blinking and ARP rate. Can you help me again, to get this working. Once it is done, i hopefully can adapt this to reach my ‘ambitions’ :smiley: .

Hi,

Looks like you have made good progress. I’m not sure what you would want me to help with as I already showed the methodology in my earlier post.

Steve Caldwell
Bome Customer Care


Also available for paid consulting services: bome@sniz.biz

Hello Steve : ) ,

Thats a honor for me, but i think i need more progress :wink: .

I will try my best to solve it on my own. I better make some more progress and at the end, look what is left.

I need rules, that can do all LED rings of a Vpot row in one go. Currently doing the paging navigation. Restoring values from globals to print them, using just one translator for a Vpot row was somehow easy.

But i dont see, how to do it for the rings, since only one midi message can be send out and the action is triggered by page-buttons. Restoring and scaling is not the problem. Sending only one message out is :confused:

There are a several ways to send out more than 1 MIDI message with a single trigger.

  1. Multiple translators with the same incoming trigger and different outgoing action. The incoming trigger can be a preset change (on activation)
  2. Use a repeating timer with a counter to iterate through the messages you want to send. The timer looks at the counter and then determines from the count, what message to send.
  3. Use Perform within rules. You can have multiple perform rules that can call the same perform trigger to output a different message. You can specify up to 10 perform parameters.
  4. Use raw MIDI as the outgoing action and put multiple raw MIDI messages for instance: b0 00 g0 b0 01 g2 …

Steve Caldwell
Bome Customer Care


Also available for paid consulting services: bome@sniz.biz
1 Like

That is possible? OMG i am so dumb :smiling_face: :blush:

That will do it for me and is the best solution, thank you so much Steve. Your first solution point, is my current solution, but i want to get rid of it.

Somehow i like to work the most with the Raw messages. Not that the other approaches are wrong, but it is the clearest thing to me. Tommorow i will cherish you and Florian on YouTube :innocent: :sunglasses:

Ok… more progress was made :blush: Updated the documentation in first post: added Intro
added Vpot definitions (hopefully they are right)
added a CC value table for the different ring modes and animations showing them.

On the MTP project side, i have added the Split button and one use-case for it so far, but more will follow. Added Page-Button navigation, but i am not even close to finish the second page. Mainly because there are so many dependencies with some parameters, that it is not easy to restore the values, while coming from page 2 to page 1. This is a little bit sad, because i reduced and optimized the project so well and now need to divide some translators again, that i merged before (multiple single translators merged into one translator, needs to be split again :disappointed_relieved: ). Yah, time is precious :blush: , but a new version will follow in a few days.

Hope you will like it.