supernova: fix for small audio vector sizes
[supercollider.git] / HelpSource / Tutorials / Mark_Polishook_tutorial / 16_Playbuf.schelp
blob80790e22f397a8d2222c9537c29d89f1490eab33
1 title:: 16_Playbuf
2 summary:: Mark Polishook tutorial
3 categories:: Tutorials>Mark_Polishook_tutorial
4 related:: Tutorials/Mark_Polishook_tutorial/00_Introductory_tutorial
6 Breaking synthesis processes into parts that accomplish small well-defined tasks encourages modular design and component reuse (the oop mantra).
8 code::
10 // read a soundfile from disk
11 b = Buffer.read(s, Help.dir +/+ "sounds/a11wlk01.wav");
13 // a samplePlayer in mono ... one channel only
14 SynthDef("aMonoSamplePlayer", { arg bus = 0, bufnum = 0, rateScale = 1;
15         Out.ar(
16                 bus,
17                 PlayBuf.ar(
18                         1,
19                         bufnum,
20                         BufRateScale.kr(bufnum) * rateScale
21                 )
22                 *
23                 EnvGen.kr(Env.sine(BufDur.kr(bufnum)))
24         )
25 }).add;
29 // test the synthdef ... does it work? (yes, it's fine. it plays on the left channel)
30 Synth("aMonoSamplePlayer", [\bus, 0, \bufNum, b]);
35 // a simple example of component reuse ... use the \bus argument to assign synths built from
36 // the same synthdef to different channels
37 // in this case, play a 1-channel soundfile on 2 channels
38 // a different playback rate for each channel makes the effect more obvious
39 Synth("aMonoSamplePlayer", [\bus, 0, \bufNum, b, \rateScale, 0.99]);
40 Synth("aMonoSamplePlayer", [\bus, 1, \bufNum, b, \rateScale, 1.01]);
44 section::Information
46 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.
48 BufRateScale and BufDur are of a family of ugens that inherit from InfoUGenBase or BufInfoUGenBase.
50 To see the complete list of such ugens, evaluate
52 code::
53 InfoUGenBase.dumpClassSubtree;
56 It returns
58 code::
59 InfoUGenBase
60 [\r  NumRunningSynths\r  NumBuffers\r  ControlDur\r  NumControlBuses\r  SubsampleOffset\r  RadiansPerSample\r  SampleDur\r  ControlRate\r  NumInputBuses\r  NumAudioBuses\r  SampleRate\r  NumOutputBuses\r]\rInfoUGenBase
63 Evaluate
65 code::
66 BufInfoUGenBase.dumpClassSubtree;
69 and it returns
71 code::
72 BufInfoUGenBase\r[\r  BufChannels\r  BufSampleRate\r  BufRateScale\r  BufFrames\r  BufDur\r  BufSamples\r]\rBufInfoUGenBase
75 section::Loop a sample
77 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.
79 code::
81 // read a soundfile
82 b = Buffer.read(s, Help.dir +/+ "sounds/a11wlk01.wav");
84 // define a sample player that will loop over a soundfile
85 SynthDef("aLoopingSamplePlayer", { arg outBus = 0, bufnum = 0, rateScale = 1, mul = 1;
86         Out.ar(
87                 outBus,
88                 PlayBuf.ar(
89                         1,
90                         bufnum,
91                         BufRateScale.kr(bufnum) * rateScale + LFNoise1.kr(2.reciprocal, 0.05),
92                         loop: 1 // play the soundfile over and over without stopping
93                 )
94                 *
95                 mul
96         )
97 }).add;
99 // apply amplitude modulation to an audio source
100 SynthDef("ampMod", { arg inBus = 0, outBus = 0, modFreq = 1;
101         Out.ar(
102                 outBus,
103                 [       // In.ar ugen reads from an audio bus
104                         In.ar(inBus, 1) * SinOsc.kr(modFreq),
105                         In.ar(inBus, 1) * SinOsc.kr(modFreq - 0.02)
106                 ]
107         )
108 }).add;
110 // apply a low pass filter to an audio source
111 SynthDef("aLowPassFilter", { arg inBus = 0, outBus = 0, freq = 300, freqDev = 50, boost = 1;
112         Out.ar(
113                 outBus,
114                 RLPF.ar(
115                         In.ar(inBus, 2),
116                         Lag.kr(LFNoise0.kr(1, freqDev, freq), 1),
117                         0.2
118                 )
119                 *
120                 boost
121                 *
122                 LFPulse.kr(1, [0.25, 0.75], [0.5, 0.45])
123                 +
124                 In.ar(inBus, 2)
125         )
126 }).add;
129 // define 2 groups, 1 for source material and the other for effects
131 ~source = Group.head(s);
132 ~effect = Group.tail(~s);
136 // add the samplePlayer to the source group
137 ~theSource = Synth.head(
138         ~source,
139         "aLoopingSamplePlayer", [\outBus, 3, \bufNum, b, \rateScale, 1, \mul, 0.051]);
140 // add an amplitude modulation synth to the head of the effects group
141 ~fx1 = Synth.head(
142         ~effect,
143         "ampMod", [\inBus, 3, \outBus, 5, \modFreq, 1]);
144 // add filtering to the tail of the effects group
145 ~fx2 = Synth.tail(
146         ~effect,
147         "aLowPassFilter", [\inBus, 5, \outBus, 0, \boost, 5])
150 // examine the nodes
152 s.queryAllNodes;
156 code::
157 // a diagram
159     RootNode
160         |
161   default_node
162       /\
163      /  \
164 ~source  ~effects       // ~source and ~effects are groups
165  |        |      \
166  |        |       \
167  synth    synth    synth
170 code::
171 // Changing argument (control) values effects timbre
173  ~theSource.set(\rateScale, 0.95.rrand(1.05), \mul, 0.051.rrand(0.07));
174  ~fx1.set(\modFreq, 800.0.rrand(1200));
175  ~fx2.set(\freq, 500.rrand(700), \freqDev, 180.rrand(210), \boost, 7);
179 ////////////////////////////////////////////////////////////////////////////////////////////////////
181 go to link::Tutorials/Mark_Polishook_tutorial/17_Delays_reverbs::