“Cheap” Hook for 15 potentiometers


#1

Hi all,

I have a pretty full patch that I’d like to control using 15 potentiometers, with a switch to go between an “A” state and a “B” state - therefore giving 30 controllable parameters. Using the Hook object is a great way of doing this for a few, but for 15 it starts to get pretty big and sucks a lot of SRAM. Is there an easier/cheaper way of “Hooking” 15 different pot inputs?

While I’m at it, is there a way to implement a “soft” hook? Similar to the relative pickup mode in Ableton?


What should a standard metal enclosure look like?
#2

the first thing to do would be to remove the UI control, this is not needed when used in conjunction with pots, then you use a 'hook inlet' , to tell it the hook state has changed - you could also use a int8_t for the state variables, which will save a bunch more.

from there, gets more complex, you could create an object which has many hooks in one object, assuming a/b are global to them all. by doing this there are various optimisations you can make - e.g. combining the states into 2 bit variables, one hook/unhook inlet.

anything is possible, can you describe this better, ive not played with this in Live.
are you talking about what the manual calls "Value Scaling" mode?

(i thought relative, was the mode used by encoders, were it sends changes rather than absolute values)


Ambient patches
#3

Ahhh right, so removing the UI stuff is best. What's the best way to do this without errors? If I just remove the Parameter from it's respective page, I get an error code. I've had this problem before when trying to replace a param with an inlet, or simply adding an inlet. I read the "Hacking an object 101" thread but it seems to only work that simply in some cases. This is the error I received after removing the knob in the hook object:

Start compiling patch
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: In member function 'void rootc::instancehook__1::dsp(int32_t, bool, int32_t&, bool&)':
/Users/mitchadmin/Documents/axoloti/build/xpatch.cpp:123:15: error: 'param_value' was not declared in this scope
outlet_out = param_value;
^
/Users/mitchadmin/Documents/axoloti/build/xpatch.cpp:142:21: error: 'param_value' was not declared in this scope
if (param_cache != param_value)
^
/Users/mitchadmin/Documents/axoloti/build/xpatch.cpp:145:37: error: 'PARAM_INDEX_hook__1_value' was not declared in this scope
PExParameterChange(&parent->PExch[PARAM_INDEX_hook__1_value],inlet_in,0xFFFD);
^
make: *** [/Users/mitchadmin/Documents/axoloti/build/xpatch.bin] Error 1
shell task failed, exit value: 2
Compiling patch failed ( untitled )

Yep - this is actually what I referring too, I got confused with something else. Any way of implementing this?


#4

yeah, you'll need to do more than just remove the parameter , you'll need to adjust the code too. essentially all you need to do is replace the param_value with a local uint32t, which is just storing the hooked value. the PExParameterChange then just becomes a simple assignment.
(basically the parameter display is being used to also hold the hooked value)

value scaling, id need to have a look at exactly how it works as i don't use it.
but i think the general idea is rather than absolute locking, when its unhooked, you basically start moving the hooked value close to the incoming value.
(I'm not sure if this is just as you move the knob, or if there is also a time smoothing used too... i.e. does the hooked value, slowly move to the new value if your not turning it still - this is what id need to play with in Live to see how it feels/works)

its not really any more difficult to implement, if anything its possibly simpler since you don't need to maintain a complex hook state, you simply need to need to make the internal value move slowly to the real value.


#5

Hey @thetechnobear - I'm just returning back to this after a good few months away.

I still can't wrap my head around what I need to do, and where, to remove the UI stuff from the Hook object. It's just beyond me.

Any chance you could make one for me? It'd be nice to be able to compare a modded one to the original, so I can visualise the coding differences. Might make hacking other objects a little bit easier.

All good if you're too busy though!


#6

Try the patch below. I found that the cheapest way is to map the pots to midi cc, even if that means less resolution. But you can also get the unrounded values from the outlets.

15 control.axp (10.5 KB)


#7

Hey @Captain_Burek, I'm probably showing my supreme coding/DSP ignorance here - but I have literally no idea how to rig up that patch you've provided! I'm a novice when it comes to tables in particular, aside from knowing that they store/read data - I can't see how the patch would function as a 15-way "hook" though? Where would I hook up the GPIO inputs, for example? Or the switch to go between two lots of stored data?

Apologies for the rudimentary questions, this stuff really doesn't sink into my brain for some reason...


#8

Sorry. The GPIO inputs are already in the object. If you hook up pots to the analog inputs on the axo board, the patch that i posted will display them.

To switch, add 15/30/45 etc to the offset inlet of the reader object. Just make sure that the table is at least as big as the total number of values you want to store.

You can get the values of your 15/30/45 parameters on the `value' outlet, but in that case you have to use a giant muxer to distribute the value output to your 15/30/... outlets, according to the 'ccNo'outlet.

The easier way is via Midi cc, which the object sends internally. In the 'map' attribute you just give it a list of 15/30/45... cc numbers between 1 and 128 to which the gpio analog inputs 1-15 (and if you use offsets, 16-30, 31-45 etc) should be sent. You can then use MIDI CC on any controller object, or use a MIDI/in/cc object, as i did in the patch, to get the value of any cc.

Does that help, and will it do what you want to?

Here's a (hopefully) more self-explanatory version of the patch.

15 control.axp (15.8 KB)

ps: corrected a bug in the patch


#9

I found that I don't like the dead movements behavior of the "hook" function much more than values that jump.
So I created my own solution. I had to sacrifice one-to-one tracking behavior though.
It is a sub patch (plus help file), so you can look and learn (and modify). I called it "softhook".
It may be what you were looking for.

softhook.axh (3.4 KB)
softhook.axs (5.0 KB)


#10

And a bipolar version.

softhook.axh (5.7 KB)
softhookbip.axs (5.6 KB)


#11

Someone just asked me to explain how "softhook" works. So:

It is not possible to understand "softhook" without being aware of the Axoloti execution order, which I am exploiting at two places, see below. Used the right way, it allows to access a value of the previous control-rate cycle.
1. The "to f" object to_1 is executed before the "inlet f". Thus, at its output we have the previous-cycle inlet value. I am using this to detect the input value changes. The value-change signal will be much too short to be seen on a disp/dial object, though: It's 1 cycle = 1/3 ms long, after which it will be zero again.
2. The feedback loop of "mux" mux_1 creates a value storage (or memory). Without input change, its value cycles in the loop all the time. At input changes, positive or negative, the cycled value is being increased or decreased, respectively. The amount of increase or decrease ist determined by suitably scaling the input change (that's the "soft" in softhook).
(The second "to f" object does not have any effect, btw, just makes it look a bit more clear.)