def voice(old_voiced, nxt_chord): if old_voiced is None: return chords.from_shorthand(nxt_chord) old = [notes.note_to_int(n) for n in old_voiced] new = {notes.note_to_int(n) for n in chords.from_shorthand(nxt_chord)} res = [] for note in old: if new: closest = min(new, key=lambda n: abs(note - n)) res.append(closest) new.remove(closest) else: if len(old) == 4: res.append(res[0]) for n in new: best_index = 0 min_dist = 12 for i in range(0, len(old)): dist = abs(old[i] - n) if dist < min_dist: min_dist = dist best_index = i res.insert(i, n) return [notes.int_to_note(n) for n in res]
def test_determine(self): map(lambda x: self.assertEqual(True, chords.determine(chords.from_shorthand('C' + x)) != [], "'C%s' should return a value" % x), chords.chord_shorthand.keys()) map(lambda x: self.assertEqual('C' + chords.chord_shorthand_meaning[x], chords.determine(chords.from_shorthand('C' + x))[0], "The proper naming of '%s' is not '%s',expecting '%s'" % ('C' + x, chords.determine(chords.from_shorthand('C' + x)), 'C' + chords.chord_shorthand_meaning[x])), [x for x in chords.chord_shorthand.keys() if x != '5']) self.chordsTest([[['A13'], [ 'A', 'C#', 'E', 'G', 'B', 'D', 'F#', ]], [['Am13'], [ 'A', 'C', 'E', 'G', 'B', 'D', 'F#', ]], [['AM13'], [ 'A', 'C#', 'E', 'G#', 'B', 'D', 'F#', ]]], lambda x: chords.determine(x, True), 'chord name')
def test_determine(self): for x in chords.chord_shorthand: self.assertEqual( True, chords.determine(chords.from_shorthand("C" + x)) != [], "'C%s' should return a value" % x, ) for x in (x for x in chords.chord_shorthand if x != "5"): self.assertEqual( "C" + chords.chord_shorthand_meaning[x], chords.determine(chords.from_shorthand("C" + x))[0], "The proper naming of '%s' is not '%s',expecting '%s'" % ( "C" + x, chords.determine(chords.from_shorthand("C" + x)), "C" + chords.chord_shorthand_meaning[x], ), ) self.chordsTest( [ [["A13"], ["A", "C#", "E", "G", "B", "D", "F#",]], [["Am13"], ["A", "C", "E", "G", "B", "D", "F#",]], [["AM13"], ["A", "C#", "E", "G#", "B", "D", "F#",]], ], lambda x: chords.determine(x, True), "chord name", )
def sheets(): if request.method == 'GET': sheets = Sheet.query.all() return jsonify({'sheets': [s.to_dict() for s in sheets]}) elif request.method == 'POST': data = request.json sheet = Sheet(name=data['name']) chords = [] for c in data['chords']: shorthand_notation = c['name'] chord = Chord(name=shorthand_notation) chord.notes = ' '.join(ch.from_shorthand(shorthand_notation)) print(chord.notes) inversions = [ ' '.join(ch.first_inversion(chord.notes.split(' '))), ' '.join(ch.second_inversion(chord.notes.split(' '))), ' '.join(ch.third_inversion(chord.notes.split(' '))) ] chord.inversions = [ Inversion(name=str(i), notes=notes) for i, notes in enumerate(inversions) ] chords.append(chord) sheet.chords = chords db.session.add(sheet) db.session.commit() return jsonify(sheet.to_dict()), 201
def root_only_voice(chord:str): ''' Expects a shorthand string like 'CM7' and will return with the root only (as semitone integer) ''' note_names = chords.from_shorthand(chord) # shorthand -> unpitched note strings ['C', 'E', 'G', 'B'] voiced_semitones = rebuild_chord_upwards([int(Note(note_names[0], octave=3))]) return voiced_semitones # ensure we voice from root upwards (in case e.g. everything defaulted to same octave)
def addquickchordinselection(self, text, midi): if text: colonindex = text.find(";") if colonindex < 0: chordtext = text arptext = "" else: chordtext = text[0:colonindex] arptext = text[colonindex + 1:] try: chordlist = CHORDS.from_shorthand(chordtext) except: self.setalert("onbekende chord.") chordlist = [] if chordlist: for i in range(len(chordlist)): chordlist[i] = NOTES.note_to_int(chordlist[i]) chordlist = list(set(chordlist)) chordlist.sort() tickmin, tickmax, midimin, midimax = self.getselectionregion() self.addchordinregion(chordlist, [tickmin, tickmax], [midimin, midimax], arptext) self.setcurrentticksandload(self.currentabsoluteticks) #self.anchor = 0 self.setstate(state=self.NAVIGATIONstate) return {}
def analyze_7th_chord(chord): """ :param chord: :return: chord_notes, chord_type_full, chord_modes Example: >>> chord_notes, chord_type_full, results = analyze_chord("G7") >>> for chord_degree, key, harmonic_func_full in results: ... print("{} (comprising {}) is a {} chord ({}) of the key of {}".format(chord_type_full,', '.join(chord_notes), ... chord_degree, harmonic_func_full, ... key)) G dominant seventh (comprising G, B, D, F) is a V chord (dominant seventh) of the key of C """ chord_notes = chords.from_shorthand(chord) chord_type_full = chords.determine_seventh(chord_notes)[0] chord_type_short = chords.determine_seventh(chord_notes, shorthand=True)[0] type_key = 'M7' if chord_type_short[-2:] == 'M7' else ( 'm7' if chord_type_short[-2:] == 'm7' else ('m7b5' if chord_type_short[-2:] == 'm7b5' else '7')) chord_modes = [] for key in CIRCLE_OF_5THS: harmonic_func = determine(chord_notes, key, shorthand=True)[0] harmonic_func_full = determine(chord_notes, key, shorthand=False)[0] chord_degree = harmonic_func[:-1] if chord_degree in MODE_CHORD_TYPE: func_chord_type = MODE_CHORD_TYPE[chord_degree] if func_chord_type == type_key: chord_modes.append((chord_degree, key, harmonic_func_full)) return chord_notes, chord_type_full, chord_modes
def analyze_7th_chord(chord): """ :param chord: :return: chord_notes, chord_type_full, chord_modes Example: >>> chord_notes, chord_type_full, results = analyze_chord("G7") >>> for chord_degree, key, harmonic_func_full in results: ... print("{} (comprising {}) is a {} chord ({}) of the key of {}".format(chord_type_full,', '.join(chord_notes), ... chord_degree, harmonic_func_full, ... key)) G dominant seventh (comprising G, B, D, F) is a V chord (dominant seventh) of the key of C """ chord_notes = chords.from_shorthand(chord) chord_type_full = chords.determine_seventh(chord_notes)[0] chord_type_short = chords.determine_seventh(chord_notes, shorthand=True)[0] type_key = ( "M7" if chord_type_short[-2:] == "M7" else ("m7" if chord_type_short[-2:] == "m7" else ("m7b5" if chord_type_short[-2:] == "m7b5" else "7")) ) chord_modes = [] for key in CIRCLE_OF_5THS: harmonic_func = determine(chord_notes, key, shorthand=True)[0] harmonic_func_full = determine(chord_notes, key, shorthand=False)[0] chord_degree = harmonic_func[:-1] if chord_degree in MODE_CHORD_TYPE: func_chord_type = MODE_CHORD_TYPE[chord_degree] if func_chord_type == type_key: chord_modes.append((chord_degree, key, harmonic_func_full)) return chord_notes, chord_type_full, chord_modes
def normalizeChords(chordBlocks): allChords = [] allChordNotes = [] allStream = music21.stream.Stream() for chordBlock in chordBlocks: blockChords = [] blockChordNotes = [] blockStream = music21.stream.Stream() for line in chordBlock.lines: if line: for index, chord in line: chords.append(chord) try: if chord in ['A', 'B', 'C', 'D', 'E', 'F', 'G']: notes = [chord] else: notes = [note.replace('b', '-') for note in mingus_chords.from_shorthand(chord)] allChordNotes.append(notes) blockChordNotes.append(notes) except Exception as e: _chordErrors.add(str(e)) if len(blockChords) > 0: [blockStream.insert(music21.chord.Chord([note.replace('b', '-') for note in notes])) for notes in blockChordNotes] keys = [blockStream.analyze(type).tonicPitchNameWithCase for type in ['AardenEssen', 'Simple', 'BellmanBudge', 'KrumhanslSchmuckler', 'KrumhanslKessler', 'TemperleyKostkaPayne']] key = max(set(keys), key=keys.count) consensus = keys.count(key) / float(len(keys)) chordBlock['metaData']['key'] = key chordBlock['metaData']['keyConsensus'] = consensus
def chord(sheetId, chordId): if request.method == 'GET': chord = db.session.query(Chord).join(Sheet).filter( Sheet.id == sheetId).filter(Chord.id == chordId).first() return jsonify(chord.to_dict()) elif request.method == 'PUT': data = request.json chord = db.session.query(Chord).join(Sheet).filter( Sheet.id == sheetId).filter(Chord.id == chordId).first() shorthand_notation = data['name'] chord.name = shorthand_notation chord.notes = ' '.join(ch.from_shorthand(shorthand_notation)) inversions = [ ' '.join(ch.first_inversion(chord.notes.split(' '))), ' '.join(ch.second_inversion(chord.notes.split(' '))), ' '.join(ch.third_inversion(chord.notes.split(' '))) ] chord.inversions = [ Inversion(name=str(i), notes=notes) for i, notes in enumerate(inversions) ] chord.updated_at = dt.utcnow() db.session.commit() return jsonify(chord.to_dict()), 201 elif request.method == 'DELETE': db.session.query(Chord).filter(Chord.sheet_id == sheetId).filter( Chord.id == chordId).delete() db.session.query(Inversion).filter( Inversion.chord_id == chordId).delete() db.session.commit() return jsonify( {"msg": f"Chord {chordId} has been deleted from Sheet {sheetId}."}), 201
def default_voice(chord:str): ''' Expects a shorthand string like 'CM7' and will return with the natural voicing of ascending extensions as semitones (integers) ''' note_names = chords.from_shorthand(chord) # shorthand -> unpitched note strings ['C', 'E', 'G', 'B'] voiced_semitones = rebuild_chord_upwards([int(Note(note)) for note in note_names]) return voiced_semitones # ensure we voice from root upwards (in case e.g. everything defaulted to same octave)
def longhand_trans(soup): # iterate over line in section in dup_free_c_list, convert to longhand & append to longhand_chords list longhand_chords = [] for section in clean_duplicates(soup): for line in section: for chord in line: longhand_chords.append(chords.from_shorthand(chord)) return longhand_chords
def test_determine(self): map(lambda x: self.assertEqual(True, \ chords.determine(chords.from_shorthand("C" + x)) != [],\ "'C%s' should return a value" % x), \ chords.chord_shorthand.keys()) map(lambda x: self.assertEqual("C" + \ chords.chord_shorthand_meaning[x],\ chords.determine(chords.from_shorthand("C" + x))[0], \ "The proper naming of '%s' is not '%s',"\ "expecting '%s'" % ("C" + x, \ chords.determine(chords.from_shorthand("C" + x)), \ "C" + chords.chord_shorthand_meaning[x])),\ [x for x in chords.chord_shorthand.keys() if \ x != '5']) self.chordsTest([ [['A13'], ['A', 'C#', 'E', 'G', 'B', 'D', 'F#']],\ [['Am13'], ['A', 'C', 'E', 'G', 'B', 'D', 'F#']],\ [['AM13'], ['A', 'C#', 'E', 'G#', 'B', 'D', 'F#']]],\ lambda x: chords.determine(x, True), "chord name")
def test_determine(self): list( map( lambda x: self.assertEqual( True, chords.determine(chords.from_shorthand('C' + x)) != [], "'C%s' should return a value" % x), list(chords.chord_shorthand.keys()))) list( map( lambda x: self.assertEqual( 'C' + chords.chord_shorthand_meaning[x], chords.determine(chords.from_shorthand('C' + x))[0], "The proper naming of '%s' is not '%s',expecting '%s'" % ('C' + x, chords.determine(chords.from_shorthand('C' + x)), 'C' + chords.chord_shorthand_meaning[x])), [x for x in list(chords.chord_shorthand.keys()) if x != '5'])) self.chordsTest([[['A13'], [ 'A', 'C#', 'E', 'G', 'B', 'D', 'F#', ]], [['Am13'], [ 'A', 'C', 'E', 'G', 'B', 'D', 'F#', ]], [['AM13'], [ 'A', 'C#', 'E', 'G#', 'B', 'D', 'F#', ]]], lambda x: chords.determine(x, True), 'chord name')
def _naive(self): naivebassline= [] for chord in self.bassline: chord, _ , time = chord.split(' ') if chord in ['R','r']: naivebassline.append(['R']*int(time)); continue notes = chords.from_shorthand(chord) accessory_notes = notes[1:] shuffle(accessory_notes) naivebassline.append([notes[0]]+accessory_notes[:(int(time)-1)]) self.bassline = flatten(naivebassline) self.bassline = map(lambda x:_note_sub[x],self.bassline)
def from_chord_shorthand(self, shorthand): """Empties the container and adds the notes in the shorthand. \ See mingus.core.chords.from_shorthand for an up to date list of recognized format. {{{ >>> nc = NoteContainer() >>> nc.from_chord_shorthand("Am") ['A-4', 'C-5', 'E-5'] }}}""" self.empty() self.add_notes(chords.from_shorthand(shorthand)) return self
def from_chord_shorthand(self, shorthand): """Empty the container and add the notes in the shorthand. See mingus.core.chords.from_shorthand for an up to date list of recognized format. Example: >>> NoteContainer().from_chord_shorthand('Am') ['A-4', 'C-5', 'E-5'] """ self.empty() self.add_notes(chords.from_shorthand(shorthand)) return self
def __dump_chord(self, chord): if self.__notes_depot: logging.info("Notes in melody are: %s" % (", ".join(self.__notes_depot))) self.__notes_depot = [] if chord: try: chord_tones = chords.from_shorthand(chord) logging.info("\nChord is %s" % chord) logging.info("Chord tones are: %s" % (", ".join(chord_tones))) except mt_exceptions.FormatError: logging.error("Error parsing chord symbol %s" % chord)
def from_chord_shorthand(self, shorthand): """Empties the container and adds the notes in the shorthand. See \ mingus.core.chords.from_shorthand for an up to date list of recognized \ format. {{{ >>> nc = NoteContainer() >>> nc.from_chord_shorthand(\"Am\") ['A-4', 'C-5', 'E-5'] }}}""" self.empty() self.add_notes(chords.from_shorthand(shorthand)) return self
def get_notes_from_chord(self, chord = 'Cmaj7', octaves_above = 0, octaves_below = 0): notes = [] for n in chords.from_shorthand(chord): note = Note(n) notes.append(note) for i in xrange(octaves_above): note = Note(n) note.octave += i + 1 notes.append(note) for i in xrange(octaves_below): note = Note(n) note.octave -= i + 1 notes.append(note) return sorted(notes)
def progression_to_chords(progression, prog_type='shorthand'): ''' progression is list of symbols -> chords_ is a list of unvoiced str e.g. as numerals ['I7', 'V7', 'II'] and output is unvoiced chord strings -> [['C', 'E', 'G', 'Bb'], ...] NOTE: for numerals input, lower-case should not be used to imply minor (specify using '-', 'm', 'min') ''' progression = parse_progression( progression ) # to prevent mingus' diatonic parsing doing something like I7->Cmaj7 if prog_type == 'shorthand': # e.g. Am7 chords_ = [chords.from_shorthand(chord) for chord in progression] elif prog_type == 'numerals': # e.g. IIm7 chords_ = [progressions.to_chords(chord)[0] for chord in progression] return chords_ #a list of lists [['C', 'E', 'G', 'B'],...]
def get_notes_from_chord(self, chord='Cmaj7', octaves_above=0, octaves_below=0): notes = [] for n in chords.from_shorthand(chord): note = Note(n) notes.append(note) for i in xrange(octaves_above): note = Note(n) note.octave += i + 1 notes.append(note) for i in xrange(octaves_below): note = Note(n) note.octave -= i + 1 notes.append(note) return sorted(notes)
def play_smart_solo_over_chords(chord_list): fluidsynth.set_instrument(13, 45) fluidsynth.set_instrument(10, 108) fluidsynth.main_volume(13, 75) fluidsynth.main_volume(10, 100) solo = Track() bars = generate_solo(chord_list) for i in range(len(bars)): chord = NoteContainer(chords.from_shorthand(chord_list[i])) bar = bars[i] fluidsynth.play_NoteContainer(chord, 13) fluidsynth.play_Bar(bar, 10) fluidsynth.stop_NoteContainer(chord, 13) solo.add_bar(bar) return solo
def bassline(chord, beat_probas): chord_tones = chords.from_shorthand(chord) octave = 2 b = Bar() for (bass, els, octa) in beat_probas: p = random.random() if p < bass: b.place_notes(Note(chord_tones[0], octave), 8) elif p < bass + els: b.place_notes(Note(random.choice(chord_tones[1:]), octave), 8) elif p < bass + els + octa: b.place_notes(Note(chord_tones[0], octave + 1), 8) else: b.place_rest(8) return b
def get_notes_from_chord(response, fb_id): """Determine notes in a chord given the chord's name.""" # ? AND/OR: Extract the notes user sent. Input to library function and return identified chord as response back to user # ? When user requests 7th chord, check if trait "7th" is present # ? When user requests inversions, check if trait "inversion" and get it's value, then use inversion function on chord try: # Extract Key-Quality (e.g. F major) kq_entity = response['entities']["Key_Quality:Key_Quality"][0] except KeyError as e: text = "Sorry! I couldn't identify the chord name :/" return text # Exit early # Handle the various valid forms of key quality (e.g. f maj) key_quality = kq_entity['value'] key_quality = key_quality.lower() key_quality = key_quality.capitalize() try: # Extract the key of the chord note = kq_entity['entities'][0]['value'] except (KeyError, IndexError) as e: # Could arise when user joins key with quality (e.g. Fmajor) text = "Sorry! I'm not sure what the key is :/" return text # Exit early # Format user input to requirement of from_shorthand() method if 'maj' in key_quality or 'major' in key_quality: key_quality = note + 'maj' elif 'min' in key_quality or 'minor' in key_quality: key_quality = note + 'min' else: key_quality = note try: # Determine the notes in requested chord notes_list = chords.from_shorthand(key_quality) notes_str = ', '.join(notes_list) text = f"The notes in a {key_quality} chord are {notes_str}." except Exception as e: print("EXCEPTION:", e) text = f"Sorry! I can't identify a {kq_entity['body']} chord :/" return text
def sheet(sheetId): if request.method == 'GET': sheet = Sheet.query.get(sheetId) return jsonify({'sheet': sheet.to_dict()}) elif request.method == 'PUT': data = request.json shorthand_notation = data['name'] chord = Chord(name=shorthand_notation, sheet_id=sheetId) chord.name = shorthand_notation chord.notes = ' '.join(ch.from_shorthand(shorthand_notation)) inversions = [ ' '.join(ch.first_inversion(chord.notes.split(' '))), ' '.join(ch.second_inversion(chord.notes.split(' '))), ' '.join(ch.third_inversion(chord.notes.split(' '))) ] chord.inversions = [ Inversion(name=str(i), notes=notes) for i, notes in enumerate(inversions) ] chord.updated_at = dt.utcnow() db.session.add(chord) db.session.commit() return jsonify(chord.to_dict()), 201 elif request.method == 'DELETE': chordIds = [ chord.id for chord in db.session.query(Chord).join(Sheet).filter( Sheet.id == sheetId).all() ] db.session.query(Sheet).filter(Sheet.id == sheetId).delete() for id in chordIds: db.session.query(Chord).filter(Chord.sheet_id == sheetId).filter( Chord.id == id).delete() db.session.query(Inversion).filter( Inversion.chord_id == id).delete() db.session.commit() return jsonify({"msg": f"Sheet {sheetId} has been deleted."}), 201
def test_from_shorthand(self): answers = { # Triads Augmented Sevenths Sixths 6/9 Slash chords # Suspended chords 9 11 13 Altered chords Special Poly # chords 'Amin': ['A', 'C', 'E'], 'Am': ['A', 'C', 'E'], 'A-': ['A', 'C', 'E'], 'Amaj': ['A', 'C#', 'E'], 'AM': ['A', 'C#', 'E'], 'A': ['A', 'C#', 'E'], 'Adim': ['A', 'C', 'Eb'], 'Aaug': ['A', 'C#', 'E#'], 'A+': ['A', 'C#', 'E#'], 'A7#5': ['A', 'C#', 'E#', 'G'], 'Amaj7+5': ['A', 'C#', 'E#', 'G'], 'Amaj7+': ['A', 'C#', 'E#', 'G#'], 'Amin7+': ['A', 'C#', 'E#', 'G'], 'Amin7': ['A', 'C', 'E', 'G'], 'Am7': ['A', 'C', 'E', 'G'], 'Ami7': ['A', 'C', 'E', 'G'], 'A-7': ['A', 'C', 'E', 'G'], 'Amaj7': ['A', 'C#', 'E', 'G#'], 'AM7': ['A', 'C#', 'E', 'G#'], 'Ama7': ['A', 'C#', 'E', 'G#'], 'A7': ['A', 'C#', 'E', 'G'], 'Amin7b5': ['A', 'C', 'Eb', 'G'], 'Am7b5': ['A', 'C', 'Eb', 'G'], 'Adim7': ['A', 'C', 'Eb', 'Gb'], 'Am/M7': ['A', 'C', 'E', 'G#'], 'Am/ma7': ['A', 'C', 'E', 'G#'], 'AmM7': ['A', 'C', 'E', 'G#'], 'Am/maj7': ['A', 'C', 'E', 'G#'], 'Amin6': ['A', 'C', 'E', 'F#'], 'Am6': ['A', 'C', 'E', 'F#'], 'Amaj6': ['A', 'C#', 'E', 'F#'], 'A6': ['A', 'C#', 'E', 'F#'], 'A6/9': ['A', 'C#', 'E', 'F#', 'B'], 'A69': ['A', 'C#', 'E', 'F#', 'B'], 'A/G': ['G', 'A', 'C#', 'E'], 'Amin/G': ['G', 'A', 'C', 'E'], 'Am/M7/G': ['G', 'A', 'C', 'E', 'G#'], 'Asus2': ['A', 'B', 'E'], 'Asus4': ['A', 'D', 'E'], 'Asus47': ['A', 'D', 'E', 'G'], 'A11': ['A', 'E', 'G', 'D'], 'Asus': ['A', 'D', 'E'], 'Asus4b9': ['A', 'D', 'E', 'Bb'], 'Asusb9': ['A', 'D', 'E', 'Bb'], 'Amaj9': ['A', 'C#', 'E', 'G#', 'B'], 'A9': ['A', 'C#', 'E', 'G', 'B'], 'Amin9': ['A', 'C', 'E', 'G', 'B'], 'Am9': ['A', 'C', 'E', 'G', 'B'], 'A7#11': ['A', 'C#', 'E', 'G', 'D#'], 'Am11': ['A', 'C', 'E', 'G', 'D'], 'Amin11': ['A', 'C', 'E', 'G', 'D'], 'Amaj13': [ 'A', 'C#', 'E', 'G#', 'B', 'F#', ], 'A13': [ 'A', 'C#', 'E', 'G', 'B', 'F#', ], 'Am13': [ 'A', 'C', 'E', 'G', 'B', 'F#', ], 'A7b9': ['A', 'C#', 'E', 'G', 'Bb'], 'A7#9': ['A', 'C#', 'E', 'G', 'B#'], 'A7b5': ['A', 'C#', 'Eb', 'G'], 'A6/7': ['A', 'C#', 'E', 'F#', 'G'], 'A67': ['A', 'C#', 'E', 'F#', 'G'], 'A5': ['A', 'E'], 'Ahendrix': ['A', 'C#', 'E', 'G', 'C'], 'N.C.': [], 'NC': [], 'Dm|G': ['G', 'B', 'D', 'F', 'A'], 'Dm7|G': [ 'G', 'B', 'D', 'F', 'A', 'C', ], 'Am7|G7': [ 'G', 'B', 'D', 'F', 'A', 'C', 'E', 'G', ], } map(lambda x: self.assertEqual(answers[x], chords.from_shorthand(x), 'The shorthand of %s is not %s, expecting %s' % (x, chords.from_shorthand(x), answers[x])), answers.keys())
def test_from_shorthand(self): answers = { # Triads Augmented Sevenths Sixths 6/9 Slash chords # Suspended chords 9 11 13 Altered chords Special Poly # chords 'Amin': ['A', 'C', 'E'], 'Am': ['A', 'C', 'E'], 'A-': ['A', 'C', 'E'], 'Amaj': ['A', 'C#', 'E'], 'AM': ['A', 'C#', 'E'], 'A': ['A', 'C#', 'E'], 'Adim': ['A', 'C', 'Eb'], 'Aaug': ['A', 'C#', 'E#'], 'A+': ['A', 'C#', 'E#'], 'A7#5': ['A', 'C#', 'E#', 'G'], 'Amaj7+5': ['A', 'C#', 'E#', 'G'], 'Amaj7+': ['A', 'C#', 'E#', 'G#'], 'Amin7+': ['A', 'C#', 'E#', 'G'], 'Amin7': ['A', 'C', 'E', 'G'], 'Am7': ['A', 'C', 'E', 'G'], 'Ami7': ['A', 'C', 'E', 'G'], 'A-7': ['A', 'C', 'E', 'G'], 'Amaj7': ['A', 'C#', 'E', 'G#'], 'AM7': ['A', 'C#', 'E', 'G#'], 'Ama7': ['A', 'C#', 'E', 'G#'], 'A7': ['A', 'C#', 'E', 'G'], 'Amin7b5': ['A', 'C', 'Eb', 'G'], 'Am7b5': ['A', 'C', 'Eb', 'G'], 'Adim7': ['A', 'C', 'Eb', 'Gb'], 'Am/M7': ['A', 'C', 'E', 'G#'], 'Am/ma7': ['A', 'C', 'E', 'G#'], 'AmM7': ['A', 'C', 'E', 'G#'], 'Am/maj7': ['A', 'C', 'E', 'G#'], 'Amin6': ['A', 'C', 'E', 'F#'], 'Am6': ['A', 'C', 'E', 'F#'], 'Amaj6': ['A', 'C#', 'E', 'F#'], 'A6': ['A', 'C#', 'E', 'F#'], 'A6/9': ['A', 'C#', 'E', 'F#', 'B'], 'A69': ['A', 'C#', 'E', 'F#', 'B'], 'A/G': ['G', 'A', 'C#', 'E'], 'Amin/G': ['G', 'A', 'C', 'E'], 'Am/M7/G': ['G', 'A', 'C', 'E', 'G#'], 'Asus2': ['A', 'B', 'E'], 'Asus4': ['A', 'D', 'E'], 'Asus47': ['A', 'D', 'E', 'G'], 'A11': ['A', 'E', 'G', 'D'], 'Asus': ['A', 'D', 'E'], 'Asus4b9': ['A', 'D', 'E', 'Bb'], 'Asusb9': ['A', 'D', 'E', 'Bb'], 'Amaj9': ['A', 'C#', 'E', 'G#', 'B'], 'A9': ['A', 'C#', 'E', 'G', 'B'], 'Amin9': ['A', 'C', 'E', 'G', 'B'], 'Am9': ['A', 'C', 'E', 'G', 'B'], 'A7#11': ['A', 'C#', 'E', 'G', 'D#'], 'Am11': ['A', 'C', 'E', 'G', 'D'], 'Amin11': ['A', 'C', 'E', 'G', 'D'], 'Amaj13': [ 'A', 'C#', 'E', 'G#', 'B', 'F#', ], 'A13': [ 'A', 'C#', 'E', 'G', 'B', 'F#', ], 'Am13': [ 'A', 'C', 'E', 'G', 'B', 'F#', ], 'A7b9': ['A', 'C#', 'E', 'G', 'Bb'], 'A7#9': ['A', 'C#', 'E', 'G', 'B#'], 'A7b5': ['A', 'C#', 'Eb', 'G'], 'A6/7': ['A', 'C#', 'E', 'F#', 'G'], 'A67': ['A', 'C#', 'E', 'F#', 'G'], 'A5': ['A', 'E'], 'Ahendrix': ['A', 'C#', 'E', 'G', 'C'], 'N.C.': [], 'NC': [], 'Dm|G': ['G', 'B', 'D', 'F', 'A'], 'Dm7|G': [ 'G', 'B', 'D', 'F', 'A', 'C', ], 'Am7|G7': [ 'G', 'B', 'D', 'F', 'A', 'C', 'E', 'G', ], } list( map( lambda x: self.assertEqual( answers[x], chords.from_shorthand( x), 'The shorthand of %s is not %s, expecting %s' % (x, chords.from_shorthand(x), answers[x])), list(answers.keys())))
def main(): misty_numerals = 'IM7, v-7, I7, IVM7, iv-9, bVII7, IM7, vi-7, ii-7, V7, iii-7, VI7, ii-7, V7, \ IM7, v-7, I7, IVM7, iv-9, bVII7, IM7, vi-7, ii-7, V7, I6, bVII9, IM7, \ v-7, I7b9, IVM7, IVM7,\ bv-7, VII7, II7, iii-7, VI7b9, ii-7, V7, \ IM7, v-7, I7, IVM7, iv-9, bVII7, IM7, vi-7, ii-7, V7, I6, I6' misty_durs = [ 1, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 1, 2, 2, 2, 2, 1, 1, 1, 1 ] mistyChart = sidewinder.Chart(progression=misty_numerals, key='F') mistyChart.set_durations(durations=misty_durs) twofiveone = ['IIm7', 'V7', 'IM7'] two_five_ones = detect_numeral_pattern( mistyChart.get_numeral_representation(), pattern=twofiveone, transposing='True', original_key=mistyChart.key) print(two_five_ones) tfo_durs = [[ mistyChart.durations[tf['start_index']], mistyChart.durations[tf['start_index'] + 1], mistyChart.durations[tf['start_index'] + 2] ] for tf in two_five_ones['hits']] # from random import choices # # asc = [1,2,3,4,5,4,3,1] # asc = [1,2,4,'b7','b9'] # p = choices(asc, weights=[1,2,2,2,1], k=32) # print(p) # melody = get_scale_patterns('chromatic', p=p, keys=['F'], pattern_as_chromatic=True) # print(melody['F'][0]) # add a selection of melody to a selection of bars in the Composition arps = [[from_shorthand(chord)[i] for i in (0, 1, 2, 3, 2, 1, 0, 1)] for chord in mistyChart.progressionShorthandList] notes_ = [] note_durations = [] for arp, chord_dur in zip(arps, mistyChart.durations): if chord_dur == 1: note_durations += [8 for _ in range(8)] notes_ += [arp[i] for i in range(8)] elif chord_dur == 2: note_durations += [8 for _ in range(4)] notes_ += [arp[i] for i in range(4)] assert len(notes_) == len(note_durations) t = Track() for i, _ in enumerate(note_durations): t.add_notes(notes_[i], note_durations[i]) # use the db to add/overlay a 251 lick in the right place start_index = two_five_ones['hits'][0][ 'start_index'] # refers to index in chord progression (not bar) key = two_five_ones['hits'][0]['key'] durs = tfo_durs[0] # [1,1,1] # chords_ = mistyChart.progressionShorthandList[start_index:start_index+len(twofiveone)] ### now search db for a 251 in F w/ duratons 1,1,1 then place at start_index db = TinyDB( r'C:\Users\Sam\Documents\Sidewinder\local files\jazz-licks-db-260720-new.json' ) # set-up / connection # candidate_licks = find_partial_matches(db, {'tags':'251'}) # gives db id's (doc_id) # searching should be better, done on actual chord metadata candidate_licks = find_by_chords_durations(db, chords=['Gm7', 'C7', 'FM7'], durations=[1, 1, 1]) # candidate_licks = [load_entry(db, doc_id) for doc_id in candidate_licks] # instantiate from db lick251 = load_entry(db, candidate_licks[0]) # for doc_id in candidate_licks[-15:]: # print(db.get(doc_id=doc_id)) # print(candidate_licks[0].chords) # candidate_licks[0].to_midi() notes_ = [nc[2] for bar in lick251.passage for nc in bar] notes_ = [nc[0] if bool(nc) else None for nc in notes_] durations_ = [nc[1] for bar in lick251.passage for nc in bar] # [start of Misty ... 251 lick notes_,durations_ ... rest of Misty] start_bar = 8 # could compute using start_index and misty_durs t2 = Track_from_list(t[:start_bar - 1]) for n, d in zip(notes_, durations_): t2.add_notes(n, d) for bar in Track_from_list( t[start_bar - 1 + 4:] ): # known that the lick is 4 bars, could probably compute from lick251.passage t2 + bar track_to_midi(t2, name='midi_out\\test251_lick_add')
def test_from_shorthand(self): answers = { # Triads Augmented Sevenths Sixths 6/9 Slash chords # Suspended chords 9 11 13 Altered chords Special Poly # chords "Amin": ["A", "C", "E"], "Am": ["A", "C", "E"], "A-": ["A", "C", "E"], "Amaj": ["A", "C#", "E"], "AM": ["A", "C#", "E"], "A": ["A", "C#", "E"], "Adim": ["A", "C", "Eb"], "Aaug": ["A", "C#", "E#"], "A+": ["A", "C#", "E#"], "A7#5": ["A", "C#", "E#", "G"], "Amaj7+5": ["A", "C#", "E#", "G"], "Amaj7+": ["A", "C#", "E#", "G#"], "Amin7+": ["A", "C#", "E#", "G"], "Amin7": ["A", "C", "E", "G"], "Am7": ["A", "C", "E", "G"], "Ami7": ["A", "C", "E", "G"], "A-7": ["A", "C", "E", "G"], "Amaj7": ["A", "C#", "E", "G#"], "AM7": ["A", "C#", "E", "G#"], "Ama7": ["A", "C#", "E", "G#"], "A7": ["A", "C#", "E", "G"], "Amin7b5": ["A", "C", "Eb", "G"], "Am7b5": ["A", "C", "Eb", "G"], "Adim7": ["A", "C", "Eb", "Gb"], "Am/M7": ["A", "C", "E", "G#"], "Am/ma7": ["A", "C", "E", "G#"], "AmM7": ["A", "C", "E", "G#"], "Am/maj7": ["A", "C", "E", "G#"], "Amin6": ["A", "C", "E", "F#"], "Am6": ["A", "C", "E", "F#"], "Amaj6": ["A", "C#", "E", "F#"], "A6": ["A", "C#", "E", "F#"], "A6/9": ["A", "C#", "E", "F#", "B"], "A69": ["A", "C#", "E", "F#", "B"], "A/G": ["G", "A", "C#", "E"], "Amin/G": ["G", "A", "C", "E"], "Am/M7/G": ["G", "A", "C", "E", "G#"], "Asus2": ["A", "B", "E"], "Asus4": ["A", "D", "E"], "Asus47": ["A", "D", "E", "G"], "A11": ["A", "E", "G", "D"], "Asus": ["A", "D", "E"], "Asus4b9": ["A", "D", "E", "Bb"], "Asusb9": ["A", "D", "E", "Bb"], "Amaj9": ["A", "C#", "E", "G#", "B"], "A9": ["A", "C#", "E", "G", "B"], "Amin9": ["A", "C", "E", "G", "B"], "Am9": ["A", "C", "E", "G", "B"], "A7#11": ["A", "C#", "E", "G", "D#"], "Am11": ["A", "C", "E", "G", "D"], "Amin11": ["A", "C", "E", "G", "D"], "Amaj13": ["A", "C#", "E", "G#", "B", "F#",], "A13": ["A", "C#", "E", "G", "B", "F#",], "Am13": ["A", "C", "E", "G", "B", "F#",], "A7b9": ["A", "C#", "E", "G", "Bb"], "A7#9": ["A", "C#", "E", "G", "B#"], "A7b5": ["A", "C#", "Eb", "G"], "A6/7": ["A", "C#", "E", "F#", "G"], "A67": ["A", "C#", "E", "F#", "G"], "A5": ["A", "E"], "Ahendrix": ["A", "C#", "E", "G", "C"], "N.C.": [], "NC": [], "Dm|G": ["G", "B", "D", "F", "A"], "Dm7|G": ["G", "B", "D", "F", "A", "C",], "Am7|G7": ["G", "B", "D", "F", "A", "C", "E", "G",], } for x in answers: self.assertEqual( answers[x], chords.from_shorthand(x), "The shorthand of %s is not %s, expecting %s" % (x, chords.from_shorthand(x), answers[x]), )
def tritone_substitution(chord): chord_notes = chords.from_shorthand(chord) new_note = reduce_accidentals(tritone(chord_notes[0])) new_chord = new_note + '7' new_notes = chords.from_shorthand(new_chord) return new_chord, new_notes
def ending(first_track, second_track, subject, key=r""): if not bool(key): key = 'C' canon_subject = shift(subject, 2) cadence = [chord.I(key), chord.IV(key), chord.V(key), chord.I(key)] notes = [] for note in canon_subject[-1]: if note[-1][0].name not in notes: notes.append(note[-1][0].name) bar = Bar(key=key) # Hitta om det finns ett ackord med de sista noterna i subjektet i, i så fall, komplettera det ackordet if len(notes) <= 2 or len(chord.determine(notes, True)) == 0: chord_notes = [intervals.fourth(notes[0], key)] else: subject_chord = chord.determine(notes, True)[0] chord_notes = chord.from_shorthand(subject_chord) if len(chord_notes) != len(notes): for note in notes: chord_notes.remove(note) else: chord_notes = chord_notes[0] bar.place_notes(chord_notes[random.randint(0, len(chord_notes) - 1)], 2) first_track.add_bar( bar) #Sätt något som passar med andra hälften av subjektet while second_track[ -1].current_beat < 1: #Placing fitting notes in second to last bar #print('test1') duration = 2**random.randint(1, 3) pitch = cadence[0][random.randint(1, len(cadence[0]) - 1)] # If the randomized duration doesn't fit in the bar, make it fit if 1 / duration > 1 - second_track[-1].current_beat: duration = 1 / (1 - second_track[-1].current_beat) # Place the new note in the bar second_track[-1].place_notes(pitch, duration) first_track[-1].place_notes(cadence[0][0], 2) bar = Bar(key=key) bar.place_notes(cadence[1][0], 2) bar.place_notes(cadence[2][0], 2) first_track.add_bar(bar) bar = Bar(key=key) bar.place_notes(cadence[3][0], 1) first_track.add_bar(bar) bar = Bar(key=key) while bar.current_beat < 0.5: #print('test2') # Randomize pitch and duration of each note. duration = 2**random.randint(1, 3) pitch = cadence[1][random.randint(1, len(cadence[1]) - 1)] # If the randomized duration doesn't fit in the bar, make it fit if 1 / duration > 1 - bar.current_beat: duration = 1 / (1 - bar.current_beat) # Place the new note in the bar bar.place_notes(pitch, duration) while bar.current_beat < 1: #print('test3') duration = 2**random.randint(1, 3) pitch = cadence[2][random.randint(1, len(cadence[2]) - 1)] # If the randomized duration doesn't fit in the bar, make it fit if 1 / duration > 1 - bar.current_beat: duration = 1 / (1 - bar.current_beat) # Place the new note in the bar bar.place_notes(pitch, duration) second_track.add_bar(bar) bar = Bar(key=key) bar.place_notes(cadence[3][2], 1) second_track.add_bar(bar)
def test_from_shorthand(self): answers = { # Triads "Amin" : ["A", "C", "E"], "Am" : ["A", "C", "E"], "A-" : ["A", "C", "E"], "Amaj" : ["A", "C#", "E"], "AM" : ["A", "C#", "E"], "A" : ["A", "C#", "E"], "Adim" : ["A", "C", "Eb"], # Augmented "Aaug" : ["A", "C#", "E#"], "A+" : ["A", "C#", "E#"], "A7#5" : ["A", "C#", "E#", "G"], "Amaj7+5" : ["A", "C#", "E#", "G"], "Amaj7+" : ["A", "C#", "E#", "G#"], "Amin7+" : ["A", "C#", "E#", "G"], # Sevenths "Amin7" : ["A", "C", "E", "G"], "Am7" : ["A", "C", "E", "G"], "Ami7" : ["A", "C", "E", "G"], "A-7" : ["A", "C", "E", "G"], "Amaj7" : ["A", "C#", "E", "G#"], "AM7" : ["A", "C#", "E", "G#"], "Ama7" : ["A", "C#", "E", "G#"], "A7" : ["A", "C#", "E", "G"], "Amin7b5" : ["A", "C", "Eb", "G"], "Am7b5" : ["A", "C", "Eb", "G"], "Adim7" : ["A", "C", "Eb", "Gb"], "Am/M7" : ["A", "C", "E", "G#"], "Am/ma7" : ["A", "C", "E", "G#"], "AmM7" : ["A", "C", "E", "G#"], "Am/maj7" : ["A", "C", "E","G#"], # Sixths "Amin6" : ["A", "C", "E", "F#"], "Am6" : ["A", "C", "E", "F#"], "Amaj6" : ["A", "C#", "E", "F#"], "A6" : ["A", "C#", "E", "F#"], # 6/9 "A6/9" : ["A", "C#", "E", "F#", "B"], "A69" : ["A", "C#", "E", "F#", "B"], # Slash chords "A/G" : ["G", "A", "C#", "E"], "Amin/G" : ["G", "A", "C", "E"], "Am/M7/G" : ["G", "A", "C", "E", "G#"], # Suspended chords "Asus2" : ["A", "B", "E"], "Asus4" : ["A", "D", "E"], "Asus47" : ["A", "D", "E", "G"], "A11" : ["A", "E", "G", "D"], "Asus" : ["A", "D", "E"], "Asus4b9" : ["A", "D", "E", "Bb"], "Asusb9" : ["A", "D", "E", "Bb"], # 9 "Amaj9" : ["A", "C#", "E", "G#", "B"], "A9" : ["A", "C#", "E", "G", "B"], "Amin9" : ["A", "C", "E", "G", "B"], "Am9" : ["A", "C", "E", "G", "B"], # 11 "A7#11" : ["A", "C#", "E", "G", "D#"], "Am11" : ["A", "C", "E", "G", "D"], "Amin11" : ["A", "C", "E", "G", "D"], # 13 "Amaj13" : ["A", "C#", "E", "G#", "B", "F#"], "A13" : ["A", "C#", "E", "G", "B", "F#"], "Am13" : ["A", "C", "E", "G", "B", "F#"], # Altered chords "A7b9" : ["A", "C#", "E", "G", "Bb"], "A7#9" : ["A", "C#", "E", "G", "B#"], "A7b5" : ["A", "C#", "Eb", "G"], "A6/7" : ["A", "C#", "E", "F#", "G"], "A67" : ["A", "C#", "E", "F#", "G"], # Special "A5" : ["A", "E"], "Ahendrix" : ["A", "C#", "E", "G", "C"], "N.C." : [], "NC" : [], # Poly chords "Dm|G" : ["G", "B", "D", "F", "A"], "Dm7|G" : ["G", "B", "D", "F", "A", "C"], "Am7|G7" : ["G", "B", "D", "F", "A", "C", "E", "G"], } map(lambda x: self.assertEqual(answers[x], chords.from_shorthand(x),\ "The shorthand of %s is not %s, expecting %s" % (x, chords.from_shorthand(x), answers[x])),\ answers.keys())
"""Allen Forte has a theory of musical harmony based on set theory, and he says it's the key to understanding some of the weirder 20th century music. His analysis does a lot with "intervalic vectors," which are lists of each kind of interval in a chord. I'm hoping to see what I can do with Forte-style analyses of music in the form of MIDI files. """ import mingus.core.chords as chords import mingus.core.intervals as intervals augurs_of_spring_chord = chords.from_shorthand("Eb7|Fb") # Example chord w/ interesting vector interval_class_map = [0, 1, 2, 3, 4, 5, 6, 5, 4, 3, 2, 1] # Interval with i semitones is class A[i]. def interval_class(note_first, note_second): """ class 1: minor seconds/major sevenths (1 or 11) class 2: major seconds/minor sevenths (2 or 10) class 3: minor thirds /major sixths (3 or 9) class 4: major thirds /minor sixths (4 or 8) class 5: perfect fourths & fifths (5 or 7) class 6: tritones (6) """ return interval_class_map[intervals.measure(note_first, note_second)] def chord_to_vector(chord): vector = [0, 0, 0, 0, 0, 0] for i_first, note_first in enumerate(chord): # For each note, for i_second, note_second in enumerate(chord[i_first+1:]): # pair it with each subsq. note determined_class = interval_class(note_first, note_second)
determine_key_and_function(chord) elif args.action == 'tritone_substitution': for chord in args.chords: new_chord, new_notes = tritone_substitution(chord) print("The tritone substitution of {} is {} ({})".format( chord, new_chord, ', '.join(new_notes))) elif args.action == 'reharmonize_v_to_ii_v': for chord in args.chords: ii_chord_type_short, chord = reharmonize_v_to_ii_v(chord) print("II-V ({}, {})".format(ii_chord_type_short, chord)) elif args.action == 'ii_v_tritone_substitution': for chord in args.chords: chord_notes = chords.from_shorthand(chord) new_note = reduce_accidentals(tritone(chord_notes[0])) new_chord = new_note + '7' ii_chord_type_short, chord = reharmonize_v_to_ii_v(new_chord) print("{} {}".format(ii_chord_type_short, new_chord)) elif args.action == 'chord_modes': chords = [ chords.determine_seventh(mode_func(args.key), shorthand=True)[0] for mode_func in MODE_CHORD_FUNCTIONS ] print(', '.join(chords)) elif args.action == '12_bar_blues': for four_bars in twelve_bar_blues(args.key):
from mingus.core import chords, intervals, notes, scales from mingus.containers import Note, NoteContainer, Bar, Track, Composition from mingus.containers.Instrument import MidiInstrument from mingus.midi import MidiFileOut from improv import generate_solo from subprocess import call num_progressions = 4 chords_list = ['CM', 'G7', 'CM7', 'FM7', 'G7', 'Am7', 'G7', 'C#+'] chords_bars = [] for chord in chords_list: chord_nc = NoteContainer(chords.from_shorthand(chord)) bar = Bar() bar.place_notes(chord_nc, 1) chords_bars.append(bar) solo_track = Track() chords_track = Track() for _ in range(num_progressions): for bar in generate_solo(chords_list): solo_track.add_bar(bar) for bar in chords_bars: chords_track.add_bar(bar) guitar = MidiInstrument() guitar.instrument_nr = 26 solo_track.instrument = guitar piano = MidiInstrument() piano.instrument_nr = 0 chords_track.instrument = piano
def create_walking_bassline(_chords, durations=None): ''' Will assume 4/4 and create patterns like http://www.thejazzpianosite.com/jazz-piano-lessons/jazz-chord-voicings/walking-bass-lines/ params: - _chords as a list of shorthand symbols - durations as list of integers (for each chord) ''' chords_ = [chord_note_and_family(c) for c in _chords] if durations is None: durations = [1] * len(chords_) variants = ['pedal', 'arp7', 'arp', 'diat', 'chrom', 'dblchrm'] variant_weights = [.5, 5, 5, 2, .5, .3] styles = random.choices(population=variants, weights=variant_weights, k=len(chords_)) bassline = [] new_durations = [] for i, chord in enumerate(chords_): new_dur = [ 4, 4, 4, 4 ] # by default a full bar becomes 4 crotchets (TO-DO: add more variation) chord = rebuild_chord_upwards([ Note(n) for n in from_shorthand(chords_[i][0] + chords_[i][1]) ]) # ints style = styles[i] if style == 'pedal': basspattern = [chord[0]] * 4 elif style == 'arp7': basspattern = [chord[0], chord[1], chord[2], chord[-1] ] # get last in case triad (won't have a seventh) elif style == 'arp': basspattern = [chord[0], chord[1], chord[2], chord[1]] # root, 3rd, 5th, 3rd elif style == 'diat': if chords_[i][1] == 'M7' or chords_[i][1] == 'Maj7': basspattern = [chord[0], chord[1], chord[2], chord[1]] # root, 3rd, 5th, 3rd else: basspattern = [ chord[0], chord[0] + 2, chord[1], chord[2] ] # TO-DO chords from other modes will need adjustment e.g. b9 elif style == 'chrom': if 'minMaj' in chords_[i][1]: basspattern = [chord[0], chord[1], chord[2], chord[3]] # root, 3rd, 5th, 7th elif 'm' in chords_[i][1]: basspattern = [ chord[0], chord[1], chord[2] - 1, chord[1] + 1 ] # root, minor 3, flat 5, b11 (leading tone for V/II-7) elif 'M' in chords_[i][1]: basspattern = [chord[0], chord[0] + 1, chord[0] + 2, chord[2]] # root, b9, 2, 5th elif chords_[i][1] in ['7', '7b9']: basspattern = [chord[0], chord[1], chord[2], chord[0] + 1] # root, 3rd, 5th, b9 elif chords_[i][1] in ['9']: basspattern = [ chord[0], chord[1], chord[0] + 2, chord[3] - 12 ] # root, 3rd, 9th, down to b7 else: print( f'No chromatic basspattern given for chord type {chords_[i][1]}' ) elif style == 'dblchrm': if chords_[i][1] == 'M7' or chords_[i][1] == 'Maj7': basspattern = [chord[0], chord[2], chord[2] + 2, chord[0] + 1] # root, 5th, 6th, b9 else: basspattern = [chord[0], chord[0], chord[2] - 1, chord[2] - 1] # root, root, b5, b5 # TO-DO: need to drop octaves where we end up going to high... if durations[i] == 2: basspattern = [basspattern[0], basspattern[3]] new_dur = [4, 4] if durations[i] == 4: basspattern = [basspattern[0]] new_dur = [4] bassline.append( basspattern) # as list of sublists of ints (one sublist per bar) new_durations += new_dur amount_of_extra_leading_tones = 0.25 for i, chord in enumerate(chords_): roll = random.random() if roll < amount_of_extra_leading_tones and i < len(chords_) - 1: next_root = bassline[i + 1][0] bassline[i][-1] = next_root - 1 bassline = notes_durations_to_track( [Note().from_int(int(n) - 12) for b in bassline for n in b], new_durations) # - 12 to bring down to octave 3 return bassline
def generate_solo(chord_list): notes = [] bars = [] note = random.choice(chords.from_shorthand(chord_list[0])) note = Note(note) syncopate = random.randrange(1) == 0 bar = Bar() duration = random.choice([4, 8, 16]) if syncopate: bar.place_notes(None, duration) bar.place_notes(note, duration) notes.append(note) first = True for chord_name in chord_list: if first: beat = bar.current_beat first = False else: bar = Bar() beat = 0 scale = generate_scale(chord_name) while beat < 1: if beat % .25 == 0: duration = random.choice([4, 8, 16]) elif beat % .125 == 0: duration = random.choice([8, 16]) rest = random.randrange(10) == 0 # 1/10 if rest: bar.place_notes(None, duration) else: beginning = beat == 0 stepwise = random.randrange(5) != 0 # 4/5 leap = random.randrange(2) == 0 # 1/2 if len(notes) >= 2: prev_motion = measure_motion(notes[-2], notes[-1], scale) else: prev_motion = random.choice([-1, 1]) direction = int(math.copysign(1, prev_motion)) resolve = False if abs(prev_motion) == 2: if len(notes) >= 3: prev2_motion = measure_motion(notes[-3], notes[-2], scale) else: prev2_motion = 0 if prev2_motion == 2: if random.randrange(2) == 0: stepwise, leap = False, False else: stepwise, leap = False, False elif abs(prev_motion) > 2: stepwise, resolve = True, True if beginning: chord_tones = chords.from_shorthand(chord_name) note = closest_note(notes[-1], chord_tones) elif stepwise: if resolve: interval = -direction else: interval = random.choice([direction, direction, -direction]) # 2/3 probability to continue in same direction if notes[-1].octave <= 3: interval = 1 elif notes[-1].octave >= 5: interval = -1 note = note_at_interval(notes[-1], interval, scale) elif leap: # (1 - 4/5) * 1/2 = 1/10 interval = random.choice([-1, 1]) \ * random.choice(range(3, len(scale))) note = note_at_interval(notes[-1], interval, scale) else: # outlining a chord interval = 2 * direction note = note_at_interval(notes[-1], interval, scale) bar.place_notes(note, duration) notes.append(note) beat = bar.current_beat bars.append(bar) print(notes) return bars
def test(): return jsonify({"C": ch.from_shorthand("C")})
for chord in args.chords: determine_key_and_function(chord) elif args.action == 'tritone_substitution': for chord in args.chords: new_chord, new_notes = tritone_substitution(chord) print("The tritone substitution of {} is {} ({})".format(chord, new_chord, ', '.join(new_notes))) elif args.action == 'reharmonize_v_to_ii_v': for chord in args.chords: ii_chord_type_short, chord = reharmonize_v_to_ii_v(chord) print("II-V ({}, {})".format(ii_chord_type_short, chord)) elif args.action == 'ii_v_tritone_substitution': for chord in args.chords: chord_notes = chords.from_shorthand(chord) new_note = reduce_accidentals(tritone(chord_notes[0])) new_chord = new_note + '7' ii_chord_type_short, chord = reharmonize_v_to_ii_v(new_chord) print("{} {}".format(ii_chord_type_short, new_chord)) elif args.action == 'chord_modes': chords = [chords.determine_seventh(mode_func(args.key), shorthand=True)[0] for mode_func in MODE_CHORD_FUNCTIONS] print(', '.join(chords)) elif args.action == '12_bar_blues': for four_bars in twelve_bar_blues(args.key): print('\t'.join(four_bars))
def play_solo_bar_with_chord(chord_name): chord = NoteContainer(chords.from_shorthand(chord_name)) solo = solo_bar(chord_name) fluidsynth.play_NoteContainer(chord, 13) fluidsynth.play_Bar(solo, 10) fluidsynth.stop_NoteContainer(chord, 13)
"""Allen Forte has a theory of musical harmony based on set theory, and he says it's the key to understanding some of the weirder 20th century music. His analysis does a lot with "intervalic vectors," which are lists of each kind of interval in a chord. I'm hoping to see what I can do with Forte-style analyses of music in the form of MIDI files. """ import mingus.core.chords as chords import mingus.core.intervals as intervals augurs_of_spring_chord = chords.from_shorthand( "Eb7|Fb") # Example chord w/ interesting vector interval_class_map = [0, 1, 2, 3, 4, 5, 6, 5, 4, 3, 2, 1] # Interval with i semitones is class A[i]. def interval_class(note_first, note_second): """ class 1: minor seconds/major sevenths (1 or 11) class 2: major seconds/minor sevenths (2 or 10) class 3: minor thirds /major sixths (3 or 9) class 4: major thirds /minor sixths (4 or 8) class 5: perfect fourths & fifths (5 or 7) class 6: tritones (6) """ return interval_class_map[intervals.measure(note_first, note_second)] def chord_to_vector(chord): vector = [0, 0, 0, 0, 0, 0] for i_first, note_first in enumerate(chord): # For each note,
def get_chord(self, chord, scope): notes = chords.from_shorthand(chord) return self.get_notes(notes, scope)
def read_notes(fn, notes): with open(fn) as f: content_lines = f.readlines() content = [] for line in content_lines: if not (line.startswith('#')): content.extend(line.split()) elif (line.startswith('### ')): meta = line[4:] var, val = meta.split(':') print(var + '\t' + val) # # loop through content, computing start and end events # currtime = 0 tie_forward = False for line in content: tie_backward = tie_forward tie_forward = False if line[:4] in "<key:": # get key for interpreting chords # print "key:", line[5:-1], "keylet:", line[5:6] nkey = pitch_class_dict[line[5:6]] key = line[5:-1] if key[-1] == 'm': key = key.lower() # key=key[:-1].lower() # print "key:", key, "nkey:", nkey if line[0] in "<": # skip tags such as <sot>, <eot>, <time>, <bar> continue # print("line:", line) note, duration = line.split(":") if duration.endswith('t'): tie_forward = True duration = duration[:-1] try: dnum, ddenom = duration.split("/") duration_num = float(dnum) / float(ddenom) except: duration_num = int(duration) if note[0] in "ABCDEFG": n = NoteContainer(Note(note)) velocity = velocity_normal if tie_backward: velocity = velocity_slur notes.append([currtime, n, "S", velocity]) notes.append([currtime + duration_num, n, "E"]) currtime += duration_num elif note == "rest": currtime += duration_num elif note == "backup": currtime = currtime - duration_num elif note == "forward": currtime = currtime + duration_num # # roman numeral chords, e.g. rchord-viidim7:1 # elif "rchord" in note: # roman numeral chord such as I, IV x, c = note.split('-') simple_c = simplify_chord(c) log("rchord: " + c + "\tsimple: " + simple_c + "\tkey:" + key) progression = progressions.to_chords([simple_c], key) chord = NoteContainer(progression[0]) notes.append([currtime, chord, "S", velocity_chord]) notes.append([currtime + duration_num, chord, "E"]) currtime += duration_num # # numeric chord, e.g. nchord-145 = tonic (1) + third (16) + fifth (128) # elif "nchord" in note: x, c = note.split('-') # print "--chord:", c, "key:", key nc = int(c) n = 0 while nc > 0: if nc & 1: note = note_dict[(n + nkey) % 12] # print " --note", note notes.append( [currtime, [n + nkey + 48], "S", velocity_chord]) notes.append( [currtime + duration_num, [n + nkey + 48], "E"]) n += 1 nc = nc // 2 currtime += duration_num elif "chord" in note: # chord such as Am7 x, c = note.split('-') chord = NoteContainer(chords.from_shorthand(c)) notes.append([currtime, chord, "S", velocity_chord]) notes.append([currtime + duration_num, chord, "E"]) currtime += duration_num else: print "Illegal music token item:", note