Hacking objects 101: adding modulation inlets


#1

Some users often ask contributors to add modulation inlets to their objects.
While a workaround exists (adding a patch/modsource object and right-clicking on the parameter to modulate), sometimes this solution is not efficient or not available at all (see for example integer boxes).

What to do in one of these cases?
1) you can ask the contributor here on the forum to add inlets (lame!) (just kidding!!!) (not really: we are lazy)
2) you can HACK THE OBJECT in few steps

Click on the little arrow of the object you want to edit

Embed as patch/object, this way you can't do permanent disasters. DON'T EDIT OBJECT DEFINITION, UNLESS YOU'RE VERY SKILLED IN TROUBLESHOOTING C++ CODE

Click on edit

Select the inlet tab on the left and then add as many inlets as you need.

Give a name to such inlets, something you can remember. Do not use spaces or symbols, just letters or numbers.
As for the type: dials (knobs) correspond to frac32 inlets (blue). Buttons and toggles correspond to bool32 inlets. Integer boxes correspond to int32 inlets. All the other stuff is just labels on the object (you can experiment on this).
Also, buffered inlets refer to the audio rate stuff. It's not the case to touch those.

Now the tricky part: you have to search in the k-rate and s-rate code every reference to the parameter you want to hack. You'll find stuff like param_ParameterName.
You have a few options here: you can add the inlet to the parameter (see the middle portion of image) or override it completely (delete param_ParameterName and substitute it with inlet_InletName)
Remember to add ";" at the end of rows (the code won't start otherwise).
If you choose to override completely a parameter you can then go in the parameters tab and delete the parameter.

You're done!

For this example i hacked ctrl/dial.

Something can go wrong while doing this. Aside from syntax errors, there are some cases in which a parameter is bound inside a very specific range. Outside that range weird stuff might happen (pleasantly weird but also patch-crashing weird).
This might happen because of variable overflowing, for reading/writing arrays outside their range or for similar reasons.
Troubleshooting these errors is often hard and requires skill. If you don't have the skill, just be careful with what you feed into these inlets. You could use math/sat and math/satp objects as a quick fix


How to modulate objects that lack inlets?
Modulating table play loop parameters
Comprehensive noob guide to creating "objects"?
Assign GPIO to parameters that are NOT "AVAILABLE"?
How to get inside certain objects?
Mapping Axocontrol knobs/buttons to CC for parameter control
Recall knob position at startup in stand alone mode
Most efficient way to toggle parameters with integer for changing radio buttons?
Using modsources on more than one destination
Possible to assign CC to fields like these?
#2

Thanks for posting this, Sputnki.

I get so far, but I'm confused about how I need to edit the code. I'll give a step-by-step of what I did so that you have exactly what I have. If you were to copy what I did using the exact same object and input name that I used, you could post a screenshot of the edited k-rate code, then I would understand.

  • Add the object fx/lmnts/reverb
  • Add an inlet and name it test
  • Assign the type as frac32

In my example, I wish to use the inlet named test to drive the dial named amount. In this case, there's no code to edit under S-rate, only K-rate, but what do I change to make it work?

It'd be great if you would post a screenshot of the edited K-rate code for my specific example, it'd be easier to understand because it'd be a real example to learn from.


#3

You can see in the image all references to the parameters highlighted.

You could substitute row 6 with the following:

reverb.set_amount(q27_to_float(param_amount + inlet_test));

#4

That makes way more sense now that I see it :smile:
Thanks again!


Correct Application of Sub-patching - all complicated patches?
#5

@axoman did you have any luck with this? I just tried the same - got a compiling error:

Compiling patch... with /Applications/Axoloti.app/Contents/Java/firmware
BDIR = /Users/mitchadmin/Documents/axoloti/build
FIRMWARE = .
RM
APP
! /Users/mitchadmin/Documents/axoloti/build/xpatch.h.gch
/Users/mitchadmin/Documents/axoloti/build/xpatch.cpp:1:24: fatal error: ./rings_fx.h: No such file or directory
#include "./rings_fx.h"
^
compilation terminated.
make: *** [/Users/mitchadmin/Documents/axoloti/build/xpatch.bin] Error 1
shell task failed, exit value: 2
Compiling patch failed ( /Users/mitchadmin/Desktop/AXOLOTI/reverb inlet test.axp )

Any ideas? Would be great to easily add inlets this easily!


#6

Sorry mlbstrd, but I never got to the point where did a specific edit to a specific object, I was just super-pleased that I could do it at all. I know I practiced at the time and saw results, but whether it was done right and bug free is another thing entirely.

The problem might not actually be your coding, it might be something to do with the patching environment so hopefully someone who knows what they're talking about will step in and advise, but I'm sorry I can't help.


#7

this is where things go wrong.

you see, the example @Sputnki gave with embedding objects only works for self contained objects (objects without reference to external files)

the generated error means, that an include file is missing, because you embedded the object and there is currently no way to include a file in an embedded object.

so, in this case this method won't work. that being said, there are only a handful of objects with includes in axoloti world.


#8

@mlbstrd You can make your own versions of those objects, the rings for example:

  1. Embed the object.
  2. Go to "edit object definition" and "copy to library" to save the object as a real object to a folder you like.
  3. Go to the "rings" folder, in the factory library, then simply copy the header file "rings_fx.h" to the folder that you saved your own version of the object in.
  4. Voila, the object will now load and you have created your own local version that you can edit to taste :slight_smile:

(It's because the object need to have a specific path so it MUST be saved(copy to library).... And then next the object expects the headerfile to be in the same folder as the object itself. So you need to copy it over manually, as described above).


#9

Hi!

After using workarounds for a while, I'm trying to mashup some oscillator objects that I like to create my dream oscillator. I've had a little bit of success, but now I'm stuck.

For vector synthesis, I need:

  1. an oscillator with a fast, stable sync input so that i can use it in conjunction with video VSYNC pulses. @toneburst sinesync is the only thing i've found that syncs stably.

  2. multiple waveforms (@DrJustice multiwave LFO, @beat multiwave)

  3. Quadrature outputs for to use for rotating a video raster.

  4. An LFO version, and a VCO version (k-rate, s-rate)

SO, an amalgam of a few of these oscillators would do it, but none of them are up to the task on their own.

Here's what I was able to accomplish -- I successfully added a quadrature outputs to sine-sync. (

Now I just need to add the other waveforms and I'm a little overwhelmed. I also tried converting the dual multiwave LFO to s-rate, but I can't get it to work. I changed the inlet/outlet types and parameter types to match what i've seen other s-rate oscillators use. I also cut and paste the code from k-rate to s-rate. Didn't work, lol. Am I even close?


#10

I didn't want to start an extra 101-thread, so:
Is it as "easy" (as easy as modulation-inputs) to make stereo out of mono-modules?
e.g. "stereorize" a filter/sampler/delay?
Or is to dublicate the modules the best way?
It would save a lot of sram + time to setting up...
Thanks!


#11

I think the easiest way is to make a subpatch and throw it all in there.

You can write it in code, for example making a for loop X times depending on how many you want.

Or you could just copy the code inside and object and rename the variables for the second version. Like if you have some variables called "int a" and you copy that one, you neeed to rename it, cause you can only have one variable with that specific name.

So basically if you know a little code you can try the above.

Time yes, but S-ram I am not sure, cause you still need 2 of each. I think its going to be very little you save if its just a stereo delay.

For the S-ram, try using the delay that uses SD-ram. There are a lot more SD-ram than S-ram, so you can save the S-ram for other purposes.


#12

How would be the subpatch way go? I mean I'd have to still have the module 2x in the subpatch + make all the parameters/dials available on parent, to assign them to midi quickly.... or is that actually the main SRAM saving tip, to have simply INS & OUTS on parent & rest hidden in the subpatch, but still mapped to midi or analog-pots? Hm...
Probably I confuse what RAM is needed for what. All the dials on an object is it in SRAM, right?


#13

I dont think you should worry too much about a couple of dials, there are other things that will take up alot more memory than dial, like for example if you use a delay that uses S-ram, instead of the SD-ram version.

I am no expert on the details about how much resources they use, I think someone else who know code a lot better than me can answer that for you... Ut a couple of dials...... Dont worry about that :slight_smile:

Anyway, I think you should just start patching and if you eventually get to the point where you hit the limit there are always ways to optimize a little bit here and there. But overall I think you should just build what you like and the realise if you actually have issues or not. Use some of the tips above, like use SD-rams for the delay anf you will go far.

About the stereo thing, the essence of stereo is, that its two channels, so if you want stereo.... :slight_smile:

I know the community library is huge, but its definately worth the while spending some hours looking through it to see whats there. Its a really good way of finding inspiration for your own pacthes. Not only check the community library objects but also the the patches that you find in >

file > library
file > community


#14

Hi,

I am trying to add extra inlets to an Euclydiean Rhythm object. It seems to be ok, but when I am trying to change values with dials it does anything.

Here is the code:

o = 0;
if(inlet_trig > 0 && !ntrig){
ntrig = 1;
o = ((((counter++ + param_rotation + inlet_rot) * param_hits + inlet_hits) % param_length + inlet_leng) < param_hits + inlet_hits);
}
if(!(inlet_trig > 0)) ntrig = 0;
outlet_trig = o;

Any idea?

Thanks,


#15

The blue inlet you are using and the parameters you feed to the blue inlets are not the same type of variables as the destination that you are trying to change.

The parameters fed to the blue inlet are fractionals. The destination are integers. So you need to rescale the fractional blue inlets to integers. Try something like this:

o = ((((counter++ + param_rotation + (inlet_rot<<21)) * param_hits + (inlet_hits<<21)) % param_length + (inlet_leng<<21)) < param_hits + (inlet_hits<<21));

Basically putting a parantese around the inlet_leng, so ONLY the inlet is affectced and then bit shift 21:
(inlet_leng<<21)

If that doest work, then try to switch the <> for all of the changes I have made. I don't have my Axo board fired up ath the moment and I always get those two switched around, so if one doesn't work, try the other.

To understand Axoloti and working with variables a bit better:
Red color = Audio
Blue color = K-rate/fractionals
Green color = Integers


#16

Thank you very much for your answer jaffasplaffa.

I have tried it but the first option doesn't make any difference. It doesnt respond to the Dials, even changing to int32 in Type inlet options and getting them green.

The <> option cannot be executed it said "shell task failed, exit value: 2".

Any other idea.


#17

Just changing the inlet doesnt do it, you also need to do the rescaling.

It was either >>21 or <<21 ...

Could you post the patch?

It makes it a lot easier to troubleshoot.


#18

Here it is

eucly_2.axp (3.1 KB)


#19

The euclydSeq_2 object is not there.

You need to embed it first.
1. Push the small triangle in top left corner of object.
2. Select Embed as patch/object.

And then save the patch and post again.


#20

Sorry... Please, try now

eucly_2.axp (4.8 KB)