aboutsummaryrefslogtreecommitdiff
path: root/doc/tutorials/footils/pddrums/pddrums.txt
blob: c4ccb39e4367ac3b1e403f3eabad59d8bee4e4bd (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
====================
Building Drums in PD
====================

:Autor: Frank Barknecht
:Contact: fbar@footils.org

:Abstract: 
	This quicktoot describes how PD can be used to build a simple drum 
	synthesizer with graphical controls and a step sequencer. 


.. contents:: 


Small is beautiful
------------------

Pure Data - or short PD - is a multimedia software environment written 
by Miller Puckette and others that can be used to make art in several 
media like music, sound or graphics. In this quicktoot we will use the 
sound generating capabilities of PD to build a module for drum sounds. 
Our drum synthesizer will use a synthesis algorithm that's very 
similar to the early analog or digital drumsynths of the eighties. We 
will not use pre-recorded samples but instead employ simple sound 
generators. You will be surprised, how effective this is and how much 
variety is possible with just two or three sound sources. On the other 
hand our design leaves room for improvment. By the end of this article 
you will be able to add these on your own. Our drummer includes a 
preset database: When you have found a sound, that you like, you can 
save it and recall it again later. 

I will not go into much detail on how to install or how to use PD: You 
should read the documentation that comes with PD for that. I will of 
course explain the more advanced features of PD used and everything 
that is needed to follow this tutorial. 

The Creator 
------------------

Creating something in PD is very much like the genesis of a world as described
in, well, the Bible's first book "Genesis".  In the beginning you have nothing,
just a large white area. You, the Creator, can create objects by a simple
button press "Ctrl-1", which actually means "Let there be an object". And there
was an object. But your first object is a small empty rectangle and it can do
nothing, it has no way of communicating, it isn't alive yet. To create a living
object you have to give it a name, you have to call it by typing the name onto
the object, for example "noise~". And there was noise. With time you can
populate the area with more objects, you can let them talk to each other, you
can create more worlds, and you will create by giving all of them names. We
maybe come to ``[moses]`` later. Our drumsynth will have the name "angriff",
which is german for "attack". So our goal is, that someone can create a
drumsynth by typing the name "angriff" on a new object.

This is achieved in PD by a so called "abstraction". An abstraction is 
simply a saved PD patch. So our very first and basically unusable 
version of angriff is this: A nearly empty patch with a noise~ object 
inside, saved under the name "angriff-01.pd".

.. figure:: angriff-01.png

   angriff-01.pd_, an unusable first version.

.. _angriff-01.pd: angriff-01.pd

Even this can be used as an object. Just create a new, empty patch 
(with "Ctrl-n"), put an object in it and call it "angriff-01", i.e. the 
name of our first drum patch without the .pd-suffix.

.. figure:: using_angriff-1.png

   Using the unusable angriff-01.pd in another patch. using_angriff-1.pd_

.. _using_angriff-1.pd: using_angriff-1.pd

PD searches for something that matches the object "angriff-01" in 
several places: in the list of builtin objects like "noise~", in 
external libraries or in its path for abstractions. If angriff-01.pd 
is in the same directory as the using patch or in a path known to PD 
through the startup option "-path /a/pd-path/", it gets found. If you 
click on angriff-01, you can open it to see, what's inside. 
Abstractions itself can use other abstractions so it's a good idea to 
put often used functionality into abstractions. As our final drumsynth 
should have a sound generating part and a GUI to control this, we will 
seperate both parts from each other by use of abstractions. For the 
synthesis of sound we will build and use an abstraction called "drumcenter"
inside of the main "angriff" patch. The main patch includes the control 
elements for the parameters provided by "drumcenter". This way our 
synthesis model and the view to the user are separated.

Bring The Noise
------------------

How do drums drum? Although human dummers can spend hours tuning their 
drumset, drums are generally non-pitched, percussive sounds. So for 
our first usable version of a drumsound we take some noise as a sound 
source and put an amplitude envelope around the noise. A simple, 
builtin envelope generator in PD is line~. drumcenter-01.pd show the 
noise, the envelope and both multiplied together.

.. figure:: drumcenter-01.png

  Enveloped noise, drumcenter-01.pd_

.. _drumcenter-01.pd: drumcenter-01.pd 

If you listen to this patch, it already sounds a bit like a snare, 
doesn't it? To make this sound a bit more variable we can use filtered 
noise, for example with a lowpass or highpass filter. PD comes with 
both, so lets use them. Her's the noise filtered with the lop~ filter 
at a cutoff frequency of 400 Hertz: 

.. figure:: drumcenter-02.png
            
	    Lowpass filtered and enveloped noise, drumcenter-02.pd_

.. _drumcenter-02.pd: drumcenter-02.pd

Now our patch is beginning to get a bit crammed and chaotic, so let's 
replace some chords with "send" and "receive" pairs, abbreviated "s" and "r". 
If we give those pairs names starting with $0, they get names starting 
with unique numbers instead of the $0 while performing. This way, we 
can later use several instances of our patches without conflicts 
between their own send and receive variables. We can also hide stuff 
we don't need to see in so called subpatches. Subpatches are areas 
inside a patch that are hidden in an object box starting with ``[pd]``. 
They are like curtains hiding things in a room, but the hidden objects 
are a full part of the surrounding patch. The special objects ``[inlet]``, 
``[outlet]``, ``[inlet~]`` and ``[outlet~]`` create points of connections between 
the surroundig patch and the subpatch. They work with abstractions as well.

.. figure:: drumcenter-03.png
	
	Cleaning up in the house, drumcenter-03.pd_

.. _drumcenter-03.pd: drumcenter-03.pd


Let It Swing
------------------

I lied in the previous chapter: Drums are indeed pitched, although 
just a little bit pitched. If a drummer kicks a bassdrum, the drum 
begins to oscillate slightly at a low frequency. But this oscillation 
is soon damped to an even lower frequency and then disapears. To 
simulate this behaviour, we use PD's ``[osc~]`` object with an added 
frequency envelope as show in drumcenter-04.pd:

.. figure:: drumcenter-04.png
            
	    Percussive oscillator, drumcenter-04.pd_

.. _drumcenter-04.pd: drumcenter-04.pd

The right inlet of ``[osc~]`` is used here to set the start phase of the 
oscillator. If we wouldn't set it, it would be different everytime we 
start the envelope, because an object like the ``[osc~]`` is always on and 
goes through its cycle even if we don't listen to it. The main inlet 
sets the frequency, that's going from a starting value to a lower 
frequency in a short time.

Going faster
------------------

So far we used ``[line~]`` for all envelopes and a controlling message 
like ``[1, 0 50(``. This tells ``[line~]`` to first go immediatly to 1, then 
start going to 0 for 50 milliseconds. For our oscillator frequency 
this is fine, but instantly going to an amplitude of 1 produces 
clicks, as you might have heard. So we need to specify an attack time, 
in that the amplitude raises from 0. The first guess would be a 
message like ``[1 10, 0 50(``, but that simply doesn't work. So this has to 
be solved with two messages to the ``[line~]`` object, for example ``[1 10(``
to go in 10 msecs to 1 and then the release: ``[0 50(``. Between them a 
``[del]`` is placed, that delays for as long as the first line segment's 
duration is. But this also has a problem, as shown in the next figure: 
a ``[del]`` always delays in blocks of 64 samples, and that is a time of 
around 1.45 msecs at a sampling rate of 44100 Hertz. A bit too long 
for the short attack times used in drum synths.

.. figure:: fastline.png

  Two line~ segments started with delay, fastline.pd_

.. _fastline.pd: fastline.pd

This problem isn't trivial at all and it appears everywhere, one wants 
to contol messages in PD quicker than the signal blocksize allows, for 
example in granular synthesis patches. A solution to this are "
Time-Tagged Triggers" (T3) as proposed by Gerhard Eckel and Manuel 
Rocha Iturbide for Max/FTS. In PD T3-objects are made available as 
externals in IEMLIB. Time-Tagged Triggers are a replacment for the 
standard "bang" message that is normally used in PD or Max. Eckel 
writes: "In Max/FTS, a T3 is nothing else than a message containing one 
floating-point number which specifies the delay in ms after which, 
counting from the current tick, the trigger should go off." We will now 
use the T3 break point envelope generator ``[t3_bpe]`` to generate faster 
envelopes. 

.. figure:: t3-fastline.png

  Two line~ segments started with delay, t3-fastline.pd_

.. _t3-fastline.pd: t3-fastline.pd

*to be continued...*