def move_chord(chord: Chord, pitch: Pitch) -> Chord: while abs(chord_mean_distance(chord, pitch)) > 12.0: dist = chord_mean_distance(chord, pitch) if dist < 0: chord = chord.transpose(12) else: chord = chord.transpose(-12) return chord
class SpotifyChord(): def __init__(self, spotify_figure: str = None, figure: str = None, bass: str = None, root: str = None, kind: str = None, chord: Chord = None): if spotify_figure == 'NC': self.bass = None self.root = None self.chord = Chord() self.structure = 'NC' elif chord: assert root and figure self.bass = Pitch(bass[1:]) if bass else None self.root = Pitch(root) self.chord = chord self.structure = spotify_figure if spotify_figure else figure elif figure: assert root chord_symbol = ChordSymbol(figure=figure) self.chord = Chord(chord_symbol.pitches) self.bass = Pitch(bass[1:]) if bass else None if self.bass: self.bass.octave = None self.root = Pitch(root) self.root.octave = None self.structure = figure else: assert root and kind chord_symbol = ChordSymbol(bass=bass, root=root, kind=kind) self.chord = Chord(chord_symbol.pitches) self.bass = Pitch(bass) if bass else None if self.bass: self.bass.octave = None self.root = Pitch(root) self.root.octave = None self.structure = chord_symbol.figure def __str__(self): return self.structure def __repr__(self): return self.__str__() def __hash__(self) -> int: return self.structure.__hash__() def __eq__(self, o: object) -> bool: if type(o) is not SpotifyChord: return False return self.structure.__eq__(o.structure) def has_same_notes(self, a_chord: 'SpotifyChord') -> bool: if self.get_num_notes() != a_chord.get_num_notes(): return False for i in range(self.get_num_notes()): if self.note_at(i) != a_chord.note_at(i): return False return True def get_num_notes(self) -> int: if self.is_no_chord(): return 0 return len(self.chord.pitches) @classmethod def from_bass_root_kind(cls, bass, root, kind): return SpotifyChord(bass=bass, root=root, kind=kind) @classmethod def from_figure(cls, figure: str) -> 'SpotifyChord': # if figure of type Xkind/X- : build it from an other enharmonic as bass if len(figure.split('/')) > 1 and list(figure)[0] == list( figure.split('/')[1])[0]: return SpotifyChord.from_figure( list(figure)[0] + '/' + Note(list(figure.split( '/')[1])[0]).pitch.getAllCommonEnharmonics()[0].name) #if figure == 'Am/A-': # return SpotifyChord(bass='A-', root='A', kind='minor') #if figure == 'E7/E-': # return SpotifyChord(bass='E-', root='E', kind='dominant-seventh') if figure == 'NC': return SpotifyChord(spotify_figure='NC') root, structure, bass = split(figure) spotify_figure = None if structure in [ '', '+', '7+', '7+ add 9', 'dim', 'add 2', 'add 4', '7 add 11', 'm add 2', 'm7 add 4', 'm add 4', 'maj7', 'M7', 'M9', 'M11', 'M13', '/o7', 'o7', 'm', 'm6', 'm7', 'm9', 'm11', 'm13', '6', '7', '9', '11', '13', 'sus', 'sus2', 'sus4', 'sus add 7', 'm add 9', 'm7 add 9', 'm7 add 11', '6 add 9', 'm6 add 9', 'pedal', 'power' ]: # explicit_figure = figure explicit_figure = root + structure + bass elif structure == '9 alter b5': explicit_figure = root + bass + '9b5' elif structure == '7 alter b5': explicit_figure = root + bass + '7b5' elif structure == '7 alter #5': explicit_figure = root + bass + '7#5' elif structure == 'm7 alter b5': explicit_figure = root + bass + '/o7' elif structure == '7 add 4 subtract 3': explicit_figure = root + bass + 'sus add 7' elif structure == 'sus add 7 add 9': # TODO Check if the 7th should be diminished explicit_figure = root + bass + ',45b79' spotify_figure = root + bass + '9sus4 ' elif structure == 'sus add 7 add 13': # TODO Check if the 7th should be diminished # Pitches are not in the right order explicit_figure = root + bass + ',45b713' spotify_figure = root + bass + 'sus4 add7 add13' elif structure == 'sus add 7 add 9 add 13': # TODO Check if the 7th should be diminished # Pitches are not in the right order explicit_figure = root + bass + ',45b7913' spotify_figure = root + bass + 'sus4 add7 add9 add13' elif structure == 'sus add 7 add b9': # TODO Check if the 7th should be diminished explicit_figure = root + bass + ',45b7b9' spotify_figure = root + bass + 'b9sus4 ' elif structure == 'sus add 7 add 9 add 11 add 13': explicit_figure = root + bass + ',45791113' spotify_figure = root + bass + '13sus4 ' elif structure == 'pedal': explicit_figure = root + bass + 'pedal' elif structure == '7 add #11': explicit_figure = root + bass + '7 #11' elif structure == '7 alter #5 add #9': explicit_figure = root + bass + '+7 #9' elif structure == '9 alter #5': explicit_figure = root + bass + '9 #5' elif structure == 'm alter #5': explicit_figure = root + bass + 'm #5' elif structure == '7 alter b5 add b9': explicit_figure = root + bass + '7 b5b9' elif structure == 'm7 alter #5': explicit_figure = root + bass + 'm7 #5' elif structure == '7 alter b5 add #9': explicit_figure = root + bass + '7 b5#9' elif structure == '7 add b9': explicit_figure = root + bass + '7 b9' elif structure == '7 add #9': explicit_figure = root + bass + '7 #9' elif structure == '9 add #11': explicit_figure = root + bass + '9 #11' elif structure == '7 add b13': explicit_figure = root + bass + '7 b13' elif structure == '7 add #9 add #11': explicit_figure = root + bass + '7 #9#11' elif structure == '7 add b9 add b13': explicit_figure = root + bass + '7 b9b13' elif structure == 'add 9': explicit_figure = root + bass + 'add9' elif structure == 'maj7 add #11': explicit_figure = root + bass + 'maj7 #11' elif structure == 'sus add b9 add b9': explicit_figure = root + bass + 'sus b9' elif structure == 'm7 add b9': explicit_figure = root + bass + 'm7 b9' elif structure == 'add #11': explicit_figure = root + bass + ',#11' elif structure == '7 subtract 5 add b9 add #9 add #11 add b13': # TODO Pitches are not in the correct order explicit_figure = root + bass + ',3b7b9#9#11b13' spotify_figure = root + bass + '7 -5 b9 #9 #11 b13' elif structure == '13 alter b5': explicit_figure = root + bass + '13b5' elif structure == 'alter b5': explicit_figure = root + bass + ',b5' elif structure == 'maj7 alter #5': explicit_figure = root + bass + 'maj7 #5' elif structure == 'maj7 alter b5': explicit_figure = root + bass + 'maj7 b5' elif structure == '7 alter #5 add b9': explicit_figure = root + bass + '+7 b9' elif structure == '7 alter #5 add #9 add #11': explicit_figure = root + bass + '+7 #9#11' elif structure == '7+ add b9': explicit_figure = root + bass + '+7 b9' elif structure == '7 add #9 add b13': explicit_figure = root + bass + '7 #9b13' elif structure == 'M9 add #11': explicit_figure = root + bass + 'M9 #11' elif structure == 'M9 alter b5': explicit_figure = root + bass + 'M9 b5' elif structure == '7 add #11 add b9 add #5': explicit_figure = root + bass + '+7 b9#11' elif structure in ['7+ add #9', '7 add #9 alter #5']: explicit_figure = root + bass + '+7 #9' elif structure == 'm11 alter b5': explicit_figure = root + bass + 'm11 b5' elif structure == 'bpedal': # TODO This is a hack, replacing the 'b' by a '-' explicit_figure = root + bass + '-pedal' elif structure in ['13 add #11', '13 alter #11']: # TODO Check if a better solution exists # 1) This chord should be 13 alter #11 # 2) The order of the pitches is wrong explicit_figure = root + bass + ',35b7913#11' spotify_figure = '13 alter #11' elif structure in ['13 add b9', '13 alter b9']: # TODO Check if a better solution exists # 1) This chord should be 13 alter #11 # 2) The order of the pitches is wrong explicit_figure = root + bass + ',35b7b91113' spotify_figure = '13 alter b9' elif structure in ['13 add b9', '13 alter b9']: # TODO Check if a better solution exists # 1) This chord should be 13 alter #11 # 2) The order of the pitches is wrong explicit_figure = root + bass + ',35b7b91113' spotify_figure = '13 alter b9' elif structure == '13 subtract 5 subtract 11': # TODO Check if a better solution exists # 1) This chord should be 13 alter #11 # 2) The order of the pitches is wrong explicit_figure = root + bass + ',3b7913' spotify_figure = '13 sus4 omit 11' elif structure == 'm9 alter b5': explicit_figure = root + bass + 'm9 b5' elif structure == '7 subtract 5': explicit_figure = root + bass + '7 omit5' elif structure == 'pedal add 5': explicit_figure = root + bass + 'omit3' else: raise ValueError('unknown chord symbol ' + root + bass + structure) return SpotifyChord(spotify_figure=spotify_figure, figure=explicit_figure, bass=bass, root=root) def note_string(self) -> str: if self.is_no_chord(): return '' return str([str(p) for p in self.chord.pitches]) def is_no_chord(self): return self.structure == 'NC' def transposed_to( self, pitch: Pitch = Pitch()) -> Tuple['SpotifyChord', Optional[Interval]]: if self.is_no_chord(): return self, None tr_int = interval.notesToInterval(self.root, pitch) return self.transposed_by(tr_int), tr_int def transposed_by(self, tr_int: Interval) -> 'SpotifyChord': if self.is_no_chord(): return self if tr_int.semitones == 0: return deepcopy(self) new_root = _get_transposed_pitch(self.root, tr_int.directedName) new_root.simplifyEnharmonic(inPlace=True) new_chord = self.chord.transpose(tr_int, inPlace=False) if self.bass: new_bass = _get_transposed_pitch(self.bass, tr_int.directedName) new_bass.simplifyEnharmonic(inPlace=True) new_structure = self.structure.replace('/' + str(self.bass), '/' + str(new_bass), 1) new_structure = new_structure.replace(str(self.root), str(new_root), 1) return SpotifyChord(root=str(new_root), bass='/' + str(new_bass) if new_bass else None, chord=new_chord, figure=new_structure) else: new_structure = self.structure.replace(str(self.root), str(new_root), 1) return SpotifyChord(root=str(new_root), chord=new_chord, figure=new_structure) def note_at(self, i): if self.is_no_chord() or i >= self.get_num_notes(): return None return self.chord.pitches[i]