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
42 changes: 42 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -369,3 +369,45 @@ Public `status` is one of: `matched` · `no_match` · `not_configured` · `inval
## License

[MIT](LICENSE) — free to use and modify.


## Source-reviewed architecture overview

```mermaid
%% Source-reviewed overview; 2026-10-03; commit 2671ccab1802f330083f122561e7ab6c2718dd9f
%% Solid edges: core flow. Dashed edges: optional or separately invoked services.
%%{init: {"theme":"base","securityLevel":"loose","fontFamily":"Arial, sans-serif","themeVariables":{"background":"#0b1220","primaryColor":"#17283d","primaryTextColor":"#edf4ff","primaryBorderColor":"#71c4ec","lineColor":"#9fadc1","secondaryColor":"#213548","tertiaryColor":"#17283d","edgeLabelBackground":"#0b1220","clusterBkg":"#101d2e","clusterBorder":"#456783","fontSize":"17px"},"flowchart":{"htmlLabels":true,"curve":"linear","nodeSpacing":35,"rankSpacing":50}}}%%
flowchart TD
I["Microphone / file input"]
W["CLI + Flask entry points"]
N["Validate + normalize audio"]
D["Matcher + fallback dispatch"]
L["Local hashes + fingerprint index"]
P["Optional remote providers"]
F["CLI FFT diagnostic"]
R["Status / result presentation"]
ART["External album-art URLs"]
I --> W
R -. optional album art .-> ART
W --> N
N --> D
N -.->|CLI diagnostic before matching| F
D -->|configured index| L
D -.->|configured audio/fingerprint request| P
L --> R
P -.->|provider response| R
N -->|invalid audio status| R
click ART "https://github.com/icecold009/Audio-Recognition/blob/2671ccab1802f330083f122561e7ab6c2718dd9f/shazam_project/display.py" "Open source"
click I "https://github.com/icecold009/Audio-Recognition/blob/2671ccab1802f330083f122561e7ab6c2718dd9f/main.py" "Open source"
click W "https://github.com/icecold009/Audio-Recognition/blob/2671ccab1802f330083f122561e7ab6c2718dd9f/web/app.py" "Open source"
click N "https://github.com/icecold009/Audio-Recognition/blob/2671ccab1802f330083f122561e7ab6c2718dd9f/shazam_project/recorder.py" "Open source"
click D "https://github.com/icecold009/Audio-Recognition/blob/2671ccab1802f330083f122561e7ab6c2718dd9f/shazam_project/matcher.py" "Open source"
click L "https://github.com/icecold009/Audio-Recognition/blob/2671ccab1802f330083f122561e7ab6c2718dd9f/shazam_project/fingerprint.py" "Open source"
click P "https://github.com/icecold009/Audio-Recognition/blob/2671ccab1802f330083f122561e7ab6c2718dd9f/shazam_project/matcher.py" "Open source"
click F "https://github.com/icecold009/Audio-Recognition/blob/2671ccab1802f330083f122561e7ab6c2718dd9f/shazam_project/fft_analyze.py" "Open source"
click R "https://github.com/icecold009/Audio-Recognition/blob/2671ccab1802f330083f122561e7ab6c2718dd9f/web/static/app.js" "Open source"
classDef core fill:#17283d,stroke:#71c4ec,stroke-width:1.6px,color:#edf4ff;
class I,W,N,D,L,P,F,R,ART core;
```

See the [architecture case study](docs/architecture/README.md), [coverage](docs/architecture/coverage.md), and [publication evidence and rendered previews](docs/architecture/publication.md).
5 changes: 5 additions & 0 deletions TODO.md
Original file line number Diff line number Diff line change
Expand Up @@ -286,3 +286,8 @@ Record evidence here as work lands:
| 2026-07-31 | Matcher correctness slice | Provider adapters now return stable `error_code` values with diagnostic detail; mocked RapidAPI, AudD, and AcoustID success/no-match/HTTP/timeout/malformed-output tests and temporary-WAV cleanup tests were added. | 36 pytest tests passed; branch coverage is 59%; real provider behavior and credentialed smoke tests remain open |
| 2026-07-31 | Polishing roadmap | Added an ordered eight-task execution roadmap covering benchmark evidence, audio validation, web ownership, production security, test depth, CI/repository hygiene, documentation reconciliation, and distinctiveness evaluation. | Roadmap recorded; complete one main task at a time |
| 2026-07-31 | CI quality-gate slice | `.github/workflows/ci.yml` runs pytest on every push and pull request across Python 3.10–3.12, enforces 50% branch coverage on Python 3.12, and uploads `coverage.xml`. | Workflow structure verified; later PR #4 evidence supersedes the pending remote/Codecov note |


## Architecture documentation publication — 2026-10-04

Goal: publish source-linked architecture documentation and diagram previews. Scope: README, this backlog and docs/architecture artifacts. Source snapshot: 2671ccab1802f330083f122561e7ab6c2718dd9f; no runtime, dependency, data or deployment changes. Acceptance: pinned inventory/source-map/embedding checks, ten intended negative cases, renderer checks, bounded Jev review, documentation-only commit and remotely verified PR. Jev remains advisory; pre-existing workspace changes are excluded.
104 changes: 104 additions & 0 deletions docs/architecture/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
# Audio Recognition: architecture case study

CLI and Flask inputs share a bounded audio contract and configurable recognition backends.

Source snapshot: `2671ccab1802f330083f122561e7ab6c2718dd9f`. Reviewed on **2026-10-03**. This describes the selected committed source, excluding unrelated uncommitted work in the canonical checkout. It is not a runtime, provider, deployment or security certification.

## Overview

```mermaid
%% Source-reviewed overview; 2026-10-03; commit 2671ccab1802f330083f122561e7ab6c2718dd9f
%% Solid edges: core flow. Dashed edges: optional or separately invoked services.
%%{init: {"theme":"base","securityLevel":"loose","fontFamily":"Arial, sans-serif","themeVariables":{"background":"#0b1220","primaryColor":"#17283d","primaryTextColor":"#edf4ff","primaryBorderColor":"#71c4ec","lineColor":"#9fadc1","secondaryColor":"#213548","tertiaryColor":"#17283d","edgeLabelBackground":"#0b1220","clusterBkg":"#101d2e","clusterBorder":"#456783","fontSize":"17px"},"flowchart":{"htmlLabels":true,"curve":"linear","nodeSpacing":35,"rankSpacing":50}}}%%
flowchart TD
I["Microphone / file input"]
W["CLI + Flask entry points"]
N["Validate + normalize audio"]
D["Matcher + fallback dispatch"]
L["Local hashes + fingerprint index"]
P["Optional remote providers"]
F["CLI FFT diagnostic"]
R["Status / result presentation"]
ART["External album-art URLs"]
I --> W
R -. optional album art .-> ART
W --> N
N --> D
N -.->|CLI diagnostic before matching| F
D -->|configured index| L
D -.->|configured audio/fingerprint request| P
L --> R
P -.->|provider response| R
N -->|invalid audio status| R
click ART "https://github.com/icecold009/Audio-Recognition/blob/2671ccab1802f330083f122561e7ab6c2718dd9f/shazam_project/display.py" "Open source"
click I "https://github.com/icecold009/Audio-Recognition/blob/2671ccab1802f330083f122561e7ab6c2718dd9f/main.py" "Open source"
click W "https://github.com/icecold009/Audio-Recognition/blob/2671ccab1802f330083f122561e7ab6c2718dd9f/web/app.py" "Open source"
click N "https://github.com/icecold009/Audio-Recognition/blob/2671ccab1802f330083f122561e7ab6c2718dd9f/shazam_project/recorder.py" "Open source"
click D "https://github.com/icecold009/Audio-Recognition/blob/2671ccab1802f330083f122561e7ab6c2718dd9f/shazam_project/matcher.py" "Open source"
click L "https://github.com/icecold009/Audio-Recognition/blob/2671ccab1802f330083f122561e7ab6c2718dd9f/shazam_project/fingerprint.py" "Open source"
click P "https://github.com/icecold009/Audio-Recognition/blob/2671ccab1802f330083f122561e7ab6c2718dd9f/shazam_project/matcher.py" "Open source"
click F "https://github.com/icecold009/Audio-Recognition/blob/2671ccab1802f330083f122561e7ab6c2718dd9f/shazam_project/fft_analyze.py" "Open source"
click R "https://github.com/icecold009/Audio-Recognition/blob/2671ccab1802f330083f122561e7ab6c2718dd9f/web/static/app.js" "Open source"
classDef core fill:#17283d,stroke:#71c4ec,stroke-width:1.6px,color:#edf4ff;
class I,W,N,D,L,P,F,R,ART core;
```

[Editable Mermaid](overview.mmd). Solid edges show the core flow; dashed edges show optional or separately invoked paths. Diagram connections summarize control/data flow rather than a complete import graph.

## Main flow

A user records or uploads audio through the CLI or Flask interface. The shared recorder validates duration and encoding, then normalizes samples. The dispatcher attempts RapidAPI, AcoustID, AudD, then the local matcher, skipping missing configuration and stopping on success or a terminal result: remote provider adapters send audio or derived fingerprints when enabled, while the local backend searches constellation hashes against a configured index. Results become stable public statuses and CLI or browser output. The CLI runs FFT diagnostics before matching and stops on diagnostic failure; the web route omits FFT.

## Engineering decision

Use one audio contract and one result contract across CLI, browser and recognition backends. This keeps validation and recovery behavior consistent while allowing provider fallback. The tradeoff is dependence on provider catalogs or a locally prepared fingerprint index rather than guaranteed recognition.

## Source map

| Component | Review path |
| --- | --- |
| Microphone / file input | [main.py](../../main.py) |
| CLI + Flask entry points | [web/app.py](../../web/app.py) |
| Validate + normalize audio | [shazam_project/recorder.py](../../shazam_project/recorder.py) |
| Matcher + fallback dispatch | [shazam_project/matcher.py](../../shazam_project/matcher.py) |
| Local hashes + fingerprint index | [shazam_project/fingerprint.py](../../shazam_project/fingerprint.py) |
| Optional remote providers | [shazam_project/matcher.py](../../shazam_project/matcher.py) |
| CLI FFT diagnostic | [shazam_project/fft_analyze.py](../../shazam_project/fft_analyze.py) |
| External album-art URLs | [shazam_project/display.py](../../shazam_project/display.py) |
| Status / result presentation | [web/static/app.js](../../web/static/app.js) |

## Boundaries and limitations

- The local matcher needs an index; remote providers need credentials and may receive the submitted audio when invoked. This differs from Launchpad browser-local audio processing.
- FFT output is diagnostic, not the recognition algorithm. Browser history is session-only; product accounts and persistent history are not implemented.
- No recognition accuracy, latency benchmark, credentialed provider result or public deployment was verified here.

## GitDiagram provenance

GitDiagram draft dated 2026-09-19 and the existing detailed Mermaid/PNG are retained. The reviewed overview emphasizes shared normalization, provider transmission and diagnostic boundaries.

[GitDiagram reference](https://gitdiagram.com/icecold009/Audio-Recognition) · [Repository](https://github.com/icecold009/Audio-Recognition)

The compact overview is a source-reviewed adaptation authored for this snapshot and rendered locally, not an unmodified GitDiagram export. Existing detailed assets remain at [Mermaid](audio-recognition.mmd) and [PNG](audio-recognition.png).

## Interview explanation

> The interesting part is the shared audio and result contracts, not an FFT picture. CLI and Flask normalize inputs consistently, and the matcher isolates local fingerprinting from optional provider adapters. Real accuracy still needs a lawful corpus and measured evaluation.

## Verification and refresh

Documentation-only acceptance: validate every relative source link and commit-specific diagram link, render Mermaid, inspect the dark PNG for readability, inspect the complete diff, and obtain a bounded Jev diff review. The repository proposal contains no new binary images; separately delivered PNG previews are independently checked because Jev reviews text. Results and Jev coverage are recorded in this task’s delivery report rather than treated as application test evidence.

After an architecture change, inspect the new source, update this snapshot identifier, regenerate the overview from Mermaid, and recheck links and image appearance. Keep planned integrations explicitly separate from implemented paths.

## Review status

Integration is pending warning resolution. Earlier Jev uncertainty has not been accepted or waived. The proposed repository changes are text only, including embedded Mermaid; PNG previews are separate delivery outputs. Source claims describe this committed snapshot. The coverage register accounts for tracked paths and does not prove every execution path or deployed behavior.

## Detailed coverage

See [the subsystem diagram and complete tracked-file register](coverage.md) and [editable detail Mermaid](detail.mmd). This supplement records recovery, optional services, delivery boundaries and original-checkout drift beyond the overview.

[Documentation verification record](verification.md).

Source clarification: the CLI invokes FFT diagnostics before matching and stops on a diagnostic error. The web match route does not invoke FFT. When artwork is returned, the CLI display and browser can request its external image URL separately from recognition.
168 changes: 168 additions & 0 deletions docs/architecture/coverage.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
# Subsystem coverage register

Snapshot: `2671ccab1802f330083f122561e7ab6c2718dd9f`. The overview is intentionally compact; this detail layer accounts for the selected Git-tracked tree. Inventory coverage is not proof of every behavior, dynamic dependency, ignored file or deployed system. Nodes group modules rather than reproducing every function. Credentials, local datasets and generated dependencies are excluded.

```mermaid
flowchart TB
%% Solid arrows: runtime/data dependency; dotted arrows: optional, build or local-only boundary.
UI["CLI microphone/PCM and browser capture/upload"]
API["Flask validation, quotas and status/health routes"]
CONVERT["Bounded FFmpeg normalization and temp cleanup"]
DIAG["CLI FFT diagnostic before matching"]
FP["Local constellation fingerprints and index"]
MATCH["Dispatcher: RapidAPI, AcoustID, AudD, then local"]
CONFIG["Runtime configuration and provider policy"]
QUOTA["Atomic Supabase quota schema; in-memory mode"]
TOOLS["Fingerprint index construction and benchmarks"]
RUN["Gunicorn/container and deployment definitions"]
NORM["Shared validated AudioClip normalization"]
REMOTE["RapidAPI / AudD audio; AcoustID fingerprints"]
RESULT["Matched/no-match/not-configured/invalid/error results"]
SUPPORT["Supporting tests, assets, documentation and delivery config"]
ART["External album-art URLs"]
UI --> API
UI -. optional album art .-> ART
UI --> NORM
API --> CONVERT
CONVERT --> NORM
NORM --> MATCH
CONFIG --> API
CONFIG --> MATCH
API --> QUOTA
TOOLS --> FP
RUN -. configured entry .-> API
UI -. CLI diagnostic before matching .-> DIAG
MATCH -. local backend .-> FP
MATCH -. configured remotes .-> REMOTE
MATCH --> RESULT
RESULT --> UI
SUPPORT -. supports .-> UI
```

## Flow and boundary notes

- The CLI captures PCM/WAV; the web upload path normalizes supported formats with bounded FFmpeg execution and temporary-file cleanup. Both paths reach the shared AudioClip normalization and matcher contract. The CLI always performs FFT diagnostics before matching and returns on diagnostic failure. The web match route skips FFT; FFT is not itself the song-identification algorithm.
- The dispatcher attempts RapidAPI, AcoustID, AudD, then the local matcher, skipping unavailable configuration and stopping on a match or other terminal result. It is not local-first. RapidAPI/AudD can receive audio; AcoustID receives derived fpcalc fingerprints. The local backend uses its constellation index. These are separate privacy and network boundaries.
- Status, health and readiness routes differ from recognition success. Quota enforcement can use memory or the atomic Supabase schema. Container/render configuration describes packaging, not verified hosting; benchmark/index scripts are offline tooling.

## Original checkout differences

Pre-existing changed paths at audit: `M supabase/config.toml`, `M web/templates/index.html`. This documentation targets the commit above; these unrelated changes remain in the original checkout.

## File accounting

69 tracked paths, each assigned exactly once below. Supporting items remain explicit without becoming runtime services. Root dependency/build/CI files and otherwise unassigned support files are in DELIVERY; that bucket must be inspected for misclassified runtime modules.

### UI: CLI microphone/PCM and browser capture/upload (7)

- `main.py`
- `shazam_project/display.py`
- `shazam_project/recorder.py`
- `web/static/app.js`
- `web/static/style.css`
- `web/static/typography.css`
- `web/templates/index.html`

### API: Flask validation, quotas and status/health routes (1)

- `web/app.py`

### CONVERT: Bounded FFmpeg normalization and temp cleanup (0)

External or cross-cutting concept; source is shared with other nodes.

### DIAG: CLI FFT diagnostic before matching (1)

- `shazam_project/fft_analyze.py`

### FP: Local constellation fingerprints and index (1)

- `shazam_project/fingerprint.py`

### MATCH: Dispatcher: RapidAPI, AcoustID, AudD, then local (1)

- `shazam_project/matcher.py`

### CONFIG: Runtime configuration and provider policy (2)

- `shazam_project/__init__.py`
- `shazam_project/config.py`

### QUOTA: Atomic Supabase quota schema; in-memory mode (3)

- `supabase/.gitignore`
- `supabase/config.toml`
- `supabase/migrations/20260801145213_production_rate_limits.sql`

### TOOLS: Fingerprint index construction and benchmarks (7)

- `evaluation/sources.example.csv`
- `scripts/__init__.py`
- `scripts/benchmark.py`
- `scripts/build_fingerprint_index.py`
- `scripts/evaluation.py`
- `scripts/record_benchmark.py`
- `scripts/update_readme.py`

### RUN: Gunicorn/container and deployment definitions (4)

- `Dockerfile`
- `compose.yaml`
- `gunicorn.conf.py`
- `render.yaml`
### TEST (16)

- `tests/__init__.py`
- `tests/conftest.py`
- `tests/test_audio_pipeline.py`
- `tests/test_benchmark.py`
- `tests/test_ci_hardening.py`
- `tests/test_config.py`
- `tests/test_core.py`
- `tests/test_deployment.py`
- `tests/test_display.py`
- `tests/test_fingerprint.py`
- `tests/test_providers.py`
- `tests/test_rate_limits.py`
- `tests/test_recorder.py`
- `tests/test_reproducible_benchmark.py`
- `tests/test_web.py`
- `tests/test_web_pipeline.py`

### DOC (17)

- `LICENSE`
- `README.md`
- `TODO.md`
- `docs/01-product-requirements.md`
- `docs/02-technical-requirements.md`
- `docs/03-app-flow.md`
- `docs/04-ui-ux-design-brief.md`
- `docs/05-backend-schema.md`
- `docs/architecture/audio-recognition.mmd`
- `docs/architecture/audio-recognition.png`
- `docs/screenshots/fft-output.png`
- `evaluation/README.md`
- `showcase/audio-recognition/case-study.md`
- `showcase/audio-recognition/diy-shazam-showcase.pptx`
- `showcase/audio-recognition/evidence-checklist.md`
- `showcase/audio-recognition/presentation-outline.md`
- `showcase/audio-recognition/presentation-script.md`

### ASSET (0)

None in this snapshot.

### DELIVERY (9)

- `.dockerignore`
- `.env.example`
- `.gitattributes`
- `.github/container_smoke_wsgi.py`
- `.github/workflows/ci.yml`
- `.gitignore`
- `pyproject.toml`
- `requirements-dev.txt`
- `requirements.txt`

Source clarification: the CLI invokes FFT diagnostics before matching and stops on a diagnostic error. The web match route does not invoke FFT. When artwork is returned, the CLI display and browser can request its external image URL separately from recognition.
Loading
Loading