zama1 commited on
Commit
8a4d64b
·
verified ·
1 Parent(s): 449d393

Add 2 files

Browse files
Files changed (2) hide show
  1. README.md +7 -5
  2. index.html +636 -19
README.md CHANGED
@@ -1,10 +1,12 @@
1
  ---
2
- title: Harmonygen
3
- emoji: 🔥
4
- colorFrom: yellow
5
- colorTo: indigo
6
  sdk: static
7
  pinned: false
 
 
8
  ---
9
 
10
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
1
  ---
2
+ title: harmonygen
3
+ emoji: 🐳
4
+ colorFrom: blue
5
+ colorTo: red
6
  sdk: static
7
  pinned: false
8
+ tags:
9
+ - deepsite
10
  ---
11
 
12
+ Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
index.html CHANGED
@@ -1,19 +1,636 @@
1
- <!doctype html>
2
- <html>
3
- <head>
4
- <meta charset="utf-8" />
5
- <meta name="viewport" content="width=device-width" />
6
- <title>My static Space</title>
7
- <link rel="stylesheet" href="style.css" />
8
- </head>
9
- <body>
10
- <div class="card">
11
- <h1>Welcome to your static Space!</h1>
12
- <p>You can modify this app directly by editing <i>index.html</i> in the Files and versions tab.</p>
13
- <p>
14
- Also don't forget to check the
15
- <a href="https://huggingface.co/docs/hub/spaces" target="_blank">Spaces documentation</a>.
16
- </p>
17
- </div>
18
- </body>
19
- </html>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>HarmonyGen - Multilingual Chord Progression Generator</title>
7
+ <script src="https://cdn.tailwindcss.com"></script>
8
+ <script src="https://unpkg.com/tone@14.7.77/build/Tone.js"></script>
9
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
10
+ <style>
11
+ @import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&family=Montserrat:wght@400;500;600;700&display=swap');
12
+
13
+ body {
14
+ font-family: 'Inter', sans-serif;
15
+ background: linear-gradient(135deg, #1a1a2e 0%, #16213e 100%);
16
+ min-height: 100vh;
17
+ color: #e2e8f0;
18
+ }
19
+
20
+ .chord-card {
21
+ transition: all 0.3s ease;
22
+ transform-style: preserve-3d;
23
+ }
24
+
25
+ .chord-card:hover {
26
+ transform: translateY(-5px) scale(1.03);
27
+ box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.3);
28
+ }
29
+
30
+ .chord-playing {
31
+ animation: pulse 1s infinite;
32
+ box-shadow: 0 0 0 5px rgba(74, 222, 128, 0.5);
33
+ }
34
+
35
+ @keyframes pulse {
36
+ 0% { box-shadow: 0 0 0 0 rgba(74, 222, 128, 0.7); }
37
+ 70% { box-shadow: 0 0 0 10px rgba(74, 222, 128, 0); }
38
+ 100% { box-shadow: 0 0 0 0 rgba(74, 222, 128, 0); }
39
+ }
40
+
41
+ .language-selector {
42
+ background: rgba(255, 255, 255, 0.1);
43
+ backdrop-filter: blur(10px);
44
+ }
45
+
46
+ .genre-selector {
47
+ scrollbar-width: thin;
48
+ scrollbar-color: #4f46e5 #1e293b;
49
+ }
50
+
51
+ .genre-selector::-webkit-scrollbar {
52
+ height: 8px;
53
+ }
54
+
55
+ .genre-selector::-webkit-scrollbar-track {
56
+ background: #1e293b;
57
+ border-radius: 10px;
58
+ }
59
+
60
+ .genre-selector::-webkit-scrollbar-thumb {
61
+ background-color: #4f46e5;
62
+ border-radius: 10px;
63
+ }
64
+ </style>
65
+ </head>
66
+ <body class="min-h-screen flex flex-col">
67
+ <!-- Header with Language Selector -->
68
+ <header class="py-4 px-6 flex justify-between items-center border-b border-gray-700">
69
+ <div class="flex items-center space-x-2">
70
+ <i class="fas fa-music text-indigo-500 text-2xl"></i>
71
+ <h1 class="text-xl font-bold bg-gradient-to-r from-indigo-400 to-purple-500 bg-clip-text text-transparent">HarmonyGen</h1>
72
+ </div>
73
+
74
+ <div class="relative">
75
+ <select id="language-selector" class="language-selector px-4 py-2 rounded-full text-sm font-medium border border-gray-600 appearance-none focus:outline-none focus:ring-2 focus:ring-indigo-500">
76
+ <option value="en">English</option>
77
+ <option value="fr">Français</option>
78
+ <option value="es">Español</option>
79
+ <option value="de">Deutsch</option>
80
+ <option value="it">Italiano</option>
81
+ <option value="ja">日本語</option>
82
+ </select>
83
+ <i class="fas fa-chevron-down absolute right-3 top-1/2 transform -translate-y-1/2 text-gray-400 pointer-events-none"></i>
84
+ </div>
85
+ </header>
86
+
87
+ <!-- Main Content -->
88
+ <main class="flex-1 container mx-auto px-4 py-8">
89
+ <div class="max-w-4xl mx-auto">
90
+ <div class="text-center mb-10">
91
+ <h2 id="main-title" class="text-3xl md:text-4xl font-bold mb-3">Generate Beautiful Chord Progressions</h2>
92
+ <p id="main-subtitle" class="text-gray-400 max-w-2xl mx-auto">Create harmonic sequences with one click. Perfect for songwriting and music theory practice.</p>
93
+ </div>
94
+
95
+ <!-- Genre Selector -->
96
+ <div class="mb-8">
97
+ <h3 id="genre-label" class="text-lg font-semibold mb-3">Select Music Style</h3>
98
+ <div class="genre-selector flex space-x-3 pb-2 overflow-x-auto">
99
+ <button data-genre="pop" class="genre-btn flex-shrink-0 px-4 py-2 rounded-full bg-indigo-900 text-indigo-100 hover:bg-indigo-700 transition">Pop</button>
100
+ <button data-genre="rock" class="genre-btn flex-shrink-0 px-4 py-2 rounded-full bg-gray-700 hover:bg-gray-600 transition">Rock</button>
101
+ <button data-genre="jazz" class="genre-btn flex-shrink-0 px-4 py-2 rounded-full bg-amber-900 hover:bg-amber-800 transition">Jazz</button>
102
+ <button data-genre="blues" class="genre-btn flex-shrink-0 px-4 py-2 rounded-full bg-blue-900 hover:bg-blue-800 transition">Blues</button>
103
+ <button data-genre="classical" class="genre-btn flex-shrink-0 px-4 py-2 rounded-full bg-purple-900 hover:bg-purple-800 transition">Classical</button>
104
+ <button data-genre="electronic" class="genre-btn flex-shrink-0 px-4 py-2 rounded-full bg-pink-900 hover:bg-pink-800 transition">Electronic</button>
105
+ <button data-genre="flamenco" class="genre-btn flex-shrink-0 px-4 py-2 rounded-full bg-red-900 hover:bg-red-800 transition">Flamenco</button>
106
+ <button data-genre="reggae" class="genre-btn flex-shrink-0 px-4 py-2 rounded-full bg-green-900 hover:bg-green-800 transition">Reggae</button>
107
+ </div>
108
+ </div>
109
+
110
+ <!-- Key Selector -->
111
+ <div class="mb-8">
112
+ <h3 id="key-label" class="text-lg font-semibold mb-3">Select Key</h3>
113
+ <div class="grid grid-cols-4 sm:grid-cols-7 gap-3">
114
+ <button data-key="C" class="key-btn px-4 py-2 rounded bg-gray-700 hover:bg-gray-600 transition">C</button>
115
+ <button data-key="D" class="key-btn px-4 py-2 rounded bg-gray-700 hover:bg-gray-600 transition">D</button>
116
+ <button data-key="E" class="key-btn px-4 py-2 rounded bg-gray-700 hover:bg-gray-600 transition">E</button>
117
+ <button data-key="F" class="key-btn px-4 py-2 rounded bg-gray-700 hover:bg-gray-600 transition">F</button>
118
+ <button data-key="G" class="key-btn px-4 py-2 rounded bg-gray-700 hover:bg-gray-600 transition">G</button>
119
+ <button data-key="A" class="key-btn px-4 py-2 rounded bg-gray-700 hover:bg-gray-600 transition">A</button>
120
+ <button data-key="B" class="key-btn px-4 py-2 rounded bg-gray-700 hover:bg-gray-600 transition">B</button>
121
+ </div>
122
+ </div>
123
+
124
+ <!-- Generate Button -->
125
+ <div class="text-center mb-10">
126
+ <button id="generate-btn" class="px-8 py-3 rounded-full bg-gradient-to-r from-indigo-500 to-purple-600 hover:from-indigo-600 hover:to-purple-700 text-white font-semibold shadow-lg transition transform hover:scale-105">
127
+ <i class="fas fa-magic mr-2"></i>
128
+ <span id="generate-text">Generate Progression</span>
129
+ </button>
130
+ </div>
131
+
132
+ <!-- Results Section -->
133
+ <div id="results-section" class="hidden">
134
+ <div class="flex justify-between items-center mb-4">
135
+ <h3 id="progression-label" class="text-xl font-semibold">Your Chord Progression</h3>
136
+ <button id="play-btn" class="px-4 py-2 rounded bg-green-600 hover:bg-green-700 text-white flex items-center">
137
+ <i class="fas fa-play mr-2"></i>
138
+ <span id="play-text">Play</span>
139
+ </button>
140
+ </div>
141
+
142
+ <div id="chord-container" class="grid grid-cols-2 sm:grid-cols-4 gap-4 mb-8">
143
+ <!-- Chord cards will be inserted here -->
144
+ </div>
145
+
146
+ <div class="flex flex-wrap justify-center gap-3">
147
+ <button id="save-btn" class="px-4 py-2 rounded bg-indigo-600 hover:bg-indigo-700 text-white flex items-center">
148
+ <i class="fas fa-save mr-2"></i>
149
+ <span id="save-text">Save</span>
150
+ </button>
151
+ <button id="share-btn" class="px-4 py-2 rounded bg-blue-600 hover:bg-blue-700 text-white flex items-center">
152
+ <i class="fas fa-share-alt mr-2"></i>
153
+ <span id="share-text">Share</span>
154
+ </button>
155
+ <button id="export-midi-btn" class="px-4 py-2 rounded bg-purple-600 hover:bg-purple-700 text-white flex items-center">
156
+ <i class="fas fa-file-export mr-2"></i>
157
+ <span id="export-text">Export MIDI</span>
158
+ </button>
159
+ </div>
160
+ </div>
161
+
162
+ <!-- Music Theory Tips -->
163
+ <div id="theory-tips" class="mt-12 p-6 bg-gray-800 rounded-lg hidden">
164
+ <h3 id="tips-title" class="text-xl font-semibold mb-3">Music Theory Insight</h3>
165
+ <p id="tips-content" class="text-gray-300">This progression uses a classic I-V-vi-IV pattern which is very common in pop music. The movement from the tonic (I) to dominant (V) creates tension that resolves back to the tonic.</p>
166
+ </div>
167
+ </div>
168
+ </main>
169
+
170
+ <!-- Footer -->
171
+ <footer class="py-6 px-4 border-t border-gray-700 text-center text-gray-400 text-sm">
172
+ <p id="footer-text">© 2023 HarmonyGen - All rights reserved | Made with <i class="fas fa-heart text-red-500"></i> for music lovers</p>
173
+ </footer>
174
+
175
+ <script>
176
+ // Internationalization data
177
+ const translations = {
178
+ en: {
179
+ title: "Generate Beautiful Chord Progressions",
180
+ subtitle: "Create harmonic sequences with one click. Perfect for songwriting and music theory practice.",
181
+ genreLabel: "Select Music Style",
182
+ keyLabel: "Select Key",
183
+ generateText: "Generate Progression",
184
+ progressionLabel: "Your Chord Progression",
185
+ playText: "Play",
186
+ saveText: "Save",
187
+ shareText: "Share",
188
+ exportText: "Export MIDI",
189
+ tipsTitle: "Music Theory Insight",
190
+ tipsContent: "This progression uses a classic I-V-vi-IV pattern which is very common in pop music. The movement from the tonic (I) to dominant (V) creates tension that resolves back to the tonic.",
191
+ footer: "© 2023 HarmonyGen - All rights reserved | Made with ♥ for music lovers"
192
+ },
193
+ fr: {
194
+ title: "Générez de Belles Progressions d'Accords",
195
+ subtitle: "Créez des séquences harmoniques en un clic. Parfait pour l'écriture de chansons et la pratique de la théorie musicale.",
196
+ genreLabel: "Sélectionnez le Style Musical",
197
+ keyLabel: "Sélectionnez la Tonale",
198
+ generateText: "Générer une Progression",
199
+ progressionLabel: "Votre Progression d'Accords",
200
+ playText: "Jouer",
201
+ saveText: "Enregistrer",
202
+ shareText: "Partager",
203
+ exportText: "Exporter MIDI",
204
+ tipsTitle: "Conseil de Théorie Musicale",
205
+ tipsContent: "Cette progression utilise un motif classique I-V-vi-IV très courant dans la musique pop. Le mouvement de la tonique (I) à la dominante (V) crée une tension qui se résout vers la tonique.",
206
+ footer: "© 2023 HarmonyGen - Tous droits réservés | Fait avec ♥ pour les amoureux de la musique"
207
+ },
208
+ es: {
209
+ title: "Genera Hermosas Progresiones de Acordes",
210
+ subtitle: "Crea secuencias armónicas con un clic. Perfecto para componer canciones y practicar teoría musical.",
211
+ genreLabel: "Selecciona Estilo Musical",
212
+ keyLabel: "Selecciona Tonalidad",
213
+ generateText: "Generar Progresión",
214
+ progressionLabel: "Tu Progresión de Acordes",
215
+ playText: "Reproducir",
216
+ saveText: "Guardar",
217
+ shareText: "Compartir",
218
+ exportText: "Exportar MIDI",
219
+ tipsTitle: "Consejo de Teoría Musical",
220
+ tipsContent: "Esta progresión utiliza un patrón clásico I-V-vi-IV muy común en la música pop. El movimiento de la tónica (I) a la dominante (V) crea tensión que se resuelve hacia la tónica.",
221
+ footer: "© 2023 HarmonyGen - Todos los derechos reservados | Hecho con ♥ para amantes de la música"
222
+ },
223
+ de: {
224
+ title: "Erzeuge Schöne Akkordfolgen",
225
+ subtitle: "Erstelle harmonische Sequenzen mit einem Klick. Perfekt für Songwriting und Musiktheorie-Übungen.",
226
+ genreLabel: "Musikstil auswählen",
227
+ keyLabel: "Tonart auswählen",
228
+ generateText: "Akkordfolge generieren",
229
+ progressionLabel: "Deine Akkordfolge",
230
+ playText: "Abspielen",
231
+ saveText: "Speichern",
232
+ shareText: "Teilen",
233
+ exportText: "MIDI exportieren",
234
+ tipsTitle: "Musiktheorie-Tipp",
235
+ tipsContent: "Diese Folge verwendet ein klassisches I-V-vi-IV-Muster, das in der Popmusik sehr verbreitet ist. Die Bewegung von der Tonika (I) zur Dominante (V) erzeugt Spannung, die sich zur Tonika auflöst.",
236
+ footer: "© 2023 HarmonyGen - Alle Rechte vorbehalten | Mit ♥ für Musikliebhaber gemacht"
237
+ },
238
+ it: {
239
+ title: "Genera Belle Progressioni di Accordi",
240
+ subtitle: "Crea sequenze armoniche con un clic. Perfetto per scrivere canzoni e praticare la teoria musicale.",
241
+ genreLabel: "Seleziona Stile Musicale",
242
+ keyLabel: "Seleziona Tonalità",
243
+ generateText: "Genera Progressione",
244
+ progressionLabel: "La Tua Progressione di Accordi",
245
+ playText: "Riproduci",
246
+ saveText: "Salva",
247
+ shareText: "Condividi",
248
+ exportText: "Esporta MIDI",
249
+ tipsTitle: "Consiglio di Teoria Musicale",
250
+ tipsContent: "Questa progressione utilizza un classico pattern I-V-vi-IV molto comune nella musica pop. Il movimento dalla tonica (I) alla dominante (V) crea tensione che si risolve verso la tonica.",
251
+ footer: "© 2023 HarmonyGen - Tutti i diritti riservati | Fatto con ♥ per gli amanti della musica"
252
+ },
253
+ ja: {
254
+ title: "美しいコード進行を生成",
255
+ subtitle: "ワンクリックでハーモニックなコード進行を作成。作曲や音楽理論の練習に最適です。",
256
+ genreLabel: "音楽スタイルを選択",
257
+ keyLabel: "キーを選択",
258
+ generateText: "コード進行を生成",
259
+ progressionLabel: "あなたのコード進行",
260
+ playText: "再生",
261
+ saveText: "保存",
262
+ shareText: "共有",
263
+ exportText: "MIDIエクスポート",
264
+ tipsTitle: "音楽理論のヒント",
265
+ tipsContent: "この進行は、ポップミュージックで非常に一般的な古典的なI-V-vi-IVパターンを使用しています。トニック(I)からドミナント(V)への動きは、トニックに解決する緊張感を作り出します。",
266
+ footer: "© 2023 HarmonyGen - 全著作権所有 | 音楽愛好家のために♥で作られました"
267
+ }
268
+ };
269
+
270
+ // Chord translations
271
+ const chordTranslations = {
272
+ en: {
273
+ C: "C", G: "G", Am: "Am", F: "F", Em: "Em", Dm: "Dm", Bb: "Bb",
274
+ D: "D", A: "A", E: "E", B: "B", Fm: "Fm", Cm: "Cm", Gm: "Gm",
275
+ D7: "D7", G7: "G7", C7: "C7", A7: "A7", E7: "E7", B7: "B7"
276
+ },
277
+ fr: {
278
+ C: "Do", G: "Sol", Am: "Lam", F: "Fa", Em: "Mim", Dm: "Rém", Bb: "Sib",
279
+ D: "Ré", A: "La", E: "Mi", B: "Si", Fm: "Fam", Cm: "Dom", Gm: "Solm",
280
+ D7: "Ré7", G7: "Sol7", C7: "Do7", A7: "La7", E7: "Mi7", B7: "Si7"
281
+ },
282
+ es: {
283
+ C: "Do", G: "Sol", Am: "Lam", F: "Fa", Em: "Mim", Dm: "Rem", Bb: "Sib",
284
+ D: "Re", A: "La", E: "Mi", B: "Si", Fm: "Fam", Cm: "Dom", Gm: "Solm",
285
+ D7: "Re7", G7: "Sol7", C7: "Do7", A7: "La7", E7: "Mi7", B7: "Si7"
286
+ },
287
+ de: {
288
+ C: "C", G: "G", Am: "Am", F: "F", Em: "Em", Dm: "Dm", Bb: "B",
289
+ D: "D", A: "A", E: "E", B: "H", Fm: "Fm", Cm: "Cm", Gm: "Gm",
290
+ D7: "D7", G7: "G7", C7: "C7", A7: "A7", E7: "E7", B7: "H7"
291
+ },
292
+ it: {
293
+ C: "Do", G: "Sol", Am: "Lam", F: "Fa", Em: "Mim", Dm: "Rem", Bb: "Sib",
294
+ D: "Re", A: "La", E: "Mi", B: "Si", Fm: "Fam", Cm: "Dom", Gm: "Solm",
295
+ D7: "Re7", G7: "Sol7", C7: "Do7", A7: "La7", E7: "Mi7", B7: "Si7"
296
+ },
297
+ ja: {
298
+ C: "C", G: "G", Am: "Am", F: "F", Em: "Em", Dm: "Dm", Bb: "B♭",
299
+ D: "D", A: "A", E: "E", B: "B", Fm: "Fm", Cm: "Cm", Gm: "Gm",
300
+ D7: "D7", G7: "G7", C7: "C7", A7: "A7", E7: "E7", B7: "B7"
301
+ }
302
+ };
303
+
304
+ // Common chord progressions by genre
305
+ const progressions = {
306
+ pop: ["C", "G", "Am", "F"],
307
+ rock: ["E", "B", "C#m", "A"],
308
+ jazz: ["Dm7", "G7", "Cmaj7", "A7"],
309
+ blues: ["C7", "F7", "G7", "C7"],
310
+ classical: ["C", "G", "Am", "Em", "F", "C", "F", "G"],
311
+ electronic: ["Cm", "Bb", "Ab", "Eb"],
312
+ flamenco: ["Am", "G", "F", "E"],
313
+ reggae: ["A", "D", "E", "A"]
314
+ };
315
+
316
+ // Music theory tips by genre
317
+ const theoryTips = {
318
+ pop: {
319
+ en: "This I-V-vi-IV progression is the most common in pop music, found in countless hit songs. The movement from the tonic (I) to dominant (V) creates tension that resolves satisfyingly.",
320
+ fr: "Cette progression I-V-vi-IV est la plus courante dans la musique pop, présente dans d'innombrables tubes. Le mouvement de la tonique (I) à la dominante (V) crée une tension qui se résout de manière satisfaisante.",
321
+ es: "Esta progresión I-V-vi-IV es la más común en la música pop, presente en innumerables éxitos. El movimiento de la tónica (I) a la dominante (V) crea tensión que se resuelve de manera satisfactoria.",
322
+ de: "Diese I-V-vi-IV-Folge ist die häufigste in der Popmusik und findet sich in unzähligen Hits. Die Bewegung von der Tonika (I) zur Dominante (V) erzeugt Spannung, die sich befriedigend auflöst.",
323
+ it: "Questa progressione I-V-vi-IV è la più comune nella musica pop, presente in innumerevoli canzoni di successo. Il movimento dalla tonica (I) alla dominante (V) crea tensione che si risolve in modo soddisfacente.",
324
+ ja: "このI-V-vi-IV進行はポップミュージックで最も一般的で、無数のヒット曲に見られます。トニック(I)からドミナント(V)への動きは、満足のいく解決をもたらす緊張感を作り出します。"
325
+ },
326
+ rock: {
327
+ en: "This powerful progression uses the classic rock formula with strong root movements. The V-IV-I pattern creates a driving energy perfect for anthemic rock songs.",
328
+ fr: "Cette progression puissante utilise la formule rock classique avec des mouvements de basse forts. Le motif V-IV-I crée une énergie entraînante parfaite pour les chansons rock hymne.",
329
+ es: "Esta progresión poderosa utiliza la fórmula clásica del rock con fuertes movimientos de raíz. El patrón V-IV-I crea una energía impulsora perfecta para canciones de rock himno.",
330
+ de: "Diese kraftvolle Folge verwendet die klassische Rockformel mit starken Grundtonbewegungen. Das V-IV-I-Muster erzeugt eine treibende Energie, die perfekt für hymnische Rocksongs ist.",
331
+ it: "Questa potente progressione utilizza la classica formula rock con forti movimenti di radice. Il pattern V-IV-I crea un'energia trainante perfetta per le canzoni rock inno.",
332
+ ja: "この力強い進行は、強力なルートムーブメントを備えたクラシックなロックの公式を使用しています。V-IV-Iパターンは、アンセミックなロックソングに最適な推進力のあるエネルギーを作り出します。"
333
+ },
334
+ jazz: {
335
+ en: "This ii-V-I progression with added 7ths is the backbone of jazz harmony. The chromatic movement and extended chords create rich harmonic color.",
336
+ fr: "Cette progression ii-V-I avec des 7èmes ajoutées est l'épine dorsale de l'harmonie jazz. Le mouvement chromatique et les accords étendus créent une riche couleur harmonique.",
337
+ es: "Esta progresión ii-V-I con séptimas añadidas es la columna vertebral de la armonía jazz. El movimiento cromático y los acordes extendidos crean un rico color armónico.",
338
+ de: "Diese ii-V-I-Folge mit hinzugefügten Septimen ist das Rückgrat der Jazzharmonik. Die chromatische Bewegung und die erweiterten Akkorde erzeugen eine reiche harmonische Farbe.",
339
+ it: "Questa progressione ii-V-I con settime aggiunte è la spina dorsale dell'armonia jazz. Il movimento cromatico e gli accordi estesi creano un ricco colore armonico.",
340
+ ja: "7thを加えたこのii-V-I進行は、ジャズハーモニーのバックボーンです。半音階の動きと拡張されたコードは、豊かなハーモニックカラーを作り出します。"
341
+ }
342
+ // More genre tips can be added here
343
+ };
344
+
345
+ // Current state
346
+ let currentLanguage = 'en';
347
+ let currentGenre = 'pop';
348
+ let currentKey = 'C';
349
+ let currentChords = [];
350
+ let isPlaying = false;
351
+ let synth;
352
+
353
+ // DOM elements
354
+ const languageSelector = document.getElementById('language-selector');
355
+ const genreButtons = document.querySelectorAll('.genre-btn');
356
+ const keyButtons = document.querySelectorAll('.key-btn');
357
+ const generateBtn = document.getElementById('generate-btn');
358
+ const playBtn = document.getElementById('play-btn');
359
+ const resultsSection = document.getElementById('results-section');
360
+ const chordContainer = document.getElementById('chord-container');
361
+ const theoryTipsSection = document.getElementById('theory-tips');
362
+
363
+ // Initialize Tone.js
364
+ function initAudio() {
365
+ synth = new Tone.PolySynth(Tone.Synth).toDestination();
366
+ synth.volume.value = -10;
367
+ }
368
+
369
+ // Translate the UI
370
+ function translateUI(lang) {
371
+ const translation = translations[lang];
372
+
373
+ document.getElementById('main-title').textContent = translation.title;
374
+ document.getElementById('main-subtitle').textContent = translation.subtitle;
375
+ document.getElementById('genre-label').textContent = translation.genreLabel;
376
+ document.getElementById('key-label').textContent = translation.keyLabel;
377
+ document.getElementById('generate-text').textContent = translation.generateText;
378
+ document.getElementById('progression-label').textContent = translation.progressionLabel;
379
+ document.getElementById('play-text').textContent = translation.playText;
380
+ document.getElementById('save-text').textContent = translation.saveText;
381
+ document.getElementById('share-text').textContent = translation.shareText;
382
+ document.getElementById('export-text').textContent = translation.exportText;
383
+ document.getElementById('tips-title').textContent = translation.tipsTitle;
384
+ document.getElementById('tips-content').textContent = translation.tipsContent;
385
+ document.getElementById('footer-text').innerHTML = translation.footer;
386
+
387
+ // Update chord names if we have a progression displayed
388
+ if (currentChords.length > 0) {
389
+ renderChords(currentChords);
390
+ }
391
+ }
392
+
393
+ // Generate a chord progression
394
+ function generateProgression() {
395
+ const baseProgression = progressions[currentGenre];
396
+
397
+ // Transpose to selected key
398
+ const keyIndex = ['C', 'D', 'E', 'F', 'G', 'A', 'B'].indexOf(currentKey);
399
+ const transposedChords = baseProgression.map(chord => {
400
+ return transposeChord(chord, keyIndex);
401
+ });
402
+
403
+ currentChords = transposedChords;
404
+ renderChords(transposedChords);
405
+
406
+ // Show results section
407
+ resultsSection.classList.remove('hidden');
408
+
409
+ // Show music theory tips if available
410
+ if (theoryTips[currentGenre] && theoryTips[currentGenre][currentLanguage]) {
411
+ document.getElementById('tips-content').textContent = theoryTips[currentGenre][currentLanguage];
412
+ theoryTipsSection.classList.remove('hidden');
413
+ } else {
414
+ theoryTipsSection.classList.add('hidden');
415
+ }
416
+
417
+ // Scroll to results
418
+ resultsSection.scrollIntoView({ behavior: 'smooth' });
419
+ }
420
+
421
+ // Transpose a chord to a new key
422
+ function transposeChord(chord, semitones) {
423
+ const notes = ['C', 'C#', 'D', 'D#', 'E', 'F', 'F#', 'G', 'G#', 'A', 'A#', 'B'];
424
+ const flats = ['C', 'Db', 'D', 'Eb', 'E', 'F', 'Gb', 'G', 'Ab', 'A', 'Bb', 'B'];
425
+
426
+ // Extract root note and quality
427
+ let root = chord.match(/^[A-G][#b]?/)[0];
428
+ const quality = chord.slice(root.length);
429
+
430
+ // Find current index
431
+ let currentIndex = notes.indexOf(root);
432
+ if (currentIndex === -1) currentIndex = flats.indexOf(root);
433
+
434
+ // Calculate new index
435
+ let newIndex = (currentIndex + semitones) % 12;
436
+ if (newIndex < 0) newIndex += 12;
437
+
438
+ // Get new root (prefer sharps for simplicity)
439
+ const newRoot = notes[newIndex];
440
+
441
+ return newRoot + quality;
442
+ }
443
+
444
+ // Render chords to the UI
445
+ function renderChords(chords) {
446
+ chordContainer.innerHTML = '';
447
+
448
+ chords.forEach((chord, index) => {
449
+ const chordCard = document.createElement('div');
450
+ chordCard.className = 'chord-card bg-gray-800 rounded-lg p-6 text-center border border-gray-700';
451
+
452
+ // Get translated chord name
453
+ const translatedChord = chordTranslations[currentLanguage][chord.replace(/[0-9]/g, '')] || chord;
454
+
455
+ chordCard.innerHTML = `
456
+ <div class="text-5xl font-bold mb-2 text-indigo-400">${translatedChord}</div>
457
+ <div class="text-sm text-gray-400">${getRomanNumeral(chord, currentKey)}</div>
458
+ <button data-index="${index}" class="mt-4 px-3 py-1 rounded bg-gray-700 hover:bg-gray-600 text-sm play-chord-btn">
459
+ <i class="fas fa-volume-up mr-1"></i>
460
+ <span>${translations[currentLanguage].playText || 'Play'}</span>
461
+ </button>
462
+ `;
463
+
464
+ chordContainer.appendChild(chordCard);
465
+ });
466
+
467
+ // Add event listeners to chord play buttons
468
+ document.querySelectorAll('.play-chord-btn').forEach(btn => {
469
+ btn.addEventListener('click', function() {
470
+ const index = parseInt(this.getAttribute('data-index'));
471
+ playChord(currentChords[index]);
472
+
473
+ // Add visual feedback
474
+ const chordCard = this.closest('.chord-card');
475
+ chordCard.classList.add('chord-playing');
476
+ setTimeout(() => {
477
+ chordCard.classList.remove('chord-playing');
478
+ }, 1000);
479
+ });
480
+ });
481
+ }
482
+
483
+ // Get Roman numeral for a chord
484
+ function getRomanNumeral(chord, key) {
485
+ const root = chord.match(/^[A-G][#b]?/)[0];
486
+ const scale = ['C', 'D', 'E', 'F', 'G', 'A', 'B'];
487
+ const keyIndex = scale.indexOf(key[0]);
488
+ const rootIndex = scale.indexOf(root[0]);
489
+
490
+ let distance = (rootIndex - keyIndex + 7) % 7;
491
+
492
+ const numerals = ['I', 'II', 'III', 'IV', 'V', 'VI', 'VII'];
493
+ return numerals[distance];
494
+ }
495
+
496
+ // Play a single chord
497
+ function playChord(chord) {
498
+ if (!synth) initAudio();
499
+
500
+ // Parse chord to get notes
501
+ const notes = getChordNotes(chord);
502
+
503
+ // Play the chord
504
+ synth.triggerAttackRelease(notes, "2n");
505
+ }
506
+
507
+ // Play the entire progression
508
+ function playProgression() {
509
+ if (isPlaying) {
510
+ // Stop playback
511
+ Tone.Transport.cancel();
512
+ isPlaying = false;
513
+ playBtn.innerHTML = `<i class="fas fa-play mr-2"></i><span>${translations[currentLanguage].playText || 'Play'}</span>`;
514
+ return;
515
+ }
516
+
517
+ if (!synth) initAudio();
518
+
519
+ isPlaying = true;
520
+ playBtn.innerHTML = `<i class="fas fa-stop mr-2"></i><span>${translations[currentLanguage].playText || 'Stop'}</span>`;
521
+
522
+ // Start Tone.js transport
523
+ Tone.start();
524
+ Tone.Transport.cancel();
525
+ Tone.Transport.bpm.value = 90;
526
+
527
+ let time = 0;
528
+ currentChords.forEach((chord, i) => {
529
+ const notes = getChordNotes(chord);
530
+
531
+ // Play chord
532
+ Tone.Transport.schedule(time => {
533
+ synth.triggerAttackRelease(notes, "2n", time);
534
+
535
+ // Highlight the playing chord
536
+ const chordCards = document.querySelectorAll('.chord-card');
537
+ chordCards.forEach(card => card.classList.remove('chord-playing'));
538
+ chordCards[i].classList.add('chord-playing');
539
+ }, time);
540
+
541
+ time += 1; // 1 measure per chord
542
+ });
543
+
544
+ // Stop highlighting when done
545
+ Tone.Transport.schedule(time => {
546
+ document.querySelectorAll('.chord-card').forEach(card => {
547
+ card.classList.remove('chord-playing');
548
+ });
549
+ isPlaying = false;
550
+ playBtn.innerHTML = `<i class="fas fa-play mr-2"></i><span>${translations[currentLanguage].playText || 'Play'}</span>`;
551
+ }, time);
552
+
553
+ Tone.Transport.start();
554
+ }
555
+
556
+ // Get notes for a chord
557
+ function getChordNotes(chord) {
558
+ const chordMap = {
559
+ 'C': ['C4', 'E4', 'G4'],
560
+ 'Cm': ['C4', 'Eb4', 'G4'],
561
+ 'C7': ['C4', 'E4', 'G4', 'Bb4'],
562
+ 'D': ['D4', 'F#4', 'A4'],
563
+ 'Dm': ['D4', 'F4', 'A4'],
564
+ 'D7': ['D4', 'F#4', 'A4', 'C5'],
565
+ 'E': ['E4', 'G#4', 'B4'],
566
+ 'Em': ['E4', 'G4', 'B4'],
567
+ 'E7': ['E4', 'G#4', 'B4', 'D5'],
568
+ 'F': ['F4', 'A4', 'C5'],
569
+ 'Fm': ['F4', 'Ab4', 'C5'],
570
+ 'F7': ['F4', 'A4', 'C5', 'Eb5'],
571
+ 'G': ['G4', 'B4', 'D5'],
572
+ 'Gm': ['G4', 'Bb4', 'D5'],
573
+ 'G7': ['G4', 'B4', 'D5', 'F5'],
574
+ 'A': ['A4', 'C#5', 'E5'],
575
+ 'Am': ['A4', 'C5', 'E5'],
576
+ 'A7': ['A4', 'C#5', 'E5', 'G5'],
577
+ 'B': ['B4', 'D#5', 'F#5'],
578
+ 'Bm': ['B4', 'D5', 'F#5'],
579
+ 'B7': ['B4', 'D#5', 'F#5', 'A5'],
580
+ 'Bb': ['Bb4', 'D5', 'F5'],
581
+ 'C#m': ['C#4', 'E4', 'G#4'],
582
+ 'F#m': ['F#4', 'A4', 'C#5']
583
+ };
584
+
585
+ return chordMap[chord] || ['C4', 'E4', 'G4']; // Default to C major if chord not found
586
+ }
587
+
588
+ // Event listeners
589
+ languageSelector.addEventListener('change', function() {
590
+ currentLanguage = this.value;
591
+ translateUI(currentLanguage);
592
+ });
593
+
594
+ genreButtons.forEach(btn => {
595
+ btn.addEventListener('click', function() {
596
+ // Update active genre button
597
+ genreButtons.forEach(b => {
598
+ b.classList.remove('bg-indigo-700', 'text-indigo-100');
599
+ const genreClass = {
600
+ pop: 'bg-indigo-900',
601
+ rock: 'bg-gray-700',
602
+ jazz: 'bg-amber-900',
603
+ blues: 'bg-blue-900',
604
+ classical: 'bg-purple-900',
605
+ electronic: 'bg-pink-900',
606
+ flamenco: 'bg-red-900',
607
+ reggae: 'bg-green-900'
608
+ }[b.dataset.genre];
609
+ b.classList.add(genreClass);
610
+ });
611
+
612
+ this.classList.remove('bg-indigo-900', 'bg-gray-700', 'bg-amber-900', 'bg-blue-900', 'bg-purple-900', 'bg-pink-900', 'bg-red-900', 'bg-green-900');
613
+ this.classList.add('bg-indigo-700', 'text-indigo-100');
614
+
615
+ currentGenre = this.dataset.genre;
616
+ });
617
+ });
618
+
619
+ keyButtons.forEach(btn => {
620
+ btn.addEventListener('click', function() {
621
+ keyButtons.forEach(b => b.classList.remove('bg-indigo-600', 'text-white'));
622
+ this.classList.add('bg-indigo-600', 'text-white');
623
+ currentKey = this.dataset.key;
624
+ });
625
+ });
626
+
627
+ generateBtn.addEventListener('click', generateProgression);
628
+ playBtn.addEventListener('click', playProgression);
629
+
630
+ // Initialize
631
+ translateUI(currentLanguage);
632
+ genreButtons[0].click(); // Select first genre by default
633
+ keyButtons[0].click(); // Select first key by default
634
+ </script>
635
+ <p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=zama1/harmonygen" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
636
+ </html>