Moonaarch_Chords_V2 / moonarch.py
Jaman's picture
Upload 4 files
c9d790f verified
raw
history blame contribute delete
2.6 kB
import autochord
import pretty_midi
import librosa
class MusicToChordsConverter:
def __init__(self, audio_file):
self.audio_file = audio_file
self.chords = None
self.midi_chords = pretty_midi.PrettyMIDI()
self.instrument_chords = pretty_midi.Instrument(program=0) # Acoustic Grand Piano
def recognize_chords(self):
"""
Perform chord recognition on the audio file.
"""
self.chords = autochord.recognize(self.audio_file, lab_fn='chords.lab')
def chord_to_midi_notes(self, chord_name):
"""
Map chord names to MIDI notes.
Args:
chord_name (str): The chord name to be mapped.
Returns:
list: A list of MIDI notes corresponding to the chord.
"""
note_mapping = {
'C:maj': ['C4', 'E4', 'G4'],
'C:min': ['C4', 'E-4', 'G4'],
'D:maj': ['D4', 'F#4', 'A4'],
'D:min': ['D4', 'F4', 'A4'],
'E:maj': ['E4', 'G#4', 'B4'],
'E:min': ['E4', 'G4', 'B4'],
'F:maj': ['F4', 'A4', 'C5'],
'F:min': ['F4', 'A-4', 'C5'],
'G:maj': ['G4', 'B4', 'D5'],
'G:min': ['G4', 'B-4', 'D5'],
'A:maj': ['A4', 'C#5', 'E5'],
'A:min': ['A4', 'C5', 'E5'],
'B:maj': ['B4', 'D#5', 'F#5'],
'B:min': ['B4', 'D5', 'F#5']
}
return note_mapping.get(chord_name, [])
def generate_midi(self):
"""
Generate a MIDI file from the recognized chords.
"""
for chord in self.chords:
start_time = chord[0]
end_time = chord[1]
chord_name = chord[2]
if chord_name != 'N': # Ignore no-chord
chord_notes = self.chord_to_midi_notes(chord_name)
for note_name in chord_notes:
midi_note = pretty_midi.Note(
velocity=100,
pitch=librosa.note_to_midi(note_name),
start=start_time,
end=end_time
)
self.instrument_chords.notes.append(midi_note)
self.midi_chords.instruments.append(self.instrument_chords)
def save_midi(self, output_file):
"""
Save the generated MIDI file to disk.
Args:
output_file (str): The path where the MIDI file should be saved.
"""
self.midi_chords.write(output_file)
print(f"Saved chords to {output_file}")