Also @zebra mentioned something on the github about accelerated 24.8 multiplication primitives. Possible that leveraging those could be another way to get this thing running lean enough to avert the failure condition…
just posted the track with Grains all over it in the latest tracks thread
I’m sure it’s reproducible because I did it twice last night, but this morning I can’t seem to crash it. I’ll note the parameters next time it crashes
Hmm so thinking more about this maybe simultaneous tweaking both delaytime params would be the highest-stress thing one could do to this. Will try a bees scene that rags those two hard tonight, see if I can reproduce myself. Also I now have working serial comms in bees - so can actually do a much more comprehensive/reproducible stress test from host machine…
awesome looking forward to listening tonight!
Ok just tried it. Brilliant work, really!
The learning curve is quite steep for sure, but it already allowed me to get into some very unusual things.
I am now trying to set some simple effects running (one easily gets into distorted FM madness with high frequencies all over the place), but I must admit it’ll take some time before I get the hang of Grains haha - which is most probably a good thing! Anyway iIt’ll be nice to set some simple scenes with this, in order to put most people on track. I’ll be happy to contribute, if you feel like it.
Haha I get it !! Expect some music soon, and before that quite a few questions to come!
Just playing with the echo parameters made my day, and the rest just seems like even more fun.
This will open up for a lot of possibilities in a near future, so thanks a lot!
Got a few questions now, and it might be that I will find some of the answers myself before you answer, but I think these descriptions will be useful to most. I am now trying to play with the Echo and Scrub parts only with one single input and one grain (not even using the Matrix), yet some things are still unclear to me. So I wrote what I found, hoping you can correct me where I am wrong:
- echoSpeed - fine and simple to understand. Negative values will play your sound backwards. This modifies the speed at which the loop is played, so if you want to play with pitch independantly from time, you should try the scrubPitch function (see below). A trick I found: with echoSpeed at -0.999999 you get a reverse sound with the same length. Then playing with scrubPitch allows you to change the reverse sound’s pitch. In this way it could be fun to trigger echoSpeed between 1 and -1 mostly, although I like its classic Varispeed effect a lot. Also, when setting scrubEnable at 1, this won’t change the pitch anymore - only the speed!
- echoTime - only useful if set between echoMin and echoMax. With echoWrap set at 0, will play a one-shot. If then the value of echoTime is above echoMax, it’ll play from echoMax. If it is below echoMin, it won’t play. With echoWrap set at 1, will restart the loop wherever you place it. If then echoTime is set outside of the range, it will set a burst (scratch-like) of sound before getting back to the loop. If set within the range, it’ll retsart the loop from that very place.
- echoWrap - choice between one-shot (0) or loop (1) between echoMin and echoMax when WriteEnable is set to 0. When WriteEnable is set to 1, seems to work as a bypass button for the whole Echo module (it still records the buffer, but won’t play it).
- echoFadeLength - very useful part, allowing to crossfade between the loop end and its beginning. Small values give a natural sound (good for long loops), large values make the crossfade quite powerful (good for very short loops). Not sure I get the “ratio to echomax-echomin” calculation though. For very short loops (echoMax-echoMin<40, for instance) it seems no fade is good enough, but in most cases you can find a sweet spot.
- echoMin and echoMax - somehow the range in time for the echo function. It seems the buffer goes from Max to Min, which is in my mind a bit confusing if I think of it as a loop, but I understand it comes from the fact that echoMin represents the echo boundary nearest to the write-head. Therefore it will show the last part of your looped sound… Also, I noticed the whole buffer seems to be looped 8 times over the 32767 possible values for echoMin and echoMax, meaning the buffer is about 4096 “values” long, and the loop can be set to more. Am I correct? And if so, why not use the full range for the buffer (here it is about 5 seconds long), or why not limit the size of the loop then?
*WriteEnable - set to 1, it will generate a single echo, providing wrap is set to 1. Set to 0, it will create a loop defined by echoMin and echoMax. Sometimes I get very weird wraps though, even with WriteEnable set to 1. Something like a very strong scratch effect, which I have no clue how to trigger. All I know is I can stop it by playing with some values like echoMin and echoMax again.
Now for the Grain Scrub function, here’s what I got:
- scrubEnable - that is very clear, although somehow even when set to 0 it sounds like something is happening within the echo module, as explained just above. I also found that when set to 0 scrubLength would become a kind of scratch function, whereas scrubPitch got disabled and scrubPitchDetect adds only a subtle watery alteration of the pitch stability.
- scrubPitch - this controls your pitch independently of the tempo. I don’t understand the need for negative values here, as they don’t play reverse (UNLESS scrubLength is set to a high value and scrubPitchDetect is on, but then there is quite some echo). In all cases it introduces a subtle change in the sound, making it less natural than positive values and that’s mostly it. Also, if I understand correctly your formula indicates that there are 256 subdivisions between a value of 1 and 2, for instance. Right? I have to say that the way this works differs strongly depending on the value of scrubLength, and it can be quite tough to master, although it’s a lot of fun.
- scrubLength - this one is, to me, the trickiest control so far. At 0 it kind of cancels anything you want to do with scrubPitch, UNLESS scrubPitchDetect is set to 1. Then with scrubPitchDetect set to 1, if you go up to about 4000 and scrubPitch set to negative values then you get a mix of normal and reverse sounds. At 30.000 it is fully reverse then, but with a lot of (nice) echo… Around 600 you can get pretty natural pitched sounds IF scrubPitch is between 0 and 2. For the rest, below 500 and with scrubPitchDetect set to 0 you get a sort of Ring Modulation, and above 1000 it creates - for me - random possibilities, somehow it changes the echo feedback while changing the scrub reaction to pitch change but I can’t relate the values to the results I get. Very interesting still, and very difficult to control apart from those simple parts I mentioned. Also, you write “Length of scrubber read distance from echo readhead before cross-fading. This is expressed as a ratio to the scrubberFadeLength” but I haven’t seen any scrubberFadeLength. Did you mean echoFadeLength? Not sure I understand this at all.
- scrubPitchDetect - this one changes the behavior of the whole, adding some more natural sounding pitch changes on the whole. BUT depending on the settings of scrubLength it can entirely change of behavior ! When scrubLength is pushed to the max for instance it will only react to the next integer value, whereas with small values for scrubLength it will act somehow linear… I could use some more precise explanations there.
That’ll be it for now. This is really something special, I am making a simple scene or two to take advantage of my new discoveries now. Hope this is something you can comment on, mostly the parts where I am very wrong - or those which I obviously don’t get!
Edit: just one more question: what is the effect bus in here? I mean, we have 4 inputs and two grains, and all can send to an effect bus which I can hear has an effect indeed, but what is it? Can’t see any detail about that anywhere, and although I suspect it is something already defined in here I would like to know. Sorry for the tremendously long post!
@rick_monster think i was totally wrong about 24.8 intrinsics, we need to roll our own
also, i had not yet said, somehow, how awesome Grains is. wonderful work. thanks so much for making it.
its embarrassing but i’m just now finally taking some time to actually use it myself. like others, still finding my way around.
@Yann_Coppier your writeup is really useful. wouldn’t go amiss to have a sort of more narrative description of what things do, included with this and other modules.
AFAICT, the ‘effect’ bus just provides a way to patch stuff arbitrarily back into the grains inputs?
Yes I got that afterwards: Grain 2 was using the effect bus as a source, which explains the effect I got. It becomes a bit crazy when it is sent again into the effect bus. Feeeeedback, some sort of ascending or descending short delay. I’ll keep writing about what I find in here. It almost all makes sense to me now, after a whole day of tryouts. I am about to try and create a scene for it, possibly with a Grid. Or maybe I should wait for an even more stable version?
Ha - ok so i couldn’t even see any way that hardware-accelerated 24.8 multiplies could help with 24.8 addressed delay line. But grains grew out of me exploring DSP as a total beginner so yeah - probably still missing a lot of tricks!
The patch matrix concept is still confusing because UI is bad (needs some work on the bees side). Patch matrix indices will, in future, display the name of where the ‘virtual cable’ connects to rather than a number 1-12 or whatever it is now.
Be warned I may break scene compatibility in next release - dunno how easy it would be to then migrate complex scenes to the new version.
Patch matrix enables patching stuff back into grains inputs, e.g:
- ringmod by patching the LFO to the AM grain input
- karplus-strong by setting up a regular feedback delay & patching noise-source to grain audio input. When you turn off scrubbing, the scrublength becomes a fine-adjust for delay time
- FM tracking-synth by patching the pitch-detect oscillator of one grain to the FM grain input with envelope enabled (or try AM grain input with envelope disabled)
- Tracking synth by patching the pitch-detect oscillator of one grain to mixer input 3 or 4 with envelope enabled
It’s all somewhat baroque… Would make a lot of sense if I release a demo scene showing how to statically patch all the canonical settings. These use-cases were the single design consideration that drove development, so one way to understand the program better is to be familiar with those. Having said that the reason I wanted to make this module was to explore all the in-between possibilities…
I could reproduce all of these, indeed, except for the Karplus-Strong one: I guess I have another way than yours to create a feedback delay. Anyway this thing can really do a lot! I’ll follow your advice and will wait a bit before making bigger scenes… and by the way the Patch matrix numbers are ok - one just needs to get used to it, and after a day really it’s fine.
to reproduce the karplus strong you may have to route the noise source out through one of mixer channels 3 & 4, then use the effect bus to mix the feedback with input from the noise source. Or sample acoustic noise source from a mic, load that into the other ‘grain’ (gosh the naming is terrible - sorry!) & mix that in via the effect send on grain output.
Other tips - try flipping the phase with this high feedback configuration - think that’s the difference between an organ pipe & a string (or something). Also try tweaking high pass filter on grain input in that configuration & obviously scrubbing/pitch detection should be off, scrubTime becomes fine delay tune.
You need to add patch tips to the readme!
I just made a 128 Grid behave as a complete Matrix patch, meaning it is routing the 15 available sources to the 8 elements that can take them. The last column is used for 8 button features (such as WriteEnable_g1). It is a very simple patch, with 9 operators. Here is the schematics, for those who want to work faster with Grains!
Only thing is, it would be lovely to be able to have objects such as Zones for the Grid, which would allow one to have only one matrix point lit per Row, for instance. I have been thinking about it for a long time actually, and as I am not really able to pull it myself I have create a new thread for those interested: Aleph - new ZONE operator?
Anyway this should help. The numbers below the Operators are for my patch (GRID is number 12, here). The numbers addressed by the two ROUTE8 objects are inputs from Grains (74 is then 074 WriteEnable_g2 here).
For those who will look into this, I strongly recommend you take notes while playing with this simple patch, and also to take some time - at least a few hours! This is extremely cool, the ability to switch buffers into one another, to add FM or AM synthesis on the fly based on your own voice or on an LFO, etc. Can’t describe how many cool uses there can be here! The tough part then is to get to switch functions with the knobs, but that can easily be fixed, using presets…
gotta figure out a way to get one LED per row - I have a feeling this may already possible without adding new bees operators. Gonna have a think how to do that. Since ‘patch matrix’ does not permit mixing several outputs to one input the grid UI should reflect that - also I still want to see the name of each patch matrix output as a reminder. All well and good memorising the numbers eventually but don’t ask me which number is LFO I’d have to go back on the code & check (or hope & pray the README is correct)…
I would like to experiment with “grains”, however, I was having trouble loading it onto Aleph.
When you say “copy these files to your SD card”, which ones exactly?
Thanks all- much to learn here
Closest thing to a release-candidate is:
If I recall correctly, the folder structure of the zip file should mirror that of an SD card set up for aleph.
Sounds as if some people have experienced some bugs with certain param combinations with the module so be slightly wary! Meanwhile I immediately dove into into aleph BEES side of things attempting to add the features I want there, so haven’t had much chance to destruction test grains through intensive real-world use.
Once I’m done with latest round of BEES changes I have an idea for possible optimisation of grains, which may permit a couple more features within the cpu limit…
Also I want a four-track tape recorder module & a ‘beep-box’ module that turns aleph into a basic groove-box.
Still a MASSIVE amount of unrealised potential with this hardware & any programmers (or would-be programmers) out there keen to try out embedded programming now is the time to get on board - even one more active developer in our tiny community would be a huge boost!
This 4 track idea is really exciting stuff ! Wishing I knew how to program so I could help. Maybe it is time to learn !