Beispiel #1
0
def _chord_label_to_chord_str(chord_label: int, alphabet: ChordAlphabet) -> str:
    """
    Translate the integer chord label to a chord string

    :param chord_label: Chord index in the chord_vocabulary (integer)
    :return: Chord string (str)
    """
    if chord_label == 0:
        return 'N'
    return str(Chord.from_common_tab_notation_string(alphabet.alphabet_list[chord_label]))
Beispiel #2
0
    def _add_chord_from_str(self, chord_str: str, chord_x: int):
        """
        Find the Chord from chord_str and add it to self.chords

        :param chord_str: String of the Chord
        :param chord_x: Integer index of the Chord
        """
        chord = Chord.from_common_tab_notation_string(chord_str)
        if chord is not None:
            self.chords.append((chord_x, chord))
Beispiel #3
0
def _write_final_labels(final_labels, lab_path, alphabet):
    """
    Write the row of final labels (after data fusion) from the chord matrix to a .json file at lab_path
    :param final_labels: The row of final labels after data fusion
    :param lab_path: The path to write the final .json file to
    :param alphabet: The chord vocabulary (used to translate chord indices to chord strings)
    """
    # First, we fill the write_labels list with (start_time, end_time, chord_string) 3-tuples
    write_labels = []
    current_beat = 1
    final_list = []
    start_time = -1
    last_chord = ''
    last_added = True
    for i in range(len(final_labels)):
        if final_labels[i] == last_chord:
            last_added = False
        else:
            if not last_added:
                # Write previous chord
                write_labels.append((start_time, float(i) / 100, last_chord))
            # Set parameters for next
            start_time = float(i) / 100
            last_chord = final_labels[i]
    if not last_added:
        # The last chord has not been added yet, so we do it now
        write_labels.append(
            (start_time, float(len(final_labels) - 1) / 100, last_chord))

    # Now write the chords to the .json file in .json format
    with open(lab_path, 'w') as write_file:
        for write_label in write_labels:
            chord_string = str(
                Chord.from_common_tab_notation_string(
                    alphabet[write_label[2]]))
            if chord_string == 'None':
                chord_string = 'N'
            dictionary = {}
            dictionary['current_beat'] = current_beat
            dictionary['current_beat_time'] = write_label[0]
            dictionary['estimated_chord'] = chord_string
            final_list.append(dictionary)
            current_beat += 1
        json.dump(final_list, write_file, indent=4)
Beispiel #4
0
    def add_tab_block(self, tab_block_str: [Line]):
        """
        Process the content of a tab block (6 subsequent lines of LineType Tablature), add chords to self.chords

        :param tab_block_str: Six subsequent Lines of the LineType Tablature
        """
        smallest_line_length = min(
            [len(block_line_str) for block_line_str in tab_block_str])
        for chord_x in range(0, smallest_line_length):
            # Read all six strings together per x-coordinate
            finger_list = []
            for tab_block_line_str in reversed(tab_block_str):
                finger_list.append(tab_block_line_str[chord_x])
            fingers = ''.join(finger_list)

            if re.match(r'[x0-9]{6}', fingers) and fingers != 'xxxxxx':
                # A chord sounds at this x position!
                fingering = Fingering('1', fingers[0], fingers[1], fingers[2],
                                      fingers[3], fingers[4], fingers[5])
                fingering_chroma = fingering.get_extended_chroma_vector()

                # Find nearest chord from vocabulary
                smallest_distance = 2
                best_matching_chord_str = 'X'
                for chord_template in ALL_CHORDS_LIST.chord_templates:
                    cosine_distance = ssd.cosine(fingering_chroma[:12],
                                                 chord_template.chroma_list)
                    if cosine_distance < smallest_distance:
                        smallest_distance = cosine_distance
                        best_matching_chord_str = str(
                            PitchClass(
                                chord_template.key))[0] + chord_template.mode
                chord = Chord.from_common_tab_notation_string(
                    best_matching_chord_str)

                # Fix bass note
                bass_note = PitchClass(fingering_chroma[12])
                bass_interval = Interval.from_pitch_class_distances(
                    chord.root_note, bass_note)
                chord.bass_degree = bass_interval

                # Add to self.chords
                self.chords.append((chord_x, chord))
Beispiel #5
0
    def find_most_likely_chord(self, chord_vocabulary: ChordVocabulary) -> Tuple[ChordAnnotationItem, float]:
        """
        Find the chord to which the chroma of this event matches best.

        :param chord_vocabulary: List of all chords for classification
        """
        best_matching_chord_score = -2.99
        best_matching_chord_str = 'X'
        best_key_note_weight = 0
        for chord_template in chord_vocabulary.chord_templates:
            chord_score = self._score_compared_to_template(chord_template)
            if chord_score > best_matching_chord_score or (chord_score == best_matching_chord_score and
                                                           self.chroma[chord_template.key] > best_key_note_weight):
                best_matching_chord_score = chord_score
                best_matching_chord_str = str(PitchClass(chord_template.key)) + chord_template.mode
                best_key_note_weight = self.chroma[chord_template.key]
        if best_matching_chord_str == 'X':
            most_likely_chord = None
        else:
            most_likely_chord = Chord.from_common_tab_notation_string(best_matching_chord_str)
        return ChordAnnotationItem(self.start_time, self.end_time, most_likely_chord), best_matching_chord_score
Beispiel #6
0
def _write_final_labels(final_labels, lab_path, alphabet):
    """
    Write the row of final labels (after data fusion) from the chord matrix to a .lab file at lab_path

    :param final_labels: The row of final labels after data fusion
    :param lab_path: The path to write the final lab file to
    :param alphabet: The chord vocabulary (used to translate chord indices to chord strings)
    """

    # First, we fill the write_labels list with (start_time, end_time, chord_string) 3-tuples
    write_labels = []
    start_time = -1
    last_chord = ''
    last_added = True
    for i in range(len(final_labels)):
        if final_labels[i] == last_chord:
            last_added = False
        else:
            if not last_added:
                # Write previous chord
                write_labels.append((start_time, float(i) / 100, last_chord))
            # Set parameters for next
            start_time = float(i) / 100
            last_chord = final_labels[i]
    if not last_added:
        # The last chord has not been added yet, so we do it now
        write_labels.append(
            (start_time, float(len(final_labels) - 1) / 100, last_chord))

    # Now write the chords to the .lab file in Harte format
    with open(lab_path, 'w') as write_file:
        for write_label in write_labels:
            chord_string = str(
                Chord.from_common_tab_notation_string(
                    alphabet[write_label[2]]))
            if chord_string == 'None':
                chord_string = 'N'
            write_file.write('{0} {1} {2}\n'.format(str(write_label[0]),
                                                    str(write_label[1]),
                                                    chord_string))