# Desktop ↔ Web Comparison: comm-in-thread-forum__39_blues_machine

- **Timestamp:** 2026-06-18T15:06:10.757Z
- **Capture window:** 30000 ms

## Code
```ruby
# Source: https://in-thread.sonic-pi.net/t/blues-machine-12-bar-blues-variations/9619
# Author: rothen_s
# Title: Blues Machine - 12-Bar-Blues-Variations
# Captured: 2026-04-24

use_bpm 80
use_random_seed 70

# Chord diffs relative to the root (halftone steps)
g_chord_diffs = [0, [0,5], 0, 0,
 5, 5, 0, 0,
 7, 5, 0, [0,7]]
g_licks = {
 lick_pause:
 [[:r],[4]],
 lick_cjamblues_1:
 [[3,0,3,0], [0.5,0.5,0.5,2.5]],
 lick_cjamblues_2:
 [[7,5,3,0],[0.5,0.5,0.5,2.5]],
 lick_cjamblues_3:
 [[:r, 0],[2,2]],
 lick_cjamblues_4:
 [[5,3,0,:r],[1,0.5,1.5,1]],
 lick_cjamblues_5:
 [[-2,-2,0,3,0,-2, 0],[0.5,0.5,1.0,0.5,0.5,0.5,0.5]]
}

g_max = g_licks.length - 1

g_sleep = 4
g_times = 1
g_grundton = :C3
g_note = g_grundton

# Drums
with_fx :reverb, room: 0.6, mix: 0.3 do
 live_loop :ll_drums do
 with_fx :compressor, threshold: 0.2, slope_above: 0.5 do
 sample :drum_bass_hard, amp: [1.3,1.5,1.7].choose
 sleep 0.5
 p_times = 1
 if one_in 4 then
 p_times = [1,2,3].choose
 end
 p_times.times do
 sample [:drum_snare_soft, :drum_snare_hard].choose, amp: [1.1,1.4,1.6].choose
 sleep 0.5 / p_times
 end
 end
 end
end

# Chords
live_loop :ll_chords, delay: 8 do
 use_synth :piano
 use_synth_defaults decay: g_sleep, amp: 2

 g_chord_diffs.each do |p_diff|
 if p_diff.kind_of?(Array) then
 l_diff = p_diff.choose
 else
 l_diff = p_diff
 end
 g_note = g_grundton + l_diff
 if l_diff == 0 then
 l_chord = (chord g_note, '6')
 else
 l_chord = (chord g_note, '7')
 end
 g_times.times do
 play l_chord
 sleep g_sleep
 end
 end
end

# Licks
with_fx :reverb, room: 0.6, mix: 0.3 do
 live_loop :ll_licks, delay: 8 do
 use_synth :pluck
 use_synth_defaults amp: 4, coef: [0.2,0.3,0.4].choose, sustain: 0.5
 temp_num = rrand_i(0, g_max)
 p_lick = g_licks.values[temp_num]
 l_notes = p_lick[0].map {|a| a + 12 + note_info(g_note).midi_note}
 play_pattern_timed l_notes, p_lick[1]
 end
end

# Bass
live_loop :ll_bass, delay: 4 do
 use_synth :bass_foundation
 l_note = g_note - 24
 play l_note, release: 0.5, amp: 1.5
 sleep 0.5
 play l_note + 7, release: 0.5, amp: 1.2
 sleep 0.5
 play l_note + 12, release: 0.5, amp: 1
 sleep 0.5
 play l_note + 7, release: 0.5, amp: 1.3
 sleep 0.5
end
```

## Stats (Level 3 — observation, not inference)

| Metric | Desktop SP | SonicPi.js (web) | Δ (desk − web) |
|---------------|------------------------|-------------------------|----------------|
| Duration (s) | 31.369 | 29.696 | 1.673 |
| Peak | 1.0000 | 0.3805 | 0.6195 |
| RMS | 0.1219 | 0.0639 | 0.0580 |
| Clipping (%) | 0.00 | 0.00 | 0.00 |
| Sample rate (Hz) | 48000 | 48000 | 0 |
| Channels | 2 | 2 | — |

## Verdict
### ❌ EVENT-DIVERGE — per-synthdef `/s_new` onset-sequence/notes diverge from desktop : Web DROPPED 1 significant layer(s) desktop produces: pluck×17. Real engine divergence (the audio verdict stands; the cos heuristic does not apply).

### Tier 0 — Validity gates
- ✓ 0.1 Sample rate consistent (48000 Hz)
- ⚠ 0.2 Capture-window misaligned (Δ 1.67s > 0.5s) — note-count / level aggregates unreliable **(SOFT — Tier 3 + 1.3 unreliable; Tier 1 pitch still valid)**
- ◦ 0.3 equal preconditions / 0.4 lossless capture / 0.5 routing sanity — not auto-checked; ensure SP.app reset + raw-float32 + FX-bus wired 

### Tier 1 — Musical correctness (THE verdict — energy/MFCC may never override)
- **1.1 Note progression:** ✗ PITCH DIVERGENCE at note 2 (desktop 42 vs web 40)
 - method: desktop `onset` (conf 1) · web `onset` (conf 1)
 - desktop: `41,56,42,56,41,56,41,56,43,56,41,43,43,56,41,43,57,55,55,55,55,55,55,55`
 - web&nbsp;&nbsp;&nbsp;: `41,56,40,54,40,54,41,56,43,56,48,43,43,43,41,43,52,52,60`
- **1.2 Tempo (inter-onset):** ✓ desktop 0.380s · web 0.380s/note
- **1.3 Onset count:** desktop 28 · web 19 (Δ explained by Tier-0 window misalignment)
- ◦ 1.4 note duration / 1.5 polyphony / 1.6 determinism — not auto-tracked here (unit tests cover determinism; see /)

### Tier 1.0 — Event parity (`/s_new` onset-sequence vs desktop — authoritative tiebreaker)
- **Structure (synthdef multiset):** STRUCTURE-DIVERGE — desktop 220 voice `/s_new`, web 199
- **Onset sequence (ε=15ms, prefix-compared, + per-tick NOTE multiset):** ✗ DIVERGE
 - ✓ `basic_mono_player` — 89 onsets within ε (max Δ 0ms), notes match
 - ✗ `bass_foundation` — onset times match within ε but per-tick NOTE multiset differs — wrong notes (transposition?)
 - ✓ `piano` — 36 onsets within ε (max Δ 0ms), notes match
- ❌ **NOT event-match:** STRUCTURE-DIVERGE — Web DROPPED 1 significant layer(s) desktop produces: pluck×17 (real engine divergence; the audio verdict stands).

### Tier 3 — Level / gain (reported; NOT a musical-correctness blocker — known ~0.5× web gain-staging)
> ⚠ Tier-0 SOFT failed — these ratios span misaligned windows; treat as indicative only.
- 3.1 RMS ratio web/desktop = 0.52× (within 0.5–2× band)
- 3.2 Peak ratio web/desktop = 0.38×
- 3.3 Clipping: desktop 0% · web 0% ✓ (< 1%)

### Tier 2 — Spectral / timbral (supporting only) · Tier 4 — FX/routing · Tier 5 — lifecycle
- Tier 2: see **Spectrogram comparison** section below (MFCC carries its mandatory caveat there).
- Tier 4 (FX accumulation/suppression 200ms scan, per-FX-scope energy): **not analysed** by this tool — use the FX-sweep / boundary-scan tools when FX is in scope.
- Tier 5 (Run/Stop/hot-swap, cold-start, long-run drift): **not analysed** — single capture; use `tools/test-run-stop-cycle.ts` for lifecycle.

## Source WAVs
- **Desktop:** /Users/mrityunjaybhardwaj/Documents/projects/sonicPiWeb/.captures/desktop-recordings/desktop_2026-06-18T15-04-55-482Z_comm-in-thread-forum__39_blues_machine.wav
- **Web:** /Users/mrityunjaybhardwaj/Documents/projects/sonicPiWeb/.captures/2026-06-18T15-04-56-679Z_inline_audio.wav

## Spectrogram comparison
![spectrogram comparison](/Users/mrityunjaybhardwaj/Documents/projects/sonicPiWeb/.captures/compare_2026-06-18T15-05-32-682Z_comm-in-thread-forum__39_blues_machine_spectrogram.png)

| Metric | Value | Reading |
|---|---|---|
| L2 distance (mel-dB) | 14.50 | < 10 = very close · 10–25 = similar shape · > 25 = divergent |
| MFCC distance (timbre) | 141.63 | < 30 = similar · 30–80 = noticeably different · > 80 = unrelated |
| ↳ MFCC caveat | — | **Tier-2 supporting only.** Confounded by the known ~0.5× web gain ratio + desktop reverb-tail length; **never overrides Tier 1** . A high MFCC with a Tier-1 PITCH-MATCH means timbre/gain, not wrong notes. |
| Frames compared | 2785 | overlapping window after length-aligning |
| Peak freq desktop | 196.3 Hz | dominant frequency |
| Peak freq web | 165.2 Hz | dominant frequency |
⚠ MFCC distance 141.63 is high — **check Tier 1 first**: if pitch-track matched, this is timbre/gain (the known 0.5× + reverb tail), NOT wrong notes. Only treat as "different synth/sample chain" when Tier 1 also diverges.

## Tool stdout (debug)
### Desktop
```
▶ Desktop capture (30000ms): comm-in-thread-forum__39_blues_machine
✓ Report: /Users/mrityunjaybhardwaj/Documents/projects/sonicPiWeb/.captures/desktop_2026-06-18T15-04-55-482Z_comm-in-thread-forum__39_blues_machine.md
✓ WAV: /Users/mrityunjaybhardwaj/Documents/projects/sonicPiWeb/.captures/desktop-recordings/desktop_2026-06-18T15-04-55-482Z_comm-in-thread-forum__39_blues_machine.wav
 31.37s · peak 1 · RMS 0.1219 · clip 0%
```
### Web
```
Launching Chromium (headed, audio capture)...
 Running: inline (30000ms)...

Capture saved: /Users/mrityunjaybhardwaj/Documents/projects/sonicPiWeb/.captures/inline.md
No errors detected.
```