File: 16_Playbuf.schelp

package info (click to toggle)
supercollider 1%3A3.6.6~repack-2-1
  • links: PTS, VCS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 23,792 kB
  • ctags: 25,269
  • sloc: cpp: 177,129; lisp: 63,421; ansic: 11,297; python: 1,787; perl: 766; yacc: 311; sh: 286; lex: 181; ruby: 173; makefile: 168; xml: 13
file content (204 lines) | stat: -rw-r--r-- 4,626 bytes parent folder | download | duplicates (7)
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
title:: 16_Playbuf
summary:: Mark Polishook tutorial
categories:: Tutorials>Mark_Polishook_tutorial
related:: Tutorials/Mark_Polishook_tutorial/00_Introductory_tutorial

Breaking synthesis processes into parts that accomplish small well-defined tasks encourages modular design and component reuse (the oop mantra).

code::
(
// read a soundfile from disk
b = Buffer.read(s, Platform.resourceDir +/+ "sounds/a11wlk01.wav");

// a samplePlayer in mono ... one channel only
SynthDef("aMonoSamplePlayer", { arg bus = 0, bufnum = 0, rateScale = 1;
	Out.ar(
		bus,
		PlayBuf.ar(
			1,
			bufnum,
			BufRateScale.kr(bufnum) * rateScale
		)
		*
		EnvGen.kr(Env.sine(BufDur.kr(bufnum)))
	)
}).add;
)

(
// test the synthdef ... does it work? (yes, it's fine. it plays on the left channel)
Synth("aMonoSamplePlayer", [\bus, 0, \bufNum, b]);
)


(
// a simple example of component reuse ... use the \bus argument to assign synths built from
// the same synthdef to different channels
// in this case, play a 1-channel soundfile on 2 channels
// a different playback rate for each channel makes the effect more obvious
Synth("aMonoSamplePlayer", [\bus, 0, \bufNum, b, \rateScale, 0.99]);
Synth("aMonoSamplePlayer", [\bus, 1, \bufNum, b, \rateScale, 1.01]);
)
::

section::Information

The BufRateScale and the BufDur ugens, as shown in the previous example, control the rate at which PlayBuf plays the soundfile and the length of the envelope applied to the playbuf.

BufRateScale and BufDur are of a family of ugens that inherit from InfoUGenBase or BufInfoUGenBase.

To see the complete list of such ugens, evaluate

code::
InfoUGenBase.dumpClassSubtree;
::

It returns

code::
InfoUGenBase
[
  NumRunningSynths
  NumBuffers
  ControlDur
  NumControlBuses
  SubsampleOffset
  RadiansPerSample
  SampleDur
  ControlRate
  NumInputBuses
  NumAudioBuses
  SampleRate
  NumOutputBuses
]
InfoUGenBase
::

Evaluate

code::
BufInfoUGenBase.dumpClassSubtree;
::

and it returns

code::
BufInfoUGenBase
[
  BufChannels
  BufSampleRate
  BufRateScale
  BufFrames
  BufDur
  BufSamples
]
BufInfoUGenBase
::

section::Loop a sample

The next example uses three synthsdefs to make a chain. The first synthdef is a sample player that loops through a buffer. The second synthdef ring modulates its input. The third synthdef applies a lowpass filter.

code::
(
// read a soundfile
b = Buffer.read(s, Platform.resourceDir +/+ "sounds/a11wlk01.wav");

// define a sample player that will loop over a soundfile
SynthDef("aLoopingSamplePlayer", { arg outBus = 0, bufnum = 0, rateScale = 1, mul = 1;
	Out.ar(
		outBus,
		PlayBuf.ar(
			1,
			bufnum,
			BufRateScale.kr(bufnum) * rateScale + LFNoise1.kr(2.reciprocal, 0.05),
			loop: 1	// play the soundfile over and over without stopping
		)
		*
		mul
	)
}).add;

// apply amplitude modulation to an audio source
SynthDef("ampMod", { arg inBus = 0, outBus = 0, modFreq = 1;
	Out.ar(
		outBus,
		[	// In.ar ugen reads from an audio bus
			In.ar(inBus, 1) * SinOsc.kr(modFreq),
			In.ar(inBus, 1) * SinOsc.kr(modFreq - 0.02)
		]
	)
}).add;

// apply a low pass filter to an audio source
SynthDef("aLowPassFilter", { arg inBus = 0, outBus = 0, freq = 300, freqDev = 50, boost = 1;
	Out.ar(
		outBus,
		RLPF.ar(
			In.ar(inBus, 2),
			Lag.kr(LFNoise0.kr(1, freqDev, freq), 1),
			0.2
		)
		*
		boost
		*
		LFPulse.kr(1, [0.25, 0.75], [0.5, 0.45])
		+
		In.ar(inBus, 2)
	)
}).add;
)

// define 2 groups, 1 for source material and the other for effects
(
~source = Group.head(s);
~effect = Group.tail(~s);
)

(
// add the samplePlayer to the source group
~theSource = Synth.head(
	~source,
	"aLoopingSamplePlayer", [\outBus, 3, \bufNum, b, \rateScale, 1, \mul, 0.051]);
// add an amplitude modulation synth to the head of the effects group
~fx1 = Synth.head(
	~effect,
	"ampMod", [\inBus, 3, \outBus, 5, \modFreq, 1]);
// add filtering to the tail of the effects group
~fx2 = Synth.tail(
	~effect,
	"aLowPassFilter", [\inBus, 5, \outBus, 0, \boost, 5])
)

// examine the nodes
(
s.queryAllNodes;
)
::

code::
// a diagram

    RootNode
	|
  default_node
      /\
     /  \
~source  ~effects	// ~source and ~effects are groups
 |        |      \
 |        |       \
 synth    synth    synth
::

code::
// Changing argument (control) values effects timbre
(
 ~theSource.set(\rateScale, 0.95.rrand(1.05), \mul, 0.051.rrand(0.07));
 ~fx1.set(\modFreq, 800.0.rrand(1200));
 ~fx2.set(\freq, 500.rrand(700), \freqDev, 180.rrand(210), \boost, 7);
)
::

////////////////////////////////////////////////////////////////////////////////////////////////////

go to link::Tutorials/Mark_Polishook_tutorial/17_Delays_reverbs::