CoolFace
Apppublic

WCA0202/Timbre-Audio-to-Brief

sourceHugging Faceotherupdated 4mo agoView on Hugging Face
0likes
App README

Timbre β€” Audio-to-Brief Engine

![Hugging Face Spaces](https://huggingface.co/spaces/WCA0202/Timbre-Audio-to-Brief) ![Web](https://timbrebrief.com)

Timbre is a two-sided creative marketplace connecting clients who need music made with musicians, producers, and bands who make it. The core product is the Brief Engine β€” it translates a client's emotional description into a structured acoustic specification that musicians can actually execute.


Repository Structure

.
β”œβ”€β”€ app.py                  # Hugging Face / Gradio entry point + JSON API
β”œβ”€β”€ recommend_v2.py         # Semantic matching engine (imported by app.py)
β”œβ”€β”€ requirements.txt        # Production dependencies
β”‚
β”œβ”€β”€ training/               # Offline data pipeline (run once)
β”‚   β”œβ”€β”€ download_songs_v2.py   # Bulk YouTube downloader + Kworb Japan scraper
β”‚   β”œβ”€β”€ build_library.py       # Scan songs/ β†’ data/song_library.csv
β”‚   β”œβ”€β”€ download_models.py     # Download Essentia .pb models (~500 MB)
β”‚   β”œβ”€β”€ extract_features.py    # Feature + genre score extraction
β”‚   β”œβ”€β”€ get_song_emotions.py   # Assign emotion labels
β”‚   └── enrich_metadata.py     # Refresh language + genre columns only
β”‚
β”œβ”€β”€ data/                   # Generated CSVs (gitignored)
β”‚   β”œβ”€β”€ song_features.csv   # Source of truth β€” acoustic + genre data (~9,983 songs)
β”‚   └── song_library.csv    # Song index with language/ISRC
β”‚
β”œβ”€β”€ ui/                     # HF Space frontend assets
β”‚   └── emotion_ui.html     # Standalone interactive bubble UI
β”‚
β”œβ”€β”€ docs/                   # Project documentation
β”‚   β”œβ”€β”€ CONTRIBUTING.md     # Dev setup, scripts, PR checklist
β”‚   β”œβ”€β”€ RUNBOOK.md          # Deployments, health, rollback
β”‚   β”œβ”€β”€ ENV.md              # Environment variables & secrets
β”‚   β”œβ”€β”€ architecture/
β”‚   β”‚   └── backend.md      # D1 + Workers + Stripe design notes
β”‚   └── 剡ζ₯­θ¨ˆεŠƒζ›Έ.md       # Business plan (Chinese)
β”‚
└── web/                    # timbrebrief.com β€” Vite + React SPA
    β”œβ”€β”€ src/
    β”‚   β”œβ”€β”€ App.jsx             # Root β€” page router, global state (darkMode, lang)
    β”‚   β”œβ”€β”€ theme.js            # Light / dark design tokens
    β”‚   β”œβ”€β”€ data.js             # Sample data (emotions, brief, musicians)
    β”‚   β”œβ”€β”€ pages/
    β”‚   β”‚   β”œβ”€β”€ HomePage.jsx         # Hero + Brief preview + trust strip
    β”‚   β”‚   β”œβ”€β”€ ExplorePage.jsx      # Emotion Explorer (full React port)
    β”‚   β”‚   β”œβ”€β”€ HowClientsPage.jsx   # 5-step editorial for clients
    β”‚   β”‚   β”œβ”€β”€ HowMusiciansPage.jsx # 5-step editorial + commission split
    β”‚   β”‚   β”œβ”€β”€ PricingPage.jsx      # Two-column pricing + FAQ accordion
    β”‚   β”‚   β”œβ”€β”€ OnboardingFlow.jsx   # 6-step brief builder + Clerk auth
    β”‚   β”‚   └── Dashboards.jsx       # Client dashboard, ProjectPage, MusicianDashboard
    β”‚   └── components/
    β”‚       β”œβ”€β”€ Nav.jsx              # Global nav β€” page links, dark mode, lang toggle
    β”‚       β”œβ”€β”€ BriefDoc.jsx         # Acoustic brief document component
    β”‚       β”œβ”€β”€ EmotionExplorer.jsx  # Compact bubble selector (legacy; onboarding now uses ExplorePage embedded)
    β”‚       β”œβ”€β”€ EmotionCanvas.jsx    # Canvas-based emotion visualization
    β”‚       β”œβ”€β”€ AcousticRadar.jsx    # Radar chart for acoustic features
    β”‚       β”œβ”€β”€ MusicianCard.jsx     # Musician match card
    β”‚       └── StatusPill.jsx       # Project status badge
    └── public/
        └── songs.json          # ~9,983 songs β€” normalized acoustic data for offline recs

Product Overview

Pages

Route (state)ComponentDescription
homeHomePageHero, brief preview, trust strip, footer
exploreExplorePageFull-screen 4-layer Emotion Explorer
how-clientsHowClientsPageEditorial: how the brief flow works for clients
how-musiciansHowMusiciansPageEditorial: how matching + commission works
pricingPricingPageClient (free) + musician (commission) pricing
onboardingOnboardingFlow6-step guided brief builder
signup-client / signup-musicianSignupPageClerk <SignUp>
loginLoginPageClerk <SignIn>
dashboardClientDashboardSidebar + project list
projectProjectPage3-col: brief / conversation / deliverables
musician-dashboardMusicianDashboardBrief inbox, earnings, profile

Onboarding Flow (6 steps)

  1. 1.Start β€” choose entry point: describe a feeling / upload reference tracks
  2. 2.Explore β€” full ExplorePage (4-layer bubble UI) embedded inline, or upload reference tracks
  3. 3.Purpose β€” placement context, audience, story, commercial vs. personal use
  4. 4.Technical β€” tempo, length, instrumentation, stems, exclusivity, revisions (pre-filled from mood)
  5. 5.Review β€” full BriefDoc preview, all fields editable
  6. 6.Match β€” 3 musician cards matched to the brief; choose one to start the project

Business Model

  • β€”Clients β€” entirely free. Brief engine, Emotion Explorer, matching, project workspace, file delivery, messaging, milestone management.
  • β€”Musicians β€” no subscription, no pay-per-lead. One commission per completed project (the majority of the project fee stays with the musician). Shown as a line item on every transaction.

Trust & Safety Features

  • β€”Escrow payments β€” funds held until client approval
  • β€”Brief-as-contract β€” scope is locked at brief stage
  • β€”Dispute resolution β€” Timbre mediates
  • β€”Transparent commission β€” one line item, always visible

Emotion Explorer

A full-screen interactive 4-layer emotional journey implemented in React (ExplorePage.jsx), ported from the original vanilla JS ui/emotion_ui.html.

Layers:

  1. 1.Core emotion β€” Joy, Calm, Sadness, Anger, Fear, Anticipation (click one or blend two)
  2. 2.Nuance β€” 6 fine-grained descriptors per emotion
  3. 3.Somatic sensation β€” where you feel it in the body
  4. 4.Action urge β€” what the emotion wants to do

After completing the constellation:

  • β€”Emotion path is mapped to a weighted acoustic profile
  • β€”Top-25 matching songs are surfaced from songs.json (fully offline β€” no API call)
  • β€”Client view: paginated reference track list with YouTube search links
  • β€”Musician view: tracks + auto-generated Acoustic Brief (tempo, energy, tone, style tags, production suggestions)

Bilingual: full δΈ­ζ–‡ / English support. Language toggle is global (in Nav) and switches the entire UI mid-session without losing state.


Recommendation Engine

Web (offline, ExplorePage.jsx)

  1. 1.Constellation path β†’ emotion key (from LABEL_TO_KEY map)
  2. 2.Emotion key β†’ acoustic target profile from EMOTION_PROFILES (valence, arousal, mood scores, danceability)
  3. 3.Songs from songs.json scored: score = mood_dot_product βˆ’ distance Γ— 1.5
  4. 4.Top 25 returned, paginated by 5

HF Space (recommend_v2.py)

  1. 1.User text β†’ cosine similarity against 16 EMOTION_DESCRIPTIONS via paraphrase-multilingual-MiniLM-L12-v2
  2. 2.Matched emotion β†’ target feature vector from MOOD_PROFILES
  3. 3.Songs ranked by Euclidean distance in normalized feature space
  4. 4.Primary emotion label: boost=100; neighbouring emotions: boost=30

Isolated ML Microservices (HF Spaces)

Two single-responsibility Gradio Spaces handle on-demand ML inference. Both are stateless and ephemeral β€” no CSV reads/writes.

WCA0202/Timbre-Feature-Extractor

Extracts acoustic features from an uploaded audio file using Essentia.

  • β€”Repo: github.com/willwang0202/Timbre-Feature-Extractor
  • β€”Models: Discogs-EffNet (mood heads + danceability), MusiCNN β†’ DEAM (valence/arousal), RhythmExtractor2013 (BPM)
  • β€”Input: audio file (MP3, WAV, AAC, FLAC, M4A)
  • β€”Output: { "emotion": "melancholic", "features": { "bpm", "valence", "arousal", "mood_*", "danceability" } }
  • β€”Web call: @gradio/client with handle_file(file); large WAV uploads use a longer analysis timeout than the Space startup/connect timeout.
  • β€”API:
  POST /call/analyze_audio   { "data": [<audio>] }  β†’ { "event_id": "..." }
  GET  /call/analyze_audio/{event_id}               β†’ SSE stream

WCA0202/Timbre-Text-to-Emotion

Classifies a free-text mood description into a Timbre emotion + acoustic target profile.

  • β€”Repo: github.com/willwang0202/Timbre-Text-to-Emotion
  • β€”Model: j-hartmann/emotion-english-distilroberta-base (~82MB, DistilRoBERTa fine-tuned on 6 emotion labels)
  • β€”Input: plain text string (e.g. "driving alone at night, feeling weightless")
  • β€”Output: { "emotion": "melancholic", "confidence": 0.87, "acoustic_profile": { "valence", "arousal", "bpm", "mood_*", "danceability" } }
  • β€”API:
  POST /call/classify_mood   { "data": ["mood text"] }  β†’ { "event_id": "..." }
  GET  /call/classify_mood/{event_id}                   β†’ SSE stream

When to call which:

  • β€”Client uploads a track β†’ Timbre-Feature-Extractor
  • β€”Client types a mood description β†’ Timbre-Text-to-Emotion
  • β€”Client uses the Emotion Explorer bubble UI β†’ offline scoring against songs.json (no API call needed)

Running Locally

HF Space (Python/Gradio)

bash
source .venv/bin/activate
python app.py
# http://0.0.0.0:7860

Requires data/song_features.csv. If missing, run the data pipeline first.

Web Frontend

bash
cd web
npm install
npm run dev      # http://localhost:5173
npm run build    # β†’ web/dist/

Environment variable (create web/.env.local):

VITE_CLERK_PUBLISHABLE_KEY=pk_live_...

Data Pipeline (one-time setup)

bash
# 1. Download songs via YouTube (global top 10,000)
python training/download_songs_v2.py

# 2. Download Japanese songs from Kworb.net
python training/download_songs_v2.py --japan

# 3. Scan songs/ β†’ data/song_library.csv
python training/build_library.py

# 4. Download Essentia models (first time only, ~500 MB)
python training/download_models.py

# 5. Extract acoustic + genre features β†’ data/song_features.csv
python training/extract_features.py

# 6. Assign emotion labels
python training/get_song_emotions.py

To regenerate web/public/songs.json after updating data/song_features.csv:

bash
node web/scripts/export-songs.mjs

Enriching without re-extraction

bash
python training/build_library.py
python training/enrich_metadata.py

Deployment

Web β€” Vercel

Configured via vercel.json at repo root.

  • β€”Build command: cd web && npm install && npm run build
  • β€”Build output: web/dist
  • β€”Env vars: VITE_CLERK_PUBLISHABLE_KEY, VITE_SUPABASE_URL, VITE_SUPABASE_ANON_KEY β€” set in Vercel dashboard

Domain: timbrebrief.com β€” registered on Cloudflare Registrar; DNS points at Vercel (A record 76.76.21.21, grey cloud).

Git Remotes

RemoteURLPurpose
originhttps://huggingface.co/spaces/WCA0202/Timbre-Audio-to-BriefHugging Face Spaces (Python app)
githubhttps://github.com/willwang0202/Timbre-Audio-to-BriefGitHub β†’ Vercel (web)

Always push to both:

bash
git push origin main   # β†’ Hugging Face
git push github main   # β†’ GitHub / Vercel

Auth β€” Clerk

  • β€”Package: @clerk/react
  • β€”Production instance tied to timbrebrief.com
  • β€”<ClerkProvider> in main.jsx with global theme tokens
  • β€”Protected routes: dashboard, project, musician-dashboard, onboarding β€” redirect to login when signed out
  • β€”unsafeMetadata.role: 'client' or 'musician' saved on signup

Tech Stack

LayerTech
Web frontendVite + React 18, deployed on Vercel
AuthClerk (@clerk/react)
Emotion UICustom physics bubble engine β€” ported to React
Offline matchingScored against songs.json (9,983 songs)
HF matchingsentence-transformers paraphrase-multilingual-MiniLM-L12-v2
Text-to-emotionj-hartmann/emotion-english-distilroberta-base (HF Space)
Audio feature extractionEssentia β€” Discogs-EffNet, MusiCNN, DEAM (HF Space)
Cloud appGradio on Hugging Face Spaces
Domain / CDNCloudflare Registrar + Vercel

Open TODOs

  • β€”Project workspace β€” project pages read Supabase projects/messages/milestones, store musician deliverables in private Supabase Storage, and move milestones through submit/approve/revision checkpoints; next step is Stripe capture + Connect payout on approved milestones
  • β€”Musician onboarding/profile β€” onboarding now saves matchable profile data to Supabase; next step is runtime audio analysis for uploaded portfolio files
  • β€”Clerk social connections β€” Google OAuth live; Spotify OAuth planned for reference-track import
  • β€”HF cold start β€” free-tier Spaces sleep after 48h; consider $9/mo always-on for Feature Extractor and Text-to-Emotion
  • β€”Wire Text-to-Emotion to frontend β€” StepUpload β†’ Timbre-Feature-Extractor is live; StepExplore free-text input β†’ Timbre-Text-to-Emotion not yet wired (next step: add text input + /classify_mood call in StepExplore)
  • β€”ExplorePage dark mode β€” canvas and bubble UI currently hardcodes light cream palette regardless of darkMode prop

License

All rights reserved. This codebase is proprietary and confidential. Access is granted solely for authorized use. No part of this software may be copied, modified, distributed, or used without explicit written permission from the copyright holder.