From the original SynthMaker forum (2004–2014), with its members’ names and dates.
oddson ·
I've made a rough first go at a custom envelope that tracks a drawn path.
It reads the vertical value of the drawn array and outputs this value for the first pass, then as it cycles through the sustain section it adjusts the output by the sustain loop gain, which is the ratio of the crossing points of the sustain end and start values (the white lines). Currently it's not limited so it can overdrive if the value is above 1 and you go through enough cycles.
During the release phase it tracks the path to the right of the sustain and scales the value by the output current when the release occurs. (At least that is what I hope it's doing.) Again, without limits, this means you can make paths that output values well above unity.
There's a smooth module thrown in to avoid nasty jumps between draw points.
drawnEnvelope.osm
Any comments and suggestions are welcome, particularly on improving the coding as I'm sure there is a great deal of optimization possible.
The schematic is a little rougher than I usually like to post but I'm looking for some feedback early on.
Shifrin ·
What an interesting idea!!!
Thanks for sharing this oddson 🙂
Shif.
sambean ·
Brilliant.. Never seen an envelope like this before.. Great idea. The cpu's not too bad either considering it's mostly running at sample rate. You may even geat away with 'hopping' it down a few factors then it would be negligable.
I've found a minor bug though 😈 If you set both the sustain start/end points to zero you get no sound out of it.
You get some pretty interesting granular envelopes having everything set to zero apart from lots of spikes..
Cool
Sam
Tom7777 ·
Nice idea 🙂
oddson ·
sambean wrote: Never seen an envelope like this before..
😮 Really... I've had the idea for a long time -- I even tried to do it a long time ago but I didn't have the skills for it yet.
sambean wrote: The cpu's not too bad either considering it's mostly running at sample rate. You may even geat away with 'hopping' it down a few factors then it would be negligable.
I thought I had to process every sample because I was waiting for the first sample where the release had triggered to reset the counter to start reading the release curve. Turns out as long and the code is skipping them together it doesn't have to be that exact sample.
sambean wrote: I've found a minor bug though 😈 If you set both the sustain start/end points to zero you get no sound out of it.
Actually I think it depends on where the first data point is. I certainly didn't bullet proof it from unusual settings so I'm not too surprised.
sambean wrote: You get some pretty interesting granular envelopes having everything set to zero apart from lots of spikes..
Not sure what you mean here... espcially since you just said you got no output with the sustain points at zero... but I think the 'granular envelopes' you're referring to is just massive overdrive.
Thanks for making me rethink the hop thing. I've got the CPU load down to a reasonable level. Right now I've got the hop over the main code to 256 which I know is pretty high. I have to do the math to find the appropriate setting so that it still tracks 1 point spikes in the graph with sufficient accuracy. It depends on the duration of envelope though -- which determines the samples/data point -- so I'll have to consider some minimum envelope length to work it out.
Updated the link above...
oddson ·
Fixed a few things and cleaned it up a bit.
drawnEnvelope1.osm
I've limited the gain to avoid overdrive. I'm starting to realize there are a lot of choices in how this thing can/should behave. I might add some of these as options later on.
I'll keep posting here.
cAPSLOCK ·
Very cool man. This is one of those "Why didn't someone already think of this" type things. Nice work - you get to be first.
oddson ·
I'll be suprised if there isn't a prior example somewhere. It's a big ol' world.
electrogear ·
Nice! How feasible would it be to have a little box with 3 buttons at the side to select between drawing a straight line, a curve, or the current "freehand" mode. Guess that would be difficult. Can't wait until I can make things like this (one day...)
Cheers,
Mike
rlahalla ·
Oddson, this is great! Thanks for sharing this 😀
oddson ·
@electrogear - I'll be adding something to allow staight segments as well as some other shaping options.
I was thinking using the shift-key to allow straight segments with clicks. This is dead easy - just force the 'dragging' input on the Float Array Draw. I'll post this later today. Curved lines are a little harder - I'm thinking about these issues though.
I was thinking of processing the array with some kind of low-pass filter to smooth the points out. The irony here is that it's hard to filter green array data in this manner. The loop would work but I'm concerned it would be very slow. I could try shifting the float into stream data but getting in back means some kind of ticker-based reader.
Another option is to process the smoothing while you draw. I've got some ideas for that.
Like I said, I've got dozens of ideas for this and I will keep posting. Please continue with suggestions.
EDIT - I've fiqured how to do a low-order FIR on array data using the Array shift and array multiply components. Just have to work out how to get reasonable coefficents calculated and deal with wrap error from the shift (I don't think you want the start of your attack affecting the end of the release).
oddson ·
drawnEnvelope2.osm
I've added the shift line draw. It doesn't work as I would have hoped.
You click with shift down and then let up and click again and it runs a straight line between your two clicks. If you want to keep going leave the shift down but you have to let up one click before you're done. I will likely have a go at a better mechanism than this. The button idea is not bad but I'm not sure yet.
The main thing in this version is a smoothing filter for the graph points.
It's a weighted moving average and the weighting scheme has no theoretical basis that I know of, it's just something I came up with to give the effect I was looking for. I'd try to explain it but you can see for yourselfs how the coefs work (it's pretty simple). Then there's a trick to avoiding the wrap effect. The array was padded with zeros between the start and end to avoid contamination of the attack and release phases with each other.
Turns out with this you don't need to rely on the smoothing at sample rate filter. So I've added the option to turn off sample smoothing.
oddson ·
drawnEnvelope3.osm
Main change here is that I've implemeted a second envelope type.
This one, called 'Complete Envelope' runs through the entire envelope regardless of the length of the note. If the note is held beyond the sustain end point it will cycle through the sustain cycle with (limited) gain change.
When the release is recieved the current sustain cycle will complete before the release phase happens.
The older version is here named 'Quick Release' and, as before it goes directly to the release phase on getting the note off message.
I've got a few more tricks us my sleeve but I'm going to focus on user interface for a while (as it's still pretty crude).
EDIT - minor update to improve drawing. Shift used as sample&hold to prevent array processing prior to smoothing.
oddson ·
drawnEnvelope4.osm
Added a boolean input that tells the envelope whether or not to accumulate gain changes as it cycles through the sustain phase.
The major interface change so far is some markers to help the user see what's going on.
Next up is looking at some way to change the time scale that seems intuitive.
One idea is to have vertical ms markers that can be draged to alter the scale.
I'd really appreciate any feedback.
rlahalla ·
I had started playing with version 3 of this to figure out what you've done...I'll take a look at this too. This is a wonderful example oddson, much appreciate your time and efforts 🙂
oddson ·
drawnEnvelope5.osm
Added timescaling feature (drag boxes on bottom) and a possible interface for the smoothing feature (now bumped up to 8 pre and post points in the weighted moving average).
Not sure what timescale info should display while dragging nor where it should appear.
sambean ·
Brilliant! You can get some great effects out of this. 🙂
You could have the timescale in a seperate window similar to the scrollbar of the graphic ADSR? One thing I noticed here is that sometimes grabbing the drag boxes, I'd miss and redraw a section of envelope. You could have it as a seperate resizable window and if a user wished to have them overalayed it would be fairly straightforward to do manually.
Sam
oddson ·
Thanks Sam... I think what I'll do is to add two channels to the top and bottom and exclude them from the graph draw and limit them to dragging the indicators.
I'm also going to add an 'undo' for draw so you can get back the shape prior to the last edit. Multiple undo would be nice but would need an array of arrays to handle it. I could make a small number of undo's possible with some kind of selector and held arrays.
Any thoughts on the 'smoother' interface?
Tom7777 ·
Really cool project Oddson, i had the chance to test the latest last night, makes some nice sound and the smoothing features a really cool idea 🙂
oddson ·
Thanks Dan... how did you find the interface for the smoother?
This is an aspect I'm very curious about. It makes perfect sense to me but I'm wondering if an intelligent user can figure out what it's doing and to alter the settings. Did you even notice that the bar-chart adjusts with mouse input?
I'm thinking it's not clear enough. Any thoughts anyone?
GaryG ·
Personally, i thought it was very clear - spikier or smoother...
Why do you have doubts? Has anyone specifically said they didn't understand it?
.g
Tom7777 ·
Did you even notice that the bar-chart adjusts with mouse input?
Yeah i noticed this, it's clear i think 😀
oddson ·
...Has anyone specifically said they didn't understand it?
Thanks guys. No... just me not knowing how clear it would be.
oddson ·
GaryG wrote: Personally, i thought it was very clear - spikier or smoother...
Actually, it's supposed to be a little more specific than that. It's displaying the weighting of the data points to the left and right of the point being averaged. When it's flat - it's an unweighted moving average. When it's spikey it's weighting the points nearer to the centre higher. Also, dragging left will narrow the degree of the filter while dragging right will increase it.
I think the overall intent is clear enough and this finer point can be in a help file somewhere. Mostly it doesn't matter that much as I often find repeated iterations work best and the exact characteristics of the filter don't matter much.
The only time it really has much inpact is if you are trying to get very subtle changes to spike points -- as opposed to getting rid of hand jitter from drawing or rounding the corners from flat segments.
GaryG ·
sorry, I didn't mean to be so simplistic, I can't say I appreciated exactly what was happening but, yeah, I did notice there was the left/right adjustment too... 🙂
.g
oddson ·
Cool! Thanks again.
oddson ·
drawnEnvelope6.osm
Latest version
stefan ·
Brilliant! I find it very simple to work with and it's very wysiwyg.
Shifrin ·
This is fantastic 😀
Shif.
lalo ·
great stuff oddson!!!
rl ·
Supah dupah stuff. Minor glitch: it's possible to move the zoom markers out of range.
oddson ·
rl wrote: ...Minor glitch: it's possible to move the zoom markers out of range.
What's wrong with that?
rl ·
how can I get them back? (the mouse area is outside the module)
oddson ·
Are we talking about the coloured markers on the bottom? (since you said 'zoom' I would assume so).
The min and max settings on the length of the env should mean there is always one of them showing. The redish one is 100ms the yellow=1sec and the green 10sec. You should always have at least one of them showing but you can drag one off the right-hand-side but the next smaller scale should still be visable. Once there is room for 25 intervals in the env length the vertical lines for that scale disappear.
Any suggestions on how to make this clearer are welcome. (I will be adding some kind of readout of the time scale that changes while dragging but I haven't sorted where to put it. Should it drag with the marker you're moving or stay in one place on the right side?)
rl ·
ah, I see. that makes sense.
dutchound ·
hiya, i just figured out how this works, it's awesome! can you please upload version 4 again as the link has expired.
thanks!
oddson ·
This is a blast from the past...
I've posted the old version 4 file to the server in the old post (back then you had to host your own attachments).
oddson ·
From your other posts it seems you're trying to generalize this into LFOs.
I was working on this back in Dec. 2006 but I got side tracked by other stuff going on in my life and never got back too it.
Here is the previously unposted Version 7
I have a handful of other files after this where I was trying get a single interface to act upon many separately running instances but they're not really fit for sharing without some review.
infuzion ·
oddson wrote: I was working on this back in Dec. 2006 but I got side tracked by other stuff going on in my life and never got back too it. Here is the previously unposted Version 7
The GUI is handy; thanks!
Wrote something here? To have a post removed or your name hidden, write to [email protected].