Parameter/inlet change functions


#1

Continuing the discussion from Improvements/Wishes for the patcher:


Improvements/Wishes for the patcher
#2

EDIT: moved to new thread

Its an interesting idea,
probably worthy of a separate thread.... the reason I say this is... it would be interesting to discuss how this is used in practice.

the thing is, axoloti is not 'event driven', unlike JS etc , so I wonder how it applies. (not saying it doesn't, just wondering how) e.g. its possible for 2 parameters and the incoming signal all to change in the same execution cycle... they are not applied in series as in JS etc. also all parameters etc are evaluated every cycle.

(perhaps some use-case examples you have in mind could help)

I do agree, we do have some 'boiler plate' code going on at times.. e.g. copying inlets into member variables, and things like 'gates' and triggers and how they interact. but Im a little unclear on how this would work with the above, or generally how we can improve this.

that said, we know that the rising/falling triggers could be more than booleans, ie. I think they should only be true when they cross, this would remove some of the boiler plate code.
(though code migration, because a big concern to change this behaviour)

anyway, as I said, perhaps something we need to understand better?


#3

OK if I chip in here?

a|x


#4

Worth a separate thread, moved to the developer corner, sure.

Sure!


#5

Cool.

The way I'd envisage it working is that you'd bind a (named) function to a particular event on a particular param or inlet.

When that event occurred, the function would be triggered for that cycle only (though of course the function could set a flag variable that would cause other things to happen on subsequent cycles).

Multiple bound functions could be triggered on the same cycle.

It just eliminates the need for potentially unwieldy (with several params/inlets) boilerplate code.

While I understand that JS event-driven model isn't necessarily directly applicable to Axoloti, on a code level, the event-binding paradigm is well understood by anyone who's worked in Web-Design (and that constituency is way larger than the number of people with C experience), and provides an easy way of making sure things happen when you want them to.

a|x


#6

First let me clarify: there is a distinction between parameters and inlets. Inlets are assumed to be able to change at control rate. While parameters are assumed to change only occasionally.

So parameter changes can be processed outside the dsp loop at a lower priority.

Some parameter types have bound functions, but so far they can only transform the parameter value, not access any other object variables. And so far they're defined as distinct parameter types, objects cannot provide their own. This is a limitation I'd like to lift somehow, but it's not really easy. Current parameter functions are sharing code across objects, that avoids duplicate code which would waste binary code space.
The goal of avoiding code duplication conflicts with the desire to access object variables, and providing parameter functions in an object definition.

Inlets have a different constraint, since changes at control rate are to be expected. So far there are no inlet change functions.
Inlet functions benefit from code inlining, function call overhead is better avoided here. I don't think there is a performance or code size advantage in separating inlet change function. There is a demand to unify parameters and inlets, so there should be a way added to apply the same parameter transform function to inlets, where this function can be inlined.

I think boolean inlet rising edge triggers are a special and common case. What I have in mind here is a adding specific boolean inlet type, that converts "running" booleans to one that is only true on an incoming rising edge. This 'd be the same mechanism that emits data type conversion glue code cfr. src/main/java/axoloti/datatypes
That would de-duplicate rising edge detecting code, the object would still need

if (inlet1_rising) {
}

in its dsp function.

Thoughts/comments welcome!


#7

I can see inlets and parameters work in different ways. I'd assumed parameters were updated at k-rate, but you seem to imply that's not the case. It doesn't actually matter, as long as some kind of flag is passed to the next cycle of the object that can be used to trigger a function when the parameter value changes, and utilised something like this, in the object code:

param_myparam.change = functionname();

(again, syntax could be different, but you get the idea).

The idea of arbitrary pre-transform algorithms for parameter values is a good one, I think. On the other hand maybe just a larger set of pre-defined pre-transform functions would save time. Again, I'm falling back on my knowledge of webdesign coding conventions/standards here, but a range of preset interpolation functions a little like those provided for CSS3 transition/animation would be super-handy, I think. These could be applied to parameters in the XML definition.

a|x


#8

Id also like more (and flexible) transformation functions (scaling, curves, offset) as its a pretty common thing to want to do, and is not trivial with the Q number format, and data definitions.

my only concern with adding the event type stuff, is its another layer..
another thing for new users to have to learn/be familiar with, and its a pretty high barrier to enter already.... and its more stuff to be documented , a more complex XML/editor.

(Im assuming we are talking about adding the above to the XML, I would now want to move the code away from standard C/C++... to some kind of axoloti 'C' with JS extensions.)

I actually really liked the simplicity of axoloti when I started, just dsp/midi functions, just directly using the parameters/inlets. I generally don't like things that have a lot of syntax sugar... it means you have to know more, before you can just 'dig' in.
But I do understand, Im from a C background, so not the 'target audience'

also is this the right direction?

its not going to turn Axoloti into javascript, so those users will still need to be familiar with C, and general DSP processing and many other concepts custom object programming requires.

perhaps the DSL topic/idea might get you closer to what you want? ( e.g. a JS interface) and though that talked of generating patches, you could write something that generated objects/C code.

I think other similar environments (e.g. max) take this kind of approach i.e. providing different language support... and gen in max, they provide their own language.

of course, I do recognise adding other language support, is pretty ambitious for a project like Axoloti, and fear a bit too much with current resources.

anyway, just my thoughts... Id love to hear others opinions too...
how many JS coders out there do we have? (its been mentioned a couple of times already)


#9

Absolutely! I'm still struggling to get my head around fixed-point maths.

Here are some interactive graphs of the standard CSS3 easing curves
http://easings.net
Not all of these would be useful in terms of parameter pre-transformation, but quite a few would be, I think. It might also be cool to be able to specify you own cubic bezier curves, using floating-point coordinates for the two handles, like
http://cubic-bezier.com/

In terms of adding complexity, I do see where you're coming from. I think actually, though, it wouldn't have to have that effect. If there were some new XML tags, or even a few additional properties to add to existing tags in the parameter definition section of the object code, that wouldn't be introducing another language, just a handful of new properties.

At the risk of getting irritating you by suggesting implementations, I'm thinking something along these lines

<frac32.s.map name="myparam" description="description" interpolation="exponential"/>

That's not complex (and a hell of a lot less complex, as you point out, than transforming the param value in the object code itself). You could even add a dropdown menu or some other UI device in the Parameters section of the Object Definition editor to choose the interpolation-type. Easy-peasy.

a|x


#10

I do think JS support on some level would be cool, but that's because I have more experience using JS than C. In this case, though, I was just using JS as an example of an event-driven paradigm that I thought could perhaps be applied in a very limited sense, for a particular task. I'm sure it could be done using C syntax, however, so there's no need to shoehorn full JS support into the Editor, just for this.

Where I've used JavaScript in a node-based editor in the past (in Quartz Composer, though I understand Max also has JS support), it's been for complex logic, that would otherwise require a large number of discrete nodes. Beyond a certain level of complexity, or when dealing with arrays of data, it becomes easier to write and annotate code to create the logic or control values than to use a large number of discrete nodes connected together in a complicated tangle of virtual wires.

Having given the matter some thought, I'm now tending towards thinking that he fact that all Axoloti objects are defined in easily-edited XML makes the need for support for other languages less of a necessity.

We may be moving a bit OT, here though.

a|x


#11

I guess there are two ways of looking at this. From my point of view, I'd rather 'dig in' to coding the 'exciting' bit of the object code - the bit that actually creates k or s-rate signals that make cool things happen further downstream.

Having to write reams of code just to transform parameter values so controls work in an intuitive manner, or even more boringly, just handle gate on/off inputs takes time away from the interesting stuff, and means I end up writing the same logic structures over again and again.

Personal viewpoint, of course, but I imagine others probably feel the same.

a|x