programextensions/audio/demos/spectrum.xtl

The music visualizer: an Ogg Vorbis (or MP3, WAV) file plays while X_eTaL turns what is playing into a spectrum and the spectrum into 16 spokes in a 3D window -- Rust decodes, plays and draws; the analysis and the picture's geometry are X_eTaL arrays. Run: just demo audio spectrum (Space: pause, j/k: back/on 5 s, q: quit) Another file: change the path below (Ogg Vorbis, MP3 or WAV).

source · imports au: extensions/audio/lib/Audio.xtl; sc: extensions/scene/lib/Scene.xtl; s: std/Stats.xtl

a : Int

value · line 12
a ← ᵃᵘo̲pen "demos/data/arpeggio.ogg"

rate : Float

value · line 13
rate ← 1 s̲elect ᵃᵘi̲nfo a
Used in: t

The analysis: 1024 samples under the playhead, a Hann taper, and the

n : Int

value · line 19

loudness at 8 frequencies an octave apart, 60 Hz to 7680 Hz, for each channel: one inner product with cosine and sine tables (1024 by 8)

n ← 1024
Used in: t, hann, taper, ᵘf̲rame

f : Float

value · line 20
f ← 60.0 120.0 240.0 480.0 960.0 1920.0 3840.0 7680.0
Used in: x

t : Float

value · line 21
t ← (f̲loat r̲ange n) ÷ rate
Used in: x

x : Float

value · line 22
x ← 6.283185307179586 × t '× t̲able f
Used in: ᵘl̲oudness

hann : Float

value · line 23
hann ← 0.5 − 0.5 × c̲os 6.283185307179586 × (f̲loat r̲ange n) ÷ f̲loat n
Used in: taper

taper : Float

value · line 24
taper ← (2 c̲at n) r̲eshape hann
Used in: ᵘl̲oudness

ᵘl̲oudness : Float -> Float

function · line 25
ᵘl̲oudness ← { w →
  v ← w × taper
  re ← v '+ '× i̲nner c̲os x
  im ← v '+ '× i̲nner s̲in x
  m ← ((re × re) + im × im) ^ 0.5
  1.3 × m ÷ m + 12.0
}
Used in: ᵘf̲rame

The picture: 16 spokes, the left channel's 8 on one half of the

k : Float

value · line 37

circle, the right's mirrored on the other; bass nearest the center; loudness lengthens a spoke outward and lifts its tip

k ← f̲loat r̲ange 8
Used in: th, r0

th : Float

value · line 38
th ← 3.141592653589793 × (k − 0.5) ÷ 8.0
Used in: ang

ang : Float

value · line 39
ang ← th c̲at 0.0 − th
Used in: ᵘs̲pokes

r0 : Float

value · line 40
r0 ← 16 r̲eshape 0.35 + 0.16 × k − 1.0
Used in: ᵘs̲pokes

ᵘs̲pokes : Float -> Float

function · line 41
ᵘs̲pokes ← { l →
  len ← r̲avel l
  r1 ← r0 + len
  cs ← c̲os ang
  sn ← s̲in ang
  flat ← (r0 × cs) c̲at (16 r̲eshape 0.0) c̲at (r0 × sn) c̲at (r1 × cs) c̲at (0.9 × len) c̲at r1 × sn
  i ← r̲avel (r̲ange 16) '+ t̲able 16 × (r̲ange 6) − 1
  16 6 r̲eshape i s̲elect flat
}
Used in: ᵘd̲raw

w : Int

value · line 50
w ← "Spectrum -- X_eTaL" ˢᶜo̲pen! 720 540

c : Int

value · line 51
c ← w ˢᶜc̲amera! 0.0 0.9 3.6 0.12

ᵘr̲ows : a -> a

function · line 54

n by 3 points from their x, y and z columns, laid end to end

ᵘr̲ows ← { flat →
  n ← f̲loor (t̲ally flat) ÷ 3
  i ← r̲avel (r̲ange n) '+ t̲able n × (r̲ange 3) − 1
  (n c̲at 3) r̲eshape i s̲elect flat
}
Used in: ring

g : Float

value · line 61

a faint ring where the spokes stand

g ← 6.283185307179586 × (f̲loat r̲ange 65) ÷ 64.0
Used in: ring

ring : Int

value · line 62
ring ← ((f̲loat w c̲at 4) c̲at 0.25 0.27 0.33) ˢᶜp̲olyline! ᵘr̲ows (0.3 × c̲os g) c̲at (65 r̲eshape 0.0) c̲at 0.3 × s̲in g

ᵘd̲raw : Float -> Float

function · line 65

one colored object per band: bass blue, mid green, high orange

ᵘd̲raw ← { l →
  m ← ᵘs̲pokes l
  b ← ((f̲loat w c̲at 1) c̲at 0.25 0.55 1.0) ˢᶜs̲egments! 12 3 r̲eshape r̲avel (1 2 3 9 10 11) s̲elect₁ m
  d ← ((f̲loat w c̲at 2) c̲at 0.3 0.9 0.4) ˢᶜs̲egments! 12 3 r̲eshape r̲avel (4 5 6 12 13 14) s̲elect₁ m
  h ← ((f̲loat w c̲at 3) c̲at 1.0 0.6 0.2) ˢᶜs̲egments! 8 3 r̲eshape r̲avel (7 8 15 16) s̲elect₁ m
  l
}
Used in: ᵘf̲rame

The loop: each frame read an event, then the window, then draw; the

p : Int

value · line 76

spokes ease toward the new loudness so they move smoothly

p ← ᵃᵘp̲lay! a

ᵘq̲uit : Any a => a -> Float

function · line 77
ᵘq̲uit ← { l →
  x ← ˢᶜc̲lose! w
  y ← ᵃᵘc̲lose! a
  2 8 r̲eshape -1.0
}
Used in: ᵘf̲rame

ᵘk̲ey : Char -> Int

function · line 82
ᵘk̲ey ← { e →
  s ← ᵃᵘs̲tate a
  (e m̲atch "key Space") × s = 1 ? ᵃᵘp̲ause! a
  e m̲atch "key Space" ? ᵃᵘp̲lay! a
  e m̲atch "key j" ? f̲loor a ᵃᵘs̲eek! 0.0 m̲ax (ᵃᵘp̲osition a) − 5.0
  e m̲atch "key k" ? f̲loor a ᵃᵘs̲eek! (ᵃᵘp̲osition a) + 5.0
  0
}
Used in: ᵘf̲rame

ᵘf̲rame : Float -> Float

function · line 90
ᵘf̲rame ← { l →
  0.0 > f̲irst r̲avel l ? l
  e ← ˢᶜn̲ext! w
  ((e m̲atch "close") + (e m̲atch "key q") + 0 = ᵃᵘs̲tate a) > 0 ? ᵘq̲uit l
  z ← ᵘk̲ey e
  now ← ᵘl̲oudness a ᵃᵘw̲indow n
  ᵘd̲raw (0.6 × l) + 0.4 × now
}
Used in: last

last : Float

value · line 98
last ← 100000 'ᵘf̲rame p̲ower 2 8 r̲eshape 0.0