openvisengine/src/lib/ava/presets.ts
2026-11-04 05:50:06 +00:00

271 lines
7.9 KiB
TypeScript
Executable file

// AVA — built-in preset scripts
//
// These five presets are adaptations of the real Winamp AVS presets the user
// supplied (Google Drive → visbot.net scene classics). The core math of each
// original Superscope / Texer II concept is preserved and translated to the
// AVA expression dialect. The original binary .avs files ship alongside the
// app in /avs-originals/ for reference and download.
export interface BuiltinPreset {
name: string
author: string
description: string
originalFile?: string
content: string
}
export const STARTER_TEMPLATE = `# AVA visualization script -- starter template
# Tap "Help" in the editor for the full variable & function reference.
name: My Visualization
author: you
mode: lines
blend: additive
persist: 0.85
linewidth: 2
[init]
n = 400
t = 0
[frame]
# t advances faster when the bass hits
t = t + dt * (0.5 + bass)
hue = hue + dt * 0.05
[beat]
flash = 1
[point]
# a circle whose radius breathes with the bass
a = i * 6.28318
rad = 0.2 + bass * 0.5 + flash * 0.05
x = sin(a + t) * rad / aspect
y = cos(a + t) * rad
red = 0.2 + bass
green = 0.8
blue = 0.25 + treb
`
export const BUILTIN_PRESETS: BuiltinPreset[] = [
{
name: 'Gap The Mind',
author: 'synth-c (adapted)',
description:
'Radial waveform circles with the original polar-warp distortion. The radius tracks a rolling average of the audio, treble warps the ring geometry, and the hue sweeps on every beat. Adapted from the Winamp AVS classic (Visbot 17).',
originalFile: '/avs-originals/Synth-C - Gap The Mind.avs',
content: `# Adapted from "Synth-C - Gap The Mind" (Winamp AVS / visbot.net)
# Core of the original Superscope preserved:
# r = i*2pi; d = snd; x = sin(r)*d; y = cos(r)*d
# d = d*(1 - sin((r-pi/2)*7)*.03); r = r + cos(d*12)*.03
name: Gap The Mind
author: synth-c (adapted)
mode: lines
blend: additive
persist: 0.9
linewidth: 2
[init]
n = 480
hue = 0
rot = 0
avg = 0
[frame]
# rolling average of the audio energy (the original used a getosc ring buffer)
avg = avg * 0.8 + (bass + vol) * 0.2
hue = hue + dt * (0.05 + mid * 0.12) + beat * 0.015
rot = rot + dt * (0.1 + mid_att * 0.9)
rad = 0.25 + avg * 0.85
warp = 1 + treb * 0.5
[point]
r = i * 6.28318
d = rad + abs(v) * 0.45
d = d * (1 - sin((r - 1.5708) * 7) * 0.03 * warp)
r = r + cos(d * 12) * 0.03 * warp + rot
x = sin(r) * d / aspect
y = cos(r) * d
red = 0.5 + 0.5 * sin(hue * 6.28318)
green = 0.5 + 0.5 * sin(hue * 6.28318 + 2.094)
blue = 0.5 + 0.5 * sin(hue * 6.28318 + 4.188)
`,
},
{
name: "wonder 'bout",
author: 'zamuz (adapted)',
description:
'A field of rings that spawn, expand and fade -- each at its own tempo, sized by the bass, in stable per-ring colors (the original spawned Texer II ring sprites with random colors and bass-scaled sizes). From the visbot.net classic by zamuz.',
originalFile: '/avs-originals/zamuz - wonder bout.avs',
content: `# Adapted from "wonder 'bout" by zamuz (Winamp AVS / visbot.net)
# The original spawned Texer II ring sprites: ss = ss + .05 per frame,
# size = |ss| * min(w,h)*.006, random color & position on wrap,
# grow-scale sampled from the bass (getspec(.1,.1,0)).
name: wonder 'bout
author: zamuz (adapted)
mode: lines
blend: additive
persist: 0.88
linewidth: 1.8
[init]
n = 480
groups = 12
hue = 0
[frame]
# expansion speed rises with the smoothed bass (original: reg01 = .05/frame)
speed = 0.25 + bass_att * 0.9
hue = hue + dt * 0.1
[point]
g = floor(i * groups)
gi = frac(i * groups)
# per-ring phase, drifting at its own tempo
ph = frac(rand(g * 7.3 + 1) + time * speed * (0.7 + rand(g + 31) * 0.6))
px0 = rand(g + 3.7) * 1.7 - 0.85
py0 = rand(g + 9.1) * 1.7 - 0.85
rad = ph * (0.3 + bass * 0.6)
cr = rand(g + 21.7)
cg = rand(g + 15.3)
cb = rand(g + 27.9)
fade = (1 - ph) * (0.25 + ph * 2.2)
a = 6.28318 * (gi * 1.05 - 0.025)
x = px0 + cos(a) * rad / aspect
y = py0 + sin(a) * rad
red = cr * fade * (0.7 + 0.3 * sin(hue * 6.28318 + g))
green = cg * fade * (0.7 + 0.3 * sin(hue * 6.28318 + g + 2.09))
blue = cb * fade * (0.7 + 0.3 * sin(hue * 6.28318 + g + 4.19))
skip = if(below(gi, 0.025), 1, 0)
`,
},
{
name: 'Quantization',
author: 'synth-c (adapted)',
description:
'Audio-reactive rings snapped to a pixel grid -- the original quantized scope coordinates ((x*40)|0)/40 and rendered a sound heightmap as dot fog. Here the rings are quantized dots that thicken with the mid range.',
originalFile: '/avs-originals/Synth-C - Quantization.avs',
content: `# Adapted from "Synth-C - Quantization" (Winamp AVS / visbot.net)
# Original Superscope: r = i*2pi; d = snd + .5; x = sin(r)*d; y = cos(r)*d
# with pixel quantization x = ((x*40)|0)/40 and a dot-fog sound heightmap.
name: Quantization
author: synth-c (adapted)
mode: dots
blend: additive
persist: 0.82
linewidth: 3
[init]
n = 720
hue = 0
q = 34
avg = 0
[frame]
hue = hue + dt * 0.06
avg = avg * 0.8 + vol * 0.2
rad = 0.28 + avg * 0.75
zoom = 0.9 + bass * 0.3
[point]
r = i * 6.28318
d = rad + abs(v) * 0.4
x0 = sin(r) * d * zoom
y0 = cos(r) * d * zoom
# snap to the quantization grid (the |0 division from the original)
x = floor(x0 * q) / q / aspect
y = floor(y0 * q) / q
red = 0.5 + 0.5 * sin(hue * 6.28318 + d * 3)
green = 0.5 + 0.5 * sin(hue * 6.28318 + d * 3 + 2.09)
blue = 0.5 + 0.5 * sin(hue * 6.28318 + d * 3 + 4.19)
size = 2 + mid * 5
`,
},
{
name: "keep tryin'",
author: 'zamuz (adapted)',
description:
"Bass-driven particle bursts that expand outward with a sinusoidal swirl -- the original spawned white Texer dots with radius = bass*3+.3 and pushed the screen through sin(y*20) swirl movements. Dot size follows the highs.",
originalFile: '/avs-originals/zamuz - keep tryin.avs',
content: `# Adapted from "keep tryin'" by zamuz (Winamp AVS / visbot.net)
# Original Texer II dots: rs = getspec(.1,.1,0)*3 + .3 on spawn,
# swirl movement x = x + .002*sin(y*20); y = y + .002*sin(x*20).
name: keep tryin'
author: zamuz (adapted)
mode: dots
blend: additive
persist: 0.85
linewidth: 3
[init]
n = 900
travel = 0
hue = 0
[frame]
travel = travel + dt * (0.35 + bass_att * 1.2)
swirl = 0.15 + mid * 0.5
hue = hue + dt * 0.15
[point]
d = frac(rand(i + 0.13) + travel)
ang = rand(i + 0.77) * 6.28318 + d * swirl * 6.28318
rad = d * (0.3 + bass * 0.7)
x0 = sin(ang) * rad
y0 = cos(ang) * rad
# the swirl distortion from the original movement
x = x0 + 0.05 * sin(y0 * 20) / aspect
y = y0 + 0.05 * sin(x0 * 20)
fade = sin(d * 3.14159)
red = fade * (0.25 + 0.75 * sin(hue * 6.28318))
green = fade * (0.25 + 0.75 * sin(hue * 6.28318 + 2.09))
blue = fade * (0.25 + 0.75 * sin(hue * 6.28318 + 4.19))
size = 1.5 + treb * 3
`,
},
{
name: 'vorticity',
author: 'synth-c / zamuz (adapted)',
description:
'Swirling spiral arms rotating in a vortex -- the original advected 3D particle trails through a rotating vector field at sound-driven speed. Here six arms twist harder as the mid range rises and the whole vortex spins with the bass.',
originalFile: '/avs-originals/zamuz - vorticity brain activity remix.avs',
content: `# Adapted from "vorticity (brain activity remix)" -- original by synth-c,
# remix by zamuz (Winamp AVS / visbot.net). The original ran 3D particle
# trails through rotating vector fields at sound-driven speed (sndspd = 10).
name: vorticity
author: synth-c / zamuz (adapted)
mode: lines
blend: additive
persist: 0.92
linewidth: 1.6
[init]
n = 1200
t = 0
hue = 0
[frame]
t = t + dt * (0.4 + bass_att * 1.6)
twist = 1.2 + mid * 2.6
zoom = 0.75 + bass * 0.45
hue = hue + dt * 0.04 + beat * 0.01
[point]
arm = floor(i * 6)
fa = frac(i * 6)
d = fa
ang = arm * 1.047 + d * twist * 3.14159 + t
rad = (0.06 + d * d * 1.1) * zoom
x = sin(ang) * rad / aspect
y = cos(ang) * rad
red = (0.3 + 0.7 * d) * (0.35 + bass)
green = (0.3 + 0.7 * d) * (0.25 + mid)
blue = (0.3 + 0.7 * d) * (0.2 + treb + hue * 0.25)
skip = if(below(fa, 0.03), 1, 0)
`,
},
]
/** Download path for each original Winamp .avs file. */
export function originalFileUrl(name: string): string | undefined {
return BUILTIN_PRESETS.find((p) => p.name === name)?.originalFile
}