Is there a way to smooth the result from chop?

I was just wondering if there is a way in TidalCycles to smooth the result of i.e. chop.
For example, when I execute the following code, I get a stutter effect:

d1 $ slow 12 $ chop 256 $ s "bev"

This is completely normal for granular synthesis without smoothing and therefore not surprising. For this reason, you can normally crossfade between the individual grains.

Does TidalCycles currently offer a way to represent such behavior? Or is something like that possibly too computationally intensive?

3 Likes

There is striateBy which allows you to specify the duration of each grain:

d1 $ slow 12 $ striateBy 256 (1/128) $ s "bev"

There isn't chopBy unfortunately, but there probably should be! Where there's just one sound per cycle, striate and chop behave the same.

I'm not sure if there's something on the superdirt side that could help with this. I guess it's a bit tricky as if I understand you right, you want to start each sound a bit earlier and end it a bit later to make that crossfade possible and stretch the sound out over a longer period. I think due to the way things are scheduled, that would be hard to do on the synthesiser side of things.

All striate and chop are really doing is duplicating events and manipulating begin and end. So you can do this sort of thing:

d1 $ (slow 16 $ chop 256 $ s "bev")
  |- begin "0.005"
  |+ end "0.005"

That plays an extra 1/200th of the sample at the beginning and end of each grain (parens are added to make sure this happens after the chopping).

One thing I'm trying to get my head around is superdirt's tilt parameter. This isn't currently set by Tidal so you have to do this to get access to it:

tilt = pF "tilt"

This then makes it sound smoother:

d1 $ (slow 16 $ chop 256 $ s "bev")
  |- begin "0.005"
  |+ end "0.005"
  # tilt 0.5

This is surprising, as looking at the superdirt code, 0.5 should be the default. @julian maybe you have a thought about this?

5 Likes

Nice!!!!

Wow that's pretty awesome! The tilt parameter gives the twist. Besides the sound design with the granular synthesis I am also interested in the re-synthesis.

My intention is (for example) to change the pitch of samples (even long samples) without changing the length of the sample.
Thanks to your code examples this is indeed feasible and sounds pretty good (in terms of research):

d1 $ trigger 1 $ (slow 8 $ chop 128 $ s "bev")
  |- begin "0.005"
  |+ end "0.005"
  # tilt 0.5 # speed "<0.7 0.8 0.9 1 1.1 1.2 1.3 1.4>" 

Time stretching without pitch change is also possible. I will definitely play around with it and think that a chopBy would be pretty cool.

1 Like

And maybe this functionality can be extended. Two cases can occur during re-synthesis:

  1. the grains become shorter, gaps appear between them.
  2. the grains become longer, they overlap

This is a good example of that:

d1 $ trigger 1 $ (slow 12 $ chop 128 $ s "bev")
  |- begin "0.002"
  |+ end "0.002"
  # tilt 0.5

I think it is possible to implement an automatism on the SuperDirt side for this. Probably there is already a solution for this in SuperCollider. I would have to look at this.

The general solutions are

  1. for short grains with gaps: the gaps between the grains are filled by multiplying the grains.
  2. for longer grain which overlaps: the resulting overlaps are compensated for by fading and shortening the grains

Both can be currently be realized manually with begin and end. However, the parameters might have to be determined by trial and error, which could be tricky live. For now, these are only fixed thoughts on this topic.

There is already a superdirt issue about timestretching:
https://github.com/musikinformatik/SuperDirt/issues/146

@bgold has a nice looking PR open: https://github.com/musikinformatik/SuperDirt/pull/149

1 Like

I'm not sure if there's something on the superdirt side that could help with this. I guess it's a bit tricky as if I understand you right, you want to start each sound a bit earlier and end it a bit later to make that crossfade possible and stretch the sound out over a longer period. I think due to the way things are scheduled, that would be hard to do on the synthesiser side of things.

I don't see the problem with superdirt – you can schedule as many grains in parallel as you like. Could you explain where you see the main issue?

This is surprising, as looking at the superdirt code, 0.5 should be the default. @julian maybe you have a thought about this?

adding a tilt parameter will add an envelope over each grain. So even when tilt has the default value, setting it will change the sound.

Adding such an envelope is something you want for some purposes, probably not ofr others.

With regard to time stretching etc. I still think that the best way would be to integrate wavests synthesis, which would mean analysing the soundfiles for zero crossings and making those available as parameters to tidal. Not terribly hard, but something extra for maintenance.

1 Like

E.g. lets say tidal chops a sound into three parts over a cycle. The cycle is longer than the sound so there are gaps. You can fix this on the tidal side by scheduling the second slice to start sounding earlier, playing from an earlier point in the sound file, and continuing for longer so that the gaps are filled in. I'm saying it wouldn't really work to let superdirt take care of this calculation.. Because scheduling happens first, by which time it's too late to go back in time to start playing earlier.

This seems like a minor technical issue to solve (or maybe not, as it is solvable on the Tidal side) but I think is related to more interesting general issues about cue points - we're always setting sounds in time relative to the first sample of an audio file or onset of synth attack which doesn't always make sense.

Ok, I see. Yes, I also think this is better solved on the tidal side. For this, tidal will need to get information sent from superdirt about the durations of the samples.