Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -173,32 +173,58 @@ SORTED_QUALITIES = sorted(CHORD_INTERVALS.keys(), key=len, reverse=True)
|
|
| 173 |
|
| 174 |
def parse_chord_to_midi(chord_string):
|
| 175 |
if not chord_string or chord_string == 'N': return [], ""
|
| 176 |
-
|
| 177 |
-
#
|
| 178 |
-
|
| 179 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 180 |
root_note = chord_string[0]
|
| 181 |
remainder = chord_string[1:]
|
| 182 |
-
|
| 183 |
-
# Check for sharps or flats
|
| 184 |
if remainder and remainder[0] in ['s', 'b']:
|
| 185 |
root_note += remainder[0]
|
| 186 |
remainder = remainder[1:]
|
| 187 |
|
| 188 |
root_midi = NOTE_TO_MIDI.get(root_note, 60)
|
| 189 |
|
| 190 |
-
#
|
| 191 |
quality = 'maj'
|
| 192 |
intervals = CHORD_INTERVALS['maj']
|
| 193 |
-
|
| 194 |
-
# Check against our sorted list (e.g., checks 'min7' before 'min')
|
| 195 |
for q in SORTED_QUALITIES:
|
| 196 |
if remainder.startswith(q):
|
| 197 |
intervals = CHORD_INTERVALS[q]
|
| 198 |
quality = q
|
| 199 |
break
|
| 200 |
|
| 201 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 202 |
# General MIDI Patch Numbers (0-indexed)
|
| 203 |
INSTRUMENT_MAP = {
|
| 204 |
"Acoustic Grand Piano": 0,
|
|
|
|
| 173 |
|
| 174 |
def parse_chord_to_midi(chord_string):
|
| 175 |
if not chord_string or chord_string == 'N': return [], ""
|
| 176 |
+
|
| 177 |
+
# 1. Check for a slash chord bass note!
|
| 178 |
+
bass_note_str = None
|
| 179 |
+
if '/' in chord_string:
|
| 180 |
+
parts = chord_string.split('/')
|
| 181 |
+
chord_string = parts[0] # The main chord (e.g., 'Amin')
|
| 182 |
+
bass_note_str = parts[1] # The bass note (e.g., 'E')
|
| 183 |
+
|
| 184 |
+
# 2. Parse the main chord's root note
|
| 185 |
root_note = chord_string[0]
|
| 186 |
remainder = chord_string[1:]
|
|
|
|
|
|
|
| 187 |
if remainder and remainder[0] in ['s', 'b']:
|
| 188 |
root_note += remainder[0]
|
| 189 |
remainder = remainder[1:]
|
| 190 |
|
| 191 |
root_midi = NOTE_TO_MIDI.get(root_note, 60)
|
| 192 |
|
| 193 |
+
# 3. Find the chord quality
|
| 194 |
quality = 'maj'
|
| 195 |
intervals = CHORD_INTERVALS['maj']
|
|
|
|
|
|
|
| 196 |
for q in SORTED_QUALITIES:
|
| 197 |
if remainder.startswith(q):
|
| 198 |
intervals = CHORD_INTERVALS[q]
|
| 199 |
quality = q
|
| 200 |
break
|
| 201 |
|
| 202 |
+
pitches = [root_midi + i for i in intervals]
|
| 203 |
+
|
| 204 |
+
# 4. Inject the custom bass note
|
| 205 |
+
if bass_note_str:
|
| 206 |
+
# Parse the bass note (checking for sharps/flats)
|
| 207 |
+
b_root = bass_note_str[0]
|
| 208 |
+
b_rem = bass_note_str[1:]
|
| 209 |
+
if b_rem and b_rem[0] in ['s', 'b']:
|
| 210 |
+
b_root += b_rem[0]
|
| 211 |
+
|
| 212 |
+
bass_midi = NOTE_TO_MIDI.get(b_root, 60)
|
| 213 |
+
|
| 214 |
+
# Force the bass note to sit below our root note
|
| 215 |
+
while bass_midi >= root_midi:
|
| 216 |
+
bass_midi -= 12
|
| 217 |
+
|
| 218 |
+
# Drop it one more octave for a deep, rich foundation
|
| 219 |
+
bass_midi -= 12
|
| 220 |
+
|
| 221 |
+
pitches.append(bass_midi)
|
| 222 |
+
|
| 223 |
+
# Update the display name so it shows the slash in the final output!
|
| 224 |
+
quality += "/" + bass_note_str
|
| 225 |
+
|
| 226 |
+
return pitches, quality
|
| 227 |
+
|
| 228 |
# General MIDI Patch Numbers (0-indexed)
|
| 229 |
INSTRUMENT_MAP = {
|
| 230 |
"Acoustic Grand Piano": 0,
|