From 8b917c78ad593f55bcf0f8a107fa947a7a6db229 Mon Sep 17 00:00:00 2001 From: orfelorfel23 Date: Sat, 12 Sep 2026 23:55:22 +0200 Subject: [PATCH] fix(wheel): align camelot wheel and key mappings with Mixed In Key standard --- db/schema.sql | 118 +++++++++++++++++----------------- docs/KeySelector_SPEC.md | 104 +++++++++++++++--------------- public/search.js | 24 +++---- public/wheel.js | 16 ++--- server/routes/metadata.js | 76 +++++++++++++++++----- shared/camelot-to-musickey.js | 24 +++---- shared/color-matrix.js | 24 +++---- 7 files changed, 216 insertions(+), 170 deletions(-) diff --git a/db/schema.sql b/db/schema.sql index 8c8ab84..1654570 100644 --- a/db/schema.sql +++ b/db/schema.sql @@ -23,75 +23,75 @@ CREATE INDEX IF NOT EXISTS idx_tracks_bpm ON tracks(bpm); CREATE INDEX IF NOT EXISTS idx_tracks_artist ON tracks(artist); CREATE INDEX IF NOT EXISTS idx_tracks_title ON tracks(title); --- Initial curated seed data across all 24 Camelot keys +-- Initial curated seed data across all 24 Camelot keys (Mixed In Key Standard) INSERT INTO tracks (artist, title, camelot_key, bpm, music_key, tags, source) VALUES --- 1B & 1A (C-Dur / A-Moll) -('Axwell /\\ Ingrosso', 'More Than You Know', '1B', 123, 'C', ARRAY['house', 'edm'], 'seed'), -('Avicii', 'The Nights', '1B', 126, 'C', ARRAY['dance', 'melodic'], 'seed'), -('Tiësto', 'The Business', '1A', 120, 'Am', ARRAY['deep house', 'bass'], 'seed'), -('Meduza', 'Piece Of Your Heart', '1A', 124, 'Am', ARRAY['house', 'electronic'], 'seed'), +-- 12B & 12A (E-Dur / C#-Moll) +('Avicii', 'Wake Me Up', '12B', 124, 'E', ARRAY['folk-dance', 'anthem'], 'seed'), +('Otto Knows', 'Million Voices', '12B', 126, 'E', ARRAY['progressive house'], 'seed'), +('Fred again..', 'Delilah (pull me out of this)', '12A', 134, 'C#m', ARRAY['electronic', 'club'], 'seed'), +('Robin Schulz', 'Sugar', '12A', 123, 'C#m', ARRAY['deep house', 'pop'], 'seed'), --- 2B & 2A (G-Dur / E-Moll) -('Calvin Harris', 'Summer', '2B', 128, 'G', ARRAY['dance', 'summer'], 'seed'), -('David Guetta ft. Sia', 'Titanium', '2B', 126, 'G', ARRAY['edm', 'pop'], 'seed'), -('Martin Garrix', 'Animals', '2A', 128, 'Em', ARRAY['big room', 'electro'], 'seed'), -('Fisher', 'Losing It', '2A', 125, 'Em', ARRAY['tech house', 'club'], 'seed'), +-- 1B & 1A (B-Dur / G#-Moll) +('Galantis', 'Runaway (U & I)', '1B', 126, 'B', ARRAY['electro pop', 'edm'], 'seed'), +('Kygo', 'Firestone', '1B', 114, 'B', ARRAY['tropical house'], 'seed'), +('CamelPhat & Elderbrook', 'Cola', '1A', 122, 'G#m', ARRAY['tech house', 'deep house'], 'seed'), +('Peggy Gou', '(It Goes Like) Nanana', '1A', 130, 'G#m', ARRAY['house', 'summer'], 'seed'), --- 3B & 3A (D-Dur / H-Moll) -('Swedish House Mafia', 'Don''t You Worry Child', '3B', 129, 'D', ARRAY['progressive', 'anthem'], 'seed'), -('Alesso', 'Heroes (we could be)', '3B', 126, 'D', ARRAY['edm', 'euphoric'], 'seed'), -('ACRAZE', 'Do It To It', '3A', 125, 'Bm', ARRAY['house', 'viral'], 'seed'), -('Faithless', 'Insomnia', '3A', 127, 'Bm', ARRAY['classic', 'trance'], 'seed'), +-- 2B & 2A (F#-Dur / D#-Moll) +('Disclosure ft. Sam Smith', 'Latch', '2B', 122, 'F#', ARRAY['garage', 'house'], 'seed'), +('Major Lazer', 'Lean On', '2B', 98, 'F#', ARRAY['dancehall', 'moombahton'], 'seed'), +('Eric Prydz', 'Opus', '2A', 126, 'D#m', ARRAY['progressive house', 'masterpiece'], 'seed'), +('Darude', 'Sandstorm', '2A', 136, 'D#m', ARRAY['trance', 'classic'], 'seed'), --- 4B & 4A (A-Dur / F#-Moll) -('Daft Punk', 'One More Time', '4B', 123, 'A', ARRAY['french house', 'disco'], 'seed'), -('Alphaville', 'Big in Japan', '4B', 118, 'A', ARRAY['80s', 'synth-pop'], 'seed'), -('Dua Lipa', 'Don''t Start Now', '4A', 124, 'F#m', ARRAY['nu-disco', 'dance'], 'seed'), -('The Weeknd', 'Blinding Lights', '4A', 171, 'F#m', ARRAY['synthwave', '80s'], 'seed'), +-- 3B & 3A (Db-Dur / Bb-Moll) +('Calvin Harris', 'Feel So Close', '3B', 128, 'Db', ARRAY['dance', 'pop'], 'seed'), +('Gigi D''Agostino', 'L''Amour Toujours', '3A', 138, 'Bbm', ARRAY['italo dance', 'classic'], 'seed'), +('Paul Kalkbrenner', 'Sky and Sand', '3A', 122, 'Bbm', ARRAY['minimal', 'berlin techno'], 'seed'), --- 5B & 5A (E-Dur / C#-Moll) -('Avicii', 'Wake Me Up', '5B', 124, 'E', ARRAY['folk-dance', 'anthem'], 'seed'), -('Otto Knows', 'Million Voices', '5B', 126, 'E', ARRAY['progressive house'], 'seed'), -('Fred again..', 'Delilah (pull me out of this)', '5A', 134, 'C#m', ARRAY['electronic', 'club'], 'seed'), -('Robin Schulz', 'Sugar', '5A', 123, 'C#m', ARRAY['deep house', 'pop'], 'seed'), +-- 4B & 4A (Ab-Dur / F-Moll) +('Clean Bandit', 'Rather Be', '4B', 121, 'Ab', ARRAY['deep house', 'classical crossover'], 'seed'), +('Swedish House Mafia', 'One', '4A', 125, 'Fm', ARRAY['electro house', 'classic'], 'seed'), +('Alan Walker', 'Faded', '4A', 90, 'Fm', ARRAY['electro', 'melodic'], 'seed'), --- 6B & 6A (H-Dur / G#-Moll) -('Galantis', 'Runaway (U & I)', '6B', 126, 'B', ARRAY['electro pop', 'edm'], 'seed'), -('Kygo', 'Firestone', '6B', 114, 'B', ARRAY['tropical house'], 'seed'), -('CamelPhat & Elderbrook', 'Cola', '6A', 122, 'G#m', ARRAY['tech house', 'deep house'], 'seed'), -('Peggy Gou', '(It Goes Like) Nanana', '6A', 130, 'G#m', ARRAY['house', 'summer'], 'seed'), +-- 5B & 5A (Eb-Dur / C-Moll) +('deadmau5', 'Strobe', '5B', 128, 'Eb', ARRAY['progressive house'], 'seed'), +('Bicep', 'Glue', '5B', 130, 'Eb', ARRAY['breakbeat', 'ambient'], 'seed'), +('Benny Benassi', 'Satisfaction', '5A', 130, 'Cm', ARRAY['electro house', 'legend'], 'seed'), +('Kungs vs Cookin'' on 3 Burners', 'This Girl', '5A', 122, 'Cm', ARRAY['funk house', 'brass'], 'seed'), --- 7B & 7A (F#-Dur / D#-Moll) -('Disclosure ft. Sam Smith', 'Latch', '7B', 122, 'F#', ARRAY['garage', 'house'], 'seed'), -('Major Lazer', 'Lean On', '7B', 98, 'F#', ARRAY['dancehall', 'moombahton'], 'seed'), -('Eric Prydz', 'Opus', '7A', 126, 'D#m', ARRAY['progressive house', 'masterpiece'], 'seed'), -('Darude', 'Sandstorm', '7A', 136, 'D#m', ARRAY['trance', 'classic'], 'seed'), +-- 6B & 6A (Bb-Dur / G-Moll) +('Modjo', 'Lady (Hear Me Tonight)', '6B', 126, 'Bb', ARRAY['french touch', 'filter house'], 'seed'), +('Fatboy Slim', 'Praise You', '6B', 110, 'Bb', ARRAY['big beat', 'breakbeat'], 'seed'), +('Robin S', 'Show Me Love', '6A', 120, 'Gm', ARRAY['90s house', 'anthem'], 'seed'), +('Robert Miles', 'Children', '6A', 138, 'Gm', ARRAY['dream trance', '90s'], 'seed'), --- 8B & 8A (Db-Dur / B-Moll) -('Calvin Harris', 'Feel So Close', '8B', 128, 'Db', ARRAY['dance', 'pop'], 'seed'), -('Gigi D''Agostino', 'L''Amour Toujours', '8A', 138, 'Bbm', ARRAY['italo dance', 'classic'], 'seed'), -('Paul Kalkbrenner', 'Sky and Sand', '8A', 122, 'Bbm', ARRAY['minimal', 'berlin techno'], 'seed'), +-- 7B & 7A (F-Dur / D-Moll) +('Shouse', 'Love Tonight', '7B', 123, 'F', ARRAY['indie dance', 'choir'], 'seed'), +('Stardust', 'Music Sounds Better With You', '7B', 124, 'F', ARRAY['french house', 'disco'], 'seed'), +('Faithless', 'God Is a DJ', '7A', 131, 'Dm', ARRAY['dance anthem', 'classic'], 'seed'), +('Paul van Dyk', 'For an Angel', '7A', 138, 'Dm', ARRAY['trance', 'berlin'], 'seed'), --- 9B & 9A (Ab-Dur / F-Moll) -('Clean Bandit', 'Rather Be', '9B', 121, 'Ab', ARRAY['deep house', 'classical crossover'], 'seed'), -('Swedish House Mafia', 'One', '9A', 125, 'Fm', ARRAY['electro house', 'classic'], 'seed'), -('Alan Walker', 'Faded', '9A', 90, 'Fm', ARRAY['electro', 'melodic'], 'seed'), +-- 8B & 8A (C-Dur / A-Moll) +('Axwell /\\ Ingrosso', 'More Than You Know', '8B', 123, 'C', ARRAY['house', 'edm'], 'seed'), +('Avicii', 'The Nights', '8B', 126, 'C', ARRAY['dance', 'melodic'], 'seed'), +('Tiësto', 'The Business', '8A', 120, 'Am', ARRAY['deep house', 'bass'], 'seed'), +('Meduza', 'Piece Of Your Heart', '8A', 124, 'Am', ARRAY['house', 'electronic'], 'seed'), --- 10B & 10A (Eb-Dur / C-Moll) -('deadmau5', 'Strobe', '10B', 128, 'Eb', ARRAY['progressive house'], 'seed'), -('Bicep', 'Glue', '10B', 130, 'Eb', ARRAY['breakbeat', 'ambient'], 'seed'), -('Benny Benassi', 'Satisfaction', '10A', 130, 'Cm', ARRAY['electro house', 'legend'], 'seed'), -('Kungs vs Cookin'' on 3 Burners', 'This Girl', '10A', 122, 'Cm', ARRAY['funk house', 'brass'], 'seed'), +-- 9B & 9A (G-Dur / E-Moll) +('Calvin Harris', 'Summer', '9B', 128, 'G', ARRAY['dance', 'summer'], 'seed'), +('David Guetta ft. Sia', 'Titanium', '9B', 126, 'G', ARRAY['edm', 'pop'], 'seed'), +('Martin Garrix', 'Animals', '9A', 128, 'Em', ARRAY['big room', 'electro'], 'seed'), +('Fisher', 'Losing It', '9A', 125, 'Em', ARRAY['tech house', 'club'], 'seed'), --- 11B & 11A (Bb-Dur / G-Moll) -('Modjo', 'Lady (Hear Me Tonight)', '11B', 126, 'Bb', ARRAY['french touch', 'filter house'], 'seed'), -('Fatboy Slim', 'Praise You', '11B', 110, 'Bb', ARRAY['big beat', 'breakbeat'], 'seed'), -('Robin S', 'Show Me Love', '11A', 120, 'Gm', ARRAY['90s house', 'anthem'], 'seed'), -('Robert Miles', 'Children', '11A', 138, 'Gm', ARRAY['dream trance', '90s'], 'seed'), +-- 10B & 10A (D-Dur / H-Moll) +('Daft Punk', 'One More Time', '10B', 123, 'D', ARRAY['french house', 'disco'], 'seed'), +('Swedish House Mafia', 'Don''t You Worry Child', '10B', 129, 'D', ARRAY['progressive', 'anthem'], 'seed'), +('Alesso', 'Heroes (we could be)', '10B', 126, 'D', ARRAY['edm', 'euphoric'], 'seed'), +('ACRAZE', 'Do It To It', '10A', 125, 'Bm', ARRAY['house', 'viral'], 'seed'), +('Faithless', 'Insomnia', '10A', 127, 'Bm', ARRAY['classic', 'trance'], 'seed'), --- 12B & 12A (F-Dur / D-Moll) -('Shouse', 'Love Tonight', '12B', 123, 'F', ARRAY['indie dance', 'choir'], 'seed'), -('Stardust', 'Music Sounds Better With You', '12B', 124, 'F', ARRAY['french house', 'disco'], 'seed'), -('Faithless', 'God Is a DJ', '12A', 131, 'Dm', ARRAY['dance anthem', 'classic'], 'seed'), -('Paul van Dyk', 'For an Angel', '12A', 138, 'Dm', ARRAY['trance', 'berlin'], 'seed') +-- 11B & 11A (A-Dur / F#-Moll) +('Alphaville', 'Big in Japan', '11B', 118, 'A', ARRAY['80s', 'synth-pop'], 'seed'), +('Dua Lipa', 'Don''t Start Now', '11A', 124, 'F#m', ARRAY['nu-disco', 'dance'], 'seed'), +('The Weeknd', 'Blinding Lights', '11A', 171, 'F#m', ARRAY['synthwave', '80s'], 'seed') ON CONFLICT (artist, title) DO NOTHING; diff --git a/docs/KeySelector_SPEC.md b/docs/KeySelector_SPEC.md index 788d2b3..84baac4 100644 --- a/docs/KeySelector_SPEC.md +++ b/docs/KeySelector_SPEC.md @@ -83,63 +83,63 @@ keyselector/ ## 4. Datenstrukturen (alle aus dem Mockup übernehmen) -### 4.1 `keys` — alle 24 Camelot-Keys mit Music-Key und Farbe +### 4.1 `keys` — alle 24 Camelot-Keys mit Music-Key und Farbe (Mixed In Key Standard) ```js const keys = [ // Major (B) außen, Minor (A) innen — direkt unter dem entsprechenden Major - ['12B', 'F', '#2EC4B6'], ['12A', 'Dm', '#2EC4B6'], - ['1B', 'C', '#D62828'], ['1A', 'Am', '#D62828'], - ['2B', 'G', '#E77D11'], ['2A', 'Em', '#E77D11'], - ['3B', 'D', '#E0B423'], ['3A', 'Bm', '#E0B423'], - ['4B', 'A', '#4F9D69'], ['4A', 'F#m', '#4F9D69'], - ['5B', 'E', '#1B998B'], ['5A', 'C#m', '#1B998B'], - ['6B', 'B', '#6B4E9C'], ['6A', 'G#m', '#6B4E9C'], - ['7B', 'F#', '#3B7DD8'], ['7A', 'D#m', '#3B7DD8'], - ['8B', 'Db', '#3461A8'], ['8A', 'Bbm', '#3461A8'], - ['9B', 'Ab', '#5B3A8C'], ['9A', 'Fm', '#5B3A8C'], - ['10B', 'Eb', '#B07ECC'], ['10A', 'Cm', '#B07ECC'], - ['11B', 'Bb', '#D64966'], ['11A', 'Gm', '#D64966'], + ['12B', 'E', '#00E5FF'], ['12A', 'Dbm', '#00E5FF'], + ['1B', 'B', '#5BE8B5'], ['1A', 'Abm', '#5BE8B5'], + ['2B', 'F#', '#8AEB86'], ['2A', 'Ebm', '#8AEB86'], + ['3B', 'Db', '#B9F062'], ['3A', 'Bbm', '#B9F062'], + ['4B', 'Ab', '#E4DF6A'], ['4A', 'Fm', '#E4DF6A'], + ['5B', 'Eb', '#FFA07A'], ['5A', 'Cm', '#FFA07A'], + ['6B', 'Bb', '#FF7582'], ['6A', 'Gm', '#FF7582'], + ['7B', 'F', '#E85D9E'], ['7A', 'Dm', '#E85D9E'], + ['8B', 'C', '#C86DD7'], ['8A', 'Am', '#C86DD7'], + ['9B', 'G', '#9F72EE'], ['9A', 'Em', '#9F72EE'], + ['10B', 'D', '#8B94F8'], ['10A', 'Bm', '#8B94F8'], + ['11B', 'A', '#68B6F9'], ['11A', 'F#m', '#68B6F9'], ]; ``` ### 4.2 `codeToAngle` — Camelot-Code → Winkel im Wheel -Major und Minor am GLEICHEN Winkel. 12 Uhr = 0°, clockwise. +Major und Minor am GLEICHEN Winkel. 12 Uhr = 0°, clockwise (30° pro Stunde). ```js const codeToAngle = { - '12B': 0, '12A': 0, - '1B': 15, '1A': 15, - '2B': 30, '2A': 30, - '3B': 45, '3A': 45, - '4B': 60, '4A': 60, - '5B': 75, '5A': 75, - '6B': 90, '6A': 90, - '7B': 105, '7A': 105, - '8B': 120, '8A': 120, - '9B': 135, '9A': 135, - '10B': 150, '10A': 150, - '11B': 165, '11A': 165, + '12B': 0, '12A': 0, + '1B': 30, '1A': 30, + '2B': 60, '2A': 60, + '3B': 90, '3A': 90, + '4B': 120, '4A': 120, + '5B': 150, '5A': 150, + '6B': 180, '6A': 180, + '7B': 210, '7A': 210, + '8B': 240, '8A': 240, + '9B': 270, '9A': 270, + '10B': 300, '10A': 300, + '11B': 330, '11A': 330, }; ``` -### 4.3 `colorMatrix` — separate Farb-Matrix (vom User gewünscht, single source of truth) +### 4.3 `colorMatrix` — separate Farb-Matrix (Mixed In Key Standard) ```js const colorMatrix = { - '12B': '#2EC4B6', '12A': '#2EC4B6', - '1B': '#D62828', '1A': '#D62828', - '2B': '#E77D11', '2A': '#E77D11', - '3B': '#E0B423', '3A': '#E0B423', - '4B': '#4F9D69', '4A': '#4F9D69', - '5B': '#1B998B', '5A': '#1B998B', - '6B': '#6B4E9C', '6A': '#6B4E9C', - '7B': '#3B7DD8', '7A': '#3B7DD8', - '8B': '#3461A8', '8A': '#3461A8', - '9B': '#5B3A8C', '9A': '#5B3A8C', - '10B': '#B07ECC', '10A': '#B07ECC', - '11B': '#D64966', '11A': '#D64966', + '12B': '#00E5FF', '12A': '#00E5FF', + '1B': '#5BE8B5', '1A': '#5BE8B5', + '2B': '#8AEB86', '2A': '#8AEB86', + '3B': '#B9F062', '3A': '#B9F062', + '4B': '#E4DF6A', '4A': '#E4DF6A', + '5B': '#FFA07A', '5A': '#FFA07A', + '6B': '#FF7582', '6A': '#FF7582', + '7B': '#E85D9E', '7A': '#E85D9E', + '8B': '#C86DD7', '8A': '#C86DD7', + '9B': '#9F72EE', '9A': '#9F72EE', + '10B': '#8B94F8', '10A': '#8B94F8', + '11B': '#68B6F9', '11A': '#68B6F9', }; ``` @@ -180,22 +180,22 @@ const mixingRules = { const compatLabels = ['Perfect', 'Quinte -1', 'Quinte +1', 'Energy', 'Scale', 'Diagonal', "Jaw's", 'Mood']; ``` -### 4.5 Music-Key Mapping +### 4.5 Music-Key Mapping (Mixed In Key Standard) | Camelot | Music-Key | |---|---| -| 1B / 1A | C / Am | -| 2B / 2A | G / Em | -| 3B / 3A | D / Bm | -| 4B / 4A | A / F#m | -| 5B / 5A | E / C#m | -| 6B / 6A | B / G#m | -| 7B / 7A | F# / D#m | -| 8B / 8A | Db / Bbm | -| 9B / 9A | Ab / Fm | -| 10B / 10A | Eb / Cm | -| 11B / 11A | Bb / Gm | -| 12B / 12A | F / Dm | +| 12B / 12A | E / C#m (Dbm) | +| 1B / 1A | B / G#m (Abm) | +| 2B / 2A | F# / D#m (Ebm) | +| 3B / 3A | Db / Bbm | +| 4B / 4A | Ab / Fm | +| 5B / 5A | Eb / Cm | +| 6B / 6A | Bb / Gm | +| 7B / 7A | F / Dm | +| 8B / 8A | C / Am | +| 9B / 9A | G / Em | +| 10B / 10A | D / Bm | +| 11B / 11A | A / F#m | ## 5. UI-Komponenten (aus dem Mockup extrahieren) diff --git a/public/search.js b/public/search.js index ba40692..3ea03a9 100644 --- a/public/search.js +++ b/public/search.js @@ -256,18 +256,18 @@ function initEditKeyOptions() { if (!select) return; const camelotKeys = [ - ['12B', 'F'], ['12A', 'Dm'], - ['1B', 'C'], ['1A', 'Am'], - ['2B', 'G'], ['2A', 'Em'], - ['3B', 'D'], ['3A', 'Bm'], - ['4B', 'A'], ['4A', 'F#m'], - ['5B', 'E'], ['5A', 'C#m'], - ['6B', 'B'], ['6A', 'G#m'], - ['7B', 'F#'], ['7A', 'D#m'], - ['8B', 'Db'], ['8A', 'Bbm'], - ['9B', 'Ab'], ['9A', 'Fm'], - ['10B', 'Eb'], ['10A', 'Cm'], - ['11B', 'Bb'], ['11A', 'Gm'], + ['12B', 'E'], ['12A', 'Dbm (C#m)'], + ['1B', 'B'], ['1A', 'Abm (G#m)'], + ['2B', 'F#'], ['2A', 'Ebm (D#m)'], + ['3B', 'Db'], ['3A', 'Bbm (A#m)'], + ['4B', 'Ab'], ['4A', 'Fm'], + ['5B', 'Eb'], ['5A', 'Cm'], + ['6B', 'Bb'], ['6A', 'Gm'], + ['7B', 'F'], ['7A', 'Dm'], + ['8B', 'C'], ['8A', 'Am'], + ['9B', 'G'], ['9A', 'Em'], + ['10B', 'D'], ['10A', 'Bm'], + ['11B', 'A'], ['11A', 'F#m'], ]; select.innerHTML = ''; diff --git a/public/wheel.js b/public/wheel.js index 4c24b38..85ae716 100644 --- a/public/wheel.js +++ b/public/wheel.js @@ -5,14 +5,14 @@ /* ================================================================== */ const keys = [ - ['12B', 'F', '#2EC4B6'], ['1B', 'C', '#D62828'], ['2B', 'G', '#E77D11'], - ['3B', 'D', '#E0B423'], ['4B', 'A', '#4F9D69'], ['5B', 'E', '#1B998B'], - ['6B', 'B', '#6B4E9C'], ['7B', 'F#', '#3B7DD8'], ['8B', 'Db', '#3461A8'], - ['9B', 'Ab', '#5B3A8C'], ['10B', 'Eb', '#B07ECC'], ['11B', 'Bb', '#D64966'], - ['12A', 'Dm', '#2EC4B6'], ['1A', 'Am', '#D62828'], ['2A', 'Em', '#E77D11'], - ['3A', 'Bm', '#E0B423'], ['4A', 'F#m', '#4F9D69'], ['5A', 'C#m', '#1B998B'], - ['6A', 'G#m', '#6B4E9C'], ['7A', 'D#m', '#3B7DD8'], ['8A', 'Bbm', '#3461A8'], - ['9A', 'Fm', '#5B3A8C'], ['10A', 'Cm', '#B07ECC'], ['11A', 'Gm', '#D64966'], + ['12B', 'E', '#00E5FF'], ['1B', 'B', '#5BE8B5'], ['2B', 'F#', '#8AEB86'], + ['3B', 'Db', '#B9F062'], ['4B', 'Ab', '#E4DF6A'], ['5B', 'Eb', '#FFA07A'], + ['6B', 'Bb', '#FF7582'], ['7B', 'F', '#E85D9E'], ['8B', 'C', '#C86DD7'], + ['9B', 'G', '#9F72EE'], ['10B', 'D', '#8B94F8'], ['11B', 'A', '#68B6F9'], + ['12A', 'Dbm', '#00E5FF'], ['1A', 'Abm', '#5BE8B5'], ['2A', 'Ebm', '#8AEB86'], + ['3A', 'Bbm', '#B9F062'], ['4A', 'Fm', '#E4DF6A'], ['5A', 'Cm', '#FFA07A'], + ['6A', 'Gm', '#FF7582'], ['7A', 'Dm', '#E85D9E'], ['8A', 'Am', '#C86DD7'], + ['9A', 'Em', '#9F72EE'], ['10A', 'Bm', '#8B94F8'], ['11A', 'F#m', '#68B6F9'], ]; const hexRgba = (h, a) => { diff --git a/server/routes/metadata.js b/server/routes/metadata.js index 97d2df9..6e966ff 100644 --- a/server/routes/metadata.js +++ b/server/routes/metadata.js @@ -5,26 +5,72 @@ const db = require('../db'); const camelotToMusicKey = require('../../shared/camelot-to-musickey'); const reverseMap = { - 'c': '1B', 'a minor': '1A', 'am': '1A', - 'g': '2B', 'e minor': '2A', 'em': '2A', - 'd': '3B', 'b minor': '3A', 'bm': '3A', - 'a': '4B', 'f# minor': '4A', 'f#m': '4A', - 'e': '5B', 'c# minor': '5A', 'c#m': '5A', - 'b': '6B', 'g# minor': '6A', 'g#m': '6A', - 'f#': '7B', 'd# minor': '7A', 'd#m': '7A', - 'db': '8B', 'c#': '8B', 'bb minor': '8A', 'a# minor': '8A', 'bbm': '8A', - 'ab': '9B', 'g#': '9B', 'f minor': '9A', 'fm': '9A', - 'eb': '10B', 'd#': '10B', 'c minor': '10A', 'cm': '10A', - 'bb': '11B', 'a#': '11B', 'g minor': '11A', 'gm': '11A', - 'f': '12B', 'd minor': '12A', 'dm': '12A', - 'c major': '1B', 'g major': '2B', 'd major': '3B', 'a major': '4B', - 'e major': '5B', 'b major': '6B', 'f# major': '7B', 'db major': '8B', - 'ab major': '9B', 'eb major': '10B', 'bb major': '11B', 'f major': '12B' + // 12B / 12A (E-Dur / C#m / Dbm) + 'e': '12B', 'e major': '12B', 'e-dur': '12B', 'e maj': '12B', + 'c# minor': '12A', 'c#m': '12A', 'c#-moll': '12A', 'c# min': '12A', + 'db minor': '12A', 'dbm': '12A', 'db-moll': '12A', + + // 1B / 1A (B-Dur / H-Dur / G#m / Abm) + 'b': '1B', 'b major': '1B', 'b-dur': '1B', 'b maj': '1B', + 'h': '1B', 'h major': '1B', 'h-dur': '1B', + 'g# minor': '1A', 'g#m': '1A', 'g#-moll': '1A', 'g# min': '1A', + 'ab minor': '1A', 'abm': '1A', 'ab-moll': '1A', + + // 2B / 2A (F#-Dur / Gb-Dur / D#m / Ebm) + 'f#': '2B', 'f# major': '2B', 'f#-dur': '2B', 'f# maj': '2B', + 'gb': '2B', 'gb major': '2B', 'gb-dur': '2B', + 'd# minor': '2A', 'd#m': '2A', 'd#-moll': '2A', 'd# min': '2A', + 'eb minor': '2A', 'ebm': '2A', 'eb-moll': '2A', + + // 3B / 3A (Db-Dur / C#-Dur / Bbm / A#m) + 'db': '3B', 'db major': '3B', 'db-dur': '3B', 'db maj': '3B', + 'c#': '3B', 'c# major': '3B', 'c#-dur': '3B', + 'bb minor': '3A', 'bbm': '3A', 'bb-moll': '3A', 'bb min': '3A', + 'a# minor': '3A', 'a#m': '3A', 'a#-moll': '3A', + + // 4B / 4A (Ab-Dur / G#-Dur / Fm) + 'ab': '4B', 'ab major': '4B', 'ab-dur': '4B', 'ab maj': '4B', + 'g#': '4B', 'g# major': '4B', 'g#-dur': '4B', + 'f minor': '4A', 'fm': '4A', 'f-moll': '4A', 'f min': '4A', + + // 5B / 5A (Eb-Dur / D#-Dur / Cm) + 'eb': '5B', 'eb major': '5B', 'eb-dur': '5B', 'eb maj': '5B', + 'd#': '5B', 'd# major': '5B', 'd#-dur': '5B', + 'c minor': '5A', 'cm': '5A', 'c-moll': '5A', 'c min': '5A', + + // 6B / 6A (Bb-Dur / A#-Dur / Gm) + 'bb': '6B', 'bb major': '6B', 'bb-dur': '6B', 'bb maj': '6B', + 'a#': '6B', 'a# major': '6B', 'a#-dur': '6B', + 'g minor': '6A', 'gm': '6A', 'g-moll': '6A', 'g min': '6A', + + // 7B / 7A (F-Dur / Dm) + 'f': '7B', 'f major': '7B', 'f-dur': '7B', 'f maj': '7B', + 'd minor': '7A', 'dm': '7A', 'd-moll': '7A', 'd min': '7A', + + // 8B / 8A (C-Dur / Am) + 'c': '8B', 'c major': '8B', 'c-dur': '8B', 'c maj': '8B', + 'a minor': '8A', 'am': '8A', 'a-moll': '8A', 'a min': '8A', + + // 9B / 9A (G-Dur / Em) + 'g': '9B', 'g major': '9B', 'g-dur': '9B', 'g maj': '9B', + 'e minor': '9A', 'em': '9A', 'e-moll': '9A', 'e min': '9A', + + // 10B / 10A (D-Dur / Bm / Hm) + 'd': '10B', 'd major': '10B', 'd-dur': '10B', 'd maj': '10B', + 'b minor': '10A', 'bm': '10A', 'b-moll': '10A', 'b min': '10A', + 'h minor': '10A', 'hm': '10A', 'h-moll': '10A', 'h min': '10A', + + // 11B / 11A (A-Dur / F#m / Gbm) + 'a': '11B', 'a major': '11B', 'a-dur': '11B', 'a maj': '11B', + 'f# minor': '11A', 'f#m': '11A', 'f#-moll': '11A', 'f# min': '11A', + 'gb minor': '11A', 'gbm': '11A', 'gb-moll': '11A', }; function standardizeKey(keyString) { if (!keyString) return null; const str = keyString.toLowerCase().trim(); + const upper = str.toUpperCase(); + if (camelotToMusicKey[upper]) return upper; return reverseMap[str] || null; } diff --git a/shared/camelot-to-musickey.js b/shared/camelot-to-musickey.js index 49085dc..111d529 100644 --- a/shared/camelot-to-musickey.js +++ b/shared/camelot-to-musickey.js @@ -1,16 +1,16 @@ const camelotToMusicKey = { - '1B': 'C', '1A': 'Am', - '2B': 'G', '2A': 'Em', - '3B': 'D', '3A': 'Bm', - '4B': 'A', '4A': 'F#m', - '5B': 'E', '5A': 'C#m', - '6B': 'B', '6A': 'G#m', - '7B': 'F#', '7A': 'D#m', - '8B': 'Db', '8A': 'Bbm', - '9B': 'Ab', '9A': 'Fm', - '10B': 'Eb', '10A': 'Cm', - '11B': 'Bb', '11A': 'Gm', - '12B': 'F', '12A': 'Dm', + '12B': 'E', '12A': 'Dbm', + '1B': 'B', '1A': 'Abm', + '2B': 'F#', '2A': 'Ebm', + '3B': 'Db', '3A': 'Bbm', + '4B': 'Ab', '4A': 'Fm', + '5B': 'Eb', '5A': 'Cm', + '6B': 'Bb', '6A': 'Gm', + '7B': 'F', '7A': 'Dm', + '8B': 'C', '8A': 'Am', + '9B': 'G', '9A': 'Em', + '10B': 'D', '10A': 'Bm', + '11B': 'A', '11A': 'F#m', }; if (typeof module !== 'undefined' && module.exports) { diff --git a/shared/color-matrix.js b/shared/color-matrix.js index 52bf2cf..a0d24ba 100644 --- a/shared/color-matrix.js +++ b/shared/color-matrix.js @@ -1,16 +1,16 @@ const colorMatrix = { - '12B': '#2EC4B6', '12A': '#2EC4B6', - '1B': '#D62828', '1A': '#D62828', - '2B': '#E77D11', '2A': '#E77D11', - '3B': '#E0B423', '3A': '#E0B423', - '4B': '#4F9D69', '4A': '#4F9D69', - '5B': '#1B998B', '5A': '#1B998B', - '6B': '#6B4E9C', '6A': '#6B4E9C', - '7B': '#3B7DD8', '7A': '#3B7DD8', - '8B': '#3461A8', '8A': '#3461A8', - '9B': '#5B3A8C', '9A': '#5B3A8C', - '10B': '#B07ECC', '10A': '#B07ECC', - '11B': '#D64966', '11A': '#D64966', + '12B': '#00E5FF', '12A': '#00E5FF', + '1B': '#5BE8B5', '1A': '#5BE8B5', + '2B': '#8AEB86', '2A': '#8AEB86', + '3B': '#B9F062', '3A': '#B9F062', + '4B': '#E4DF6A', '4A': '#E4DF6A', + '5B': '#FFA07A', '5A': '#FFA07A', + '6B': '#FF7582', '6A': '#FF7582', + '7B': '#E85D9E', '7A': '#E85D9E', + '8B': '#C86DD7', '8A': '#C86DD7', + '9B': '#9F72EE', '9A': '#9F72EE', + '10B': '#8B94F8', '10A': '#8B94F8', + '11B': '#68B6F9', '11A': '#68B6F9', }; if (typeof module !== 'undefined' && module.exports) {