hmm - well with the way it’s been done, potentially you could hold down several buttons & release in a different order, then each press & release could register correctly with your patch. I’ve been playing a lot of bass recently - when you release a note can be equally important as when you hit it!
My mental model of this is that the X & Y (now called ROW & COL) are an address bus, whereas button press/release is the data. In puredata the ROW, COL, DATA would be packaged together into one message but we don’t have such luxuries in embedded world…
It’s kind of like the electronic circuit called a multiplexer. Haven’t used it enough to know whether performance degradation due to 6 bees bangs instead of 4 is worth worrying about…
I see. Of course this works fine with the grid itself (although I have a somehow counterexample below), it is mostly when I try to make the Aleph do something as well that I run into trouble… For instance I press button 15/0, which is a toggle on the grid and I want the same result inside Grains (ScrubEnable should be toggled as well, for instance). The Grid toggles, but each time I release the button ScrubEnable goes back to 0. Now if I want it to toggle and I have 8 buttons like that (the whole Column 15, here) then I need 8 CHANGE operators if I don’t want to ruin the grid’s behavior. Same thing with the rest of the grid, where I programmed one button constantly lit per row. Here it will just send twice the info each time to the Aleph, which is not so bad but quite inelegant - unless I put 8 TOG operators, again one for each row.
See, that’s 16 operators. I then made a patch to solve this issue by ruling that if COL AND ROW haven’t changed then the release should be ignored, but that forces me to use about 10 extra operators still and the whole thing takes way too much resources in the end: there won’t be much left if anybody wants to program something that actually has to do with sound! I had an idea about modifying the CHANGE op (sending a bang each time an info is blocked) but that alone won’t solve the whole heaviness here.
Anyway you got my point: isn’t there a way to solve this from the GRID object instead? I mean, for instance if I keep button 0/0 pressed and then press 2/0, button 0/0 goes blank. If I then release 0/0 it gets lit again although I still press 2/0, and when I will finally release 2/0 it will get lit while 0/0 will go blank… mostly because they send the exact same info each time, which I am still unsure is needed (couldn’t we use HISTORY if we wanted that feature in a specific patch?). Does it make sense?
EDIT: just modified my post a bit, re-read it in case please!
Actually a way to solve the problem: could COL and ROW have two separate outputs for note on and note off? If we want on/off together (the way it is now) then we could simply send the two outputs for COL or for ROW to the same object… and it would make the two infos (on/off) potentially different instead of being exactly the same. This would solve my case and, I am sure, many other ones. What do you think?
In order to move forward here, I think we should agree on a set of use-cases for the new grid operators. Then I will go through a process of tweaking the new ops until they have the right recipe to create all the example patches without too much clutter. This is the same philosophy behind grains - I set out to create something that can become sampler, FM processor, pitch-shifter, chorus/flange, echo effect without glitching too hard as it morphs between those things.
Then you can refer to those example patches to answer these ‘how do I?’ type of questions. Otherwise we get bogged down in these existential discussions about which is the ‘right’ way for each object to behave. I aim to design a highly orthogonal set of operators which can be combined efficiently to do many, many jobs. Once the ops work for all the jobs I can currently think of they’re ‘finished’…
Here’s my list of music-things that should be build-able from grid ops (then hack-able because they’re built as a patch!):
grains patch matrix manipulation & display using grid (would also like the textual display on aleph screen for patch-matrix signal sources)
monophonic step sequencer based on mem1D (one light-per-column step-sequencer)
percussion step sequencer based on mem2D (any grid light can be on/off)
generative step sequencer using life op (like a percussion sequencer but it reads from a life op not mem2D - life can have a different clock)
Pretty sure the new grid ops as they stand can already be combined to build these things without dumb stuff like 8 change operators (try playing with the write/read functionality of the mem ops). I already went through a round of revisions tweaking the new ops till until my example patches became possible! Assuming arbitrary op deletion is now working correctly (let me know - I’m at work right now), we can move forward with this exciting developmental work on bees ops!
Can you explain very clearly and simply any desired use-cases not covered by those examples above? Grid-manipulation of grains-patch-matrix was your idea originally and inspired me to create the new ops as first project with my new grid toy. Will also revisit my example to ensure I am correct in saying that my own wishlist is already fulfilled (and obviously share the patches)…
Consider this an open invitation to any aleph grid users to describe any straightforward music-control-thing they would like to build as a bees patch but doesn’t seem to be possible with the current set of operators. I’m not talking about highly integrated intricate objects such as WW, life or meadowphysics (that level of complexity probably best managed as a C program) but things around the same level of complexity as a step-sequencer…
Chucking these two ideas on the pile (not sure how musically useful but these kind of simple geometric operations should be possible with any respectable patching language)
‘line’ you hold down two grid buttons - it draws a line between the two buttons
‘zone’ you hold down two grid buttons it draws a square with corners at the two presses
Crazy idea - because we have the host serial functionality now, I think it will be possible to distribute my example patches in the form of a program (which runs on host) that inserts the example patch into an existing bees patch. I think common lisp is too fiddly to set up for most people, but a host picolisp program could almost certainly be wrapped up and made to look like regular command-line app. (I could just use python but many benefits to using a language for host app coding that can also run on the device - besides I am a crazy lisp fanatic why fight it…)
I get your point, I mostly got frustrated after making the patch I had in mind and not being able to make it perfect in the end… But everything works now without any CHANGE or TOG operators added, I just get double data each time I release a button but it doesn’t change the sound and it is such a relief playing with the grid this way, woohooo !! Then I’ll send you my scene whenever you have time to check it, you’ll probably be able to tell me what I missed and I’ll be an even happier man.
Now I just rewrote the whole patch for Grains using the fix you set with ROW/COL/VAL. Funny enough it took me quite some time to realize two things:
1/ You changed X/Y for ROW/COL on MEM2D and such, but not on GRID. Is that on purpose?
2/ and then you used this order: ROW/COL, which is the equivalent of Y/X. It doesn’t matter really, but if GRID still uses X/Y then it gets confusing.
By the way I have made a musical ‘zone’ patch already, it was just waiting for the grid to behave the way you describe! I am getting some great ideas here, will come with something about it soon!
I’ll finally add I am quite amazed at how much work you have put into this, and must say my Aleph is looking better everyday thanks to you.
Nope that’s a mistake - very easily fixed thanks for spotting…
When I’m back at the device tonight I’ll put together a simple patch showing how to ignore grid button release using only one extra operator and post here. If it’s not possible with what is there already I will add a dedicated operator 1-in/1-out . It echoes any bangs > 0 to output and ignores any bangs <= 0.
@zebra and @tehn! They nailed down so many hard & tedious problems to get this platform to where it is - granted bees seems to have a couple of architectural deficiencies but I already complained enough about those. Once you start going lower-level and understanding more about the device you see what a hell of dumb over-complexity is the embedded world, but these guys managed to gloss over sooo much uninteresting plumbing with avr32lib to provide a beautiful playground for experimenting! Also @zebra gave up a lot of his time to help me develop the features I want on the device and explaining parts of the code.
Now we start to remove some of the roadblocks in bees (please tell me the net-use-malloc branch is not buggy!?) I am bristling with excitement for some new modules (beepbox & 414). Did a lot of work on tooling for module development so I think it will be possible to rapidly develop some really fun stuff. Also thinking about a waveguide synth which is a cross between karplus-strong banjo and a tappped reverberator allpass-filter-ring…
so just got home and picked up my aleph notes. in order to ignore button release you just use the thresh operator:
GRID/BUT -> THRESH/IN
op_grid will still emit it’s address-bangs (x, y) of course. But this supresses the bangs for button lift.
There’s another trivial operation which puzzled me, which is how do you set up an operator which always outputs the same number whenever you bang it. I use mem0D for that. Set the number you want on it’s wr input, then bang read every time you want to emit the number.
Here’s the diagram of my patch-matrix patch (dug out of some notes I made), demonstrating the thresh trick & the trick with mem0D (disclaimer there may be errors in that diagram I haven’t checked it by rebuilding the patch but you get the idea):
change my mind. COL & ROW don’t work well for me at all I change back to X & Y. keep getting confused which is which and there’s no real potential for genuine confusion with the Y operator (anyway that could just be renamed to split although the Y does look kind of cool there).
These are all just toy patches for now they don’t do anything useful. Wary in case it’s necessary to break scene compatibility again so I’m trying not to spend too much time on particular patches until the dust settles a bit.
I’m curious what other users think of these new ops and way to open up grid on aleph? Have to admit patching with these guys is a little heavy on the old gray matter, even compared to coding. but I do find it pretty cool, and definitely mind-expanding.
Now I also plan to create some new bees ops, similar in spirit to life, so they move cells around inside a grid according to some rules.
snowstorm (moves particles around at const velocity inside a grid area)
pong (bounces particles around inside a grid area, output for each edge when a particle bounces off that edge)
fireworks (‘explodes’ particles radially outwards in 4 directions inside a grid area)
screen_grid (aleph screen op that ‘simulates’ grid LEDS providing the same inputs: x, y, val, on)
All of these would be similar to the life op in that the values are read out to LEDs via bees bangs, so you can re-route that visual feedback through sound generators, e.g parameters on a blackfin module
Now that is interesting. I did it in a quite different way, using MEM2D and got the same result (plus this extra line of buttons), I mean it works perfectly if I only look at the grid… By the way you meant THRESH/LIM 1, right? For various reasons, and seemingly because I understood your objects in a somehow different way than what you are showing here, the THRESH trick will not work for me at all (I am only using the BUT part for the last column here, and THRESH will kill my toggle part).
Also here you seem to only use MEM0D, which is definitely another way of thinking. I will study the patches, and will send you mine now: gridgrains_3.scn (256.1 KB)
As stated before this is a complete functional patch for Grains, which gives you access to all the main patch functions (apart from the source_CV, actually) on the 15 first columns, plus some extra elements (Scrub_enable, ScrubPitchDetect, echoWrap and writeEnable for the two Grains) on the last column, which behaves as Toggle. Thing is, I visually separated the parts (Grid functions above MEM2D with on the left the patch matrix and on the right the toggled buttons, Grains functions below MEM2D) so it is quite easy to find what is where. The whole upper part works with no issue at all, as you’ll see. It’s the lower part that gives me everything in double, and again the THRESH trick didn’t help at all.
Again this is very promising, thanks for these examples!
EDIT: By the way in my example ITER/TIMES should have a value of 15 - not 16. I am starting to understand your patch now, didn’t think of MEM0D as a way to work on a full grid. More later.
Kind of cool you are getting on well with these new ops. Now imagine we have the arbitrary op insertion feature (as well as deletion). Then it becomes a lot easier to build up complex patches by building things up in stages.
Obviously when there’s op deletion/insertion anywhere in the netlist then the next thing you’ll want is the ability to save and load ‘sub-patches’. This would not be a true hierarchical subpatch like with puredata, where the toplevel netlist hides the complexity of the subpatch. But a way to insert the contents of a subpatch into the current netlist at a given point in the operator netlist. The subpatch fileformat should pickle the user-operators, inputs & outputs. Can develop this feature on a desktop machine using beekeep…
bees seems to have a couple of architectural deficiencies
putting it mildly. bees systems designer should be taken out and shot
but seriously, this is one of those things where we know so much more now than i did when started building bees, especialy about what we want/need it to do; it really calls for a significant rewrite and refactor of most of net.c, towards a “bees 1.0” … your memory management work is a huge step in the right direction, so thanks.
Did a lot of work on tooling for module development so I think it will be possible to rapidly develop some really fun stuff.
funny, i was going to mention this. i’m in a really strange busy/not-busy situation where it is hard to accomplish significant work, and i have no hardware, but might be nice to poke at DSP development a little. so i’m looking at your JACK wrapper stuff. built ‘sim’ target of grains OK, and it seems to run, but i’ve no real idea how to use osc_test_harness.lisp … is this something you’d be interested in building out / documenting more? (in other words, i should just start getting comfy with lisp?)
…cause the other thing i’m doing is playing around with customizing pforth, simulating some of the things an aleph control app has to deal with (handling interrupt events, setting timer callbacks, etc.) and i wonder if i should just go ahead and stick a liblo client in there as well.
I was thinking of subpatches of course, it won’t necessarily make creating scenes much easier for beginners, but it could be quite brilliant, and would allow us to develop entire libraries of object behaviors!
Then I have been studying your patch_mat and it really is interesting, very simple somehow with GRID/BUT launching 1/ erase the whole line 2/ send the value for X 3/ lit X and 4/ send the info to the ROUTE object… and yet quite complex to read at first. Funny enough I have been using GRID/X to both Write and Read, which allows me to use GRID/BUT only for the last column (as far as I can see it would be quite a mess with MEM0D), but also brought me the aforementioned issue - no big deal, really I see it now. By the way, how would you create a column consisting of 8 toggling buttons with this system? Can’t figure out MEM0D/TOG in that context, to be honest (as I understand it it should toggle Write 0/1?)…
Anyway this is helping a lot to understand how you’ve been seeing these objects from the start.
Or just write a forth word that eats a string, then N numbers off the stack, then sends it off to osc server. Or a command-line OSC utility even just for test…
hmmm let me check now how does it go…
ok yeah to get some osc lisp action on the go, compile example_server from the liblo examples, run the example server in an emacs shell buffer, start up slime, load that lisp file with C-c C-k, then type (osc-send (osc:encode-message “badger” '(1 2 3)))
think I also built lines & waves against the new library try make sim in their directory too. IIRC there’s some numerical thing that’s right on the edge with grains - the fractional multiplication emulator is just a little less accurate than the hardware so some slew filter blows up somewhere after a second or two.
Should really geek out and try to reverse engineer the onboard fractional multiplication by adding special multiplication-test parameter to the analyser module. Then write a common lisp program that runs overnight collecting a lot of data via bees serial multiplying random numbers together and storing the result. Then plot the error (z) when you multiply x*y on a surface, look at it to see if it’s fairly regular. NERDFEST!
Well it is! Of course SCREEN is a dead-end object, it won’t send to anything… but here the knobs draw on the screen AND on the Grid at the same time (using varibright, by the way), plus I can draw on the screen from the Grid, even though it is 8 times less precise. So bidirectional between the Aleph and the Grid, yes sir.
compile example_server from the liblo examples, run the example server in an emacs shell buffer
ah ok, that’s what i was missing
Or just write a forth word that eats a string, then N numbers off the stack, then sends it off to osc server.
well sure, this would be the basic approach in forth. (in a customized pforth, there’s mechanisms tomake liblo functions or whatever available directly to the interpreter.) but there’s no shortage of generic methods to send OSC for testing. (supercollider, um… netcat?)
i guess what i’m really thinking is that it’d be cool if whatever control-side code i cook up for “testing” (aka messing around) could feasibly work on the aleph as well. having some musically useful control code might be a good motivation to finish an aleph interpreter.
or maybe i should just work on getting bees running on linux.
the fractional multiplication emulator is just a little less accurate than the hardware
hm, that is certainly an issue… i’ll take a look… at first glance the multiplication with the 40b result seems correct, but maybe i’m forgetting something about the hardware, will look at ASM reference.
So picolisp not common lisp. Common lisp is way too heavy for avr32 - I use it for testing because it’s my go-to language. From the looks of it x86_64 picolisp has even better C interop than common lisp. Moving test harnesses over to picolisp could be a shrewd move…
The interpreter is kind of already working - I wrote a simple etchasketch in lisp the other night by entering function definitions at the repl! Just need to write more custom lisp functions that hook into the hardware.
such a tough one! I see more immediate value in developing interpreter for aleph. But yeah - if bees menus could be driven from connected keyboard as well as encoders, then linux port would start to look more plausible, not to mention appealing as debug tool. Adding such a major feature to bees UI is pretty daunting to me - it’s a huge amount of code in the menus and stuff I am amazed by the stability with so many moving parts.
This makes me think maybe I can salvage something useful from net-refactor branch, by trying harder to not break external interfaces within that file. Did get it to the point where i could fire up a bees net on host with beekeep and ping it with gdb! Trouble is I ploughed on and ‘fixed’ pickling/unpickling and interfaces to the menus.