Namespaces

Variants
Actions

MSP Polyphony Tutorial 3: Granular Synthesis

From Cycling '74 Wiki
(Difference between revisions)
Jump to: navigation, search
(Created page with "Click here to open the tutorial patch: 03hGranularSynthesis.maxpat ===Granular synthesis=== In this tutorial we'll look at using the {{maxword|name=poly~}} object to gen...")
 
Line 3: Line 3:
 
===Granular synthesis===
 
===Granular synthesis===
  
In this tutorial we'll look at using the {{maxword|name=poly~}} object
+
In this tutorial we'll look at using the {{maxword|name=poly~}} object to generate large amounts of polyphony in order the play the contents of one {{maxword|name=buffer~}} of sample data. We'll leverage the ability of MSP to play sample data from the same {{maxword|name=buffer~}} at multiple arbitrary speeds and time points to explore the technique of ''granular synthesis''
to generate large amounts of polyphony in order the play the
+
contents of one {{maxword|name=buffer~}} of sample data. We'll
+
leverage the ability of MSP to play sample data from the
+
same {{maxword|name=buffer~}} at multiple arbitrary speeds and time
+
points to explore the technique of ''granular synthesis''
+
  
Put simply, granular synthesis is the use of very short
+
Put simply, granular synthesis is the use of very short (or, sometimes, less short) sonic events called 'grains' to generate complex textures. While the musical and written literature on the technique is beyond the scope of this tutorial (see Curtis Roads' ''Microsound'' (MIT Press: 2004) for a great exploration of this topic), we'll cover the basics here. While classic granular synthesis relies on the use of very small amounts of wavetable data, the technique we'll explore in this tutorial uses sample data taken arbitrarily from soundfiles.
(or, sometimes, less short) sonic events called 'grains'
+
to generate complex textures. While the musical and written
+
literature on the technique is beyond the scope of this
+
tutorial (see Curtis Roads' ''Microsound'' (MIT Press: 2004)
+
for a great exploration of this topic), we'll cover the basics
+
here. While classic granular synthesis relies on the use of
+
very small amounts of wavetable data, the technique we'll
+
explore in this tutorial uses sample data taken arbitrarily
+
from soundfiles.
+
  
In our tutorial patcher, we'll create an algorithmic playback
+
In our tutorial patcher, we'll create an algorithmic playback system based on constrained random values to control the following parameters of a polyphonic sample playback engine: rate, onset point, duration, pitch, amplitude. We'll also look at how adjusting envelopes changes the sonic output.
system based on constrained random values to control the
+
following parameters of a polyphonic sample playback engine:
+
rate, onset point, duration, pitch, amplitude. We'll also
+
look at how adjusting envelopes changes the sonic output.
+
  
 
===Experimenting with the patcher===
 
===Experimenting with the patcher===
  
Take a look at the tutorial patcher. There are several numbered
+
Take a look at the tutorial patcher. There are several numbered areas, each of which controls part of our granular synthesis engine. The patcher area labeled <code>1</code> is the ''grain emitter'' proper: a {{maxword|name=metro}} object schedules and fires <code>bang</code> messages into a {{maxword|name=poly~}} object that has loaded 100 voices of an abstraction named <code>polygrain~</code>. Area <code>2</code> allows us to check our CPU usage depending on the parameters of our synthesizer. Area <code>3</code> and <code>4</code> set the synthesis parameters - the sample we're using, which area of it to draw from for grains, and the parameters of the grain playback system in the <code>polygrain~</code> abstraction.
areas, each of which controls part of our granular synthesis
+
engine. The patcher area labeled <code>1</code> is the ''grain emitter''
+
proper: a {{maxword|name=metro}} object schedules and fires <code>bang</code> messages
+
into a {{maxword|name=poly~}} object that has loaded 100 voices of an
+
abstraction named <code>polygrain~</code>. Area <code>2</code> allows us to
+
check our CPU usage depending on the parameters of our synthesizer.
+
Area <code>3</code> and <code>4</code> set the synthesis parameters - the
+
sample we're using, which area of it to draw from for grains,
+
and the parameters of the grain playback system in
+
the <code>polygrain~</code> abstraction.
+
  
* In patcher area <code>1</code>, turn on the audio with the {{maxword|name=toggle}} object
+
* In patcher area <code>1</code>, turn on the audio with the {{maxword|name=toggle}} object connected to the {{maxword|name=dac~}}. Turn up either one of the {{maxword|name=gain~}} sliders; the other should follow along. At the top of the patcher, click the {{maxword|name=button}} object a few times and listen to the results. Sending a <code>bang</code> into the {{maxword|name=poly~}} object generates a single 'grain' of audio. Turn on the {{maxword|name=metro}} object by clicking the {{maxword|name=toggle}} at the top of the patcher. The {{maxword|name=poly~}} object in our patcher generates grains: single bursts of sample playback which we can control dynamically by adjusting parameters. The {{maxword|name=metro}} and {{maxword|name=button}} objects control the grain emitter. Each time the {{maxword|name=metro}} fires, it sends a <code>bang</code> into the {{maxword|name=poly~}}, prepended by the <code>note</code> message, which assigns the <code>bang</code> to the first available voice within the {{maxword|name=poly~}}. In addition, each <code>bang</code> from the {{maxword|name=metro}} object schedules the next one by adjusting the speed of the {{maxword|name=metro}}. The {{maxword|name=random}} object generates a random value which is then put through a {{maxword|name=scale}} object with a variable output range, defined by the <code>speedmin</code> and <code>speedmax</code> parameters found in patcher area <code>4</code>.
connected to the {{maxword|name=dac~}}. Turn up either one of
+
the {{maxword|name=gain~}} sliders; the other should follow along.
+
At the top of the patcher, click the {{maxword|name=button}} object a few
+
times and listen to the results. Sending a <code>bang</code> into
+
the {{maxword|name=poly~}} object generates a single 'grain' of audio.
+
Turn on the {{maxword|name=metro}} object by clicking the {{maxword|name=toggle}} at
+
the top of the patcher.
+
The {{maxword|name=poly~}} object in our patcher generates grains: single
+
bursts of sample playback which we can control dynamically by
+
adjusting parameters. The {{maxword|name=metro}} and {{maxword|name=button}} objects
+
control the grain emitter. Each time the {{maxword|name=metro}} fires,
+
it sends a <code>bang</code> into the {{maxword|name=poly~}}, prepended by
+
the <code>note</code> message, which assigns the <code>bang</code> to the
+
first available voice within the {{maxword|name=poly~}}. In addition,
+
each <code>bang</code> from the {{maxword|name=metro}} object schedules the
+
next one by adjusting the speed of the {{maxword|name=metro}}.
+
The {{maxword|name=random}} object generates a random value which is
+
then put through a {{maxword|name=scale}} object with a variable output
+
range, defined by the <code>speedmin</code> and <code>speedmax</code> parameters
+
found in patcher area <code>4</code>.
+
  
 
===Checking CPU===
 
===Checking CPU===
  
* With the grain emitter enabled (i.e. the {{maxword|name=metro}} object set
+
* With the grain emitter enabled (i.e. the {{maxword|name=metro}} object set to run), turn on the {{maxword|name=metro}} in patcher area <code>2</code>. The {{maxword|name=number}} box at the bottom of the patcher logic should output a number. Turn off the grain emitter at the top and watch the results. Turn it on again. The {{maxword|name=adstatus}} object allows us to control and view aspects of the MSP audio driver currently running. All of the viewable attributes of the ''Audio Status'' window (available under the Max '''Options''' menu) can be accessed via the {{maxword|name=adstatus}} object. The <code>cpu</code> mode of the {{maxword|name=adstatus}} object (set by its argument) instructs the object to receive <code>bang</code> messages and output the current CPU usage of MSP. Notice that when the grain emitter is turned off, the CPU usage drops to <code>0.</code>. This is because our {{maxword|name=poly~}} abstraction mutes itself when its playback has finished. When no notes are firing, all of the copies of the {{maxword|name=poly~}} abstraction should be muted.
to run), turn on the {{maxword|name=metro}} in patcher area <code>2</code>.
+
The {{maxword|name=number}} box at the bottom of the patcher logic should
+
output a number. Turn off the grain emitter at the top and watch
+
the results. Turn it on again.
+
The {{maxword|name=adstatus}} object allows us to control and view aspects
+
of the MSP audio driver currently running. All of the viewable
+
attributes of the ''Audio Status'' window (available under the
+
Max '''Options''' menu) can be accessed via the {{maxword|name=adstatus}} object.
+
The <code>cpu</code> mode of the {{maxword|name=adstatus}} object (set by its argument)
+
instructs the object to receive <code>bang</code> messages and output
+
the current CPU usage of MSP. Notice that when the grain emitter
+
is turned off, the CPU usage drops to <code>0.</code>. This is because
+
our {{maxword|name=poly~}} abstraction mutes itself when its playback has
+
finished. When no notes are firing, all of the copies of
+
the {{maxword|name=poly~}} abstraction should be muted.
+
  
 
===Adjusting parameters===
 
===Adjusting parameters===
  
* In patcher area <code>3</code>, highlight an area of the {{maxword|name=waveform~}} objects
+
* In patcher area <code>3</code>, highlight an area of the {{maxword|name=waveform~}} objects to select part of the {{maxword|name=buffer~}} named <code>thegrain</code>. Notice that when you drag on either of the {{maxword|name=waveform~}} objects, both of them highlight in the same regions. The rightmost outlet of the {{maxword|name=waveform~}} object allows us to ''link'' them together so that you can use more than one of the objects to work with a multi-channel {{maxword|name=buffer~}}. Load a different sample using the {{maxword|name=message}} boxes above the {{maxword|name=buffer~}} object and highlight different regions of the sample. The highlighted regions of the {{maxword|name=buffer~}} controls where the grain emitter draws its sample data. * In patcher area <code>4</code>, use the {{maxword|name=preset}} object to try out different parameters for our grain emitter, then try entering your own values. The ''Grain rate'' {{maxword|name=number}} boxes control the speed range of the {{maxword|name=metro}} in patcher area <code>1</code>. The ''Grain duration'' controls the ranges for how long each grain plays for inside the {{maxword|name=poly~}}. The ''Grain pitch'' values provide a range for what speed the grains play at. The ''Grain amplitude'' controls set the volume range of the grain emitter, and the ''Grain slope'' sets the sharpness of the attack and decay on each grain's envelope. Notice how different densities of grains changes the sound as well as the CPU usage of the grains. Before we look at our {{maxword|name=poly~}} abstraction, notice the effect of longer and shorter grain rates and durations on the CPU usage. Longer grain durations and shorter grain rates result in more voices inside the {{maxword|name=poly~}} being active at any one time - either they are fired more frequently, or they take longer to 'free' themselves, or both. The result is a higher CPU usage.
to select part of the {{maxword|name=buffer~}} named <code>thegrain</code>.
+
Notice that when you drag on either of the {{maxword|name=waveform~}} objects,
+
both of them highlight in the same regions. The rightmost outlet
+
of the {{maxword|name=waveform~}} object allows us to ''link'' them
+
together so that you can use more than one of the objects to work
+
with a multi-channel {{maxword|name=buffer~}}. Load a different sample using
+
the {{maxword|name=message}} boxes above the {{maxword|name=buffer~}} object and
+
highlight different regions of the sample. The highlighted regions
+
of the {{maxword|name=buffer~}} controls where the grain emitter draws its
+
sample data.
+
* In patcher area <code>4</code>, use the {{maxword|name=preset}} object to try out
+
different parameters for our grain emitter, then try entering your
+
own values. The ''Grain rate'' {{maxword|name=number}} boxes control the
+
speed range of the {{maxword|name=metro}} in patcher area <code>1</code>.
+
The ''Grain duration'' controls the ranges for how long each
+
grain plays for inside the {{maxword|name=poly~}}. The ''Grain pitch''
+
values provide a range for what speed the grains play at.
+
The ''Grain amplitude'' controls set the volume range of the
+
grain emitter, and the ''Grain slope'' sets the sharpness of
+
the attack and decay on each grain's envelope. Notice how different
+
densities of grains changes the sound as well as the CPU usage of
+
the grains.
+
Before we look at our {{maxword|name=poly~}} abstraction, notice the
+
effect of longer and shorter grain rates and durations on the
+
CPU usage. Longer grain durations and shorter grain rates result
+
in more voices inside the {{maxword|name=poly~}} being active at any
+
one time - either they are fired more frequently, or they
+
take longer to 'free' themselves, or both. The result is a
+
higher CPU usage.
+
  
* In patcher area <code>1</code>, enable the {{maxword|name=toggle}} object
+
* In patcher area <code>1</code>, enable the {{maxword|name=toggle}} object attached to the {{maxword|name=message}} box labeled <code>parallel $1</code>. Restart the audio by turning on and off the {{maxword|name=dac~}}. Notice the effect, if any, on the CPU. Depending on your computer architecture, you can take advantage of multiple cores in your computer's CPU (or multiple processors if you have a multi-processor machine) by dividing the {{maxword|name=poly~}} object's resources over multiple ''threads''. In essence, this divides the instances of the {{maxword|name=poly~}} object across the different cores or processors of your computer, allowing sets of voices to run in parallel. Depending on your computer's CPU architecture, this may provide a significant boost in performance.
attached to the {{maxword|name=message}} box labeled <code>parallel $1</code>.
+
Restart the audio by turning on and off the {{maxword|name=dac~}}. Notice
+
the effect, if any, on the CPU.
+
Depending on your computer architecture, you can take advantage
+
of multiple cores in your computer's CPU (or multiple processors
+
if you have a multi-processor machine) by dividing the {{maxword|name=poly~}} object's
+
resources over multiple ''threads''. In essence, this divides
+
the instances of the {{maxword|name=poly~}} object across the different
+
cores or processors of your computer, allowing sets of voices
+
to run in parallel. Depending on your computer's CPU architecture,
+
this may provide a significant boost in performance.
+
  
 
===Inside the patch===
 
===Inside the patch===
  
* Double-click the {{maxword|name=poly~}} object to view an instance of the
+
* Double-click the {{maxword|name=poly~}} object to view an instance of the abstraction named <code>polygrain~</code>. Take a look around the patcher. The <code>polygrain~</code> abstraction recieves a single <code>bang</code> (via the {{maxword|name=in}} object at the top of the patcher) and uses it to generate a grain of audio, using the MSP logic at the bottom of the abstraction. The {{maxword|name=trigger}} object at the top of the patch clearly sets up the order of events for generating our grain:
abstraction named <code>polygrain~</code>. Take a look around the patcher.
+
The <code>polygrain~</code> abstraction recieves a single <code>bang</code>
+
(via the {{maxword|name=in}} object at the top of the patcher) and uses it
+
to generate a grain of audio, using the MSP logic at the bottom
+
of the abstraction. The {{maxword|name=trigger}} object at the top of the
+
patch clearly sets up the order of events for generating our grain:
+
  
First, the {{maxword|name=thispoly~}} object receives a <code>mute 0</code>
+
First, the {{maxword|name=thispoly~}} object receives a <code>mute 0</code> and <code>1</code> message in immediate succession. This turns ''on'' (unmutes) the signal processing in the instance, and sets it's state to 'busy', so that it won't receive any more messages until the grain is finished.
and <code>1</code> message in immediate succession. This turns ''on'' (unmutes)
+
the signal processing in the instance, and sets it's state to 'busy',
+
so that it won't receive any more messages until the grain is finished.
+
  
Next, a <code>bang</code> is dispatched to generate a random ''amplitude''
+
Next, a <code>bang</code> is dispatched to generate a random ''amplitude'' for the grain, which goes into the right side of the {{maxword|name=*~}} object labeled 'how loud is this grain?'. This {{maxword|name=*~}} controls the scaling for the output of the {{maxword|name=line~}} object above that sets the grain envelope.
for the grain, which goes into the right side of the {{maxword|name=*~}} object
+
labeled 'how loud is this grain?'. This {{maxword|name=*~}} controls the
+
scaling for the output of the {{maxword|name=line~}} object above that sets
+
the grain envelope.
+
  
Third, a random ''pitch'' is selected which is transformed into
+
Third, a random ''pitch'' is selected which is transformed into a duration multiplier for the {{maxword|name=line~}} objects controlling the playback of the sample and its amplitude envelope. The {{maxword|name=!/}} object divides the incoming pitch into <code>1.</code>, so that a requested pitch of <code>2.</code> tells the objects downstream to multiply their durations by <code>0.5</code> (half as long, and up an octave).
a duration multiplier for the {{maxword|name=line~}} objects controlling
+
the playback of the sample and its amplitude envelope. The {{maxword|name=!/}} object
+
divides the incoming pitch into <code>1.</code>, so that a requested
+
pitch of <code>2.</code> tells the objects downstream to multiply their
+
durations by <code>0.5</code> (half as long, and up an octave).
+
  
Fourth, a random ''duration'' is generated, which sets up the
+
Fourth, a random ''duration'' is generated, which sets up the parameters for the {{maxword|name=line~}} objects so that they generate the appropriately scaled and offset values for the grain length.
parameters for the {{maxword|name=line~}} objects so that they generate
+
the appropriately scaled and offset values for the grain length.
+
  
Finally, a grain is triggered by generating a random ''start point''
+
Finally, a grain is triggered by generating a random ''start point'' based on the highlighted areas in the {{maxword|name=waveform~}} object in the main patcher. This <code>bang</code> eventually generates two messages which command the two {{maxword|name=line~}} objects to generate the playback curve for the {{maxword|name=play~}} object and the amplitude envelope for the {{maxword|name=*~}} objects.
based on the highlighted areas in the {{maxword|name=waveform~}} object in the
+
main patcher. This <code>bang</code> eventually generates two messages
+
which command the two {{maxword|name=line~}} objects to generate the playback
+
curve for the {{maxword|name=play~}} object and the amplitude envelope for
+
the {{maxword|name=*~}} objects.
+
  
Once the 'envelope' {{maxword|name=line~}} is finished, it sends a <code>bang</code>
+
Once the 'envelope' {{maxword|name=line~}} is finished, it sends a <code>bang</code> to <code>mute</code> the instance and set it to 'free' (<code>0</code>), so it can receive a new message.
to <code>mute</code> the instance and set it to 'free' (<code>0</code>), so it
+
can receive a new message.
+
  
* Under the '''File''' menu in Max, select ''Modify Read Only''.
+
* Under the '''File''' menu in Max, select ''Modify Read Only''. This will allow you to unlock the copy of the <code>simplegrain~</code> abstraction you are viewing. Unlock the patcher, and place 'watchpoints' on some of the patchcords to monitor their values. In the ''Watchpoints'' window, you should see how different values in the grain settings in the main patcher translate into values for the synthesis algorithm at work here.
This will allow you to unlock the copy of the <code>simplegrain~</code> abstraction
+
you are viewing. Unlock the patcher, and place 'watchpoints' on some
+
of the patchcords to monitor their values. In the ''Watchpoints''
+
window, you should see how different values in the grain settings
+
in the main patcher translate into values for the synthesis algorithm
+
at work here.
+
  
 
===Summary===
 
===Summary===
  
The {{maxword|name=poly~}} object allows you to have a large number of instances
+
The {{maxword|name=poly~}} object allows you to have a large number of instances of a single, simple MSP patcher. You can use {{maxword|name=send}} and {{maxword|name=receive}} to communicate to all instances of a {{maxword|name=poly~}} abstraction, which can be distributed across multiple cores or processors with the <code>parallel</code> message. The {{maxword|name=adstatus}} object allows you to access and change aspects of the MSP audio driver; the <code>cpu</code> argument to the object lets you see how much of your computer's CPU you are using with a patcher.
of a single, simple MSP patcher. You can use {{maxword|name=send}}
+
and {{maxword|name=receive}} to communicate to all instances of a {{maxword|name=poly~}}
+
abstraction, which can be distributed across multiple cores or
+
processors with the <code>parallel</code> message.
+
The {{maxword|name=adstatus}} object allows you to access and change
+
aspects of the MSP audio driver; the <code>cpu</code> argument to the
+
object lets you see how much of your computer's CPU you are using
+
with a patcher.
+
  
 
===See Also===
 
===See Also===

Revision as of 20:04, 25 June 2012

Click here to open the tutorial patch: 03hGranularSynthesis.maxpat

Contents

Granular synthesis

In this tutorial we'll look at using the poly~ object to generate large amounts of polyphony in order the play the contents of one buffer~ of sample data. We'll leverage the ability of MSP to play sample data from the same buffer~ at multiple arbitrary speeds and time points to explore the technique of granular synthesis

Put simply, granular synthesis is the use of very short (or, sometimes, less short) sonic events called 'grains' to generate complex textures. While the musical and written literature on the technique is beyond the scope of this tutorial (see Curtis Roads' Microsound (MIT Press: 2004) for a great exploration of this topic), we'll cover the basics here. While classic granular synthesis relies on the use of very small amounts of wavetable data, the technique we'll explore in this tutorial uses sample data taken arbitrarily from soundfiles.

In our tutorial patcher, we'll create an algorithmic playback system based on constrained random values to control the following parameters of a polyphonic sample playback engine: rate, onset point, duration, pitch, amplitude. We'll also look at how adjusting envelopes changes the sonic output.

Experimenting with the patcher

Take a look at the tutorial patcher. There are several numbered areas, each of which controls part of our granular synthesis engine. The patcher area labeled 1 is the grain emitter proper: a metro object schedules and fires bang messages into a poly~ object that has loaded 100 voices of an abstraction named polygrain~. Area 2 allows us to check our CPU usage depending on the parameters of our synthesizer. Area 3 and 4 set the synthesis parameters - the sample we're using, which area of it to draw from for grains, and the parameters of the grain playback system in the polygrain~ abstraction.

  • In patcher area 1, turn on the audio with the toggle object connected to the dac~. Turn up either one of the gain~ sliders; the other should follow along. At the top of the patcher, click the button object a few times and listen to the results. Sending a bang into the poly~ object generates a single 'grain' of audio. Turn on the metro object by clicking the toggle at the top of the patcher. The poly~ object in our patcher generates grains: single bursts of sample playback which we can control dynamically by adjusting parameters. The metro and button objects control the grain emitter. Each time the metro fires, it sends a bang into the poly~, prepended by the note message, which assigns the bang to the first available voice within the poly~. In addition, each bang from the metro object schedules the next one by adjusting the speed of the metro. The random object generates a random value which is then put through a scale object with a variable output range, defined by the speedmin and speedmax parameters found in patcher area 4.

Checking CPU

  • With the grain emitter enabled (i.e. the metro object set to run), turn on the metro in patcher area 2. The number box at the bottom of the patcher logic should output a number. Turn off the grain emitter at the top and watch the results. Turn it on again. The adstatus object allows us to control and view aspects of the MSP audio driver currently running. All of the viewable attributes of the Audio Status window (available under the Max Options menu) can be accessed via the adstatus object. The cpu mode of the adstatus object (set by its argument) instructs the object to receive bang messages and output the current CPU usage of MSP. Notice that when the grain emitter is turned off, the CPU usage drops to 0.. This is because our poly~ abstraction mutes itself when its playback has finished. When no notes are firing, all of the copies of the poly~ abstraction should be muted.

Adjusting parameters

  • In patcher area 3, highlight an area of the waveform~ objects to select part of the buffer~ named thegrain. Notice that when you drag on either of the waveform~ objects, both of them highlight in the same regions. The rightmost outlet of the waveform~ object allows us to link them together so that you can use more than one of the objects to work with a multi-channel buffer~. Load a different sample using the message boxes above the buffer~ object and highlight different regions of the sample. The highlighted regions of the buffer~ controls where the grain emitter draws its sample data. * In patcher area 4, use the preset object to try out different parameters for our grain emitter, then try entering your own values. The Grain rate number boxes control the speed range of the metro in patcher area 1. The Grain duration controls the ranges for how long each grain plays for inside the poly~. The Grain pitch values provide a range for what speed the grains play at. The Grain amplitude controls set the volume range of the grain emitter, and the Grain slope sets the sharpness of the attack and decay on each grain's envelope. Notice how different densities of grains changes the sound as well as the CPU usage of the grains. Before we look at our poly~ abstraction, notice the effect of longer and shorter grain rates and durations on the CPU usage. Longer grain durations and shorter grain rates result in more voices inside the poly~ being active at any one time - either they are fired more frequently, or they take longer to 'free' themselves, or both. The result is a higher CPU usage.
  • In patcher area 1, enable the toggle object attached to the message box labeled parallel $1. Restart the audio by turning on and off the dac~. Notice the effect, if any, on the CPU. Depending on your computer architecture, you can take advantage of multiple cores in your computer's CPU (or multiple processors if you have a multi-processor machine) by dividing the poly~ object's resources over multiple threads. In essence, this divides the instances of the poly~ object across the different cores or processors of your computer, allowing sets of voices to run in parallel. Depending on your computer's CPU architecture, this may provide a significant boost in performance.

Inside the patch

  • Double-click the poly~ object to view an instance of the abstraction named polygrain~. Take a look around the patcher. The polygrain~ abstraction recieves a single bang (via the in object at the top of the patcher) and uses it to generate a grain of audio, using the MSP logic at the bottom of the abstraction. The trigger object at the top of the patch clearly sets up the order of events for generating our grain:

First, the thispoly~ object receives a mute 0 and 1 message in immediate succession. This turns on (unmutes) the signal processing in the instance, and sets it's state to 'busy', so that it won't receive any more messages until the grain is finished.

Next, a bang is dispatched to generate a random amplitude for the grain, which goes into the right side of the *~ object labeled 'how loud is this grain?'. This *~ controls the scaling for the output of the line~ object above that sets the grain envelope.

Third, a random pitch is selected which is transformed into a duration multiplier for the line~ objects controlling the playback of the sample and its amplitude envelope. The !/ object divides the incoming pitch into 1., so that a requested pitch of 2. tells the objects downstream to multiply their durations by 0.5 (half as long, and up an octave).

Fourth, a random duration is generated, which sets up the parameters for the line~ objects so that they generate the appropriately scaled and offset values for the grain length.

Finally, a grain is triggered by generating a random start point based on the highlighted areas in the waveform~ object in the main patcher. This bang eventually generates two messages which command the two line~ objects to generate the playback curve for the play~ object and the amplitude envelope for the *~ objects.

Once the 'envelope' line~ is finished, it sends a bang to mute the instance and set it to 'free' (0), so it can receive a new message.

  • Under the File menu in Max, select Modify Read Only. This will allow you to unlock the copy of the simplegrain~ abstraction you are viewing. Unlock the patcher, and place 'watchpoints' on some of the patchcords to monitor their values. In the Watchpoints window, you should see how different values in the grain settings in the main patcher translate into values for the synthesis algorithm at work here.

Summary

The poly~ object allows you to have a large number of instances of a single, simple MSP patcher. You can use send and receive to communicate to all instances of a poly~ abstraction, which can be distributed across multiple cores or processors with the parallel message. The adstatus object allows you to access and change aspects of the MSP audio driver; the cpu argument to the object lets you see how much of your computer's CPU you are using with a patcher.

See Also

adstatus - Report and control audio driver settings