|
| 1 | +desc: Albeton - Autopan |
| 2 | +author: tilr |
| 3 | +version: 1.0.0 |
| 4 | +about: |
| 5 | + # Albeton - Autopan |
| 6 | + |
| 7 | + JS clone of Ableton auto-pan stock plug-in. |
| 8 | + |
| 9 | + |
| 10 | +slider1:_amount=0.5<0.0,1,0.01>Amount |
| 11 | +slider2:_rate=1<0.01,5000,0.01:log>Rate (Hz) |
| 12 | +slider3:_rate_sync=0<0,24,1{Off,1/64,1/32,1/16,1/8,1/4,1/2,1/1,2/1,3/1,4/1,1/64T,1/32T,1/16T,1/8T,1/4T,1/2T,1/1T,1/64D,1/32D,1/16D,1/8D,1/4D,1/2D,1/1D}>Rate Sync |
| 13 | +slider4:_offset=90<0,360,1>Offset |
| 14 | +slider5:_phase=180<0,360,1>Phase |
| 15 | +slider6:_spin=0<-1,1,0.01>Spin |
| 16 | +slider7:_shape=0<1,50,0.1:log>Shape |
| 17 | +slider8:_wave=0<0,3,1{Sine,Tri,Saw,Rand}>Waveform |
| 18 | +slider9:_use_spin=0<0,1,1{False,True}>-Use Spin |
| 19 | +slider10:_invert=0<0,1,1{False,True}>-Invert |
| 20 | + |
| 21 | +@init |
| 22 | +israte = 1/srate; |
| 23 | +play_pos = play_position; |
| 24 | +salpha = exp(-2.0 * $pi * 200 / srate); |
| 25 | +l.seed = floor(rand(1000000) + 10); |
| 26 | +r.seed = floor(rand(1000000) + 10); |
| 27 | +l.randphase = l.seed; |
| 28 | +r.randphase = r.seed; |
| 29 | + |
| 30 | +function sine(phase) (cos(2*$pi*phase)); |
| 31 | +function triangle(phase) |
| 32 | +( |
| 33 | + 4*abs(phase - 0.5) - 1 |
| 34 | +); |
| 35 | +function saw(phase) (1 - 2 * phase); |
| 36 | +function tanh(x) ( |
| 37 | + x = exp(2*x); |
| 38 | + (x - 1) / (x + 1) |
| 39 | +); |
| 40 | +function rand_wave() |
| 41 | +instance(randphase, prev_cycle, prev_val) |
| 42 | +local(val, cycle) |
| 43 | +( |
| 44 | + cycle = floor(randphase); |
| 45 | + val = cycle != prev_cycle |
| 46 | + ? rand() * 2 - 1 |
| 47 | + : prev_val; |
| 48 | + prev_cycle = cycle; |
| 49 | + prev_val = val; |
| 50 | + val |
| 51 | +); |
| 52 | +function wave(phase, is_right) |
| 53 | +local(val) |
| 54 | +( |
| 55 | + val = _wave == 0 ? sine(phase) : |
| 56 | + _wave == 1 ? triangle(phase) : |
| 57 | + _wave == 2 ? saw(phase) : |
| 58 | + _wave == 3 && is_right ? r.rand_wave() : |
| 59 | + _wave == 3 && !is_right ? l.rand_wave(); |
| 60 | + |
| 61 | + _shape > 1 ? tanh(val*_shape) : val |
| 62 | +); |
| 63 | +function normalize(val) ( val * 0.5 + 0.5 ); |
| 64 | + |
| 65 | +function get_sync_qn() |
| 66 | +global(_rate_sync) |
| 67 | +local(t) |
| 68 | +( |
| 69 | + t = |
| 70 | + _rate_sync == 0 ? 1.0 : // Off |
| 71 | + _rate_sync == 1 ? 0.0625 : // 1/64 |
| 72 | + _rate_sync == 2 ? 0.125 : // 1/32 |
| 73 | + _rate_sync == 3 ? 0.25 : // 1/16 |
| 74 | + _rate_sync == 4 ? 0.5 : // 1/8 |
| 75 | + _rate_sync == 5 ? 1.0 : // 1/4 |
| 76 | + _rate_sync == 6 ? 2.0 : // 1/2 |
| 77 | + _rate_sync == 7 ? 4.0 : // 1/1 |
| 78 | + _rate_sync == 8 ? 8.0 : // 2/1 |
| 79 | + _rate_sync == 9 ? 12.0 : // 3/1 |
| 80 | + _rate_sync == 10 ? 16.0 : // 4/1 |
| 81 | + _rate_sync == 11 ? 0.0625 * 2/3 : // 1/64T |
| 82 | + _rate_sync == 12 ? 0.125 * 2/3 : // 1/32T |
| 83 | + _rate_sync == 13 ? 0.25 * 2/3 : // 1/16T |
| 84 | + _rate_sync == 14 ? 0.5 * 2/3 : // 1/8T |
| 85 | + _rate_sync == 15 ? 1.0 * 2/3 : // 1/4T |
| 86 | + _rate_sync == 16 ? 2.0 * 2/3 : // 1/2T |
| 87 | + _rate_sync == 17 ? 4.0 * 2/3 : // 1/1T |
| 88 | + _rate_sync == 18 ? 0.0625 * 1.5 : // 1/64D |
| 89 | + _rate_sync == 19 ? 0.125 * 1.5 : // 1/32D |
| 90 | + _rate_sync == 20 ? 0.25 * 1.5 : // 1/16D |
| 91 | + _rate_sync == 21 ? 0.5 * 1.5 : // 1/8D |
| 92 | + _rate_sync == 22 ? 1.0 * 1.5 : // 1/4D |
| 93 | + _rate_sync == 23 ? 2.0 * 1.5 : // 1/2D |
| 94 | + _rate_sync == 24 ? 4.0 * 1.5 : // 1/1D |
| 95 | + 1.0; |
| 96 | + |
| 97 | + t; |
| 98 | +); |
| 99 | + |
| 100 | +function on_slider() |
| 101 | +( |
| 102 | + sync_qn = get_sync_qn(); |
| 103 | + sync_qnl = sync_qn; |
| 104 | + sync_qnr = sync_qn; |
| 105 | + _use_spin ? sync_qnr *= 0.25 * pow(16, (_spin + 1) * 0.5); |
| 106 | + |
| 107 | + offsetl = _offset / 360; |
| 108 | + offsetr = _offset / 360 + (_use_spin ? 0 : _phase / 360); |
| 109 | + slider_show(_phase, !_use_spin); |
| 110 | + slider_show(_spin, _use_spin); |
| 111 | +); |
| 112 | + |
| 113 | +@slider |
| 114 | + |
| 115 | +on_slider(); |
| 116 | + |
| 117 | +@block |
| 118 | +beats_per_spl = _rate_sync > 0 |
| 119 | + ? tempo / (60 * srate) |
| 120 | + : israte * _rate; |
| 121 | +play_state & 1 && _rate_sync > 0 ? ( |
| 122 | + beat_pos = beat_position; |
| 123 | +); |
| 124 | + |
| 125 | +@sample |
| 126 | + |
| 127 | +lwave = normalize(wave(lphase, 0)); |
| 128 | +rwave = normalize(wave(rphase, 1)); |
| 129 | + |
| 130 | +_invert ? ( |
| 131 | + lwave = 1 - lwave; |
| 132 | + rwave = 1 - rwave; |
| 133 | +); |
| 134 | + |
| 135 | +lsmooth = prevlsmooth*salpha + lwave*(1-salpha); |
| 136 | +prevlsmooth = lsmooth; |
| 137 | + |
| 138 | +rsmooth = prevrsmooth*salpha + rwave*(1-salpha); |
| 139 | +prevrsmooth = rsmooth; |
| 140 | + |
| 141 | +spl0 *= 1 + (lsmooth - 1) * _amount; |
| 142 | +spl1 *= 1 + (rsmooth - 1) * _amount; |
| 143 | + |
| 144 | +// update phase |
| 145 | +lphase = beat_pos / sync_qnl + offsetl; |
| 146 | +rphase = beat_pos / sync_qnr + offsetr; |
| 147 | +lphase -= floor(lphase); |
| 148 | +rphase -= floor(rphase); |
| 149 | +// rand phase |
| 150 | +l.randphase = l.seed + beat_pos / sync_qnl + offsetl; |
| 151 | +r.randphase = r.seed + beat_pos / sync_qnr + offsetr; |
| 152 | +// |
| 153 | +beat_pos += beats_per_spl; |
| 154 | + |
| 155 | +@gfx 500 140 |
| 156 | + |
| 157 | +color_bg = 0x111111; |
| 158 | +color_active = 0xffff00; |
| 159 | +winx = 0; |
| 160 | +winy = 30; |
| 161 | +winw = gfx_w; |
| 162 | +winh = gfx_h-30; |
| 163 | + |
| 164 | +function update_mouse_state() |
| 165 | +instance(cap, x, y, lx, ly, dx, dy, right_click, left_click, lleft, lright, left, right, click_time, double_click, control, lwheel, wheel) |
| 166 | +global(mouse_cap, mouse_x, mouse_y, mouse_wheel) |
| 167 | +( |
| 168 | + lleft = left; |
| 169 | + lright = right; |
| 170 | + lx = x; |
| 171 | + ly = y; |
| 172 | + cap = mouse_cap; |
| 173 | + control = mouse_cap & 4; |
| 174 | + x = mouse_x; |
| 175 | + y = mouse_y; |
| 176 | + |
| 177 | + left = cap & 1 > 0; |
| 178 | + right = cap & 2 > 0; |
| 179 | + left_click = left && lleft == 0; |
| 180 | + right_click = right && lright == 0; |
| 181 | + dx = x - lx; |
| 182 | + dy = y - ly; |
| 183 | +); |
| 184 | + |
| 185 | +function set_color(color) ( |
| 186 | + gfx_r = (color & 0xFF0000) / 0xFF0000; |
| 187 | + gfx_g = (color & 0x00FF00) / 0x00FF00; |
| 188 | + gfx_b = (color & 0x0000FF) / 0x0000FF; |
| 189 | +); |
| 190 | + |
| 191 | +function mouse_in_rect (x, y, w ,h) ( |
| 192 | + mouse.x >= x && mouse.x <= x + w && mouse.y >= y && mouse.y <= y + h; |
| 193 | +); |
| 194 | + |
| 195 | +function point_in_rect (x1, y1, x, y, w, h) ( |
| 196 | + x1 >= x && x1 <= x + w && y1 >= y && y1 <= y + h; |
| 197 | +); |
| 198 | + |
| 199 | +function gfx_wave(phase, is_right) |
| 200 | +global(_shape, _invert, _wave) |
| 201 | +local(val, r) |
| 202 | +( |
| 203 | + val = _wave == 0 ? sine(phase) : |
| 204 | + _wave == 1 ? triangle(phase - floor(phase)) : |
| 205 | + _wave == 2 ? saw(phase - floor(phase)); |
| 206 | + |
| 207 | + _wave == 3 ? ( |
| 208 | + r = floor(phase) + 5000; |
| 209 | + is_right ? r += 10000; |
| 210 | + val = sin(r * 12.9898) * 43758.5453; // pseudo rand |
| 211 | + val = (val - floor(val)) * 2 - 1; |
| 212 | + ); |
| 213 | + |
| 214 | + _shape > 1 ? val = tanh(val*_shape); |
| 215 | + _invert ? val *= -1; |
| 216 | + val; |
| 217 | +); |
| 218 | + |
| 219 | +function draw_button (x, y, w, label, toggled) ( |
| 220 | + gfx_a = 1; |
| 221 | + set_color(color_active); |
| 222 | + gfx_rect(x, y - 2, w, 10 + 2, toggled); |
| 223 | + gfx_x = x; gfx_y = y; |
| 224 | + set_color(toggled ? color_bg : color_active); |
| 225 | + gfx_drawstr(label, 1, x+w, y+10); |
| 226 | +); |
| 227 | + |
| 228 | +function draw_waveform(rat, off, is_right) |
| 229 | +global(_amount, gfx_w, gfx_h, gfx_x, gfx_y, winx, winy, winh, winw) |
| 230 | +local(inc, x, y, phase) |
| 231 | +( |
| 232 | + rat *= 2; |
| 233 | + rat < 1 ? rat = 1; |
| 234 | + x = 0; |
| 235 | + phase = off; |
| 236 | + inc = rat / winw; |
| 237 | + |
| 238 | + x = 0; |
| 239 | + gfx_x = x; |
| 240 | + gfx_y = winy + winh/2 + (winh/2 - 1) * gfx_wave(phase, is_right) * _amount; |
| 241 | + |
| 242 | + loop(gfx_w, |
| 243 | + y = winy + winh/2 + (winh/2 - 1) * gfx_wave(phase, is_right) * _amount; |
| 244 | + gfx_lineto(x, y); |
| 245 | + phase += inc; |
| 246 | + x += 1; |
| 247 | + ); |
| 248 | +); |
| 249 | + |
| 250 | +gfx_clear = color_bg; |
| 251 | +mouse.update_mouse_state(); |
| 252 | +set_color(0xffff00); |
| 253 | + |
| 254 | +draw_waveform(_rate_sync > 0 ? tempo / (60 * sync_qnl) : _rate, offsetl, 0); |
| 255 | +set_color(0x00ffff); |
| 256 | +draw_waveform(_rate_sync > 0 |
| 257 | + ? tempo / (60 * sync_qnr) |
| 258 | + : _use_spin ? _rate / (0.25 * pow(16, (_spin + 1) * 0.5)) |
| 259 | + : _rate |
| 260 | +,offsetr,1); |
| 261 | + |
| 262 | +draw_button(10,10,60,"Invert",_invert); |
| 263 | +draw_button(10 + 60 + 10,10, 60,"Spin",_use_spin); |
| 264 | + |
| 265 | +mouse.left_click && mouse_in_rect(10,10,60,12) ? ( |
| 266 | + _invert = !_invert; |
| 267 | +); |
| 268 | + |
| 269 | +mouse.left_click && mouse_in_rect(10+60+10,10,60,12) ? ( |
| 270 | + _use_spin = !_use_spin; |
| 271 | + on_slider(); |
| 272 | +); |
0 commit comments