Duplex with M-Audio Axiom MKII


i’m trying to do a duplex configuration file for the Axiom 49MKII. All is working fine but for the moment i could not achieve more than what i could do with programming directly on the controller in add with the midi learn function from Renoise.

What encourage me to start a duplex configuration is the ability to send message to the Axiom (turn on/off lights or display parameter name for exemple) but from what i’ve seen and tested, i’m not sure the Axiom could receive those message.
When i send something, the display write SYS and that’s all… sometimes, the parameters mutes appear so i imagine it could be possible but it seem’s buggy…

As i know M-Audio use a shitty application (DirectLink/HyperControl) that is usable with 4 mainstream DAW at best (what a shame), i start to fear that the Axiom is very limited for those who don’t work on those mainstream DAW…

So before i go more in deep of duplex, i’d like to be sure i could do what i want.
If someone had an experience with this controller, it could be very useful.

Thanks to all & to Danoise for Duplex who seem’s very powerful.

Hi (yes i’m about to answer to my post)

So finally, i started to write a driver for the Axiom MK2 to work with directlink on Renoise. I use lua with some C function, all that in duplex who provide a fantastic base for all the common function.

I managed to find some specification of directlink implementation but if someone got something about this, please help ^^
As i don’t know lua scripting, it will take some time but i’m an old C++ coder so the logic is the same… (even if i lost a lot of my coding skills during the last 10 years ^^)

Thanks for any help on directlink…

Nothing to do with the topic but Renoise 3 is really a great addition comparing to 2.8 ! I’m perfectly fine with the new interface & after some months, i couldn’t use 2.8 anymore… As i’ve seen a lot of complaint with the begining of R3, i feel the need to tell the Renoise Team, one more time, you have done a great job and good choice, R3 is far better than 2.8 in every aspect for me :yeah:

That’s more than I managed to find…so, you’re planning to build some C++ application that will communicate directly with the Axiom via USB?
Afraid I can’t be of much with this, at least not until you reach the lua part. But I’d be happy to help with that.

I try to write all directly with lua in duplex as from what i’ve understand from DirectLink, a simple sysex message activate the directlink mode on the axiom and then the communication work as standard midi.

I have a C++ file from someone who has managed to do a driver for Reaper so i’ll try to convert it and adapt for Renoise.
I could be able to do all that in duplex but i may be wrong as lua is a totally unknow language for me…

For the moment i could switch in directlink mode… Just doing the xml file with directlink CC assignation. in fact even the INST button or SHIFT who are totally unusable in normal mode have a standard midi CC number. I’m now trying to display something on the screen…

I’d be happy if you could help as now i need to read 20 pages of lua referecene manual to do the most little thing ^^

Cool. Makes things a lot more straight-forward…

Lua is not a hard language to learn. I would suggest that you check out the Midi examples that are part of the code snippets. It demonstrates how to receive midi and system in just a few lines of code

Making it work in Duplex is arguably the final step, once everything else is working…and I’d be happy to help out with that.

Ok so i just manage to light on the buttons :w00t:/>/>/>/>/>
All in Duplex and i think it would be sufficient.

I need to call some config file for INSTR mode (xml or ini, need to test that)…

By now i have 7 more buttons to assign to whatever i want. I need to find how to config hold + button for different behaviour and for now i couldn’t write parameter name on screen but i’m sure that’s cause i’m lost in lua ^^

Need to know how to close directlink mode too…

One thing i don’t really understand is that the rotary encoders need 0x7F command to decrease and 0x01 to increase a value by 1 so they work as a swith for now ??? Every time i increase the value, the controller send 0 and 127 when i decrease. Will have a look at this today…

So write parameters name + normal rotary encoder behaviour are my mission for today ^^

I could send you the sysex message to activate + the xml if you want ot have a look… (i haven’t write all possible command in the xml for now)

EDiT :

Here the news ^^

  • DirectLink mode doesn’t allow to change controller CC, so the config must be done with the default assignation made by m-audio.

  • You can’t configure the controller on the Axiom anymore so there’s need to write code to have exactly the same possibility you have without DirectLink (like curve response for exemple).

  • Even if the INST button behave like others buttons (assignable to whatever you want), in DirectLink it call .ini files for every VST/VSTi you had open. When you open a plugin, a .ini file is created with the name of the plugin and the parameters. The syntax is simple, could be edited really fast but it’ll be better with a dedicated interface (is duplex could do midi learn and store all in extern file ?)… It light up for a value >=1. I plan to push INST to open INST MODE & SHIFT + INST to open FX MODE but i need more test to understand exactly what i can do or not.
    Call a file with a button may be possible with all buttons but INST light up, that’s more cool ^^ Don’t know if i could use xml files witch could be very practical with duplex…

  • Button Shift could be hold to access more function (haven’t tested yet) and from what i see, it could be done with whatever button you want to so the possibility are endless ^^

  • The Display is separate in three part, you could write on part one and two (parameters name + controller name), 3rd part is for parameter value witch is receive as it should. Even if i know the sysex sequence to send message, nothing goes on the screen, need to investigate on this. It seem’s like i need a function to define the time to display the name when you select something (track / FX / instr), maybe that’s the problem… Trying to display Renoise at start do nothing even though i see the correct sysex message send to the device.

  • For the value displayed, when i move a slider on Renoise, it send value but in 0/127 range, not a big problem for the moment but i know i should manage to display the real value (dB for Volume etc…)

  • Encoders are in relative mode (even though they are in absolute mode without DirecLink). Don’t know if this is supported in Duplex, i’ve seen on a threat from 2012 it wasn’t, hope i could deal with that. If someone here as already deal with this, a confirmation that duplex could interpret those encoders would be really nice ^^

  • Some button (like F19) could manage 4 differents states for others buttons (F10-F18), don’t know how to do that for the moment…

  • Need the sysex message to return in normal mode, all i can do for the moment is turn OFF the controller and then turn ON in order to return in normal mode. A button to switch Axiom mode could be very useful and add a lot more possibility (the goal is to have just ONE patch for all in Renoise + INSTR + FX).

  • The little button on top of faders, encoders and pads, couldn’t be assigned but when you push on (ligh off), the controllers (all faders, encoders or pads) are free from DirectLink assignation and could be use as in normal mode (with different assignation). Not sure how to store that but there’s a way, just need to test… What i see from that is that a simple button could change bank of fader and encoders, think it could be very useful for large VSTi. What i’m planing is to use 4 banks for the VSTi (1-fader-OSC/MOD, 2-encoder-FiLTER, 3-fader-Instr_FX, 4-encoder-Easy,Master,Macros_Instr_Params but this is just a plan as i think INSTR MODE could do that with the ini file…

Will continue to update here bit by bit as the work progress in order to have all the actual problem in one treat…

Many controllers work like this - unless you have some very specific reason to change the CC numbers, I don’t think this is a disadvantage?
Really, it makes it easier to create a description of the device (controlmap) that would work for everyone.

Ah, and I guess this applies to the keyboard, keys and drumpads? We could of course come up with some flexible solution :slight_smile:

So, the INST button is somehow a magical shortcut to opening the plugin window? I can’t really see how does this work outside the supported DAWs - I guess the directlink software is acting as an mediator somehow then. What will happen when you turn off the DL software, does the controller still respond? Automap, for instance, needs to be active and running even if it doesn’t actually do much

I’m skeptical as to if it would be possible to hook into this DL software, with the full .ini configurations and everything. Pretty sure it’s part of the proprietary code that m-audio has shipped to only a handful of DAWs…
But having said that, it is entirely possible to open the plugin UI from the controller via lua scripting, without all this directlink/ini file stuff. From the controller’s point of view, you are just pressing a button. The button then communicates with Duplex, which will then launch the plugin.

Maybe it will. Either pressing the shift button itself will send a message, or the buttons on the controller obtain new CC numbers while you hold the button. In both cases, this can be used creatively.
But, it might also simply be that the SHIFT button will only be local on the keyboard, with no way of detecting it in our end. In which case, it isn’t so useful…

Hm, yes you got yourself a good reverse-engineering challenge there :lol:/>

From what you wrote, it sounds like a ‘relative two’s comp’ style message. Perhaps it will send more than 0 when increasing, and less than 127 when decreasing fast? In any case, this mode is supported by Duplex, you just add mode=“rel_7_twos_comp” to the relevant parameter in the controlmap. That mode is supported natively in Renoise as well - see http://tutorials.renoise.com/wiki/MIDI_Mapping

If you can reach a point in which every control will output a unique message, we can make it as dynamic as needed in the Renoise end. It’s all software then.
I’ll be happy to show you how to switch between multiple sets of buttons, using a new feature in Duplex called ‘states’.

Edit: forgot to add, in case you need to transmit a sysex message on device initialization, this is simple. For example, the APC20 is using this feature - take a look here?

Yeah that’s right it’s more easy for make a global config everyone could use and as directlink don’t allow to change patch, it’s not really a problem…

Keys are not using directlink, they all use midi in standard port so they are editable with the patch. For the pads, you could free them from directlink so you could save them too… (for toggling different duplex config for exemple) but everything in directlink are not editable on axiom so if you want to use pads for drum etc in directlink mode, you need to write code for the curve response or channel assign as it seem’s directlink use the CH16 for function button & transport and CH1 (global channel) for the controllers.

About the INST button it’s a button like the others but in directlink implementation it calls a ini or xml (depend on the DAW) but i think i’ll use it to switch configuration on duplex, seem’s more simple… The perfect solution will be to store some map somewhere (xml in duplex ?) and call them everytime i select a new instrument plus the possiblity to open VSTi GUI when i’m on VSTi instrument… This will be the last thing to do as it seem’s to be the most complicated…

Every directlink from m-audio work with a DLL with some functions used for every DAW with directlink (by chance i have the list) but i don’t know for the moment if i need a DLL or if duplex could do the same… If i need to program a DLL, i’m ok with that but i’ll need some help for the communication with Renoise…

If press the button could open the current VSTi GUI + switch duplex config, it could be enough… (at least for the VSTi that can store a defaut midi map, most of the recent one do that)

SHIFT button bahave like the others, send a midi value and could be assigned to what you want. When you hold it it change nothing so a simple code type IF (buttonA_pressed) then if (buttonB.value >=1) -> exe / elseif (buttonC.value >= 1) -> exe, etc… could be sufficient but i may be wrong. If i look at the C++ source of the DLL for Reaper, i’m pretty sure that’s simple as that ^^

Yep, that’s the most exciting part ^^
I can’t understand for now why nothing goes on screen :huh:/>/>/>/>

So that’s fine, encoders behave like i want, it seem’s even more precise than with absolute value, thanks a lot Danoise B)/>/>/>/>

Great to know it’s possible. It’s not the most important thing for the moment but the time will come… Maybe this new feature could be use for encoders/faders bank too…

Yeah that’s the first thing i’ve watched, others “driver” configuration, i’ve set autostart config so the Axiom switch to DirectLink when Renoise is opening.
I have some problems to made custom button to test sysex like when i press this then send this… etc…
But that’s cause i’m too used to C++ and Lua is very different with function… always confused.

Yesterday i manage to find some more sysex message to activate part E (encoders) and F (faders) or free them from directlink assignation, so i could use this to switch bank of faders and encoders.
These button could not be assigned to midi CC but it could be very useful to switch duplex configuration when i press them (will switch config on the axiom too).

Thanks for your advice Danoise, will continue to investigate (and read lua manual) ^^

So i’ve made some little progress ^^

First, i’m able to switch DirectLink/Normal mode with button.
The problem is that i must copy the MidiDevice callback function in my lua class file in order to manipulate midi data otherwise i always get an error (if i try to call the function and compare message[1] etc…)

Second, after hours and hours of test, i’m able to display the first letter. Don’t know why i couldn’t display more but i’m sure more function are involved…
I hope i could do all that in duplex :blink:

I’ve tested the same message with MidiOX when Reason is lauched in DirectLink mode and all the letters display normally (great to see “Renoise” on screen)…

Third, i made a shift function (basic, return “true” when pressed) but i can’t call it in configuration file in order to determine witch assignation has the buttons who are pressed when shift = true. They need to have two possible assignation but from what i understand from configuration files, i’m not sure it’s possible do determine assignation with a function ???

Anyway, i’ll continue, LUA seem’s really illogic to me on some point but i need to get it ;)

One of the least expected pitfalls i felt for was the fact that local variables are even local inside conditions and iterations.

Yeah i had some problems with iterations too.
Day after day, it make more and more sense. Hopefully the Terminal help a lot ^^

But now i faced a problem that seem’s to be related to Renoise or maybe Duplex (not sure, maybe it’s my code) ?
If i lauch Renoise, send the sysex to open directlink mode then send the sysex to write Renoise on screen, only the first character is show, the second one is a weird sign (couldn’t find in ascii table) ?
Now i open MidiOX and send the same message (directlink activate from Renoise too) and the screen display Renoise.

According to MIDI Dump, these messages are the same ?! Anyone had an idea please ? That’s drive me crazy ^^

Maybe a way to find what’s the problem is that everytime i attempt to send sysex with 2 characters on Renoise (so a sysex with more than 10 numbers), even the first one don’t work, the screen stay empty.

Anyway, i find a sysex to display the little encoder at the botton left of the screen but couldn’t find the way to display on the second line… Will try that when the fist line is fixed…
Now i could clean display screen too…

Plus i’ve made a timing function for Temp Message with os.clock(), work like a charm ^^

There’s just the display problem and the INSTR button who call xml or ini and everything is fine, just need to make condition after that <_</>/>/>/>

PS : New ‘State’ class (or function, haven’t look at it) seems very promising when i read the description…

Hm, does sound a bit strange. The xrnx code repository has a perfect little snippet of MIDI + sysex code for testing. Have you been using this code for testing the sysex message? Duplex is essentially doing the same thing, but that snippet is easier to edit and play around with…

Perhaps the characters need to be converted/escaped somehow…have you tried switching file format of the lua code/document itself - from UTF-8 to ANSI, for example?

I use the sysex function from MidiDevice class, will try with a more simple function from the snippet tonigh. I’ll test to just send the message with the more simple structure i could find…

Hmmmm, haven’t tried that but now i’m hurry to finish my work and go home for testing ^^
Thanks a lot for your help Danoise, i’ll update tonight after few more tests…

I could add that after a few more research, there’s nothing we couldn’t do in Renoise that we could do with DirectLink on other DAW. All is basic code and MIDI instruction. Even the DireckLink shared function could be simulate like TempMsg or call a file with Instrument map. All you have to do is to define the map structure in the program so as Duplex could read xml, i think it could be possible to do something.
The only thing i’m not sure i could do is a special interface for assigning the first time you open VST/VSTi but the file could be edited easily manually.

Some little thing to do too, i search a way to toggle Duplex configuration, not selecting one precise config but toggle between 2 config with a button… Think i must add MidiAction entry…
Like i’m on config 1 -> button pressed -> config 3 -> button pressed -> config 1 and i need the button to have the same function even if i’m on config 2 at start : config 2 -> button pressed -> config 3 -> pressed -> config 2 so basically the button always call the same config but return to previous config when pressed one more time.


So finally i could write on the first line, just have to use the standard DirectLink Port Out instead of the WDM port. I could continue to use WDM as input for the moment…

Can’t believe that i hadn’t test this yet.

So now i could concentrate on more programing, that’s great !
Just need to find how to write on second line but i hadn’t any example, it could be hard to find the sysex sequence… but that’s less important, just for internal parameters name…

Ok here a summary of what is done & what remain to do…

I’ve made 3 configurations files, one for mixer, one for track + fx and one for instrument mode. For the moment, i try to keep the original duplex files intact but some function let me think i must change some little things…

-Shift : Done, but i must assign parameters in my class file as i don’t really understand how to make condition in configuration file who seems very limited in possibility (but maybe i haven’t fully understand what we could do here). That’s not really a problem as SHIFT have the same function no matter the selected configuration.

Basically, i use it to change track bank (vs track with shift not pressed) in mixer/track mode. There’s a lot we could do here but now i need to really think about what i need… any suggestions are welcome.

-Write on screen : Done, i’ve had to write a function who receive string (track name for exemple), convert them to hex and sending the result to the send_sysex_message. Now i just have to send a string and the sysex is send with all the data needed to display something. Thanks to the exemple function who give me the key to convert the final table in hex string…
I think i could bypass the original function later but i keep it for the moment in order to have a clean function for testing purpose…

-Time function : Hmmmm… so i need to write a TempMsg function in order to display temp message but i having some trouble with the function using os.clock, i haven’t seen that the program is stopped when using this so i need method for using this in parallel of the rest of the program. Even if it’s only 1500ms i couldn’t use this as it is now, just good for testing…
LUA seem’s to not have a lot in term of time function, is there a way to execute a function in parallel without disturbing the main program ?

-Scrolling function : Not done, haven’t a single good idea for the moment. The screen has only 5 characters so every name with more characters must use a scrolling function. I think of a loop who send different sysex message with some ms between them but that seem’s a little shaky ^^
Plus as the timing stop the program for now, i need to investigate on this…

-Instrument Mode : Not Done. See that later.

So with this we conver all the special function of the directlink mode, just need time now…

So, the SHIFT button does transmit a value when you press it? If this is the case, yes, then “states” could become useful here.

“States” are defined entirely within the controlmap and is not “aware” of device configurations or running applications. All it does is to hide (disable) or show (enable) certain parts of the control-map (individual parameters, groups, columns or rows), and then route incoming messages into those active parts. There are certain restrictions, but I would be happy to help out making this as useful as possible - you just need to explain what you would ideally want to achieve :slight_smile:

Cool, sounds like a good approach. Keep it simple to begin with, it makes it easier to integrate such a feature later on (LCD screens are notorious for working differently for each manufacturer…still, I have a few ideas about how to make this a standardized format in Duplex without being too restrictive)

What is this time function supposed to achieve? If you are planning on invoking methods on a specific time, this will be quite wonky with the lua API, as it is called only periodically…a high degree of timing precision is only possible when the lua code is responding to some renoise-generated event.

But if you need to run code in parallel - for example, because of some methods that is CPU intensive, you can use process slicing. There’s an example tool here, which got implemented in Duplex (and used in Mlrx) as ProcessSlicer.

For this purpose, you can check out the Scheduler class - it’s purpose is to call a function with a certain delay. Easily extended into calling the method periodically (as for timing precision, a little bit of wonkyness won’t be hurt when we’re just scrolling some display).

Btw: this is exactly the kind of thing I see as being part of a dedicated LCD display class. You define the length of a text field (with one or more lines), and simply set a flag to tell if it should start scrolling when the text can’t fit.

Yes, 0x7F when pressed like others buttons… I need to make a scheme of what i exactly want to do. “States” seems to be exactly what i need now, will try to understand how to use it. As long as i haven’t start the Instrument Mode, i couldn’t go far with this as i wouldn’t like to change a lot of things later. I’ll contact you when i start with “States”, thanks for the offer :slight_smile:

I try to keep it the most simple i can and i’m sure i will upgrade it after few more test… Plus the function is made for screen display only (and with string as argument, not number) so it’s not perfect, just a easy way to send text…

Basically, i’d like to have 2 functions for sending text, the one i’ve made yesterday for permanent text and the other one for sending temp text so i need a function or method for displaying something like 1500ms and then return the previous sysex to display what was on screen before the TempMsg function. The os.clock could be perfect if the program could continue while the timing function is looped… Any help woud be really appreciated ^^
Don’t need a perfectly presice function, if i have 1600ms instead of 1500, that’s cool too. I’ve read that Renoise API have implemented something to run parallel program but i need more test…

Thanks, will look that :slight_smile:

Thanks, will look the Scheduler class tonight and comeback here ^^

Of course, a native implemented class for screen display would be great ;)

Great to see the forum back, i was lost ^^

So i’ve made a big step foward, read all the Renoise API document + all the class of Duplex, all make more sens now :slight_smile:

What a hard work you’ve done with this, there’s so much things to do, it’s just fantastic ^^

So i’ve added some functions, like instrument selection. When i select an instrument, the gui open (and the previous one close), the name display on screen and i start to try creating files for mapping and call them when instrument is loaded… after will come the time to define how to read those files. Not sure about the best way to do special mapping per instrument whitch could load with the instrument.

Maybe it’s possible to open a FX chain with the instrument in order to have a vst automation + macros all already mapped… or just a file, don’t know but i’m sure something great could be done here.

Same for track Vol, mute, solo, track selection, all display on screen with a return to previous text for the temp message.

Some things continue to bug me like a timing function, i’ve tried Scheduler class, got no error and arguments are passed to the function but that’s all, nothing happen…

Here’s my code, maybe you could help me on this… (i’ve past the class in my code, will reverse when i’ll really understood how it work)


Last self and unpack(text_msg) are the arguments to pass to the send sysex message function.

Have i missed something ? ^^

The ScheduledTask Class is in my code too…

Now i’m on the idle observer from Renoise API and trying to start something from scratch in order to really understand how this work but this timing function is a real slowdown in my coding workflow ^^

A question about the new State class. Could we imagine changing encoders bank with this if the encoders always send the same CC ?

From what i’ve understand, we could do that if they have different CC (witch is cool too as it’s possible on Axiom when you switch between DirectLink or free mode for encoders or faders) but i’m not sure it’s possible to remap the same CC to something different (same midi channel)…

I’ll do a recap for all functions done and what’s left soon, i need some time to really define what i want to do as i find new possibility everyday. I’ll post the xrnx at the same time…

Big big thanks Danoise and all the Renoise team for all this, and for the documentation about all the API and Duplex, it must be really time consuming.

So i’ve added some functions, like instrument selection. When i select an instrument, the gui open (and the previous one close), the name display on screen and i start to try creating files for mapping and call them when instrument is loaded…

Sounds cool. I still haven’t really understood what it does in other DAWs but sounds like you’re making progress :slight_smile:

Some things continue to bug me like a timing function, i’ve tried Scheduler class, got no error and arguments are passed to the function but that’s all, nothing happen…
Here’s my code, maybe you could help me on this…

Hm, did you forget to post it somewhere? I can’t see any code or lua attachments in your post.

A question about the new State class. Could we imagine changing encoders bank with this if the encoders always send the same CC ?
From what i’ve understand, we could do that if they have different CC (witch is cool too as it’s possible on Axiom when you switch between DirectLink or free mode for encoders or faders) but i’m not sure it’s possible to remap the same CC to something different (same midi channel)…

Yeah, I still haven’t really provided any actual examples of States in action, but I think I can explain it a little better:

Perhaps you can imagine a controller layout in which you have “everything you need”. Maybe you can have different CC numbers for everything? That’s cool because it’s simple. You just map each and every control to something, problem solved.

However, you might want some button to act as a “modifier”, a way to access alternative mappings. This is where you would want to define a state, and point it to some some button that should act as a the “State trigger”. Once we have such a trigger, then any parameter associated with the state will only be accessible (or visible even) while this state is active - so you could theoretically have 5 different buttons that are all responding to CC#5, but only the one that match the current state will fire.

I guess a toggling mechanism like this would be the most common scenario. But you can have multiple active states, independently of each other. A bit like how your keyboard supports both CTRL/SHIFT (“momentary” states) and CAPS-LOCK (a “toggling” state), and combinations thereof.

Hmmm ok thanks for the explanation. It sounds perfect for the shift function who is shaky at the moment…

Basically i use “message” variable from midi_callback function to make condition. Same for large FX with lot of parameters it could be very useful.

Open the door of a lot more complex configuration…

The code i use for the Scheduler was that :


Last self and unpack(text_msg) are the arguments to pass to the send sysex message function. But i’m not sure that’s the way to use it…

send_sysex_message is your function pasted in my class and Scheduler+ScheduledTask are in my class too.

So from what i’ve understand the send_sysex_message will be call in x sec. with the arguments passed as 4th arguments to the add_task function… But i’m sure i missed something ^^

I’ve had a look at the UIButton Class who use it when i init the axiom class and see you’ve created a variable equal to Scheduler function in Display Class to use in UIButton class but i’m not sure to really understand what’s the interest to do that ?

I’ll have to look more carefully, i have soooo things to do for a good driver that i start something, then continue something else, etc, etc…

For the rest, little by little, when a function is done, i remove a lot of things and keep the minimum. The only function from Duplex i will keep in my code is the midi_callback cause i’ve changed little things but i’m sure a more skilled coder could find a way to use it as the others in order to make the code more easy to read and more light.

Maybe the sysex callback too but i haven’t done the function who need to receive sysex yet… (mode change for faders or encoders only)

For the Instr function, it’s all coding -> decoding a file and return that in result readable for duplex configuration file… more easy to say than to do and usable only with vsti were you could save a custom default midi mapping. But that’s enough !

DirectLink seem’s not so cool than M-Audio want to claim, i’ve seen a lot of users complaining about the lack of possibility, all is hardcoded and if something is not as the user would want to then he could do nothing. The Instr function is ok on internal instrument from DAW and seem a lot more buggy and unusable when using with vsti.

So finally i think the best way to use directlink is to code his own program. What a shame for M-Audio ^^

And without directlink there’s no bidirectionnal, no lights, no parameters name, 7 useless boutons… so the choice are limited.

I’ll do some more change and give you the files :slight_smile:

(yeah i don’t want to give you a file full of tests, beginners errors etc ^^)

The goal is to do a driver everyone on Renoise could use i think… and maybe i made a mistake to not use the configurations files (or only for the easy thing like mixer vol etc) as it give the driver less flexibility…