Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion BACKLOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ Source: `active/sonic-architect-app` (keep in `active/` as reference). Most of t
All eight detectors emit fields visible in [`apps/backend/tests/test_analyze.py`](apps/backend/tests/test_analyze.py) `EXPECTED_TOP_LEVEL_KEYS` and run inside [`apps/backend/analyze_detection.py`](apps/backend/analyze_detection.py).

- ✅ `sidechainDetection.ts` → `sidechainDetail`
- ✅ `acidDetection.ts` → `acidDetail` (see also [`docs/acid-detection-implementation.md`](docs/acid-detection-implementation.md))
- ✅ `acidDetection.ts` → `acidDetail` (historical implementation record archived at [`docs/history/archive/acid-detection-implementation.md`](docs/history/archive/acid-detection-implementation.md))
- ✅ `reverbAnalysis.ts` → `reverbDetail`
- ✅ `vocalDetection.ts` → `vocalDetail`
- ✅ `supersawDetection.ts` → `supersawDetail`
Expand Down
60 changes: 30 additions & 30 deletions apps/backend/ARCHITECTURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -190,42 +190,42 @@ Query parameters accepted by both routes:
- `phase1`
- `diagnostics`

`phase1` contains normalized scalars:

- `bpm`
- `bpmConfidence`
- `bpmPercival`
- `bpmAgreement`
- `key`
- `keyConfidence`
- `keyProfile`
- `tuningFrequency`
- `tuningCents`
- `timeSignature`
- `durationSeconds`
- `sampleRate`
- `lufsIntegrated`
- `lufsRange`
- `lufsMomentaryMax`
- `lufsShortTermMax`
- `truePeak`
- `crestFactor`
- `dynamicSpread`
- `stereoWidth`
- `stereoCorrelation`
- `spectralBalance`

`phase1` forwards these raw analyzer sections unchanged:

- `dynamicCharacter`
`phase1` contains normalized scalars (see [`server_phase1.py`](server_phase1.py) `_build_phase1` for the authoritative list):

- BPM family: `bpm`, `bpmConfidence`, `bpmPercival`, `bpmAgreement`, `bpmDoubletime`, `bpmSource`, `bpmRawOriginal`
- Key family: `key`, `keyConfidence`, `keyProfile`, `tuningFrequency`, `tuningCents`
- Time signature: `timeSignature`, `timeSignatureSource`, `timeSignatureConfidence`
- Duration / sample rate: `durationSeconds`, `sampleRate`
- Loudness: `lufsIntegrated`, `lufsRange`, `lufsMomentaryMax`, `lufsShortTermMax`, `lufsCurve`, `truePeak`, `plr`, `crestFactor`, `dynamicSpread`
- Dynamics character: `dynamicCharacter`, `textureCharacter`
- Stereo: `stereoWidth`, `stereoCorrelation`, `monoCompatible`
- Spectral balance: `spectralBalance` (seven-band scalar object)

`phase1` forwards these raw analyzer sections (re-normalized where noted):

- `stereoDetail`
- `spectralDetail`
- `rhythmDetail` (includes `tempoStability`, `phraseGrid`)
- `spectralDetail` (per-stem keys are renamed to the top-level `Mean`-suffix shape by `_normalize_spectral_detail`)
- `spectralBalanceTimeSeries`
- `stemAnalysis` (per-stem spectralDetail renamed to match the top-level contract by `_normalize_stem_analysis`)
- `transientDensityDetail`
- `saturationDetail`
- `snareDetail`
- `hihatDetail`
- `rhythmDetail` (includes `tempoStability`, `phraseGrid`, `tempoCurve`)
- `rhythmTimeline`
- `melodyDetail`
- `transcriptionDetail`
- `pitchDetail`
- `grooveDetail`
- `beatsLoudness`
- `sidechainDetail` (includes `envelopeShape`)
- `acidDetail`
- `reverbDetail`
- `vocalDetail`
- `supersawDetail`
- `bassDetail`
- `kickDetail`
- `genreDetail`
- `effectsDetail`
- `synthesisCharacter`
- `danceability`
Expand Down
39 changes: 19 additions & 20 deletions apps/backend/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ FastAPI also serves the usual generated endpoints at `/openapi.json`, `/docs`, a

## Tech Stack

- Python 3.10+
- Python `3.11.x` (required — Essentia 2.1b6 wheels are only published for 3.11 on macOS arm64)
- Essentia
- NumPy
- Demucs
Expand Down Expand Up @@ -62,7 +62,7 @@ Bootstrap contract for this monorepo `v1.0.0` cut:
### Command

```bash
./venv/bin/python analyze.py <audio_file> [--separate] [--transcribe] [--fast] [--yes] [--pitch-note-backend BACKEND]
./venv/bin/python analyze.py <audio_file> [--separate] [--transcribe] [--fast] [--standard] [--yes] [--pitch-note-only] [--stem-dir DIR] [--stem-output-dir DIR] [--pitch-note-backend BACKEND]
```

### Flags
Expand All @@ -72,8 +72,12 @@ Bootstrap contract for this monorepo `v1.0.0` cut:
| `<audio_file>` | Required input path. |
| `--separate` | Runs Demucs before melody analysis. If `--transcribe` is also enabled, the selected pitch backend uses the `bass` and `other` stems when they exist. |
| `--transcribe` | Runs the selected pitch backend and returns `transcriptionDetail`. Without Demucs it transcribes the full mix; with Demucs it transcribes `bass` and `other` separately and merges the notes. |
| `--pitch-note-backend BACKEND` | Selects the Layer 2 backend for `--pitch-note-only`. Supported values are `auto`, `torchcrepe-viterbi`, and alias `torchcrepe`. |
| `--fast` | Runs the reduced fast-analysis preset. Core fields such as BPM, key, duration, LUFS, true peak, and crest factor are populated; most detail-heavy fields remain `null`. |
| `--standard` | Runs the standard analysis preset (mid-tier between `--fast` and the full pipeline). |
| `--pitch-note-only` | Runs only the Layer 2 pitch/note translation stage, prints its JSON, and exits. Used by the staged-runs runtime so it can call the pitch-note worker separately from full measurement. |
| `--stem-dir DIR` | When combined with `--pitch-note-only`, reads previously-separated Demucs stems from `DIR` instead of re-running Demucs. |
| `--stem-output-dir DIR` | When combined with `--pitch-note-only`, writes any newly separated stems into `DIR` so the runtime can persist them as artifacts. |
| `--pitch-note-backend BACKEND` | Selects the Layer 2 backend for `--transcribe` and `--pitch-note-only`. Supported values are `auto`, `torchcrepe-viterbi`, and alias `torchcrepe`. |
| `--yes` | Skips the interactive confirmation prompt after the CLI prints its runtime estimate. |

### Runtime Behavior
Expand Down Expand Up @@ -306,23 +310,18 @@ Compatibility note:

- `backendDurationMs` remains the subprocess wall time for backward compatibility and matches `diagnostics.timings.analysisMs`.

`phase1` currently contains these normalized scalar fields:

- `bpm`
- `bpmConfidence`
- `key`
- `keyConfidence`
- `timeSignature`
- `durationSeconds`
- `lufsIntegrated`
- `lufsRange`
- `truePeak`
- `crestFactor`
- `stereoWidth`
- `stereoCorrelation`
- `spectralBalance`

All raw `analyze.py` fields are now forwarded through the server `phase1` wrapper. See `JSON_SCHEMA.md` for the complete list of forwarded sections and scalar fields.
`phase1` currently contains these normalized scalar fields (see [`server_phase1.py`](server_phase1.py) `_build_phase1`):

- `bpm`, `bpmConfidence`, `bpmPercival`, `bpmAgreement`, `bpmDoubletime`, `bpmSource`, `bpmRawOriginal`
- `key`, `keyConfidence`, `keyProfile`, `tuningFrequency`, `tuningCents`
- `timeSignature`, `timeSignatureSource`, `timeSignatureConfidence`
- `durationSeconds`, `sampleRate`
- `lufsIntegrated`, `lufsRange`, `lufsMomentaryMax`, `lufsShortTermMax`, `lufsCurve`
- `truePeak`, `plr`, `crestFactor`, `dynamicSpread`, `dynamicCharacter`, `textureCharacter`
- `stereoWidth`, `stereoCorrelation`, `monoCompatible`
- `spectralBalance` (seven-band scalar object)

All raw `analyze.py` fields are now forwarded through the server `phase1` wrapper, including the previously-omitted `bpmPercival`, `bpmAgreement`, `dynamicCharacter`, `textureCharacter`, `segmentStereo`, and `essentiaFeatures`. See `JSON_SCHEMA.md` for the complete list of forwarded sections and scalar fields.

Example:

Expand Down
2 changes: 1 addition & 1 deletion apps/ui/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ All notable changes to `sonic-analyzer-UI` are documented here in reverse chrono

### UI/UX Improvements (Tiers 1–3)

Implemented all 15 items from the UI/UX improvement plan (`UI_UX_IMPROVEMENTS.md`). `npm run verify` passes: typecheck clean, 73 unit tests, production build, 33 smoke tests.
Implemented all 15 items from the UI/UX improvement plan (archived at [`docs/history/archive/ui-ux-improvements.md`](../../docs/history/archive/ui-ux-improvements.md)). `npm run verify` passes: typecheck clean, 73 unit tests, production build, 33 smoke tests.

#### Tier 1 — High-impact, low-risk

Expand Down
25 changes: 22 additions & 3 deletions apps/ui/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -214,25 +214,44 @@ Core measurement fields the app depends on after projection:
- `stereoCorrelation`
- `spectralBalance`

Expanded `phase1` sections the current app can consume:
Expanded `phase1` sections the current app can consume (see [`src/types/measurement.ts`](src/types/measurement.ts) `Phase1Result` for the full contract):

- `stereoDetail`
- `spectralDetail`
- `spectralBalanceTimeSeries`
- `lufsCurve`
- `stemAnalysis`
- `transientDensityDetail`
- `saturationDetail`
- `snareDetail`
- `hihatDetail`
- `rhythmDetail`
- `rhythmTimeline`
- `melodyDetail`
- `transcriptionDetail`
- `pitchDetail`
- `grooveDetail`
- `beatsLoudness`
- `sidechainDetail`
- `acidDetail`
- `reverbDetail`
- `vocalDetail`
- `supersawDetail`
- `bassDetail`
- `kickDetail`
- `genreDetail`
- `effectsDetail`
- `synthesisCharacter`
- `danceability`
- `structure`
- `arrangementDetail`
- `segmentLoudness`
- `segmentSpectral`
- `segmentStereo`
- `segmentKey`
- `chordDetail`
- `perceptual`
- `essentiaFeatures`

Diagnostics fields the UI uses or preserves:

Expand All @@ -249,9 +268,9 @@ Diagnostics fields the UI uses or preserves:
- `stdoutSnippet`
- `stderrSnippet`

Important current limitations:
Current contract notes:

- the backend omits raw analyzer fields such as `bpmPercival`, `bpmAgreement`, `dynamicCharacter`, `segmentStereo`, and `essentiaFeatures`, so the UI never receives them from `server.py`
- all raw `analyze.py` fields are now forwarded through the server `phase1` wrapper. Fields that were previously dropped (`bpmPercival`, `bpmAgreement`, `dynamicCharacter`, `segmentStereo`, `essentiaFeatures`, …) are now part of the HTTP envelope.

### Error Response

Expand Down
4 changes: 3 additions & 1 deletion docs/history/archive/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ Historical and invalidated docs kept for reference. **Nothing here is current.**
| [refactor-state-2026-03-18.md](refactor-state-2026-03-18.md) | Completion record for Phase A/B1/B2 refactor — now done. |
| [stage3-reality-audit-2026-03-18.md](stage3-reality-audit-2026-03-18.md) | Point-in-time audit. Findings resolved or rolled into the canonical staged-runs API. |
| [confidence-calibration-results-stubs.md](confidence-calibration-results-stubs.md) | Calibration run against stub data, not real audio. Results invalid; thresholds reverted. |
| [phase1-hardening-plan-alt.md](phase1-hardening-plan-alt.md) | Duplicate of root `PLAN-phase1-hardening.md`. Line numbers invalidated by the `analyze.py` module split. |
| [phase1-hardening-plan-alt.md](phase1-hardening-plan-alt.md) | Duplicate of the sibling [`../phase1-hardening-plan.md`](../phase1-hardening-plan.md). Line numbers invalidated by the `analyze.py` module split. |
| [acid-detection-implementation.md](acid-detection-implementation.md) | Completion record for the `acidDetail` detector backport. Cites the pre-split `analyze.py` and a "What's Next" list that has since fully shipped. |
| [ui-ux-improvements.md](ui-ux-improvements.md) | Completion record for the three-tier UI/UX polish workstream. All tiers shipped; moved out of `apps/ui/` so that app directory holds only living docs. |

When archiving more docs: prepend an archive note (`> **Archived YYYY-MM-DD.** …`) so readers landing in the file know its status without reading this index.
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# Acid Detection — Implementation Record

> **Archived 2026-05-13.** Completion record for the `acidDetail` backport from 2026-03-18. Several references here are no longer accurate: the implementation now lives in [`analyze_detection.py`](../../../apps/backend/analyze_detection.py) (not `analyze.py`) after the module split in commit `5c40dd44`; the test constant is `EXPECTED_TOP_LEVEL_KEYS` (not `EXPECTED_OUTPUT_KEYS`); and every item in the "What's Next" list at the bottom has since shipped — see [`BACKLOG.md`](../../../BACKLOG.md) under "Shipped — Detectors". Use this file only as a historical narrative for the original detector port.

**Date:** 2026-03-18
**Feature:** `acidDetail` — TB-303 acid bassline detection
**Source:** Backported from `active/sonic-architect-app/services/acidDetection.ts`
Expand Down
2 changes: 1 addition & 1 deletion docs/history/archive/phase1-hardening-plan-alt.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Phase 1 Hardening Plan (alt)

> **Archived 2026-05-12.** Superseded by the more detailed [`PLAN-phase1-hardening.md`](../../PLAN-phase1-hardening.md) at the repo root. Both plans pre-date the `analyze.py` module split (commit `5c40dd44`), so every Python line number they cite is now invalid — the functions live in `analyze_core.py`, `analyze_detection.py`, `analyze_rhythm.py`, `analyze_structure.py`, `analyze_segments.py`, and `analyze_transcription.py`. Use this file only for the framing of what hardening targets were originally proposed; ship status lives in [`CHANGELOG.md`](../../CHANGELOG.md).
> **Archived 2026-05-12.** Superseded by the more detailed [`phase1-hardening-plan.md`](../phase1-hardening-plan.md) one level up in `docs/history/`. Both plans pre-date the `analyze.py` module split (commit `5c40dd44`), so every Python line number they cite is now invalid — the functions live in `analyze_core.py`, `analyze_detection.py`, `analyze_rhythm.py`, `analyze_structure.py`, `analyze_segments.py`, and `analyze_transcription.py`. Use this file only for the framing of what hardening targets were originally proposed; ship status lives in [`CHANGELOG.md`](../../../CHANGELOG.md).

## Context

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# UI/UX Improvement Plan

> **Archived 2026-05-13.** Completion record for the three-tier UI/UX polish workstream. Every tier shipped; verification numbers (33 smoke / 73 unit) reflect the snapshot at archive time and have since grown — see [`apps/ui/CHANGELOG.md`](../../../apps/ui/CHANGELOG.md) for current counts. Moved here from `apps/ui/UI_UX_IMPROVEMENTS.md` so the app directory holds only living docs.

Prioritized backlog of UI/UX improvements for `sonic-analyzer-UI`.
All three tiers are implemented.

Expand Down
2 changes: 1 addition & 1 deletion docs/history/optimization-plan.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Phase 1/Phase 2 Integration Optimization Plan

> **Status: shipped (Q1 2026 — historical reference only).** Most items in this plan landed; see [`CHANGELOG.md`](CHANGELOG.md) for ship status. Some HOLD gates here cite older module structure — the `analyze.py` monolith has since been split (commit `5c40dd44`) into `analyze_core/_detection/_rhythm/_segments/_structure/_transcription.py`, so line-number references in this file are no longer valid. Don't drive new work from this document; use it for the framing of the original optimization targets.
> **Status: shipped (Q1 2026 — historical reference only).** Most items in this plan landed; see [`CHANGELOG.md`](../../CHANGELOG.md) for ship status. Some HOLD gates here cite older module structure — the `analyze.py` monolith has since been split (commit `5c40dd44`) into `analyze_core/_detection/_rhythm/_segments/_structure/_transcription.py`, so line-number references in this file are no longer valid. Don't drive new work from this document; use it for the framing of the original optimization targets.

**Target:** ableton-sonic-analyzer monorepo
**Goal:** Maximize value extraction from local DSP + LLM integration
Expand Down
2 changes: 1 addition & 1 deletion docs/history/phase1-hardening-plan.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Plan: Phase 1 Hardening

> **Status: partially shipped — historical reference.** Most items in this plan landed across Q1–Q2 2026; see [`CHANGELOG.md`](CHANGELOG.md) for ship status. The plan pre-dates the `analyze.py` module split (commit `5c40dd44`), so every Python line-number reference below is invalid — the functions now live in `analyze_core/_detection/_rhythm/_segments/_structure/_transcription.py`. The alt version of this plan ([`docs/archive/phase1-hardening-plan-alt.md`](docs/archive/phase1-hardening-plan-alt.md)) is fully archived. Use this file for the framing of original hardening targets, not for line numbers.
> **Status: partially shipped — historical reference.** Most items in this plan landed across Q1–Q2 2026; see [`CHANGELOG.md`](../../CHANGELOG.md) for ship status. The plan pre-dates the `analyze.py` module split (commit `5c40dd44`), so every Python line-number reference below is invalid — the functions now live in `analyze_core/_detection/_rhythm/_segments/_structure/_transcription.py`. The alt version of this plan ([`archive/phase1-hardening-plan-alt.md`](archive/phase1-hardening-plan-alt.md)) is fully archived. Use this file for the framing of original hardening targets, not for line numbers.

Pass all measurements through the pipeline, add DSP extensions, expose everything in the UI.

Expand Down