Granular synthesis on audio file with Pure data

Finding resources about how to make a proper patch for granular synthesis on PD was for me a lot harder than I expected. So I’m sharing what I’ve found and what I’ve figured out by myself in hope that others will save lots of their time when trying to approach granular synthesis with PD.

The patch of this tutorial can be found here and a video that explains what this patch does can be found here.

Goal: what we want to build, is a simple instructional patch that loads a wav file and at random times it takes a single grain (with random parameters) out of the loaded file and plays it. The controllable parameters of the patch will be the following:

  1. Grain density: how many grains per second we expect to listen.

  2. Grain starting time: position of the loaded file that the grain starts.

  3. Grain length: how long the grains will be.

  4. Playback speed: how quickly will the grain be played, affecting the pitch of the grain as well.

Additional parameters could be set, e.g. grain panning or volume, but for the sake of this tutorial we’ll stick to these four.

Basics: We consider a grain to be a (usually very short) segment of an audio file, the amplitude of which is regulated by an envelope. The playback speed of a grain can vary, along with other things that are not considered in this tutorial. Figure 1 shows an audio segment on the left, the envelope on the right an the resulting waveform that is obtained by applying the envelope the audio segment.

In Figure 1 the length of everything is fixed to 100 ms. Additionally, the audio segment does not come from a file but from an [osc~ 100] object.



Figure 1: Granular synthesis basics.

Load a file, take a segment and apply envelope.

As a first step, what we need to be able to do is:

  • Load an audio file.

  • Select a starting and an ending point on this file, according to the grain length.

  • Modify the length of the envelope so that it fits that of the segment.

– Load an audio file.

Loading a file is performed in the part of the patch illustrated in Figure 2. Please notice that the patch will need to know later on what the size of the file is ([s fileSize]), and the maximum length that we consider for grains ([s maxLength]). Additionally, notice that the starting index horizontal slider (as any other slider in the patch) are in [0, 1], making all values in the patch relative to the desired/selected file size and maximum grain length.


Figure 2: Loading an audio file to take grains from.


– Select a starting and an ending point on this file, according to the grain length.

A suitable object to do it is the [line~ ] object, that will allow us to read from any index to any index of the of audio_file, in any amount of milliseconds we desire. Figure 3 shows a part of a patch where we can select a starting index (left), length (middle), playback time (right) and play it by hitting bang on top. Notice that for setting starting index and length into the [line~ ] object we use an intermediate [f ] object for suppressing the bang while changing these value, since these bangs activate [line~ ] and cause glitches while values in this number boxes are changed. Notice also that priority of bangs is very important when we need to finally play the grain: first we have to set [line~ ] to the starting index directly, second we need to make sure that the desired time duration is indeed as a second value in the list and third set the first list value, activating the [line~ ] object and playing the file.


Figure 3: Selecting starting and ending points on the file.

 Modify the length of the envelope so that it fits that of the segment.

Figure 4 shows the integration of an envelope on the right side of the patch part of Figure 3. The envelope is the same as the one illustrated on the right side of Figure 1, but the one in Figure 4 receives a variable time length from the number box that also sets the grain duration time. Notice that priority of setting the envelope values and triggering it is also important. Specifically, first, the envelope [line~ ] is set to 0; then, time is set along with setting the time in the segment’s [line~ ] object; finally, the [line~ ] in the envelope part is instructed to go to 1 within the given time interval directly when the [line~ ] of the segment is activated (by the list that arrives from the [pack 0 0] object on the left).


Figure 4: Modifying the envelope length.

A simple patch built by a single grain and randomness

The example patch that implements the idea of granular synthesis discussed so far is illustrated in Figure 5, along with some annotations that clarify some of the patch parts that haven’t been explained above. The following should be noted:

  • There are horizontal sliders that control the starting index, grain length and speed (as well as an additional slider below the waveform of the loaded array to indicate the part of the file that the grain is taken from).

  • There is an automation part in the bottom-right part where all these parameters are controlled, plus a metro that activates the current grain (at random time intervals).

  • There is a tricky bit in the box that includes the [min ] object: there is a chance that the grain size is larger than the metro firing rate, e.g. if the grain length is 100 ms and the next grain comes in 50 ms (according to metro time), then a glitch is going to happen. To avoid such glitches, we take a grain length the minimum of the slider-selected grain length and the current metro firing rate.


Figure 5: The complete example patch and some explanatory indications.

Feel free to ask, comment or propose anything! I’m planning to make another tutorial patch on real-time granulation of microphone input using Pure Data’s circular buffer: the [delwrite~ ] object. Additionally, I’m planning to make available two heavy-duty PD patches I’m preparing, that take advantage of (too) many grains and additional controls for file-based and real-time granular synthesis. Stay tuned!


One comment

  1. Pingback: 20170731

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s