예제 #1
0
def cycle36_a_harmonic_minor_test():
    sc = scale.HarmonicMinorScale('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()
예제 #2
0
    def resolveDiminishedSeventhSegment(self, segmentB, doubledRoot = False):
        '''
        Can resolve a Segment whose :attr:`~music21.figuredBass.segment.Segment.segmentChord`
        spells out a diminished seventh chord. If no applicable method in
        :mod:`~music21.figuredBass.resolution` can be used, the Segment is resolved
        as an ordinary Segment.
        
        >>> from music21.figuredBass import segment
        >>> from music21 import note
        >>> segmentA = segment.Segment(bassNote = note.Note('B2'), notationString = "b7")
        >>> allDimPossib = segmentA.allCorrectSinglePossibilities()
        >>> allDimPossibList = list(allDimPossib)
        >>> len(allDimPossibList)
        7
        >>> [p.nameWithOctave for p in allDimPossibList[4]]
        ['D5', 'A-4', 'F4', 'B2']
        >>> [p.nameWithOctave for p in allDimPossibList[6]]
        ['A-5', 'F5', 'D5', 'B2']
        
        
        >>> segmentB = segment.Segment(bassNote = note.Note('C3'), notationString = "")
        >>> dimResPairs = segmentA.resolveDiminishedSeventhSegment(segmentB)
        >>> dimResPairsList = list(dimResPairs)
        >>> len(dimResPairsList)
        7
        >>> dimResPairsList[4]
        ((<...D5>, <...A-4>, <...F4>, <...B2>), (<...E5>, <...G4>, <...E4>, <...C3>))
        >>> dimResPairsList[6]
        ((<...A-5>, <...F5>, <...D5>, <...B2>), (<...G5>, <...E5>, <...E5>, <...C3>))
        '''
        dimChord = self.segmentChord
        if not dimChord.isDiminishedSeventh():
            #Put here for stand-alone purposes.
            raise SegmentException("Diminished seventh resolution: Not a diminished seventh Segment.")
        dimChordInfo = _unpackSeventhChord(dimChord)
        dimScale = scale.HarmonicMinorScale().deriveByDegree(7, dimChord.root())
        #minorScale = dimScale.getParallelMinor()
        
        tonic = dimScale.getTonic()
        subdominant = dimScale.pitchFromDegree(4)

        resChord = segmentB.segmentChord
        if dimChord.inversion() == 1: #Doubled root in context
            if resChord.inversion() == 0:
                doubledRoot = True
            elif resChord.inversion() == 1:
                doubledRoot = False

        diminishedResolutionMethods = \
        [(resChord.root().name == tonic.name and resChord.isMajorTriad(), resolution.diminishedSeventhToMajorTonic, [doubledRoot, dimChordInfo]),
         (resChord.root().name == tonic.name and resChord.isMinorTriad(), resolution.diminishedSeventhToMinorTonic, [doubledRoot, dimChordInfo]),
         (resChord.root().name == subdominant.name and resChord.isMajorTriad(), resolution.diminishedSeventhToMajorSubdominant, [dimChordInfo]),
         (resChord.root().name == subdominant.name and resChord.isMinorTriad(), resolution.diminishedSeventhToMinorSubdominant, [dimChordInfo])]
        
        try:
            return self._resolveSpecialSegment(segmentB, diminishedResolutionMethods)
        except SegmentException:
            self._environRules.warn("Diminished seventh resolution: No proper resolution available. Executing ordinary resolution.")
            return self._resolveOrdinarySegment(segmentB)
예제 #3
0
    def testDeriveByDegree(self):
        sc1 = scale.MajorScale()
        self.assertEqual(str(sc1.deriveByDegree(7, 'G#')),
                         '<music21.scale.MajorScale A major>')

        sc1 = scale.HarmonicMinorScale()
        # what scale has g# as its 7th degree
        self.assertEqual(
            str(sc1.deriveByDegree(7, 'G#')),
            '<music21.scale.HarmonicMinorScale A harmonic minor>')
        self.assertEqual(
            str(sc1.deriveByDegree(2, 'E')),
            '<music21.scale.HarmonicMinorScale D harmonic minor>')
예제 #4
0
def cycle36_drop2_a_harmonic_minor_test():
    sc = scale.HarmonicMinorScale('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()
예제 #5
0
    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
예제 #6
0
def generate_examples():
    output_dir = ".\\Examples\\"

    # Example 1 - cycle 2/7 for C major
    sc = scale.MajorScale('C')
    tonic_triad = chord.Chord(sc.pitchesFromScaleDegrees([1, 3, 5], 'C5',
                                                         'B5'))
    cycle = generate_cycle_pair(sc, tonic_triad, "2/7")
    cycle.insert(0, key.KeySignature(0))
    cycle.metadata = metadata.Metadata()
    cycle.metadata.title = "Example 1 - Cycle 2/7 in C Major"
    cycle.write("MusicXML", output_dir + "Example 1")

    # Example 2 - cycle 4/5 for D major
    sc = scale.MajorScale('D')
    tonic_triad = chord.Chord(sc.pitchesFromScaleDegrees([1, 3, 5], 'D4',
                                                         'C5'))
    cycle = generate_cycle_pair(sc, tonic_triad, "4/5")
    cycle.insert(0, key.KeySignature(2))
    cycle.metadata = metadata.Metadata()
    cycle.metadata.title = "Example 2 - Cycle 4/5 in D Major"
    cycle.write("MusicXML", output_dir + "Example 2")

    # Example 3 - cycle 3/6 for A harmonic minor
    sc = scale.HarmonicMinorScale('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.metadata = metadata.Metadata()
    cycle.metadata.title = "Example 3 - Cycle 3/6 in A Harmonic Minor"
    cycle.write("MusicXML", output_dir + "Example 3")

    # Example 4 - cycle 3/6 for C major but with drop 2 chords
    tonic = 'C'
    sc = scale.MajorScale(tonic)
    root = sc.pitchFromDegree(1)
    tonic_triad = chord.Chord([root, root.transpose(7), root.transpose(16)])
    cycle = generate_cycle_pair(sc,
                                tonic_triad,
                                "3/6",
                                voicing_type=Voicing.Drop2_A_form)
    cycle.insert(0, key.KeySignature(0))
    cycle.metadata = metadata.Metadata()
    cycle.metadata.title = "Example 4 - Cycle 3/6 in C Major\nDrop 2 voicings"
    cycle.write("MusicXML", output_dir + "Example 4")
예제 #7
0
    def testScales01(self):
        from music21 import pitch

        #==== "fig-py01"

        # Providing a tonic makes this concrete
        sc1 = scale.MajorScale('g4')
        sc2 = scale.MajorScale('e-3')

        # Comparing Concrete and Abstract Scales
        assert (sc1 == sc2) == False
        assert (sc1.abstract == sc2.abstract) == True

        # Without arguments, getPitches() returns a single span
        assert common.pitchList(
            sc1.getPitches()) == '[G4, A4, B4, C5, D5, E5, F#5, G5]'
        assert common.pitchList(sc2.getPitches(
            'c2', 'c3')) == '[C2, D2, E-2, F2, G2, A-2, B-2, C3]'

        # As a Chord, Scale pitches gain additional functionality
        assert sc1.getChord().forteClass == '7-35'

        # Given a degree, get the pitch
        assert str(sc1.pitchFromDegree(5)) == 'D5'
        assert common.pitchList(
            sc2.pitchesFromScaleDegrees([7, 2], 'e-6',
                                        'e-9')) == '[F6, D7, F7, D8, F8, D9]'

        # Get a scale degree from a pitch
        assert sc1.getScaleDegreeFromPitch('d') == 5
        assert sc2.getScaleDegreeFromPitch('d') == 7

        # Get the next pitch given step directions
        match = [pitch.Pitch('g2')]
        for direction in [1, 1, 1, -2, 4, -1, 1, 1, 1]:
            # Append the next pitch based on the last-added pitch
            match.append(sc1.next(match[-1], direction))
        assert common.pitchList(
            match), '[G2, A2, B2, C3, A2, E3, D3, E3, F#3, G3]'

        # Derive new scales based on a provided collection or degree
        assert str(sc1.derive(['c4', 'g4', 'b8',
                               'f2'])) == '<music21.scale.MajorScale C major>'
        assert str(sc1.deriveByDegree(
            7, 'C#')) == '<music21.scale.MajorScale D major>'

        # Methods unique to DiatonicScale subclasses
        assert str(
            sc2.getRelativeMinor()) == '<music21.scale.MinorScale C minor>'
        #==== "fig-py01" end

        #==== "fig-py02"
        sc1 = scale.PhrygianScale('g4')
        assert common.pitchList(
            sc1.getPitches()) == '[G4, A-4, B-4, C5, D5, E-5, F5, G5]'
        assert str(
            sc1.getRelativeMajor()) == '<music21.scale.MajorScale E- major>'
        assert str(sc1.getTonic()), str(sc1.getDominant()) == ('G4', 'D5')

        sc2 = scale.HypodorianScale('a6')
        assert common.pitchList(sc2.getPitches(
            'e2', 'e3')) == '[E2, F#2, G2, A2, B2, C3, D3, E3]'
        assert str(
            sc2.getRelativeMajor()) == '<music21.scale.MajorScale G major>'
        assert str(sc2.getTonic()), str(sc2.getDominant()) == ('A6', 'C7')

        #==== "fig-py02" end

        #==== "fig-py06"
        # see below
        #==== "fig-py06" end

        #==== "fig-py03"
        #print('\n\nfig-py03')

        sc1 = scale.HarmonicMinorScale('a3')
        assert common.pitchList(
            sc1.getPitches()) == '[A3, B3, C4, D4, E4, F4, G#4, A4]'
        assert str(sc1.getTonic()), str(sc1.getDominant()) == ('A3', 'E4')

        s = stream.Stream()
        for d in [1, 3, 2, 1, 6, 5, 8, 7, 8]:
            s.append(
                note.Note(sc1.pitchFromDegree(d, equateTermini=False),
                          type='eighth'))
        #s.show()
        #==== "fig-py03" end

        #==== "fig-py04"
        import random

        sc1 = scale.MelodicMinorScale('c4')
        assert common.pitchList(sc1.getPitches(
            direction='ascending')) == '[C4, D4, E-4, F4, G4, A4, B4, C5]'
        assert common.pitchList(
            sc1.getPitches('c3', 'c5', direction='descending')) == (
                '[C5, B-4, A-4, G4, F4, E-4, D4, ' +
                'C4, B-3, A-3, G3, F3, E-3, D3, C3]')
        assert str(sc1.getTonic()), str(sc1.getDominant()) == ('C4', 'G4')

        s = stream.Stream()
        p = None
        for i in range(8):  # was 16, but sometimes exceeded scale length.
            direction = random.choice([-1, 1])
            for j in range(2):
                p = sc1.next(p, direction)
                s.append(note.Note(p, quarterLength=.25))
        #s.show()
        #==== "fig-py04" end

        #==== "fig-py05"
        sc1 = scale.OctatonicScale('e3', 'm2')
        assert common.pitchList(
            sc1.getPitches()) == '[E3, F3, G3, A-3, B-3, C-4, D-4, D4, E4]'
        sc2 = scale.OctatonicScale('e3', 'M2')
        assert common.pitchList(
            sc2.getPitches()) == '[E3, F#3, G3, A3, B-3, C4, D-4, E-4, F-4]'

        part1 = stream.Part()
        part2 = stream.Part()
        durPart1 = [1, 1, 0.5, 0.5, 1]
        durPart2 = [3, 1]
        degrees = list(range(1, 9))
        for unused in range(4):
            random.shuffle(degrees)
            random.shuffle(durPart1)
            random.shuffle(durPart2)
            i = 0
            for dur in durPart1:
                part1.append(
                    note.Note(sc2.pitchFromDegree(degrees[i]),
                              quarterLength=dur))
                i += 1
            for dur in durPart2:
                part2.append(
                    note.Note(sc2.pitchFromDegree(degrees[i],
                                                  minPitch='c2',
                                                  maxPitch='c3'),
                              quarterLength=dur))
                i += 1
        s = stream.Score()
        s.insert(0, part1)
        s.insert(0, part2)
        #s.show()

        # add notation example; perhaps create tri-chords from scale-completing selections
        #==== "fig-py05" end

        #sc = scale.SieveScale('c2', '(-3@2 & 4) | (-3@1 & 4@1) | (3@2 & 4@2) | (-3 & 4@3)')

        #==== "fig-py07"
        # add examples
        sc1 = scale.SieveScale('c4', '3@0|4@0')
        self.assertEqual(common.pitchList(sc1.getPitches()),
                         '[C4, E-4, E4, F#4, G#4, A4, C5]')

        sc2 = scale.SieveScale('c4', '5@0|7@0')
        self.assertEqual(
            common.pitchList(sc2.getPitches()),
            '[C4, F4, G4, B-4, D5, E-5, G#5, A5, C#6, E6, F#6, B6]')

        s = stream.Stream()
        pColection = sc2.getPitches('c3', 'c7')
        random.shuffle(pColection)
        for p in pColection:
            s.append(note.Note(p, type='16th'))
        #s.show()
        #==== "fig-py07" end

        #==== "fig-py08"

        sc1 = scale.RagAsawari('g3')
        self.assertEqual(
            common.pitchList(sc1.getPitches(direction='ascending')),
            '[G3, A3, C4, D4, E-4, G4]')
        self.assertEqual(
            common.pitchList(sc1.getPitches(direction='descending')),
            '[G4, F4, E-4, D4, C4, B-3, A3, G3]')

        sc2 = scale.RagMarwa('g3')
        assert common.pitchList(sc2.getPitches(direction='ascending')
                                ) == '[G3, A-3, B3, C#4, E4, F#4, E4, G4, A-4]'
        assert common.pitchList(
            sc2.getPitches(direction='descending'
                           )) == '[A-4, G4, A-4, F#4, E4, C#4, B3, A-3, G3]'

        p1 = None
        s = stream.Stream()
        for direction in ([1] * 10) + ([-1] * 8) + ([1] * 4) + ([-1] *
                                                                3) + ([1] * 4):
            p1 = sc1.next(p1, direction)
            s.append(note.Note(p1, quarterLength=.25))
        #s.show()

        p1 = None
        s = stream.Stream()
        for direction in ([1] * 10) + ([-1] * 8) + ([1] * 4) + ([-1] *
                                                                3) + ([1] * 4):
            p1 = sc2.next(p1, direction)
            s.append(note.Note(p1, quarterLength=.25))
        #s.show()

        #==== "fig-py08" end

        #==== "fig-py09"
        #import random
        sc1 = scale.WeightedHexatonicBlues('c3')
        p = 'c3'
        s = stream.Stream()
        for n in range(32):
            p = sc1.next(p, random.choice([-1, 1]))
            n = note.Note(p, quarterLength=random.choice([.5, .25, .25]))
            s.append(n)