def getScale(self, mode=None): ''' Return a :class:`music21.scale.Scale` object (or, actually, a subclass such as :class:`~music21.scale.MajorScale` or :class:`~music21.scale.MinorScale`) that is representative of this key signature and mode. Raises KeySignatureException if mode is not in [None, 'major', 'minor']. >>> ks = key.KeySignature(3) >>> ks <music21.key.KeySignature of 3 sharps> >>> ks.getScale('major') <music21.scale.MajorScale A major> >>> ks.mode = 'minor' >>> ks.getScale() <music21.scale.MinorScale F# minor> ''' pitchObj, stored_mode = self._getPitchAndMode() if mode is None: mode = stored_mode if mode in (None, 'major'): return scale.MajorScale(pitchObj) elif mode in ('minor', ): return scale.MinorScale(pitchObj) else: raise KeySignatureException( 'No mapping to a scale exists for this mode yet: %s' % mode)
def cycle36_a_minor_test(): sc = scale.MinorScale('A') tonic_triad = chord.Chord(sc.pitchesFromScaleDegrees([1, 3, 5], 'A4', 'G5')) cycle = generate_cycle_pair(sc, tonic_triad, "3/6") cycle.insert(0, key.KeySignature(0)) cycle.show()
def get_fitting_scales_for_tune(notes): major_scales = scale.MajorScale().deriveAll(notes) minor_scales = scale.MinorScale().deriveAll(notes) scales = parse_and_format_scales(major_scales) scales.extend(parse_and_format_scales(minor_scales)) return scales
def get_all_scales(): pitches = scale.ChromaticScale('A').pitches major_scales = [scale.MajorScale(pitch) for pitch in pitches] minor_scales = [scale.MinorScale(pitch) for pitch in pitches] scales = parse_and_format_scales(major_scales) scales.extend(parse_and_format_scales(minor_scales)) return scales
def create_midi(prediction_output, Scale, fileName, BPM=120, offset=0, cycles=1, timeSignature=4): #convert the output from the prediction to notes and create a midi file from the notes Offset = 0 output_notes = [] if not offset: offset = 480 / (BPM * cycles * timeSignature) mode = Scale.split()[-1] if mode == 'Major': key = scale.MajorScale(Scale.split()[0]) diff = majors[key.tonic.name] elif mode == 'Minor': key = scale.MinorScale(Scale.split()[0]) diff = minors[key.tonic.name] scaleNotes = list(set(list(note.name for note in key.getPitches()))) # create note and chord objects based on the values generated by the model for pattern in prediction_output: # pattern is a chord if ('.' in pattern) or pattern.isdigit(): notes_in_chord = pattern.split('.') notes = [] for current_note in notes_in_chord: new_note = note.Note(int(current_note) - diff) if new_note.name not in scaleNotes: new_note = note.Note(int(current_note) - 1) notes.append(new_note) new_chord = chord.Chord(notes) new_chord.offset = Offset output_notes.append(new_chord) # pattern is a note else: new_note = note.Note(pattern) new_note = new_note.transpose(-diff) if new_note.name not in scaleNotes: new_note = new_note.transpose(-1) new_note.offset = Offset new_note.storedInstrument = instrument.Guitar() output_notes.append(new_note) seed = random.randint(1, 1000000000) # increase offset each iteration so that notes do not stack; the modulos are arbitrary if seed % 32: Offset += offset / 2 else: Offset += offset #offset += 0.5 midi_stream = stream.Stream(output_notes) midi_stream.write('midi', fp=f'./static/userMIDIs/{fileName}.mid')
def get_scale_notes(chord_index): if chord_index in scale_cache: return scale_cache[chord_index] else: chord, tonality = cg.id_to_chord(chord_index).split(':') print("Key: {} Index: {}".format(chord + ':' + tonality, chord_index)) if tonality == 'maj': sc = scale.MajorScale(chord) else: sc = scale.MinorScale(chord) res = [p.name for p in sc.getPitches(chord + '2', chord + '3')] scale_cache[chord_index] = res return res
def cycle36_drop2_a_minor_test(): sc = scale.MinorScale('A') # tonic_triad = chord.Chord(sc.pitchesFromScaleDegrees([1, 3, 5], 'A4', 'G5')) triad_root = pitch.Pitch("A4") tonic_triad = chord.Chord( [triad_root, triad_root.transpose(7), triad_root.transpose(15)]) cycle = generate_cycle_pair(sc, tonic_triad, "3/6", voicing_type=Voicing.Drop2_A_form) cycle.insert(0, key.KeySignature(0)) cycle.show()
def get_seed(self): """ Generates a seed based on the configuration file. Four main types are used: 'from_existing' - takes a seed from an existing MIDI file. A specific amount of time steps is extracted, based on a parameter from the config file. 'from_scale' - creates a seed from a specific scale ('major', 'minor' or 'harmonic_minor'). It randomises which notes will be taken for the seed. 'custom' - asks the user for a custom seed sequence. Notes have to be entered in a MIDI representation. 'from_random_file' - takes a random file from the data_dir that is set in the configuration file. :return: a seed sequence """ settings = DataHandler.get_config_params() seed = [] mode = settings["seed_mode"] if mode == 'from_existing': seed_source = self.get_note_rep_array( settings["data_dir"] + settings["seed_source"], False) for i in range(settings["seed_size"]): seed.append(seed_source[i][0]) if mode == 'from_scale': seed_scale = settings["seed_scale"] if seed_scale == 'major': sc = scale.MajorScale() seed = self.get_notes_from_scale(scale_obj=sc, length=settings["seed_size"]) if seed_scale == 'minor': sc = scale.MinorScale() seed = self.get_notes_from_scale(scale_obj=sc, length=settings["seed_size"]) if seed_scale == 'harmonic_minor': sc = scale.HarmonicMinorScale() seed = self.get_notes_from_scale(scale_obj=sc, length=settings["seed_size"]) if mode == 'custom': seed_input = input( "Please enter seed sequence (comma separated sequence of notes in MIDI representation):" ) seed = [int(i) for i in seed_input] if mode == 'from_random_file': files = os.listdir(settings["data_dir"]) file_index = np.random.randint(0, len(files)) seed_source = self.get_note_rep_array( settings["data_dir"] + files[file_index], False) for i in range(settings["seed_size"]): seed.append(seed_source[i][0]) return seed
def melodyDomain(self, number): "Return pitch domain for melody note at number." time = 0 for i in range(number): time += self.song[0][i][1] chordNum = math.floor(time/4) chords = self.song[1][chordNum] if chords.quality == 'minor': resScale = scale.MinorScale(chords.pitchNames[0]) b = [str(p) for p in resScale.getPitches("C4", "C5")] random.shuffle(b) return b else: resScale = scale.MajorScale(chords.pitchNames[0]) b = [str(p) for p in resScale.getPitches("C4", "C5")] random.shuffle(b) return b
def chord_tuning(chords): tonic_chord = chords[0] # assume first chord to be in tonic tonic_key, tonic_tonality = tonic_chord.split(":") sc = scale.MajorScale(tonic_key) if tonic_tonality == "maj" \ else scale.MinorScale(tonic_key) sc = [p.name for p in sc.getPitches(tonic_key + '2', tonic_key + '3')] # tune the ending part of the chord sequence ending_key, ending_tonality = chords[-1].split(':') leading_key, leading_tonality = chords[-2].split(':') if tonic_tonality == "maj": relative_minor_key = sc[5] dominant_key = sc[4] if ending_key == tonic_key: pass # no changes if ending on tonic elif ending_key == relative_minor_key: if leading_key != dominant_key: chords[-2] = dominant_key + ":maj" else: chords[-2] = dominant_key + ":maj" if random.uniform(0, 1) > 0.8: chords[-1] = tonic_key + ":maj" else: chords[-1] = relative_minor_key + ":min" else: relative_major_key = sc[2] major_dominant_key = sc[-2] minor_dominant_key = sc[4] if ending_key == tonic_key: pass elif ending_key == relative_major_key: if leading_key != major_dominant_key: chords[-2] = major_dominant_key + ":maj" else: if random.uniform(0, 1) > 0.8: chords[-2] = major_dominant_key + ":maj" chords[-1] = relative_major_key + ":maj" else: chords[-2] = minor_dominant_key + ":maj" chords[-1] = tonic_key + ":min" return chords
def _get_scale(self): """ Get music21 scale for a scale type :param scale_type: major, minor, dorian etc. """ pitch, scale_type = self.key if scale_type in [constants.MAJOR, constants.IONIAN]: return scale.MajorScale(pitch) elif scale_type in [constants.MINOR, constants.AEOLIAN]: return scale.MinorScale(pitch) elif scale_type == constants.DORIAN: return scale.DorianScale(pitch) elif scale_type == constants.PHRYGIAN: return scale.PhrygianScale(pitch) elif scale_type == constants.LYDIAN: return scale.LydianScale(pitch) elif scale_type == constants.LOCRIAN: return scale.LocrianScale(pitch) else: return scale.MajorScale(pitch)
def getScale(self, mode='major'): ''' Return a :class:`music21.scale.Scale` object (or, actually, a subclass such as :class:`~music21.scale.MajorScale` or :class:`~music21.scale.MinorScale`) that is representative of this key signature and mode. Raises KeySignatureException if mode is not in [None, 'major', 'minor']. >>> ks = key.KeySignature(3) >>> ks <music21.key.KeySignature of 3 sharps> >>> ks.getScale('major') <music21.scale.MajorScale A major> >>> ks.getScale('minor') <music21.scale.MinorScale F# minor> ''' pitchObj = self.asKey(mode).tonic if mode in (None, 'major'): return scale.MajorScale(pitchObj) elif mode == 'minor': return scale.MinorScale(pitchObj) else: raise KeySignatureException(f'No mapping to a scale exists for this mode yet: {mode}')
def getScale(self): ''' Return a scale that is representative of this key signature and mode. >>> ks = key.KeySignature(3) >>> ks <music21.key.KeySignature of 3 sharps> >>> ks.getScale() <music21.scale.MajorScale A major> >>> ks.mode = 'minor' >>> ks.getScale() <music21.scale.MinorScale F# minor> ''' pitchObj, mode = self._getPitchAndMode() if mode in [None, 'major']: return scale.MajorScale(pitchObj) elif mode in ['minor']: return scale.MinorScale(pitchObj) else: raise KeySignatureException('not mapping for this mode yet: %s' % mode)
def run(): msa = np.zeros((2, 200), dtype="S1") #msa[0] = np.zeros(200, dtype="S1") msa[0] = np.random.choice(['a', 'g', 'c', 't', '-'], 200) print(msa[0]) msa[1] = np.random.choice(['a', 'g', 'c', 't', '-'], 200) print(msa[1]) error_log = open('test_vectors/error_log_test2.txt', 'wr') for window_size in range(5, 30, 5): for window_duration in range(5, 60, 5): for n_nucleotides in range(1, 2): try: subdir = 'demo2_' + str(window_size) + '_' + str( window_duration) + '_' + str(n_nucleotides) pitch_algo = PitchAlgorithm( PitchAlgorithm.WORD_DISTANCES, scale=scale.MinorScale().getPitches(), n_nucleotides=1) durations_algo = DurationsAlgorithm( DurationsAlgorithm.FREQUENCIES_DYNAMIC, window_size=window_size, window_duration=window_duration, n_nucleotides=1) dynamics_algo = DynamicsAlgorithm( DynamicsAlgorithm.SHANNON_INDEX, window_size=window_size, gap_window_threshold=0.5, gap_column_threshold=0.7, criteria='local', levels=7) instruments_algo = ClusteringAlgorithm('kmeans') composer = Composer(instruments_algo, pitch_algo, durations_algo, dynamics_algo, input_type='array', alignment=msa) sequence_names = np.array( [str(i) for i in range(0, len(msa))]) i = 0 scores = composer.gen_numerical_vectors( k=2, piece_length=window_size * 2) print 'Parameters ' + str(window_size) + ' ' + str( window_duration) + ' ' + str(n_nucleotides) print 'Number of scores', len(scores) for score in scores: fw = FileWriter(score, sequence_names) fname = 'demo_' + str(i) print('fname', fname) fw.write(midi=fname, audio=fname, display=False, subdir=subdir) i += 1 print('After writing', fname) except Exception as e: print 'Error ocurred! Please check log!' error_log.write('Error occurred with windows_size = ' + str(window_size) + \ ' & window_duration = ' + str(window_duration) + ' & n_nucleotides = ' + str( n_nucleotides) + e.message + '\n')
def testBasicLegacy(self): n1 = note.Note() cMajor = scale.MajorScale(n1) self.assertEqual(cMajor.name, 'C major') self.assertEqual(cMajor.getPitches()[6].step, 'B') seventh = cMajor.pitchFromDegree(7) self.assertEqual(seventh.step, 'B') dom = cMajor.getDominant() self.assertEqual(dom.step, 'G') n2 = note.Note() n2.step = 'A' aMinor = cMajor.getRelativeMinor() self.assertEqual(aMinor.name, 'A minor', 'Got a different name: ' + aMinor.name) notes = [note1.name for note1 in aMinor.getPitches()] self.assertEqual(notes, ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'A']) n3 = note.Note() n3.name = 'B-' n3.octave = 5 bFlatMinor = scale.MinorScale(n3) self.assertEqual(bFlatMinor.name, 'B- minor', 'Got a different name: ' + bFlatMinor.name) notes2 = [note1.name for note1 in bFlatMinor.getPitches()] self.assertEqual(notes2, ['B-', 'C', 'D-', 'E-', 'F', 'G-', 'A-', 'B-']) self.assertEqual(bFlatMinor.getPitches()[0], n3.pitch) self.assertEqual(bFlatMinor.getPitches()[6].octave, 6) # harmonic = bFlatMinor.getConcreteHarmonicMinorScale() # niceHarmonic = [note1.name for note1 in harmonic] # self.assertEqual(niceHarmonic, ['B-', 'C', 'D-', 'E-', 'F', 'G-', 'A', 'B-']) # # harmonic2 = bFlatMinor.getAbstractHarmonicMinorScale() # self.assertEqual([note1.name for note1 in harmonic2], niceHarmonic) # for note1 in harmonic2: # self.assertEqual(note1.octave, 0) # # melodic = bFlatMinor.getConcreteMelodicMinorScale() # niceMelodic = [note1.name for note1 in melodic] # self.assertEqual(niceMelodic, # ['B-', 'C', 'D-', 'E-', 'F', 'G', 'A', 'B-', 'A-', 'G-', # 'F', 'E-', 'D-', 'C', 'B-']) # melodic2 = bFlatMinor.getAbstractMelodicMinorScale() # self.assertEqual([note1.name for note1 in melodic2], niceMelodic) # for note1 in melodic2: # self.assertEqual(note1.octave, 0) cNote = bFlatMinor.pitchFromDegree(2) self.assertEqual(cNote.name, 'C') fNote = bFlatMinor.getDominant() self.assertEqual(fNote.name, 'F') bFlatMajor = bFlatMinor.getParallelMajor() self.assertEqual(bFlatMajor.name, 'B- major') # scale = [note1.name for note1 in bFlatMajor.getConcreteMajorScale()] # self.assertEqual(scale, ['B-', 'C', 'D', 'E-', 'F', 'G', 'A', 'B-']) dFlatMajor = bFlatMinor.getRelativeMajor() self.assertEqual(dFlatMajor.name, 'D- major') self.assertEqual(dFlatMajor.getTonic().name, 'D-') self.assertEqual(dFlatMajor.getDominant().name, 'A-')
def testBasic(self): # deriving a scale from a Stream # just get default, c-minor, as derive will check all tonics sc2 = scale.MinorScale() # we can get a range of pitches # noinspection PyTypeChecker self.assertEqual( self.pitchOut(sc2.getPitches('c2', 'c5')), '[C2, D2, E-2, F2, G2, A-2, B-2, C3, D3, E-3, F3, G3, A-3, B-3, ' + 'C4, D4, E-4, F4, G4, A-4, B-4, C5]') # we can transpose the Scale sc3 = sc2.transpose('-m3') self.assertEqual( self.pitchOut(sc3.getPitches('c2', 'c5')), '[C2, D2, E2, F2, G2, A2, B2, C3, D3, E3, F3, G3, A3, B3, ' + 'C4, D4, E4, F4, G4, A4, B4, C5]') # getting pitches from scale degrees self.assertEqual(str(sc3.pitchFromDegree(3)), 'C4') self.assertEqual(str(sc3.pitchFromDegree(7)), 'G4') self.assertEqual(self.pitchOut(sc3.pitchesFromScaleDegrees([1, 5, 6])), '[A3, E4, F4, A4]') self.assertEqual( self.pitchOut( sc3.pitchesFromScaleDegrees([2, 3], minPitch='c6', maxPitch='c9')), '[C6, B6, C7, B7, C8, B8, C9]') # given a pitch, get the scale degree sc4 = scale.MajorScale('A-') self.assertEqual(sc4.getScaleDegreeFromPitch('a-'), 1) # default is name matching self.assertEqual(sc4.getScaleDegreeFromPitch('g#'), None) # can set pitchClass comparison attribute self.assertEqual( sc4.getScaleDegreeFromPitch('g#', comparisonAttribute='pitchClass'), 1) self.assertEqual( sc4.getScaleDegreeFromPitch('e-', comparisonAttribute='name'), 5) # showing scales # this assumes that the tonic is not the first scale degree sc1 = scale.HypophrygianScale('c4') self.assertEqual(str(sc1.pitchFromDegree(1)), 'G3') self.assertEqual(str(sc1.pitchFromDegree(4)), 'C4') # sc1.show() sc1 = scale.MajorScale() # deriving a new scale from the pitches found in a collection s = corpus.parse('bwv66.6') sc3 = sc1.derive(s.parts['#soprano']) self.assertEqual(str(sc3), '<music21.scale.MajorScale A major>') sc3 = sc1.derive(s.parts['#tenor']) self.assertEqual(str(sc3), '<music21.scale.MajorScale A major>') sc3 = sc2.derive(s.parts['#bass']) self.assertEqual(str(sc3), '<music21.scale.MinorScale F# minor>') # composing with a scale s = stream.Stream() p = 'd#4' # sc = scale.PhrygianScale('e') sc = scale.MajorScale('E4') for d, x in [(Direction.ASCENDING, 1), (Direction.DESCENDING, 2), (Direction.ASCENDING, 3), (Direction.DESCENDING, 4), (Direction.ASCENDING, 3), (Direction.DESCENDING, 2), (Direction.ASCENDING, 1)]: # use duration type instead of quarter length for y in (1, 0.5, 0.5, 0.25, 0.25, 0.25, 0.25): p = sc.nextPitch(p, direction=d, stepSize=x) n = note.Note(p) n.quarterLength = y s.append(n) self.assertEqual( self.pitchOut(s.pitches), '[E4, F#4, G#4, A4, B4, C#5, D#5, B4, G#4, E4, C#4, A3, F#3, D#3, ' + 'G#3, C#4, F#4, B4, E5, A5, D#6, G#5, C#5, F#4, B3, E3, A2, D#2, G#2, ' + 'C#3, F#3, B3, E4, A4, D#5, B4, G#4, E4, C#4, A3, F#3, D#3, E3, F#3, ' + 'G#3, A3, B3, C#4, D#4]') # s.show() # composing with an octatonic scale. s1 = stream.Part() s2 = stream.Part() p1 = 'b4' p2 = 'b3' sc = scale.OctatonicScale('C4') for d, x in [(Direction.ASCENDING, 1), (Direction.DESCENDING, 2), (Direction.ASCENDING, 3), (Direction.DESCENDING, 2), (Direction.ASCENDING, 1)]: for y in (1, 0.5, 0.25, 0.25): p1 = sc.nextPitch(p1, direction=d, stepSize=x) n = note.Note(p1) n.quarterLength = y s1.append(n) if d == Direction.ASCENDING: d = Direction.DESCENDING elif d == Direction.DESCENDING: d = Direction.ASCENDING for y in [1, 0.5, 0.25, 0.25]: p2 = sc.nextPitch(p2, direction=d, stepSize=x) n = note.Note(p2) n.quarterLength = y s2.append(n) s = stream.Score() s.insert(0, s1) s.insert(0, s2) # s.show() # compare two different major scales sc1 = scale.MajorScale('g') sc2 = scale.MajorScale('a') sc3 = scale.MinorScale('f#') # exact comparisons self.assertNotEqual(sc1, sc2) self.assertEqual(sc1.abstract, sc2.abstract) self.assertNotEqual(sc1, sc3) self.assertNotEqual(sc1.abstract, sc3.abstract) # getting details on comparison self.assertEqual( pformat(sc1.match(sc2)), '''{'matched': [<music21.pitch.Pitch A4>, <music21.pitch.Pitch B4>, <music21.pitch.Pitch D5>, <music21.pitch.Pitch E5>, <music21.pitch.Pitch F#5>], 'notMatched': [<music21.pitch.Pitch C#5>, <music21.pitch.Pitch G#5>]}''', pformat(sc1.match(sc2)))