forked from gabochi/rampcode
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtutorial.rampcode
More file actions
257 lines (159 loc) · 11.4 KB
/
tutorial.rampcode
File metadata and controls
257 lines (159 loc) · 11.4 KB
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
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
-- Welcome to Rampcode!
-- This is intended to work within Atom
-- Find the Atom package here:
-- https://atom.io/packages/atom-rampcode
-- Also, here you can do a similar thing online:
-- https://greggman.com/downloads/examples/html5bytebeat/html5bytebeat.html (select 'floatbeat')
-- Ok, let's go.
-- /////////////////////////////// WHAT'S HAPPENING? AND SYNTHAX
-- Rampcode is based on the bytebeat technique, so basically you have an lineal increasing value (ramp) and all audio output is a direct result of an operation over the actual value of that ramp.
-- The output signal will be a number between -1 and 1 and the synthax will be as follows:
-- hz @ [expression : duration of the loop in hz (timer per sec)] ;
-- and
-- [expression 1 : where $v1 is the actual ramp value] @ [expression 2: where $v1 is the output of the first expression] ;
-- /////////////////////////////// HELLO WORLD (4000hz square wave)
-- KEEP A LOW VOLUME !!!
hz @ 1;
-- Press SHIFT+ENTER to evaluate the line and ALT+. anytime to stop the sound. For now, we'll work with a simple one-second loop.
$v1 * 8000 @ $v1 % 2;
-- $v1 * 8000 : The ramp goes from 0 to 1 bt default (since it's generated with a phasor~ object) but we need a bigger number. Here I put the classic 8000 so we have a 1 second loop in which the ramp goes from 0 to 7999 (keep in mind that the standard audio rate is 44100 but we'll be fine).
-- $v1 % 2 : $v1 now is the 0 to 7999 ramp. Modulo (%) is one of the most important operators here, it returns the integer rest of a divission... In english it means that you can 'loop' or subdivide like this: 0 % 2 = 0, 1 % 2 = 1, 2 % 2 = 0, 3 % 2 = 1, etc. So? We have now an annoying 4000hz square wave (check Nyquist-Shannon sampling theorem).
-- //////////////////////////////////// IT IS ALL ABOUT FREQUENCIES
-- Try changing our square wave frequency by dividing $v1:
$v1 * 8000 @ $v1 / 64 % 2;
-- You can also multiply above the sampling rate and discover nice glitches:
$v1 * 8000 @ $v1 * 1000 % 2;
-- /////////////////////////////////////////// THE CHEAPEST MIXER
-- Volume control:
$v1 * 8000 @ $v1 % 2 * 0.25;
-- Handle 0 to 1 amplitudes.
$v1 * 8000 @ $v1%2*0.15 + $v1/10%2*0.3 + $v1/24%2*0.5 ;
-- Use volume control and addition to sum and mix 'voices'.
-- ///////////////////////////////////////////////////// COUNTERS
-- Another thing modulo is very handful is for making counters. So far, we made a square wave since the result of %2 can be only 0 or 1 but now we'll do something different:
-- $v1 / measure % steps
-- Remember that starts with 0, so maybe you want to put +1 sometimes...
$v1 * 8000 @ $v1 / ($v1/1000%4) %2 * 0.2;
-- Use it as an arpeggiator to divide the frequency
$v1 * 8000 @ $v1/8%2*0.2 * ($v1/1000%8%3==0);
$v1 * 8000 @ $v1/8%2*0.2 * ($v1/1000%8%3<2);
-- Or as a trigger condition (see it can be concatenated)
$v1 * 8000 @ $v1 / ($v1/250%4) /4 %2 * ($v1/1000%8%3==0) * 0.2;
-- Combine arpeggio and trigger (/4 is for octave adjustment)
$v1 * 8000 @ $v1 / ($v1/1000%4+1) * ($v1/2000%3+1) /4 %2 *0.2;
-- Combine inside the arpeggiator
-- ///////////////////////////////////////////////// ENVELOPES
-- There are many ways of making anything in rampcode and envelopes is one of those things I'm always trying to improve. So far, the better way I found is this:
-- * (1 - % meause / measure)
$v1 * 8000 @ $v1%2 * 0.2 * (1-$v1%2000/2000);
-- This is a 0 attack envelope
$v1 * 8000 @ $v1%2 * 0.2 * ($v1%2000/2000);
-- Erase the 1 to reverse it
$v1 * 8000 @ $v1%2 * 0.2 * pow(1-$v1%2000/2000, 4);
-- Use pow() to accent the curve
$v1 * 8000 @ $v1%2*0.2*pow(1- ($v1*($v1/4000%2+1)) %1000/1000,4);
-- Use counters inside the envelope to change the measure
$v1 * 8000 @ $v1/($v1/($v1/4000%2*24+1)%5) *($v1/1000%3+1) %2 * 0.2 * pow(1-($v1/($v1/1500%2+1))%1000/1000, $v1/1000%5*2);
-- The best thing about rampcode is that you can control everything, you can get the juice and make an interesting pattern out of any 'voice' with the right variations and combinations.
-- ////////////////////////////////////////////////// MODULATION
-- Modulation is essential when you're working with simple sounds and patterns. Of course, here we'll use more than squarewaves:
$v1 * 8000 @ sin($v1) *0.2;
$v1 * 8000 @ sin($v1/8) *0.2;
$v1 * 8000 @ sin($v1/ ($v1/1000%4) ) *0.2; -- arpeggios
$v1 * 8000 @ sin($v1*1000) *0.2; -- glitches above Nyquist-Shannon
$v1 * 8000 @ sin($v1/($v1/2%8)/32)*0.1; -- rare noisy strings fx
-- You can use sin() and cos() to make sine waves, just remember that their output is between -1 and 1.
$v1 * 8000 @ sin($v1/8 + sin($v1/16)) *0.2;
-- 2 operators FM
$v1 * 8000 @ sin($v1/8 + sin($v1/16) * sin($v1/1250) * 10 ) *0.2;
-- 3 operators (using low frequencies like $v1/1250 work as LFOs)
$v1 * 8000 @ sin($v1/16 + sin($v1/9) * sin($v1/2500) * 100 ) *0.1;
-- Change the ratios and indexes and have fun!
$v1 * 8000 @ sin($v1*$v1) * 0.2; -- FM noise, unstable behaviour
$v1 * 8000 @ sin($v1 * sin($v1)) * 0.2; -- FM noise, better result
$v1 * 8000 @ sin($v1%33 * sin($v1)) * 0.2;
$v1 * 8000 @ sin($v1 * sin($v1%8)) * 0.2;
-- Distort the signal to achieve different noise colors
$v1 * 8000 @ $v1/8%2 * sin($v1/2000) * 0.2;
$v1 * 8000 @ $v1/8%2 * sin($v1/200) * 0.2;
-- How can we forget AM ?!
-- /////////////////////////////////////////////// PERCUSSIVE FM
-- Pitching down very quickly is the oldest trick to emulate a kick or any similar percussive sound. Here are some tricks:
$v1 * 8000 @ 1000/($v1%4000) %2 * 0.2; -- Square kick
$v1 * 8000 @ sin(1000/($v1%4000)) * 0.2; -- Simple sine kick
$v1 * 8000 @ sin($v1/32 + sin($v1/32) * pow(1-$v1%1000/1000,20) * 20) * 0.2; -- Complex FM kick
-- Changing the right parametters with any of these kicks can make a whole piece by its own:
hz @ 1 ; -- previous 1 second loop
hz @ 1.0 / 4; -- 4 seconds loop
$v1 * 8000 * 4 @ 1000/(($v1*($v1/2000%4+1))%(4000-3000*($v1/7000%2))) * pow($v1/1000%4+1,3) %2 * 0.15;
$v1 * 8000 * 4 @ sin((1000-$v1/1000%3*250)/($v1/($v1/4000%3+1)%(1000/($v1/5000%2+1)))*pow($v1/2000%3+1,5) )*0.12;
$v1 * 8000 * 2 @ sin($v1/64 + sin($v1/($v1/1000%6*4+4)) * pow(1-$v1*($v1/2000%3*0.5+1)%1000/1000,($v1/500%8*2)) * ($v1/5000%3*99+15)) * 0.1;
-- /////////////////////////////////////////////// RAMP CONTROL
-- As you probably have noticed, the loop duration has changed. Since we're working with float values below 1, we need to use the point in out expression like 1.0/4 or 1/4.0
-- 1.0/4 gives you a four second loop but remember you must adjust the ramp expression too: 8000 * 4, since 8000 was just for one second. Let's try different ramp speeds:
hz @ 1.0 / 2 ;
-- Two seconds loop, understand it as 2 bars loop.
-- Think of that 1.0 as a 120 bpm tempo:
-- USEFUL FORMULA:
-- bpm = hz * 60 (120 in this case, it depends on subdivission)
-- hz = 60 / hz (also, 120 in this case)
$v1 * 44100 * 2 @ sin(2205/($v1%22050)*3)*0.1 + sin($v1*sin($v1))*pow(1-$v1*8%44100/44100,$v1*8/44100%5*2+2)*0.04 + sin($v1/4%5*sin($v1))*pow(1-$v1%44100/44100,6)*0.05;
-- Stright loop
hz @ 1.25 / 2;
-- Increase tempo
hz @ 0.9 / 2;
-- Decrease tempo
hz @ 1.0 / 3 ;
-- Decrease but divissor
hz @ 1.0 / 2;
-- Back to 120 bpm
-- //////////////////////////////////////// EXCURSE : POLYRHYTHMS
-- Tip: A simple way to handle polyrhythms with envelopes is:
-- $v1 * (measuse) % pattern-duration / pattern-duration
-- Pattern duration was 8000 when we started this tutorial (the easiest way to handle 1/8 measures with 1000 value) but now we're working more or less with the standard sampling ratio of 44100; this is not quiet precise but you'll hear more definition in some sounds.
-- $v1 * (measure) % 44100 / 44100
$v1 * 44100 * 2 @ sin(2205/($v1%22050)*3)*0.1 + sin($v1*sin($v1))*pow(1-$v1*8%44100/44100,$v1*8/44100%5*2+2)*0.04 + sin($v1/4%5*sin($v1))*pow(1-$v1*3%44100/44100,6)*0.05;
-- Polyrhythmical variation 1
$v1 * 44100 * 2 @ sin(2205/($v1%22050)*3)*0.1 + sin($v1*sin($v1))*pow(1-$v1*10%44100/44100,$v1*10/44100%6*2+2)*0.04 + sin($v1/4%5*sin($v1))*pow(1-$v1*2.5%44100/44100,6)*0.05;
-- Polyrhythmical variation 2
-- //////////////////////////////////////////////////////////
-- Let's return to the ramp control. So far we just changed the tempo but the true power of ramp control is to make different patterns and fx.
hz @ 1.0 / 8 ;
-- Make an eight bars loop.
$v1 * 8000 * 8 @ sin(1000/($v1%4000)*2)*0.2 + sin($v1%5)*pow(1-$v1%1000/1000,8)*0.15 + sin($v1*sin($v1%33))*($v1/1000%8==4)*0.1;
-- The simplest rhythm to hack in!
$v1/2 * 8000 * 8 @ sin(1000/($v1%4000)*2)*0.2 + sin($v1%5)*pow(1-$v1%1000/1000,8)*0.15 + sin($v1*sin($v1%33))*($v1/1000%8==4)*0.1;
-- $v1/2, half tempo
$v1*2 * 8000 * 8 @ sin(1000/($v1%4000)*2)*0.2 + sin($v1%5)*pow(1-$v1%1000/1000,8)*0.15 + sin($v1*sin($v1%33))*($v1/1000%8==4)*0.1;
-- $v1*2 double tempo
$v1/($v1*6%2+1) * 8000 * 8 @ sin(1000/($v1%4000)*2)*0.2 + sin($v1%5)*pow(1-$v1%1000/1000,8)*0.15 + sin($v1*sin($v1%33))*($v1/1000%8==4)*0.1;
-- $v1/ ($v1*6%2+1) sometimes straight, sometimes half
$v1*($v1*8*4%3*0.5+0.5) * 8000 * 8 @ sin(1000/($v1%4000)*2)*0.2 + sin($v1%5)*pow(1-$v1%1000/1000,8)*0.15 + sin($v1*sin($v1%33))*($v1/1000%8==4)*0.1;
-- $v1 * ($v1*8*4%3*0.5+0.5) sometimes half, sometimes straight, sometimes 1.5 ...
if($v1*8*8%4,$v1/($v1*6%2+1),$v1) * 8000 * 8 @ sin(1000/($v1%4000)*2)*0.2 + sin($v1%5)*pow(1-$v1%1000/1000,8)*0.15 + sin($v1*sin($v1%33))*($v1/1000%8==4)*0.1;
-- A nice trick is to use if() when you want to preserve any particular part of the beat and glitch the rest
if($v1*8*8%4,$v1*($v1*8*4%3*0.5+0.5)/($v1*2%2+1),$v1) * 8000 * 8 @ sin(1000/($v1%4000)*2)*0.2 + sin($v1%5)*pow(1-$v1%1000/1000,8)*0.15 + sin($v1*sin($v1%33))*($v1/1000%8==4)*0.1;
-- These two ifs are the previous examples but apply only to the part between the strong beats
$v1 * 8000 * 8 %4000 @ sin(1000/($v1%4000)*2)*0.2 + sin($v1%5)*pow(1-$v1%1000/1000,8)*0.15 + sin($v1*sin($v1%33))*($v1/1000%8==4)*0.1;
-- Use % to loop
$v1 * 8000 * 8 %4000 + 4000 @ sin(1000/($v1%4000)*2)*0.2 + sin($v1%5)*pow(1-$v1%1000/1000,8)*0.15 + sin($v1*sin($v1%33))*($v1/1000%8==4)*0.1;
-- + for offset
$v1 * 8000 * 8 % (1000*($v1*8*8%8)) @ sin(1000/($v1%4000)*2)*0.2 + sin($v1%5)*pow(1-$v1%1000/1000,8)*0.15 + sin($v1*sin($v1%33))*($v1/1000%8==4)*0.1;
-- change the size of the loop
$v1 * 8000 * 8 + (2000*($v1*8*8%5+1)) @ sin(1000/($v1%4000)*2)*0.2 + sin($v1%5)*pow(1-$v1%1000/1000,8)*0.15 + sin($v1*sin($v1%33))*($v1/1000%8==4)*0.1;
-- change the offset
$v1 * 8000 * 8 + $v1 * 8000 * 8 * 8 %2 @ sin(1000/($v1%4000)*2)*0.2 + sin($v1%5)*pow(1-$v1%1000/1000,8)*0.15 + sin($v1*sin($v1%33))*($v1/1000%8==4)*0.1;
-- add an aliasing signal to distort
$v1 * 8000 * 8 + $v1 * 8000 * 8 * 8 % (sin($v1*4) * 10) @ sin(1000/($v1%4000)*2)*0.2 + sin($v1%5)*pow(1-$v1%1000/1000,8)*0.15 + sin($v1*sin($v1%33))*($v1/1000%8==4)*0.1;
-- change the aliasing size to make some fx
-- homework : see what happens if you use larger sizes!
if($v1*8*8%4,$v1*($v1*8*4%3*0.5+0.5)/($v1*2%2+1),$v1) * 8000 * 8 + $v1 * 8000 * 8 * 8 % (sin($v1*2) * 7) * ($v1*8*8%4!=0) @ sin(1000/($v1%4000)*2)*0.2 + sin($v1%5)*pow(1-$v1%1000/1000,8)*0.15 + sin($v1*sin($v1%33))*($v1/1000%8==4)*0.1;
-- combine everything
-- I don't know if I'll be uploading more documentation. The possibilities are so many that I can't really show you everything or even discover everything myself, please help me on this and write me anytime.
-- ig : @gabovinazza
-- fb : /gedeaudiovisual /gabochiano
-- gm : gabriel.vinazza@gmail.com
-- blog: https://gabochi.github.io/b10g/
-- github & more : gabochi
hz @ 0.8 ; $v1 * 8000 @ (sin($v1/20)<sin($v1/2000)*0.75)*0.2;
-- PWM bonus ^_^