File size: 2,603 Bytes
c9d790f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
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}")