def note_minus_intvl(note_obj, intvl_obj): from pymusician import Note, Interval if not isinstance(intvl_obj, Interval): raise ValueError("Intervals can only be added to Note objects.") letter = note_obj.letter - intvl_obj.letter_diff if letter < 0: letter += 7 if note_obj.octave != 0: hard_pitch = note_obj.hard_pitch - intvl_obj.diff new_note = Note.from_values(letter, abs(hard_pitch % 12)) new_note.octave = hard_pitch // 12 else: pitch = note_obj.pitch - intvl_obj.diff if intvl_obj._displace > 0: pitch -= intvl_obj._displace * 12 if pitch < 0: pitch += 12 new_note = Note.from_values(letter, pitch) if note_obj.rhythm: print(note_obj.rhythm) new_note.rhythm = note_obj.rhythm.flags return new_note
def chord_from_notes(*notes, root=None): from pymusician import Note notes = list(notes) #root can be provided or by default is first note provided if not root: root = notes[0] del notes[0] if isinstance(root, str): try: root = Note(root) except: raise ValueError("Invalid root note ") elif not root.__class__.__name__ == "Note": raise ValueError("Invalid note passed to Chord.from_notes") symbol = root.name intvls = [] for i in range(len(notes)): note = notes[i] if isinstance(note, str): try: note = Note(note) except: raise ValueError("Invalid note passed to Chord.from_notes") elif not note.__class__.__name__ == "Note": raise ValueError("Invalid note passed to Chord.from_notes") if note.name == root.name: continue intvls.append(Interval.from_notes(root, note))
def note_minus_intvl(note_obj,intvl_obj): from pymusician import Note, Interval if not isinstance(intvl_obj,Interval): raise ValueError("Intervals can only be added to Note objects.") letter = note_obj.letter - intvl_obj.letter_diff if letter < 0: letter += 7 if note_obj.octave != 0: hard_pitch = note_obj.hard_pitch - intvl_obj.diff new_note = Note.from_values(letter,abs(hard_pitch % 12)) new_note.octave = hard_pitch // 12 else: pitch = note_obj.pitch - intvl_obj.diff if intvl_obj._displace > 0: pitch -= intvl_obj._displace * 12 if pitch < 0: pitch += 12 new_note = Note.from_values(letter,pitch) if note_obj.rhythm: print(note_obj.rhythm) new_note.rhythm = note_obj.rhythm.flags return new_note
def enharmonic(note_obj, prefer=None, gross=False): from pymusician import Note if prefer: if prefer not in ("#", "b"): raise ValueError("'prefer' parameter should be set to '#' or 'b'.") if not isinstance(gross, bool): raise ValueError("2nd arg for enharmonic should be Boolean.") if gross and note_obj.name in GROSS_ROOTS: new_name = GROSS_ROOTS[note_obj.name] if "#" in new_name and prefer == 'b': return note_obj elif 'b' in new_name and prefer == '#': return note_obj else: new_note = Note(new_name) elif len(note_obj.name) == 1: return note_obj elif len(note_obj.name) == 2: if "#" in note_obj.name: if prefer == '#': return note_obj new_letter = note_obj.letter + 1 if new_letter > 6: new_letter -= 7 else: if prefer == 'b': return note_obj new_letter = note_obj.letter - 1 if new_letter < 0: new_letter += 7 new_note = Note.from_values(new_letter, note_obj.pitch) else: new_note = note_obj new_letter = note_obj.letter limit = 2 if note_obj.pitch in NON_NATURAL else 1 while len(new_note.name) > limit: if "#" in note_obj.name: new_letter += 1 if new_letter > 6: new_letter -= 7 else: new_letter -= 1 if new_letter < 0: new_letter += 7 new_note = Note.from_values(new_letter, note_obj.pitch) if "#" in new_note.name and prefer == "b": new_note = Note.from_values(new_letter + 1, note_obj.pitch) elif "b" in new_note.name and prefer == "#": new_note = Note.from_values(new_letter - 1, note_obj.pitch) if note_obj.octave: new_note.octave = note_obj.octave if note_obj.rhythm: new_note.rhythm = note_obj.rhythm.flags return new_note
def enharmonic(note_obj,prefer=None,gross=False): from pymusician import Note if prefer: if prefer not in ("#","b"): raise ValueError("'prefer' parameter should be set to '#' or 'b'.") if not isinstance(gross, bool): raise ValueError("2nd arg for enharmonic should be Boolean.") if gross and note_obj.name in GROSS_ROOTS: new_name = GROSS_ROOTS[note_obj.name] if "#" in new_name and prefer == 'b': return note_obj elif 'b' in new_name and prefer == '#': return note_obj else: new_note = Note(new_name) elif len(note_obj.name) == 1: return note_obj elif len(note_obj.name) == 2: if "#" in note_obj.name: if prefer == '#': return note_obj new_letter = note_obj.letter + 1 if new_letter > 6: new_letter -= 7 else: if prefer == 'b': return note_obj new_letter = note_obj.letter - 1 if new_letter < 0: new_letter += 7 new_note = Note.from_values(new_letter,note_obj.pitch) else: new_note = note_obj new_letter = note_obj.letter limit = 2 if note_obj.pitch in NON_NATURAL else 1 while len(new_note.name) > limit: if "#" in note_obj.name: new_letter += 1 if new_letter > 6: new_letter -= 7 else: new_letter -= 1 if new_letter < 0: new_letter += 7 new_note = Note.from_values(new_letter,note_obj.pitch) if "#" in new_note.name and prefer == "b": new_note = Note.from_values(new_letter + 1, note_obj.pitch) elif "b" in new_note.name and prefer == "#": new_note = Note.from_values(new_letter - 1, note_obj.pitch) if note_obj.octave: new_note.octave = note_obj.octave if note_obj.rhythm: new_note.rhythm = note_obj.rhythm.flags return new_note
def run(tempo=TEMPO, key_quality=KEY_QUAL, key=KEY, harmonic_period=HARMONIC_RHYTHM): HARMONIC_RHYTHM_VALUE = Note('A', 0, HARMONIC_RHYTHM).rhythm.value HARMONIC_DURATION = (60 / TEMPO) * (HARMONIC_RHYTHM_VALUE / 128) HARMONIC_METHOD = ideas.PROGRESSIONS[randint(0, len(ideas.PROGRESSIONS) - 1)] romans = [1] prev_roman = 1 for i in range(100): if KEY_QUAL == 'whole tone': options = ideas.anything_goes_6[prev_roman] else: options = HARMONIC_METHOD[prev_roman] next_roman = options[randint(0, len(options) - 1)] romans.append(next_roman) if i > 50 and next_roman == 1: break prev_roman = next_roman chords = [] for roman in romans: index = roman - 1 chords.append(Chord(KEY.spelling[index].name + CHORD_QUALS[index])) RHYTHMIC_PERIOD = HARMONIC_RHYTHM_VALUE * len(chords) melodic_ideas = [] prev_note = None for chord in chords: melodic_ideas.append( ideas.produce_notes(chord, prev_note, HARMONIC_RHYTHM_VALUE, KEY)) prev_note = melodic_ideas[-1][-1][-1] idea_count = 1 fade = False for idea in melodic_ideas: melody_count = 1 for melodic_group in idea: duration = (60 / TEMPO) * (melodic_group[-1].rhythm.value / 128) if melody_count == len(idea) and idea_count == len(melodic_ideas): duration *= 3 fade = True stream.play_notes(duration, *melodic_group, fade=fade) melody_count += 1 idea_count += 1 stream.stream.close()
def __init__(self, root, mode): from pymusician import Note if root.__class__.__name__ == "Note": self._root = root else: try: self._root = Note(root.capitalize()) except: raise ValueError( "Mode root should be a Note object or a valid note name (str)." ) if mode not in MODES: raise KeyError( "Mode not found. View the modes json to see/add modes.") self._mode = mode self._name = self.root.name + " " + mode self._spelling = mode_speller(self.root, self.mode)
def __init__(self, symbol): from pymusician import Note, Interval self._symbol = symbol data = parse_symbol(symbol) self._root = Note(data["root"]) self._quality = data["quality"] self._intervals = data["intervals"] spelling = [self.root] intvls = [] for intvl in self._intervals.split(): if intvl not in intvls: spelling.append(self.root + Interval(intvl)) intvls.append(intvl) self._spelling = tuple(spelling)
def mode_speller(root,mode): from pymusician import Note spelling = [root] if type(MODES[mode]) is str: parent_name = MODES[mode][:len(MODES[mode])-1] offset = int(MODES[mode][-1]) - 1 elif type(MODES[mode]) is list: parent_name = mode offset = 0 else: raise ValueError("Invalid Mode pattern. (Check modes json)") parent = MODES[parent_name] for item in parent: if type(item) is not int: raise ValueError("Invalid Mode pattern. (Check modes json)") next_pitch = root.pitch next_letter = root.letter index = offset n = 1 flats = False if "b" not in root.name else True sharps = False if "#" not in root.name else True if parent_name in MODE_LETTER_SPELLINGS: for step in parent: if index == len(parent): index -= len(parent) if n == len(parent): break next_pitch += parent[index] if parent_name in MODE_LETTER_SPELLINGS: next_letter += MODE_LETTER_SPELLINGS[parent_name][index] else: next_letter += 1 if next_pitch < 0: next_pitch += 12 elif next_pitch > 11: next_pitch -= 12 if next_letter < 0: next_letter += 7 elif next_letter > 6: next_letter -= 7 if parent_name in MODE_LETTER_SPELLINGS: next_note = Note.from_values(next_letter,next_pitch) else: next_note = Note.from_values(next_letter,next_pitch) if len(next_note.name) > 2: next_note = next_note.enharmonic() if next_note.name in ("B#","Cb","E#","Fb"): next_note = next_note.enharmonic() if "#" in next_note.name: if flats: next_note = next_note.enharmonic() if not flats and not sharps: sharps = True if "b" in next_note.name: if sharps: next_note = next_note.enharmonic() if not flats and not sharps: flats = True spelling.append(next_note) index += 1 n += 1 else: flats = False if "b" not in root.name else True sharps = False if "#" not in root.name else True for step in parent: if index == len(parent): index -= len(parent) if n == len(parent): break next_pitch += parent[index] next_letter += 1 if next_pitch < 0: next_pitch += 12 elif next_pitch > 11: next_pitch -= 12 if next_letter < 0: next_letter += 7 elif next_letter > 6: next_letter -= 7 next_note = Note.from_values(next_letter,next_pitch) if len(next_note.name) > 2: next_note = next_note.enharmonic() if next_note.name in ("B#","Cb","E#","Fb"): next_note = next_note.enharmonic() if "#" in next_note.name: if flats: next_note = next_note.enharmonic() if not flats and not sharps: sharps = True if "b" in next_note.name: if sharps: next_note = next_note.enharmonic() if not flats and not sharps: flats = True index += 1 n += 1 spelling.append(next_note) return tuple(spelling)
chunk = tone * multiplier first = False continue chunk += tone * multiplier if fade: fade_in_frames = ATTACK fade_out_frames = 4000 else: fade_in_frames = ATTACK fade_out_frames = 50 fade_in = numpy.arange(0., 1., 1. / fade_in_frames) fade_out = numpy.arange(1., 0., -1. / fade_out_frames) chunk[:fade_in_frames] = numpy.multiply(chunk[:fade_in_frames], fade_in) chunk[-fade_out_frames:] = numpy.multiply(chunk[-fade_out_frames:], fade_out) self.stream.write(chunk.astype(numpy.float32).tostring()) if __name__ == '__main__': stream = Stream() stream.play_notes(1, Note("A", 3), Note("C#", 4), Note("E", 4)) stream.stream.close()
def mode_speller(root, mode): from pymusician import Note spelling = [root] if type(MODES[mode]) is str: parent_name = MODES[mode][:len(MODES[mode]) - 1] offset = int(MODES[mode][-1]) - 1 elif type(MODES[mode]) is list: parent_name = mode offset = 0 else: raise ValueError("Invalid Mode pattern. (Check modes json)") parent = MODES[parent_name] for item in parent: if type(item) is not int: raise ValueError("Invalid Mode pattern. (Check modes json)") next_pitch = root.pitch next_letter = root.letter index = offset n = 1 flats = False if "b" not in root.name else True sharps = False if "#" not in root.name else True if parent_name in MODE_LETTER_SPELLINGS: for step in parent: if index == len(parent): index -= len(parent) if n == len(parent): break next_pitch += parent[index] if parent_name in MODE_LETTER_SPELLINGS: next_letter += MODE_LETTER_SPELLINGS[parent_name][index] else: next_letter += 1 if next_pitch < 0: next_pitch += 12 elif next_pitch > 11: next_pitch -= 12 if next_letter < 0: next_letter += 7 elif next_letter > 6: next_letter -= 7 if parent_name in MODE_LETTER_SPELLINGS: next_note = Note.from_values(next_letter, next_pitch) else: next_note = Note.from_values(next_letter, next_pitch) if len(next_note.name) > 2: next_note = next_note.enharmonic() if next_note.name in ("B#", "Cb", "E#", "Fb"): next_note = next_note.enharmonic() if "#" in next_note.name: if flats: next_note = next_note.enharmonic() if not flats and not sharps: sharps = True if "b" in next_note.name: if sharps: next_note = next_note.enharmonic() if not flats and not sharps: flats = True spelling.append(next_note) index += 1 n += 1 else: flats = False if "b" not in root.name else True sharps = False if "#" not in root.name else True for step in parent: if index == len(parent): index -= len(parent) if n == len(parent): break next_pitch += parent[index] next_letter += 1 if next_pitch < 0: next_pitch += 12 elif next_pitch > 11: next_pitch -= 12 if next_letter < 0: next_letter += 7 elif next_letter > 6: next_letter -= 7 next_note = Note.from_values(next_letter, next_pitch) if len(next_note.name) > 2: next_note = next_note.enharmonic() if next_note.name in ("B#", "Cb", "E#", "Fb"): next_note = next_note.enharmonic() if "#" in next_note.name: if flats: next_note = next_note.enharmonic() if not flats and not sharps: sharps = True if "b" in next_note.name: if sharps: next_note = next_note.enharmonic() if not flats and not sharps: flats = True index += 1 n += 1 spelling.append(next_note) return tuple(spelling)
def produce_notes(chord, prev_note, harm_rhythm, key_mode, pattern=None): note_groups = [] harmony_notes = create_harmony(chord, harm_rhythm) rhythmic_divisions = RHYTHMIC_DIVISIONS rhythm_remainder = harm_rhythm chord_note_names = [note.name for note in chord] key_note_names = [ note.enharmonic().enharmonic(prefer="b").name for note in key_mode ] arp_patt = None if not prev_note: arp_patt = ARPEGGIATION_PATTERNS_TRIAD if len( chord.spelling) == 3 else ARPEGGIATION_PATTERNS_SEVENTH arp_patt = arp_patt[randint(0, len(arp_patt) - 1)] rhythm = rhythmic_divisions[randint(0, len(rhythmic_divisions) - 1)] dotted = randint( 0, 1 ) and rhythm == "3" and "4t" not in RHYTHMIC_DIVISIONS and harm_rhythm == 256 xi = 0 while round(rhythm_remainder) > 0: if arp_patt: if xi >= len(arp_patt): xi -= len(arp_patt) * (xi // len(arp_patt)) if not prev_note: mel_note = chord.spelling[arp_patt[xi]] mel_note.octave = 4 else: #!!PLEASE REFACTOR THIS, ME prev_hard_pitch = prev_note.hard_pitch for cnote in chord: cnote.octave = prev_note.octave up_or_down_range = (range( prev_hard_pitch - (2, 4)[randint(0, 1)], prev_hard_pitch), range( prev_hard_pitch + 1, prev_hard_pitch + (3, 5)[randint(0, 1)]))[randint(0, 1)] if cnote.hard_pitch in up_or_down_range: mel_note = cnote break else: for cnote in chord: cnote.octave = prev_note.octave + 1 up_or_down_range = (range( prev_hard_pitch - (2, 4)[randint(0, 1)], prev_hard_pitch), range( prev_hard_pitch + 1, prev_hard_pitch + (3, 5)[randint(0, 1)]))[randint( 0, 1)] if cnote.hard_pitch in up_or_down_range: mel_note = cnote break else: for cnote in chord: cnote.octave = prev_note.octave - 1 up_or_down_range = ( range(prev_hard_pitch - (2, 4)[randint(0, 1)], prev_hard_pitch), range(prev_hard_pitch + 1, prev_hard_pitch + (3, 5)[randint(0, 1)]))[randint(0, 1)] if cnote.hard_pitch in up_or_down_range: mel_note = cnote break else: mel_note = chord.spelling[randint( 0, len(chord.spelling) - 1)] mel_note.octave = prev_note.octave if dotted: if xi % 2 == 0: mel_note.rhythm = "3." else: mel_note.rhythm = "4" else: mel_note.rhythm = rhythm rhythm_remainder -= mel_note.rhythm.value if ARPEGGIATE_HARMONY: note_group = [(harmony_notes[randint(0, len(harmony_notes) - 1)]) for x in range(2)] else: note_group = list(harmony_notes) if mel_note.octave < 4: mel_note.octave = 4 elif mel_note.octave > 5: mel_note.octave = 5 if rhythm in RHYTHMIC_DOUBLERS: neighbored = True if not randint(0, NEIGHBORLY_RANDOMNESS) else False mel_hard_pitch = mel_note.hard_pitch mel_note.rhythm = RHYTHMIC_DOUBLERS[rhythm] direction = (-1, 1)[randint(0, 1)] attempt_note = Note.from_hard_pitch(mel_hard_pitch + direction).enharmonic( prefer="b") if 'dom' in chord.symbol: if attempt_note.pitch == chord.spelling[1].pitch - 1: neighbor = chord.spelling[1] neighbor.octave = attempt_note.octave if attempt_note.name in key_note_names: neighbor = attempt_note else: neighbor = Note.from_hard_pitch(mel_hard_pitch + direction * 2) neighbor.rhythm = RHYTHMIC_DOUBLERS[rhythm] multi_group = [mel_note, neighbor] for i in range(2): note_group_copy = list(note_group) note_group_copy.append(multi_group[i]) multi_group[i] = note_group_copy note_groups.extend(multi_group) else: note_group.append(mel_note) note_groups.append(note_group) prev_note = mel_note xi += 1 return note_groups