-
-
Notifications
You must be signed in to change notification settings - Fork 232
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Z alternative #241
Comments
A crude initial version for consideration, using an additional input as placeholder for the current sequence (state has to go somewhere):
Left inputs:
Right input:
Output:
In use: The operator is either stable (
I was unenthused about the additional input at first, but it came out cooler than expected. library.z = function OperatorZ (orca, x, y, passive) {
Operator.call(this, orca, x, y, 'z', passive)
this.name = 'lerp'
this.info = 'Transitions operand to target'
this.ports.duration = { x: -2, y: 0, default: '8' }
this.ports.stepped = { x: -1, y: 0, default: '0' }
this.ports.target = { x: 1, y: 0 }
this.ports.output = { x: 0, y: 1, sensitive: true, reader: true, output: true }
this.operation = function (force = false) {
const duration = this.listen(this.ports.duration, true)
const target = this.listen(this.ports.target, true)
const val = this.listen(this.ports.output, true)
var stepped = this.listen(this.ports.stepped, true)
if (stepped >= duration) {
stepped = duration
this.output(stepped, this.ports.stepped)
}
if (val !== target) {
if (stepped === duration) { stepped = 0 } // previous iteration done, ok to restart
const steps = duration - stepped
const remaining = target - val
const mod = Math.round(remaining / steps)
this.output(orca.keyOf(val + mod), this.ports.output)
this.output(orca.keyOf(stepped + 1), this.ports.stepped)
}
}
} |
Flipping positions of
Original |
This would break almost every set I've ever written since I use the current Z implementation to handle cross fading. I've copy this implementation over my fork to mess around with it for a few days :) Will keep you posted, can you show me how you use it to write music? I'd love to see it used in practice. |
It sure would! Hence the breaking change designator :) I do think the flipped arguments make more sense, I'm using this version to mess around: https://github.com/unthingable/Orca/tree/z. I'll try to use it in a composition and show you. Base use case is crossfades, same as original Z, except I know exactly how long the fade will take and can time it musically when I'm triggering crossfades manually, while using different target values each time. What's more, I can do synchronized multi-parameter crossfades. For example, let's say I have a complex melody consisting of 3 concurrent parts, each playing at default velocity. I can crossfade their velocities to different targets and have them get there at the same time, together.
Here I can drag the commented block up and down, variables 1, 2 and 3 will crossfade synchronously. Profit, I think. |
Sorry if took me a while to get back to you, I've been trying all sorts of different Z iterations. Someone suggested something that I kindda like, and I wanted to run it by you and know what you thought. It's basically the opposite of the current rate, where instead of being a rate at which it will change toward the target, it's the modulo of the frame at which it will change, so for example:
|
No worries at all! Yes, it is the opposite, more or less exactly the complement of original Z (covering a mostly disjoint set of cases) Another table, let's call this "this", my suggestion "duration based" and assume Z is fading from a to b (variables, not values):
I think each is interesting and they cover different sets of cases, with some overlap:
In other words, "this" and original each cover cases unattainable by the other (except one), "duration" covers all of original cases and some of "this". "This" covers cases unattainable by either of the two variants (really long fades). To me, the duration variant still seems the most practical, it's more expressive and makes it easy to synchronize fades to musical grid. Well, with #248 we can have them all :) Thought not at once. |
The problem I have with the current Z is that transitioning to another value is done very fast, and in most cases I use a rate of 1 because I want to do a slow transition, even 1 is a bit fast. So the invert where it only animates on I don't want to add an extra port to Z.. I love your markdown tables btw, always help me understand what you mean. |
A duration-based Z without an extra port would be ideal (to me), I just couldn't find a simple way to do it without storing additional state somewhere, either in a port or somewhere internally (in fact I suspect it's not even possible). |
You can simply do this if you want the feature in the meantime:
|
After using the new Z design for a while, I've reverted it to the classic version since this behavior can easily be recreated with a D operator. |
I think I'm here to advocate for a breaking change.
There are three conceptual ways to implement
Z
s "rate" parameter:Currently it's (1) but I believe (3) would make more sense.
Assume we're starting with:
Z
Z
1Z1
1Z1
zZz
1Zz
1Zz
zZz
2Zf
8Zf
7Zf
zZ5
In other words, it can go as fast as current Z, as slow as current Z, and slower than current Z can. It always takes the same number of frames regardless of the target value and allows more non-integer relationships between duration and target.
Pretty sure it's possible to implement duration-based Z with the current step-based Z but only for a subset of possible cases, because of the aforementioned limitations.
@neauoire if you would consider accepting a PR, I'm happy to attempt one. As described above It's less trivial to implement then a step-based Z because it needs to store additional state, either on the grid or elsewhere.
The text was updated successfully, but these errors were encountered: