-
Notifications
You must be signed in to change notification settings - Fork 79
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
Stretch v2 #229
Stretch v2 #229
Conversation
Shall we do a new release? Yes we should!
One comment on this is that the timestretch algorithm used here doesn't really work with the workaround for issue #196. So if you're timestretching long samples, it may sound weird, but I'm not sure when it becomes noticeable since the timestretching itself is going to sound weird. |
The timestretch algorithm unfortunately does not play well with the workaround for dealing with long samples.
I'm just trying to getting this running, I think it's just the Maybe we could call that parameter |
I've got it working now, sounding nice and gnarly! It would be nice to have a version that resizes it relative to the event duration (the |
The parameter was originally called By your second comment, you mean a version that automatically stretches the sample so that it fills the event duration? |
Ah OK, maybe @telephon remembers about the name collision. We could still call the parameter And yes that's right. A bit like |
The parameter |
How should these parameters work for synths? |
Perhaps we call it For synths I guess we'd just multiply legato up using stretch and not use it otherwise? As synths are already stretchy by nature. |
yes. synths may still use the |
Oh I hadn't realised that synths could actually be timestretched with the same effect! That's strange |
yes, they could do anything with that parameter, so that when you mix synths and samples in one pattern, they have some sort of analogy to each other. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
just a few things, I think nothing complicated …
defer timescale recalculation until sustain is almost done
Clarify how the window size is chosen, and add a new parameter to make it tweakable
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you! Just some minor things …
// OK for sounds of moderate length (around 0.5 to several seconds long). | ||
// But this is also scaled below to be a bit smaller/larger based on desired playback rate. | ||
// If it's still not good, you can use the "timescalewin" parameter to multiply the window size | ||
windowSize = timescale.clip(0.1,2) * 0.05 * BufSampleRate.ir(bufnum) * timescalewin; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- you are clipping the value here, but in line 124 you are using it unclipped. Won't this lead to problems? Also in the line
if (~timescale.notNil) { sustain = sustain * ~timescale };
above, you are using the full sustain, while in the synthdef you are clipping it, while the sustain is still the same length. - Further down, there is a line:
windowIndex = phase - (phase.div(timescaleStep) - [1.0, 0.0] * timescaleStep);
Are you sure this is correct? Note that there is no operator precedence in supercollider. I'm unsure right now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
windowSize
and timescale
can be varied completely independently and the algorithm still works, but may sound odd for certain combinations. I'm really clipping on windowSize values, but a "good" windowSize tends to scale somewhat with the length of the effect. I'm not sure what you mean about the sustain.
The windowIndex
calculation is correct, but unnecessarily obscure. I added a variable to clarify it a bit (and it might save a repeated computation).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure what you mean about the sustain.
Let's say e.g. you are setting # timescale 0.09
for a sample that is 1 second long. Then your playback synth will have a total duration (=sustain) of 0.09 seconds. But your window will be (0.1 * 0.05)
. Or, when you set # timescale 3
, your synth will be 3 seconds, but the window will be (2 * 0.05)
. But also, in line 124 (timescaleStep = windowSize / timescale;
e.g. for a very large timescale, the timescalestep will be very small, but the window won't get smaller because of the clipping.
I am not sure if all that is a problem, it just looks like a source of hard to trace errors. It might be easier to reason about when you limit the stretching before everything else?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry to have left this dangling. I meant that because timescaleStep
is clipped, the overlaps will become larger when timescale < 0.1
. Could you check if that is really correct? If that is what you want, it might be good to make a comment.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll take a look! I have since noticed that a combo of frequency shift (fshift
) and speed modification works pretty well for smaller amounts of stretching.
Let me know if you want to add more polish. |
First implementation for time stretching in tidal. bgold-cosmos, Cc-authored-by: Julian Rohrhuber
Update of #149