예제 #1
0
파일: chord.py 프로젝트: naari3/chordium
def add_new_root_notes(notes: List[str], on: str, base_oct: int = 3):
    if musthe.Note(notes[0]).number > musthe.Note(f"{on}{base_oct}").number:
        adjust = 0
    else:
        adjust = -1
    notes.insert(0, f"{on}{base_oct + adjust}")
    return notes
예제 #2
0
def my_chorus(chord_progression, length, num=1, velocity=80, channel=0):
    """
    :param chord_progression: the chord progression, chould be a list or str
    :param length: the beat
    :param num: the times of repetition
    :param velocity: 0~127,the velocity of chord
    :param channel:0~12
    :return:
    """
    d = {'C': 1, 'D': 2, 'E': 3, 'F': 4, 'G': 5, 'A': 6, 'B': 7}
    all_note = []
    if type(chord_progression) == list:  # 如果来的是一个列表,就是几个和弦
        for chord in chord_progression:
            note = []
            if chord[1:len(chord)]:
                temp = musthe.Chord(musthe.Note(chord[0]), chord[1:len(chord)]).notes
            else:
                temp = musthe.Chord(musthe.Note(chord[0])).notes
            for i in range(len(temp)):
                note.append(d[str(temp[i])])
            all_note.append(note)
    else:  # 如果来的只有一个和弦
        note = []
        if chord_progression[1:len(chord_progression)]:
            temp = musthe.Chord(musthe.Note(chord_progression[0]), chord_progression[1:len(chord_progression)]).notes
        else:
            temp = musthe.Chord(musthe.Note(chord_progression[0])).notes
        for i in range(len(temp)):
            note.append(d[str(temp[i])])
        all_note.append(note)
    major_notes = [0, 2, 2, 1, 2, 2, 2, 1]
    base_note = 60
    base_num = 0
    delay = 0
    bpm = 100
    meta_time = 60000 / bpm
    for chord_note in all_note:
        for j in range(num):
            count = 0
            for note in chord_note:
                track.append(Message('note_on', note=base_note + base_num * 12 + sum(major_notes[0:note]),
                                     velocity=velocity if count else velocity + 10, time=round(delay * meta_time),
                                     channel=channel))
            for note in chord_note:
                track.append(Message('note_off', note=base_note + base_num * 12 + sum(major_notes[0:note]),
                                     velocity=velocity if count else velocity + 10,
                                     time=0 if count else round(0.96 * meta_time * length),
                                     channel=channel))
                count = count + 1
def change(num, key, mode, count=3):
    """
    change the chord from number to str.
    example: in C major, 1 change to ['C', 'E', 'G']
    :param num: the progression number, should be int from 1~7.
    :param key: char, the first note of scale,could be C D E F G A B.
    :param mode: see doc of class Impromptu.
    :param count: default 3, could be 3, 4 or 5, corresponding triad, seventh chord and hord of the ninthc.
    :return:
    """
    d = {'C': 1, 'D': 2, 'E': 3, 'F': 4, 'G': 5, 'A': 6, 'B': 7}
    result = []
    try:
        if type(num) == int and 0 < num < 8:
            s = musthe.Scale(musthe.Note(key), mode)
            scale = []
            for i in range(len(s)):
                scale.append(str(s[i]))
            for i in range(count):
                result.append(d[scale[(num - 1 + 2 * i) % 7]])
        else:
            raise TypeError('num should be int from 1~7.')
    except NameError:
        return change(num, key, mode='aeolian', count=count)
    return result
예제 #4
0
def get_scale_idx(note, key):

    scale = theory.Scale(key[0], key[1])
    for i in range(7):
        # print scale.__getitem__(i)
        if scale.__getitem__(i).letter.__eq__(theory.Note(note).letter):
            return i + 1
    raise ValueError("note ", note, " not in scale ", key)
예제 #5
0
def get_chord_options(note, key):

    scale = theory.Scale(theory.Note(key[0]), key[1])

    scale_idx_1 = get_scale_idx(note, key)
    scale_idx_2 = scale_idx_1 - 2
    scale_idx_3 = scale_idx_1 - 4

    options = [scale_idx_1, scale_idx_2, scale_idx_3]

    for i in range(len(options)):
        if options[i] <= 0:
            options[i] += 7

    # print "chord options are ", sorted(options)
    return sorted(options)
예제 #6
0
파일: chord.py 프로젝트: naari3/chordium
def up_octave(note) -> str:
    return (musthe.Note(note) + musthe.Interval("P8")).scientific_notation()
예제 #7
0
def harmonic_random(reffile):
    chords = []
    lf = open(reffile)
    nf = open(reffile)

    for line in lf:
        label, value, time = line.split()
        if random.randint(1,10) <= 3:
            continue
        time = datetime.strptime(time, '%H:%M:%S.%f')
        chord = gen_rand_chord()
        chords.append((pychord.Chord(chord), time))

    chord_groups = [[] for c in chords]
    for line in nf:
        label, value, time = line.split()
        if label != 'NOTE':
            continue
        time = datetime.strptime(time, '%H:%M:%S.%f')

        if time < chords[0][1]:
            continue
        for i in range(len(chords)-1):
            if chords[i][1] <= time < chords[i+1][1]:
                chord_groups[i].append(value[:-1])
                break
        else:
            assert chords[-1][1] <= time
            chord_groups[-1].append(value[:-1])

    bad_notes = 0
    total_notes = 0
    for i in range(len(chords)):
        chord = chords[i][0]
        notes = chord_groups[i]
        quality = chord.quality.quality
        if quality in major_quals:
            quality = 'major'
        elif quality in minor_quals:
            quality = 'natural_minor'
        else:
            quality = None

        if quality:
            scale = musthe.Scale(musthe.Note(chord.root), quality)
            scale_notes = [str(scale[i]) for i in range(len(scale))]
        else:
            scale = []

        for i in range(len(notes)):
            lower = max(0, i-HARMONIC_WINDOW)
            upper = min(len(notes)-1, i+HARMONIC_WINDOW)
            relevant_notes = [notes[j] for j in range(lower, upper+1)]

            for note in relevant_notes:
                if note in chord.components():# or musthe.Note(note) in scale:
                    break
            else:
                bad_notes += 1

        total_notes += len(notes)

    # print('{:>8}'.format(f'{bad_notes}/{total_notes}\t'), end='')
    # print(f'{bad_notes/total_notes*100:.0f}% error')
    return bad_notes / total_notes