>>> ZPC#15 - Drum Kit In A Patch <<<

Official support for: u-he.com
RELATED
PRODUCTS

Post

Iam honored to be involved in this competition.
There are some very good settings here!
Severe voting .......

Post

Mighty Pea wrote:I'm got a few patches to submit as well, just going to tweak them untill the submission date.

One thing is annoying me though. I'm trying to make a patch where modmappers change a filter's frequency and the env's decay by key, but only the former's working. No matter what I do, I can't get different decay values this way.

Here's a screenshot that can hopefully help anyone pinpoint what I'm doing wrong:

http://dl.dropbox.com/u/17715/zebra_mmap_env.png
I had this problem ages ago when I was making drumkits-in-a-patch, and I think I mailed Urs about it. It's something to do with the way the modmapp voices are calculated or something. The answer (just tested to verify) is to set the empty parameter to the far left of the knobs to 'Delay', then increase tiny little tads until you hear the effect of the envelope. IIRC the delay is required to give the circuitry time to calculate the modmapp parameters, or something (again...)

Urs, or another knowledgeable chap will enhance or correct this information, I hope!

But you have a fix.. :)

Post

Mighty Pea wrote: But you have a fix.. :)
Thanks!

Post

CinningBao wrote:IIRC the delay is required to give the circuitry time to calculate the modmapp parameters, or something (again...)
I can give an explanation that may, or significantly may not be worth puzzling over. It's a little long, based on assumptions ... :zzz:

When we talk about a modulation source in Zebra that's time-variant, e.g. an envelope, we can mean two different things.

Immediately we probably think first about form; a collection of (mathematically defined) curves pieced together to give us a formal graph of amplitude or magnitude over time; the knobs let us stretch or flex or curve a segment, or do something trickier with a couple of segments etc. This is a 'function'.

We may also just mean the specific value of an envelope at a specific time.

Simply, we can essentially get to an expression ENV1( parameters, time ) which lets us get the specific value from the formal equation at a specific time. So it seems like we can get by with the first formal definition even when we'll want the second specific value. Most of the time, this is correct.

But it gets complicated :wheee:

One might have the ENV1 parameters themselves may be modulated by any mod source. For something like velocity or keyscaling, that's not tricky, they are specific values. But they may be modulated by another time-based modulation, such as an LFO or MSEG or ENV. These are all functional, based on parameters and time. We want specific values, but we have functions. Well, we can just compute these modulations when we come across them inside other functions, right?

WRONG! :shock: :-o :o :x :P :cry: :help: :roll:

Consider the case where ENV1 has a parameter modulated by ENV1 - it's possible in Zebra's ModMatrix. If we plan on computing the specific modulation value of ENV1, we'll need to compute it's parameters, which involves computing ... the specific modulation value of ENV1. Which involves ... and so on, in a recursive loop.

There are also nasty cases where something happens with a chain of parameters, like ENV1 modulating MSEG1 modulating LFO1 modulating ENV1. Again, it's possible in the ModMatrix.

So how do we get around this :?:

Whenever we need to compute the value of a modulation, and it asks for the value of another modulation, we just look at a table of the modulations we've built and stored in memory. To build this table, we just make one pass down a list of modulations - in the same order as modulations are assigning to a knob - and evaluate each one. (If we do things the right way, making this pass down the list is actually the only time we ever compute a modulation value. That makes things very easy to manage from a programming standpoint.)

If we've gone down the list to, for example, ENV1, there are two general cases to think about. Everything above it on the list (notably, it's mostly constant MIDI data) is recently updated. Everything including and below ENV1 is in a sense one timeframe old, but that's still pretty recent and reliable - EXCEPT during the very first pass down the list. We should get zero in that very specific case :!:

(footnote - Actually, we've probably made a *secret* first pass to set everything to zero before going down that list. It'd be even worse in this context to have something completely random there, which is what would happen if we didn't set everything to zero ... many stories could be told, many with the :oops: emoticon.)

So - this odd behavior of MMap not feeding into ENV1's decay knob is explained by MMap not having been evaluated yet, and so just spitting out zero. And also the perhaps odder behavior that if we make Zebra hiccup a bit by putting in and empty delay at the front of ENV1, we actually have tossed something into the table under MMap when we then calculate decay on a second pass.

So, that's hopefully not too crazy to think about ... but don't ask me for a similar explination with ACE :hihi:

Post

Hmm, I'm not convinced you know what you're talking about xh3rv.. ;)

I'm not a programmer, but I understand the concepts involved; would it not be programatically prudent to calculate the minimum delay required during the first table sweep of modulations and automagically introduce that into the path, rather than having to lose the Delay function from the Envelope?

Boy, this is swerved fairly off-topic from the original DrumKit patch thread..
Sorry guys!

Post

CinningBao wrote:would it not be programatically prudent to calculate the minimum delay required during the first table sweep of modulations and automagically introduce that into the path, rather than having to lose the Delay function from the Envelope?
Let me first ask if I understand correctly here - you're suggesting that instead of using the timeframes time[ now ] and time[ -1 ], we instead use time[now + 1] and time[ now ]. In order to know when time[ now+1 ] is, we consider the control rate of the synth, which I think is around 1khz in Zebra? I wouldn't swear on the absolute value but I think the general principle, that these updates occur at regular-ish intervals, is reliable. (Let's just say we're working on a hypothetical Zebra-like synth anyway, I'm sure there's plenty going on I'm not keen on, although I'm reasonably confident about this stuff).

As a solution to the special case we started with, Key-MMap->ENV1 Decay, looking ahead would be pretty plausible computationally. We could even look ahead twice as long if it was, say, Key-MMap2->MMap1->ENV1 Decay.

But if we had ENV1->MMap->ENV1 Decay, we would still be dealing with a weird recursive behavior. We could do some sort of approximation based on looking ahead a limited number of times, but that's really the same arithmetic as looking back a single frame, since we're on a fixed interval jumping through the timeline.

So I would observe that it's not that the specific case we're looking at is too difficult, but allowing for it sort of opens the door to cases that are difficult.

We could probably come up with a lot of special cases, or implement some system for tracking how deeply we need to recurse in cases of finite recursion. Either way we are making tradeoffs. One is we're creating more processing that needs to be done, more symbols to cram down the CPU pipeline, including some conditionals that can sort of jam things up because of branch prediction. Another is the actual programming is more involved, longer, and snarkier. There's a bit of a judgement call to be made - it will take more time to program initially, and still more to maintain, so much so that it may consume more developer time than it's worth. (I get the sense Urs is professionally awesome about this kind of call!)

Ultimately this is all my intuition so it is questionable :) Perhaps I'm succumbing to an urge to explain. I am merely a biological robot :P

Post

xh3rv wrote:I am merely a biological robot :P
We all are! Well put...

Post

My usual retort to door-knocking Jehovah witnesses is "I'm an organic robot, you're an organic robot, we are all organic robots, there is no god". They move on quite quickly after that..

And yes, I forgot about the recursive side to the computations. I should remember that Urs probably considers these concepts during development. I is the fool.

Post Reply

Return to “u-he”