Writing a bees op. (an attempt, help needed)

these past weeks i made progress with an operator project. (while reading please bear in mind that i’m a beginner).

the idea came from this @glia’s post (thanks !) : Emergence and Generative Art - #12 by glia
(there are drawings of 39 strange attractors.)
while i was looking for definitions, code examples, how to resolve derivative functions, etc. i’ve found this site : rendering strange attractors : 3D drawings you can play with, randomize values, zoom in and out. very nice.

what i like with these functions is the possibility to get a set of 3 values from a single input.

my goal is to write an operator that allow to

  1. choose a strange attractor out of a list of 39,
  2. choose operator behavior : output contiguous set of values at trigger or output a set of values at given index,
  3. choose a “time” delta.
    constants and values at index 0 are fixed (though one can easily change them).

(it could get along nicely with the preset system…)

but i’m stuck now.
to get to the point of an actual op, i need help.

as i’ve been trained to write simple and basic C codes that work with an OS, stdlib and stdio, getting into aleph source code is a very different experience, quite challenging and difficult. i get easily lost in it. i guess i miss something fundamental about the embedded environment that would help me to understand what it is, how things work, or are builtand get along together. if you can point me to useful info, resources, etc. i’d be pleased !

i’ve followed @rick_monster’s advice and got the environment set up (thanks for your help !). from there i thought i would go step by step (baby step i guess) and start with some kind of prototype. i’ve uploaded a folder (see down this post) where you can find the code and a ‘prog’ file : it’s an app you can run from a terminal. it will give you a taste of what i aim at.
with this app you can choose between two strange attractors, then choose a behavior, then choose a delta. after this set up, you’ll be promped to trigger the app, or to give an index, in order to get a set of three values.

i’ve built this app this way because i thought it would fit in the bees files organisation : main.c would be op_strange_attractor.c (or whatever the name will be), str_att.c and .h would be macros (is this the correct word ?) like op_math.c and .h
but is it a way to go ?
i understand this op could be a problem because of its size. how do you know there’s a limit ? where do you find the info ? why is there a limit, or how is it set ?

there is still a lot of work to do (at least to me !).

  • i’ve been reading posts regarding fixed point math, and searched the web. i get the idea i think but i really need to practice with simple examples before i can get something useful out of the strange attractors…
  • i don’t know how to label the type of the variables.
  • i’m looking for a function to trigger the op and another to input a value. could you point me to the way inputs are done from one op to another ?
  • i need to set the range and scale of the input and output values, something relevant and useful for the bees network. how do i do that ? then : what happens to the values outside of the range ? it’s wrapping, right ? (i’ve been reading the teletype posts and code about that, but i don’t understand what’s going on).
  • would you change the name of the var in str_att.c (e.g. l, m, n instead of x, y z) ?
  • is there any coding conventions or style i should be aware of ? could you point me to them ?
  • what would you do after cloning the aleph repo : create a dev branch locally, then create a branch for the op ?

any help and tips regarding these points would be great !

str_att.zip (4.5 KB)

3 Likes

cool!

did you look at this? https://monome.org/docs/aleph/dev/bees/

it will show you all the steps required to add an operator.

also i would look at the teletype CHAOS discussion on this forum, and resultant code. that’s very close to what you’re proposing (but using simpler models than lorenz/rossler.)

i’ve been reading posts regarding fixed point math, and searched the web. i get the idea i think but i really need to practice with simple examples before i can get something useful out of the strange attractors…

this is one of the situations where it’s extremely difficult or impossible to use fixed-point; these structures require accuracy over a big dynamic range (much bigger than audio). you can use floats on avr32 just fine. they are slow, like 10 instructions for a multiply. that is still millions of multiplies per second. just use them as sparingly as possible.

i don’t know how to label the type of the variables.

you mean the state variables? just make them floats (not double.) input and output variables must be io_t which is 16-bit signed.

i’m looking for a function to trigger the op and another to input a value. could you point me to the way inputs are done from one op to another ?

bees operators expose input functions that generally cause output to happen via call to net_activate when the input is set. like here
[https://github.com/monome/aleph/blob/dev/apps/bees/src/ops/op_add.c#L58]

in the case of an iterated map i guess you would have inputs for the parameters that probably don’t trigger output, and a separate “update” input that doesn’t care about its value and just acts as a “bang.”

or maybe you want the trigger input to only activate on values > 0, as in TOG (where the input is poorly named “STATE” - should be BANG or TRIG or something.)
[ https://github.com/monome/aleph/blob/dev/apps/bees/src/ops/op_tog.c#L67 ]

i need to set the range and scale of the input and output values, something relevant and useful for the bees network. how do i do that ?

as in teletype, bees input and output values are signed 16-bit. if you are working with floats you just need to scale them to the range [-32768, 32767], and cast to s16 or io_t.

see the [op_math] header: [ https://github.com/monome/aleph/blob/dev/apps/bees/src/op_math.h ]

then : what happens to the values outside of the range ? it’s wrapping, right ?
would you change the name of the var in str_att.c (e.g. l, m, n instead of x, y z) ?

see the op_math header again. overflow in multiplies will wrap, but there are sadd and ssub for saturating add and subtract.

is there any coding conventions or style i should be aware of ? could you point me to them ?

no, not really. it’s a pretty striaghtfowrad style i think… the main conttoversial thing is that there are a lot of typedef’d structs, that are then passed around:

foo.h:

typedef struct foo { } foo_t;
void do_something_with_foo(foo_t* foo);

this is a style i’ve since been convinced is inferior to passing void* (with or without typedef), and keeping all struct access explicit and confined to a single code module. oh well, too late

what would you do after cloning the aleph repo : create a dev branch locally, then create a branch for the op?

yes

2 Likes

thank you very much !

curious about this. could you explain a bit more or point to where i can find more info on this?

3 Likes

well this was discussed a bit in the C tips thread (where it probably belongs i guess). linus torvalds is a vocal opponent of typedef struct:
https://www.kernel.org/doc/html/latest/process/coding-style.html#typedefs

generally in aleph/bees, structs are typedef’d to things like op_t that are supposed to be opaque, used only by pointer with accessor functions. even linux agrees this is a fine use case. but the struct definition is still right there in the header, so its just too easy to break the opacity.

i kinda think passing void* is better because it makes the opacity explicit, and you can actually keep the struct layout out of the header. prefer typedefs only for primitive or POD types that can be passed by copy.

if you don’t want or need opacity, so the argument goes, it’s better to keep typing the struct keyword to make your intentions clear.

just one idea though. any approach works as long as its reasonably consistent

1 Like