Live Granulation:
Filter:
Tutorials (extension) | Libraries > miSCellaneous > General Tutorials | Streams-Patterns-Events

Live Granulation
ExtensionExtension

different approaches to live granulation with gui examples

Description

This file is a complement to the Buffer Granulation tutorial. It contains variants of granulation that are applied to an audio signal directly, without the explicit use of a buffer. As with buffer granulation there exist language-driven and server-driven as well as hybrid variants. Especially pattern-based live granulation raises certain accuracy issues, which are summarized in this tutorial.

WARNING:
  1. Be careful with amplitudes! To reduce feedback I've built in tanh, LPF and delay into examples with SoundIn, though better use headphones to avoid feedback at all. For tips on reducing feedback or creative use of feedback see Nathaniel Virgo's Feedback quark.
  2. Avoid too early freeing of audio buses:
    1. When there are still running synths, unintendedly sound might be routed to a processing resp. feedback chain.
    2. For the same reason don't free buses if they are hard-wired to SynthDefs, which you still want to use.

    You can free buses on occasion if you are sure that nothing is running and you won't need them again. Keep in mind that you can also (re-)start the server with a higher number of audio buses available (Ex.2c)

  3. I haven't used below setups for live performances. Although all of them work stable for me as they are, in general hangs can occasionally happen with pattern-driven setups. Often this can be tracked down to sequences of extremely short event durations (and/or long grain durations). Where this can happen as a side-effect, thresholds can be built in.

    Another possible source of hangs is careless deep nesting of Patterns where mistakes can easily occur. Starting with clear Pattern structures is recommended - and if more complications are involved: testing without sound first, after saving your patch, might be a good idea.

NOTE: With the exception of (2d) all examples use SoundIn, supposing to use input from your computer resp. soundcard. Depending on your setup you might have to change the standard input (bus = 0) passed to VarGui resp. the SoundIn ugen. Use headphones to avoid feedback!
NOTE: All live granulation variants of this file can of course be applied to any signal, thus also to any playback of a buffer. Vice versa all variants from Buffer Granulation can be applied to a buffer, which is occasionally (or continuously) filled with live input.

 

1. Live granulation scheduled by server

Ex. 1a: Basic live granulation with GrainIn

Even with overlapping grains, sequenced effect processing per grain is possible with GrainIn, but requires more effort, see Buffer Granulation: Ex.1e in the Buffer Granulation tutorial.

 

Ex. 1b: Live granulation with server-driven enveloping

In this example only non-overlapping grains are regarded, for overlapping, as with GrainIn, a multichannel approach as in Ex.1e in the Buffer Granulation tutorial can be applied. In comparison to live granulation example 1a there is hardly an advantage in this basic variant. However intermediate processings can be built into this SynthDef, which aren't possible in the above example, where granulation is encapsulated in a ugen, manipulation of the envelope signal could be one.

 

2. Live granulation driven by language

The crucial point of this strategy is a kind of incompatibility of In.ar and OffsetOut. Normally we use OffsetOut for exact buffer granulation with patterns, as the start of the synth (the grain) is corrected by a shift (standard Out.ar is only able to start at control block boundaries). However, when In.ar and OffsetOut.ar are used in the same synth the read input signal is also shifted, which results in a correct grain distance but an fluctuating input delay. This can be overcome by a little trick: we can use OffsetOut to send a trigger to a bus, which indicates its correct delay. Then the trigger can be read in the same synth and trigger again a gated envelope for the input signal, the resulting grain can be output with normal Out.ar. So grain distances are correct and input is not fluctuating (see Ex.2d for an accuracy comparison). Nevertheless language-driven sequencing is not sample-exact in realtime, no matter if In.ar is used or not, this is related to hardware control and cannot be overcome. This might be an issue with a strictly periodic input signal and very short grain distances. You can e.g. check out with granulation of a fixed-pitch triangular wave or similar, every few seconds or so there will happen an audible jump due to an irregular time interval, which is necessary for clock calibration; at that point there will, in general, also be a phase shift of the input signal (see last example of Ex.2d). This might not be noticed with an input of spoken voice e.g. Control block length is also a boundary for gated envelopes defined with EnvGen – here envelopes are established with an env buffer used by BufRd and Sweep ugens, a flexible method as Envelopes shape can be defined arbitrarily in language.

 

Ex. 2a: Basic Pbind live granulation

At that point I haven't seen a solution to pass the trigger bus as argument, in the example it is hard-wired. As the SynthDef uses a SetResetFF ugen, which relies on two triggers within control block length, grainDelta shouldn't be shorter than that. If shorter grainDeltas are required this would be possible with alternating SynthDefs and buses. For the same reason this SynthDef should only be used once at the same time by a Pbind/EventStreamPlayer. Alternatively – as in Ex.2b – a SynthDef factory can produce a number of structurally equal SynthDefs bound to a number of buses.

 

Ex. 2b: Parallel Pbind live granulation

As trigger buses have to be hard-wired, a SynthDef factory produces a number of structurally equal SynthDefs bound to a number of buses. In this variant the granulation is combined with a bandpass filter.

 

Ex. 2c: Live granulation with PbindFx

 

Ex. 2d: Accuracy comparison

This example compares the inaccuracies occuring with "normal" usage of Out.ar and the usage of In.ar + OffsetOut.ar with the strategy recommended in Ex.2a. Run the three examples, the audio output is played and recorded into three files in the recordings directory (you get the path with thisProcess.platform.recordingsDir).