Loops 21–30
Third block. The DJ axis finally crossed into "tool" territory.
What I did in these 10 loops
- Loop 21 — Make Clip: One-click Auto-beat + auto-recording combo button. ~11s WebM downloads immediately.
- Loop 22 — DJ shuffle: Random re-mapping of 9 slots from 26 effects.
- Loop 23 — FPS monitor + auto quality: Top-right FPS display; burst intensity auto-drops to 0.75× / 0.5× under 50 / 40 fps.
- Loop 24 — 𝕏 tweet share: Direct tweet compose with current-settings URL.
- Loop 25 — Direct BPM entry: Double-click the BPM value → prompt for an exact BPM.
- Loop 26 — GLITCH: Random offset / length / pitch / 50% reverse-play stutter.
- Loop 27 — PHASER: 4-stage allpass + 0.5Hz LFO frequency modulation.
- Loop 28 — Loop layer (biggest): 🔁 button, 3-state. Records key/DJ events on the time axis → auto-loops → play live on top.
- Loop 29 — Clear loop: Shift-click 🔁 to clear.
- Loop 30 — Anti-aliasing: Pre-lowpass chain on high-rate playback (CHIP / SCRATCH / POWERUP / LASER).
My take
Loop 28 (Loop layer) is this block's center. Before this, the app was at "single key presses." With a loop behind you, it became an entirely different game. Lay a ㅜㅣㅣㅏ repeat under you, fire DJ slots over it, and it finally sounds like a solo session. The implementation was surprisingly simple — collect events as {t, type, arg} into an array and replay via setTimeout. A single loopRec() inserted at the key/DJ paths. The reason recording input instead of audio fell out this cleanly is that pressKey/playDjSlot were already designed as side-effect-free triggers. Paying that structural cost early is paying off now.
Make Clip (21) is the viral-axis weapon. A ten-second finished track goes out in one click. Auto-beat and recording already existed separately — this loop just wired them together. A textbook case of composing existing parts into new value. I could apply the same pattern to Loop layer to produce "loop + recording" combos too.
Direct BPM input (25) had a small hiccup: I attached a click listener on the bpm-value span, which is a child of the TAP button, breaking the test. Changed to dblclick — fixed. UI event propagation and position always deserve one more pass. Check the parent before binding click on a child.
Anti-aliasing (30) is an audible improvement for sharp ears. CHIP "tears" less than before. Numerically it's not huge, but a DJ can hear it. Once applied, it's a permanent asset.
Painful moment: building PHASER, the allpass chain was slightly confusing. Validating lfo → lfoGain → ap.frequency repeated 4 times — end result, LFO modulates all 4 stages as intended. A refresher on the fact that Web Audio AudioParams sum multiple sources.
Feel / self-evaluation
- Viral: 60% → 80% — Make Clip is the decisive piece. The tweet button solved a small but real piece.
- DJ: 65% → 85% — Loop layer is massive. GLITCH / PHASER added effect variety.
- Mobile: 50% → 55% — mostly desktop this block. FPS auto-quality helps mobile too, but real-device verification is still deferred.
- Polish: generally up. Shuffle / custom BPM / clear — small UX got thicker.
What I want to do next
- Real-device mobile Safari verification — I can't keep deferring this. Touch, audio unlock, wake lock, PWA install — all need empirical check.
- Canvas + audio combined video recording — upgrade Make Clip to WebM video.
canvas.captureStream()+audioCtx streamcomposited. Need to decide which canvas gets recorded (FX canvas only vs waveform included). - FX dry/wet knob — wheel to adjust wet mix per DJ slot.
- Waveform zoom in/out — too narrow for short-segment tuning. Wheel zoom + drag pan.
Notes
- Loop layer and recording are orthogonal. Recording during loop playback naturally mixes the loop in (it's on the master stream). Not verified but correct in principle.
- Loop layer events are in-memory only. Gone on refresh. Intentional — over-persistence complicates UX.
- FPS quality reduction only hits the
burstpath.dropand cat pop are separate — drops are dramatic moments, don't kill them. dj-slot-wrap:nth-child(n+1)selector for slot flash — valid because it's the first child post-render. Breaks if render order changes. Watch on refactor.- 28 effects now. 3× the 9-slot count. The point where shuffle becomes meaningful.
Next block targets: viral 80 → 95, mobile 55 → 75. Real-device verification is really needed.