コード例 #1
0
    def notate_note(self, note):
        if note['pitch'] == 'rest':
            n = Rest()
        else:
            if isinstance(note['pitch'], list):
                pitches = []
                for pitch_number in note['pitch']:
                    p = Pitch(pitch_number)
                    # Force all flats
                    if p.accidental.name == 'sharp':
                        p = p.getEnharmonic()
                    pitches.append(p)
                n = Chord(notes=pitches)

            else:
                p = Pitch(note['pitch'])
                # Force all flats
                if p.accidental.name == 'sharp':
                    p = p.getEnharmonic()
                n = Note(p)

        d = Duration()
        if note['duration'] == 0:
            d.quarterLength = .125
            d = d.getGraceDuration()
        else:
            d.fill(note['durations'])
        n.duration = d
        return n
コード例 #2
0
def notate_score(musician_names, instrument_names, music):
    score = Score()

    for musician_name, instrument_name in zip(musician_names,
                                              instrument_names):
        instrument = get_instrument(instrument_name)
        instrument.partName = instrument.instrumentName
        instrument.partAbbreviation = instrument.instrumentAbbreviation

        parts = []
        part = Part()
        parts.append(part)
        part.insert(0, instrument)

        score.insert(0, part)
        score.insert(0, StaffGroup(parts))

        notes = music[musician_name]

        for pitches in notes:
            if not pitches or pitches == 'stop':
                note = Rest()
            elif len(pitches) == 1:
                pitch = Pitch(pitches[0] + 60)
                note = Note(pitch)
            else:
                note = Chord(notes=[Pitch(p + 60) for p in pitches])

            duration = Duration()
            duration.fill([4.0])
            note.duration = duration

            part.append(note)

    score.show('musicxml', '/Applications/Sibelius 7.5.app')
コード例 #3
0
 def __init__(self,
              original_figure: str = None,
              spotify_figure: str = None,
              figure: str = None,
              bass: str = None,
              root: str = None,
              kind: str = None):
     # This is the original figure, which is kept because it is needed to create a SpotifyChord equivalent to THIS
     #  SpotifyChordSymbol
     self.original_figure = original_figure
     if spotify_figure == 'NC':
         self.bass = None
         self.root = None
         self.structure = 'NC'
     elif figure:
         assert root
         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[1:], root=root, kind=kind)
         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 = chord_symbol.figure
コード例 #4
0
def move_pitch(note: Pitch, pitch: Pitch) -> Note:
    while abs(note.midi - pitch.midi) > 6:
        dist = note.midi - pitch.midi
        if dist < 0:
            note = note.transpose(12)
        else:
            note = note.transpose(-12)

    return note
コード例 #5
0
    def generate_closed_chord(self,
                              root_note: PitchInit,
                              anchor_note: PitchInit = "C4",
                              max_notes: int = 5,
                              bass_note: Optional[PitchInit] = None,
                              include_root: bool = True):

        if isinstance(root_note, str):
            root_note = Pitch(root_note)

        if isinstance(anchor_note, str):
            anchor_note = Pitch(anchor_note)

        if isinstance(bass_note, str):
            bass_note = Pitch(bass_note)

        if max_notes < 2:
            raise ValueError("Not really a chord with only one or no notes.")

        chord_heap = []

        third = root_note.transpose(self.third_quality.interval)
        fifth = root_note.transpose(self.fifth_quality.interval)
        harmonies = [root_note.transpose(harm.interval) for harm in self.harmonies]

        heappush(chord_heap, (9, third))
        for harmony in harmonies:
            heappush(chord_heap, (7, harmony))

        heappush(chord_heap, (1, fifth))
        if include_root:
            heappush(chord_heap, (3, root_note))

        if self.upper_quality is not None:
            heappush(chord_heap, (9, (root_note.transpose(self.upper_quality.interval))))

        while len(chord_heap) > max_notes:
            heappop(chord_heap)

        chord_base = Chord(note for _, note in chord_heap)

        chord_base.sortDiatonicAscending(inPlace=True)

        chord_base = move_chord(chord_base, anchor_note)
        chord_base = chord_base.closedPosition()
        inversions = all_inversions(chord_base)
        inversions = [move_chord(c, anchor_note) for c in inversions]

        best_option = min(inversions, key=lambda x: chord_mad(x, anchor_note))

        if bass_note is not None:
            bass_note = move_pitch(bass_note, anchor_note.transpose(-12))
            best_option.add(bass_note, runSort=True)

        return best_option
コード例 #6
0
def write_notation_cell(music, path, event_index):
    score = Score()

    metadata = Metadata()
    metadata.title = ''
    metadata.composer = ''
    score.insert(0, metadata)

    layout = ScoreLayout()
    layout.scalingMillimeters = 1.25
    layout.scalingTenths = 40
    score.insert(0, layout)

    for musician in music:
        instrument_name = musician['instrument']
        instrument = get_instrument(instrument_name)
        instrument.partName = instrument.instrumentName
        if instrument.instrumentName is 'Violoncello':
            instrument.partName = 'Cello'
        instrument.partAbbreviation = instrument.instrumentAbbreviation

        parts = []
        part = Part()
        parts.append(part)
        part.insert(0, instrument)

        score.insert(0, part)
        # score.insert(0, StaffGroup(parts))

        for event in musician['music']:
            pitches = event['pitches']
            dur = event['duration']
            # if not pitches or pitches == 'stop':
            #     note = Rest()
            if len(pitches) == 1:
                pitch = Pitch(pitches[0] + 60)
                note = Note(pitch)
            else:
                note = Chord(notes=[Pitch(p + 60) for p in pitches])

            duration = Duration()
            duration.fill([dur])
            note.duration = duration

            part.append(note)

    file_path = os.path.join(path, str(event_index).zfill(2))
    musicxml_file_path = file_path + '.xml'
    png_output_file_path = file_path + '.png'

    score.write('musicxml', musicxml_file_path)

    write_png_with_musescore(musicxml_file_path, png_output_file_path, dpi=600)
コード例 #7
0
def split(figure):
    _figure = figure.replace('bpedal', '-pedal')
    root = match(r'[A-Ga-g][#-]*', _figure).group()
    _figure = _figure.replace(root, '', 1)
    root_pitch = Pitch(root)
    root = str(root_pitch)
    bass = search(r'/[A-Ga-g][#-]*', _figure)
    structure = _figure.replace(bass.group(), '', 1) if bass else _figure
    if bass:
        bass_pitch = Pitch(bass.group()[1:])
        bass = '/' + str(bass_pitch)
    return root, structure.strip(), bass if bass else ''
コード例 #8
0
def make_music21_note(
    pitch_number=None,
    duration=1.0,
    staccato=False,
    tenuto=False,
    accent=False,
    falloff=False,
    plop=False,
    scoop=False,
    doit=False,
    breath_mark=False,
):
    if pitch_number == None or pitch_number == 'rest':
        n = Rest()
    elif isinstance(pitch_number, list):
        pitches = [Pitch(p) for p in pitch_number]
        for p in pitches:
            if p.accidental.name is 'natural':
                p.accidental = None
        n = Chord(pitches)
    else:
        p = Pitch(pitch_number)
        if p.accidental.name is 'natural':
            p.accidental = None
        n = Note(p)

    d = Duration()
    d.quarterLength = duration
    n.duration = d

    if staccato:
        n.articulations.append(Staccato())
    if tenuto:
        n.articulations.append(Tenuto())
    if accent:
        n.articulations.append(Accent())
    if falloff:
        n.articulations.append(Falloff())
    if plop:
        n.articulations.append(Plop())
    if scoop:
        n.articulations.append(Scoop())
    if doit:
        n.articulations.append(Doit())
    if breath_mark:
        n.articulations.append(BreathMark())

    return n
コード例 #9
0
def _transpose_pitch_in_scale_space(
    original_pitch: pitch.Pitch,
    steps: int,
    reference_scale: scale.ConcreteScale,
) -> pitch.Pitch:
    if steps == 0:
        return
    if steps > 0:
        direction = "ascending"
    else:
        direction = "descending"
        steps *= -1
    new_pitch = reference_scale.next(original_pitch, direction, steps)
    original_pitch.step = new_pitch.step
    original_pitch.octave = new_pitch.octave
    original_pitch.accidental = new_pitch.accidental
コード例 #10
0
 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
コード例 #11
0
ファイル: test_pitch.py プロジェクト: cuthbertLab/music21
    def testCopyAndDeepcopy(self):
        '''
        Test copying all objects defined in this module
        '''
        for part in sys.modules[self.__module__].__dict__:
            match = False
            for skip in ['_', '__', 'Test', 'Exception']:
                if part.startswith(skip) or part.endswith(skip):
                    match = True
            if match:
                continue
            name = getattr(sys.modules[self.__module__], part)
            # noinspection PyTypeChecker
            if callable(name) and not isinstance(name, types.FunctionType):
                try:  # see if obj can be made w/ args
                    obj = name()
                except TypeError:
                    continue
                copy.copy(obj)
                copy.deepcopy(obj)

        p1 = Pitch('C#3')
        p2 = copy.deepcopy(p1)
        self.assertIsNot(p1, p2)
        self.assertIsNot(p1.accidental, p2.accidental)
コード例 #12
0
ファイル: visualization.py プロジェクト: vug/cac
def plot_instrument_ranges(sounds):
    inst_info = {(snd.short_name, snd.low_no, snd.high_no, snd.section): None
                 for snd in sounds}.keys()
    color_map = {
        Section.PERCUSSION: "orange",
        Section.WOODWINDS: "green",
        Section.BRASS: "red",
        Section.STRINGS: "blue",
    }
    names, lows, highs, sections = zip(*inst_info)
    fig, ax = plt.subplots(figsize=(6, 6))
    ax.barh(
        y=list(range(len(names))),
        left=lows,
        width=[high - low for (low, high) in zip(lows, highs)],
        tick_label=names,
        color=[color_map[sec] for sec in sections],
    )
    # grid at Cs and Gs
    xticks = sorted(list(range(24, 111, 12)) + list(range(19, 111, 12)))
    ax.set_xticks(xticks)
    ax.set_xticklabels([Pitch(no) for no in xticks], rotation=0)
    ax.grid(axis="x", which="major")
    ax.set_title("Instrument Ranges")
    plt.tight_layout()
    plt.show()
コード例 #13
0
ファイル: make_songs.py プロジェクト: mobeets/mood-music
def get_offset_from_key(key):
    tonic, mode = key.split(' ')
    tonic = tonic.replace('b', '-')
    if mode == 'major':
        k = Key(tonic)
    else:
        k = Key(tonic.lower()).relative
    return Pitch('C').midi - k.getTonic().midi
コード例 #14
0
def main():
    parser = get_cmd_line_parser(description=__doc__)
    ParserArguments.filename(parser)
    ParserArguments.tempo(parser)
    ParserArguments.framerate(parser)
    ParserArguments.set_defaults(parser)
    ParserArguments.best(parser)
    args = parser.parse_args()
    defaults.framerate = args.framerate

    song = Stream()

    roots = 'ABCDEFG'
    scales = [scale.MajorScale, scale.MinorScale,
              scale.WholeToneScale, scale.ChromaticScale]

    print('Choosing a random scale from Major, Minor, Whole Tone, Chromatic.')
    rscale = random.choice(scales)(Pitch(random.choice(roots)))
    print('Using: %s' % rscale.name)

    print('Generating a score...')
    random_note_count = 50
    random_note_speeds = [0.5, 1]
    print('100 Random 1/8th and 1/4th notes in rapid succession...')
    for i in range(random_note_count):
        note = Note(random.choice(rscale.pitches))
        note.duration.quarterLength = random.choice(random_note_speeds)
        song.append(note)

    scale_practice_count = 4
    print('Do the scale up and down a few times... maybe %s' %
          scale_practice_count)
    rev = rscale.pitches[:]
    rev.reverse()
    updown_scale = rscale.pitches[:]
    updown_scale.extend(rev[1:-1])
    print('updown scale: %s' % updown_scale)
    for count, pitch in enumerate(cycle(updown_scale)):
        print(' note %s, %s' % (count, pitch))
        song.append(Note(pitch))
        if count >= scale_practice_count * len(updown_scale):
            break

    print('Composition finished:')
    song.show('txt')

    if args.best:
        print('Audifying the song to file "{}"...')
        wave = audify_to_file(song, args.tempo, args.filename, verbose=True)
    else:
        wave = audify_basic(song, args.tempo, verbose=True)
        print('Writing Song to file "{}"...'.format(args.filename))
        with wav_file_context(args.filename) as fout:
            fout.write_frames(wave.frames)

    return 0
コード例 #15
0
ファイル: test_pitch.py プロジェクト: cuthbertLab/music21
    def testQuarterToneA(self):
        p1 = Pitch('D#~')
        # environLocal.printDebug([p1, p1.accidental])
        self.assertEqual(str(p1), 'D#~')
        # test generation of raw musicxml output
        xmlOut = m21ToXml.GeneralObjectExporter().parse(p1).decode('utf-8')

        match = '<step>D</step><alter>1.5</alter><octave>4</octave>'
        xmlOut = xmlOut.replace(' ', '')
        xmlOut = xmlOut.replace('\n', '')
        self.assertNotEqual(xmlOut.find(match), -1)

        s = stream.Stream()
        for pStr in ['A~', 'A#~', 'A`', 'A-`']:
            p = Pitch(pStr)
            self.assertEqual(str(p), pStr)
            n = note.Note()
            n.pitch = p
            s.append(n)
        self.assertEqual(len(s), 4)
        match = [e.pitch.ps for e in s]
        self.assertEqual(match, [69.5, 70.5, 68.5, 67.5])

        s = stream.Stream()
        alterList = [
            None, 0.5, 1.5, -1.5, -0.5, 'half-sharp', 'one-and-a-half-sharp',
            'half-flat', 'one-and-a-half-flat', '~'
        ]
        sc = scale.MajorScale('c4')
        for x in range(1, 10):
            n = note.Note(sc.pitchFromDegree(x % sc.getDegreeMaxUnique()))
            n.quarterLength = 0.5
            n.pitch.accidental = Accidental(alterList[x])
            s.append(n)

        match = [str(n.pitch) for n in s.notes]
        self.assertEqual(match, [
            'C~4', 'D#~4', 'E-`4', 'F`4', 'G~4', 'A#~4', 'B`4', 'C-`4', 'D~4'
        ])

        match = [e.pitch.ps for e in s]
        self.assertEqual(
            match, [60.5, 63.5, 62.5, 64.5, 67.5, 70.5, 70.5, 58.5, 62.5])
コード例 #16
0
ファイル: __main__.py プロジェクト: napulen/romanyh
def valid_voicing(s):
    """Verifies a string of 4 space-separated pitches as a valid voicing."""
    pitchStrings = s.split()
    if len(pitchStrings) != 4:
        msg = "The voicing should have exactly 4 notes"
        raise argparse.ArgumentTypeError(msg)
    b, t, a, s = [Pitch(p) for p in pitchStrings]
    if not b <= t <= a <= s:
        msg = "The notes of the given voicing should be ordered BTAS"
        raise argparse.ArgumentTypeError(msg)
    return tuple(pitchStrings)
コード例 #17
0
ファイル: voicing.py プロジェクト: napulen/harmony
def voiceNote(noteName, pitchRange):
    """Generates voicings for a note in a given pitch range.

    Returns a list of `Pitch` objects with the same name as the note that also
    fall within the voice's range.
    """
    lowerOctave = pitchRange[0].octave
    upperOctave = pitchRange[1].octave
    for octave in range(lowerOctave, upperOctave + 1):
        n = Pitch(noteName + str(octave))
        if pitchRange[0] <= n <= pitchRange[1]:
            yield n
コード例 #18
0
ファイル: montreal.py プロジェクト: jonathanmarmor/montreal
    def __init__(self):
        self.names = ['vln', 'gtr']
        self.vln = vln = Violin()
        self.gtr = gtr = AcousticGuitar()
        self.l = [vln, gtr]
        self.d = {}
        for name, inst in zip(self.names, self.l):
            inst.nickname = name
            self.d[name] = inst

        # lowest, highest notes
        ranges = [
            ('G3', 'B6'),  # Violin
            ('E2', 'G5')  # Guitar
        ]
        for r, i in zip(ranges, self.l):
            i.lowest_note = Pitch(r[0])
            i.highest_note = Pitch(r[1])
            i.all_notes = list(frange(i.lowest_note.ps, i.highest_note.ps + 1))
            i.all_notes_24 = list(
                frange(i.lowest_note.ps, i.highest_note.ps + 1, 0.5))
コード例 #19
0
def notate_note(note):
    if note['pitch'] == 'rest':
        n = Rest()
    else:
        if isinstance(note['pitch'], list):
            pitches = []
            for pitch_number in note['pitch']:
                p = Pitch(pitch_number)
                # Force all flats
                if p.accidental.name == 'sharp':
                    p = p.getEnharmonic()
                pitches.append(p)
            n = Chord(notes=pitches)

        else:
            p = Pitch(note['pitch'])
            # Force all flats
            if p.accidental.name == 'sharp':
                p = p.getEnharmonic()
            n = Note(p)

    d = Duration()
    if note['duration'] == 0:
        d.quarterLength = .125
        d = d.getGraceDuration()
    else:
        # music21 docs say `fill` is for testing. I can't remember why I chose
        # to use it originally. It works. But not for tuplets. Maybe this blog
        # post contains a better solution:
        # http://music21-mit.blogspot.com/2015/09/durations-and-durationtuples.html
        d.fill(note['durations'])
    n.duration = d
    return n
コード例 #20
0
ファイル: test_pitch.py プロジェクト: cuthbertLab/music21
    def testUpdateAccidentalDisplaySimple(self):
        '''Test updating accidental display.
        '''
        past = [Pitch('A#3'), Pitch('C#'), Pitch('C')]

        a = Pitch('c')
        a.accidental = Accidental('natural')
        a.accidental.displayStatus = True
        self.assertEqual(a.name, 'C')
        self.assertTrue(a.accidental.displayStatus)

        a.updateAccidentalDisplay(pitchPast=past, overrideStatus=True)
        self.assertFalse(a.accidental.displayStatus)

        b = copy.deepcopy(a)
        self.assertFalse(b.accidental.displayStatus)
        self.assertEqual(b.accidental.name, 'natural')
コード例 #21
0
 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
コード例 #22
0
def freq_to_midi(freq):
    base_pitch = Pitch()
    current_interval = Interval(
        integer_interval_from(freq, base_pitch.frequency))
    return base_pitch.transpose(current_interval).midi
コード例 #23
0
ファイル: utils.py プロジェクト: cemfi/BachNet
def tensors_to_stream(outputs, config, metadata=None):
    cur_measure_number = 0
    parts = {}
    for part_name in outputs.keys():
        if part_name == 'extra':
            continue
        part = Part(id=part_name)
        parts[part_name] = part

    last_time_signature = None
    cur_time_signature = '4/4'
    for step in range(outputs['soprano'].shape[0]):
        extra = outputs['extra'][step]
        if extra[indices_extra['has_time_signature_3/4']].item() == 1:
            cur_time_signature = '3/4'
        elif extra[indices_extra['has_time_signature_4/4']].item() == 1:
            cur_time_signature = '4/4'
        elif extra[indices_extra['has_time_signature_3/2']].item() == 1:
            cur_time_signature = '3/2'
        cur_time_pos = extra[indices_extra['time_pos']].item()
        has_fermata = extra[indices_extra['has_fermata']].item() == 1

        if cur_time_pos == 1.0 or cur_measure_number == 0:
            for part_name, part in parts.items():
                part.append(Measure(number=cur_measure_number))
                if cur_measure_number == 0:
                    if part_name in ['soprano', 'alto']:
                        part[-1].append(clef.TrebleClef())
                    else:
                        part[-1].append(clef.BassClef())
                    key = int(
                        torch.argmax(
                            outputs['extra'][0, indices_extra['has_sharps_0']:
                                             indices_extra['has_sharps_11'] +
                                             1],
                            dim=0).item())
                    if key >= 6:
                        key -= 12
                    part[-1].append(KeySignature(key))
                    part[-1].append(MetronomeMark(number=90))
            cur_measure_number += 1

        if last_time_signature is None or cur_time_signature != last_time_signature:
            for part in parts.values():
                part[-1].append(TimeSignature(cur_time_signature))
            last_time_signature = cur_time_signature

        for part_name, part in parts.items():
            idx = torch.argmax(outputs[part_name][step]).item()
            if idx == indices_parts['is_continued']:
                try:
                    last_element = part[-1].flat.notesAndRests[-1]
                    cur_element = deepcopy(last_element)
                    if last_element.tie is not None and last_element.tie.type == 'stop':
                        last_element.tie = Tie('continue')
                    else:
                        last_element.tie = Tie('start')
                    cur_element.tie = Tie('stop')
                except IndexError:
                    logging.debug(
                        'Warning: "is_continued" on first beat. Replaced by rest.'
                    )
                    cur_element = Rest(quarterLength=config.time_grid)
                part[-1].append(cur_element)
            elif idx == indices_parts['is_rest']:
                part[-1].append(Rest(quarterLength=config.time_grid))
            else:
                pitch = Pitch()
                part[-1].append(Note(pitch, quarterLength=config.time_grid))
                # Set pitch value AFTER appending to measure in order to avoid unnecessary accidentals
                pitch.midi = idx + min_pitches[part_name] - len(indices_parts)

        if has_fermata:
            for part in parts.values():
                fermata = Fermata()
                fermata.type = 'upright'
                part[-1][-1].expressions.append(fermata)

    score = Score()
    if metadata is not None:
        score.append(Metadata())
        score.metadata.title = f"{metadata.title} ({metadata.number})"
        score.metadata.composer = f"Melody: {metadata.composer}\nArrangement: BachNet ({datetime.now().year})"
    for part in parts.values():
        part[-1].rightBarline = 'light-heavy'

    score.append(parts['soprano'])
    if 'alto' in parts:
        score.append(parts['alto'])
        score.append(parts['tenor'])
    score.append(parts['bass'])

    score.stripTies(inPlace=True, retainContainers=True)

    return score
コード例 #24
0
def main1():
    all_pitches = MajorScale(tonic="C").getPitches("C1", "C8")
    pitch2index = {p: ix for ix, p in enumerate(all_pitches)}
    C2 = Pitch("C2")
    C3 = Pitch("C3")
    C4 = Pitch("C4")
    C5 = Pitch("C5")
    C6 = Pitch("C6")

    def get_next_triplets(triplet: Triplet) -> Set[Triplet]:
        next_triplets = set()
        for i, pitch in enumerate(triplet.pitches):
            # TODO: improve construct_graph to accept negative values here
            for diff in [1]:
                # TODO: make this a utility function
                moved_pitch = all_pitches[pitch2index[pitch] + diff]
                if moved_pitch in triplet.pitches:
                    continue
                next_pitches = tuple(
                    p if i != j else moved_pitch for j, p in enumerate(triplet.pitches)
                )
                if (
                    not C2 <= next_pitches[0] <= C4
                    or not C3 <= next_pitches[1] <= C5
                    or not C4 <= next_pitches[2] <= C6
                ):
                    continue
                next_triplets.add(Triplet(next_pitches))
        return next_triplets

    init_pitches = (Pitch("C2"), Pitch("C3"), Pitch("C4"))
    init_triplet = Triplet(init_pitches)
    _, edges = construct_graph(init_triplet, get_next_triplets, 48)
    G = nx.DiGraph()
    G.add_edges_from(edges)
    plot_hierarchical_graph(G)  # blocking

    progression = []
    chord = init_triplet
    while chord:
        progression.append(chord)
        successors = list(G.successors(chord))
        if successors:
            chord = successors[len(successors) // 2]
        else:
            chord = None
    print(progression)

    sounds, _ = midi.initialize()

    _ = query_sound(sounds, Section.STRINGS, Instrument.BASSES, Articulation.SPICCATO)
    celli = query_sound(
        sounds, Section.STRINGS, Instrument.CELLI, Articulation.SPICCATO
    )
    violas = query_sound(
        sounds, Section.STRINGS, Instrument.VIOLAS, Articulation.SPICCATO
    )
    violins = query_sound(
        sounds, Section.STRINGS, Instrument.VIOLINS_1, Articulation.SPICCATO
    )

    _ = query_sound(sounds, Section.BRASS, Instrument.TUBA, Articulation.STACCATISSIMO)
    trombones = query_sound(
        sounds, Section.BRASS, Instrument.TENOR_TROMBONES_A3, Articulation.STACCATISSIMO
    )
    trumpets = query_sound(
        sounds, Section.BRASS, Instrument.TRUMPETS_A3, Articulation.STACCATISSIMO
    )
    horns = query_sound(
        sounds, Section.BRASS, Instrument.HORNS_A4, Articulation.STACCATISSIMO
    )

    strings = (celli, violas, violins)
    brass = (trombones, trumpets, horns)
    dt = 0.175
    dur = 0.125

    p = Player()
    for measure, triplet in enumerate(progression):
        for beat in range(4):
            for note, snd in zip(triplet.pitches, strings):
                p.schedule(snd, Pitch(note).midi, (beat + measure * 4) * dt, dur, 100)
        for note, snd in zip(triplet.pitches, brass):
            p.schedule(snd, Pitch(note).midi, measure * 4 * dt, dur * 2, 100)
            p.schedule(snd, Pitch(note).midi, (measure * 4 + 3.25) * dt, dur * 0.5, 100)
    p.play()
コード例 #25
0
 def __post_init__(self):
     self.low_no = Pitch(self.low).midi
     self.high_no = Pitch(self.high).midi
コード例 #26
0
ファイル: voicing.py プロジェクト: napulen/harmony
import copy
import argparse
import itertools
from fractions import Fraction

from music21.note import Note
from music21.pitch import Pitch
from music21.chord import Chord
from music21.roman import RomanNumeral
from music21.key import Key
from music21.meter import TimeSignature
from music21.clef import BassClef, TrebleClef
from music21.instrument import Piano
from music21.stream import Part, Score, Voice

SOPRANO_RANGE = (Pitch("C4"), Pitch("G5"))
ALTO_RANGE = (Pitch("G3"), Pitch("C5"))
TENOR_RANGE = (Pitch("C3"), Pitch("G4"))
BASS_RANGE = (Pitch("E2"), Pitch("C4"))


def voiceNote(noteName, pitchRange):
    """Generates voicings for a note in a given pitch range.

    Returns a list of `Pitch` objects with the same name as the note that also
    fall within the voice's range.
    """
    lowerOctave = pitchRange[0].octave
    upperOctave = pitchRange[1].octave
    for octave in range(lowerOctave, upperOctave + 1):
        n = Pitch(noteName + str(octave))
コード例 #27
0
ファイル: movement_2.py プロジェクト: jonathanmarmor/penguin
    def __init__(self, n, piece, movement, quadlet, couplet, lines):
        self.n = n
        self.piece = piece
        self.movement = movement
        self.quadlet = quadlet
        self.couplet = couplet
        self.lines = lines
        self.duration = quadlet.phrase_duration

        self.first = False
        if n == 1 and couplet.n == 1:
            self.first = True

        for line in lines:
            # print ('.' * int(line['rhythm'][0] * 2)) + ('-' * int(line['rhythm'][1] * 2)) + ('.' * int(line['rhythm'][2] * 2))
            part = piece.parts.d[line['instrument']]

            measure = Measure()
            if self.first and quadlet.previous_phrase_duration != self.duration:
                ts = TimeSignature('{}/4'.format(self.duration), self.duration)

                # ts.beatSequence.partitionByList(subdivide(self.duration, 4))
                # for i, b in enumerate(ts.beatSequence):
                #     if b.duration.quarterLength == 4:
                #         ts.beatSequence[i] = b.subdivide(2)
                #         # ts.beatSequence[i][0] = b.subdivide(2)
                #         # ts.beatSequence[i][1] = b.subdivide(2)
                #     elif b.duration.quarterLength == 3:
                #         ts.beatSequence[i] = b.subdivideByList([2, 1])
                #         # ts.beatSequence[i][0] = ts.beatSequence[i].subdivide(2)
                #     elif b.duration.quarterLength == 2:
                #         ts.beatSequence[i] = b.subdivide(2)
                measure.timeSignature = ts

            r1_dur, note_dur, r2_dur = line['rhythm']

            line['notes'] = []

            if r1_dur > 0:
                line['notes'].append({
                    'duration': r1_dur,
                    'pitch': 'rest'
                })

            line['notes'].append({
                'duration': note_dur,
                'pitch': line['pitch']
            })

            if r2_dur > 0:
                line['notes'].append({
                    'duration': r2_dur,
                    'pitch': 'rest'
                })

            self.fix_durations(line['notes'])

            for note in line['notes']:
                if note['pitch'] == 'rest':
                    n = Rest()
                else:
                    p = Pitch(note['pitch'])
                    # Force all flats
                    if p.accidental.name == 'sharp':
                        p = p.getEnharmonic()
                    n = Note(p)

                    # TODO add slurs
                    # TODO add glissandos
                    # TODO add -50 cent marks

                d = Duration()
                d.fill(note['durations'])
                n.duration = d

                measure.append(n)


            # if r1_dur > 0:
            #     r1 = Rest()
            #     r1.duration = Duration(r1_dur)
            #     measure.append(r1)

            # p = Pitch(line['pitch'])
            # # Force all flats
            # if p.accidental.name == 'sharp':
            #     p = p.getEnharmonic()

            # note = Note(p)
            # note.duration = Duration(note_dur)
            # measure.append(note)

            # if r2_dur > 0:
            #     r2 = Rest()
            #     r2.duration = Duration(r2_dur)
            #     measure.append(r2)


            part.append(measure)

        # Put full measure rests in instruments that aren't playing
        playing = [line['instrument'] for line in lines]
        resting = [i for i in piece.instruments.names if i not in playing]

        for i in resting:
            # print '.' * self.duration * 2
            part = piece.parts.d[i]

            measure = Measure()
            if self.first and quadlet.previous_phrase_duration != self.duration:
                ts = TimeSignature('{}/4'.format(self.duration), self.duration)

                # ts.beatSequence.subdivideNestedHierarchy(3)

                # ts.beatSequence.partitionByList(subdivide(self.duration, 4))
                # for i, b in enumerate(ts.beatSequence):
                #     if b.duration.quarterLength == 4:
                #         ts.beatSequence[i] = b.subdivide(2)
                #         # ts.beatSequence[i][0] = b.subdivide(2)
                #         # ts.beatSequence[i][1] = b.subdivide(2)
                #     elif b.duration.quarterLength == 3:
                #         ts.beatSequence[i] = b.subdivideByList([2, 1])
                #         # ts.beatSequence[i][0] = ts.beatSequence[i].subdivide(2)
                #     elif b.duration.quarterLength == 2:
                #         ts.beatSequence[i] = b.subdivide(2)
                measure.timeSignature = ts

            r = Rest()
            r.duration = Duration(self.duration)
            measure.append(r)

            # fixed_measure = measure.sliceByBeat()
            # part.append(fixed_measure)

            part.append(measure)
コード例 #28
0
ファイル: voicing.py プロジェクト: napulen/romanyh
    Rule.SEVENTH_UNPREPARED: Cost.BAD,
    Rule.SEVENTH_UNRESOLVED: Cost.VERYBAD,
    Rule.LEADINGTONE_UNRESOLVED: Cost.VERYBAD,
    # voicing rules
    Rule.VERTICAL_NOT_DOUBLINGROOT: Cost.NOTIDEAL,
    Rule.VERTICAL_SEVENTH_MISSINGNOTE: Cost.MAYBEBAD,
}


def applyRule(rule):
    """Given a rule enum, provide the cost of breaking that rule."""
    return _ruleCostMapping[rule]


voice_ranges = {
    PartEnum.SOPRANO: (Pitch("C4"), Pitch("G5")),
    PartEnum.ALTO: (Pitch("G3"), Pitch("D5")),
    PartEnum.TENOR: (Pitch("C3"), Pitch("G4")),
    PartEnum.BASS: (Pitch("E2"), Pitch("C4")),
}


verticalHorizontalMapping = {
    IntervalV.ALTO_SOPRANO: (PartEnum.SOPRANO, PartEnum.ALTO),
    IntervalV.TENOR_SOPRANO: (PartEnum.TENOR, PartEnum.SOPRANO),
    IntervalV.TENOR_ALTO: (PartEnum.TENOR, PartEnum.ALTO),
    IntervalV.BASS_SOPRANO: (PartEnum.BASS, PartEnum.SOPRANO),
    IntervalV.BASS_ALTO: (PartEnum.BASS, PartEnum.ALTO),
    IntervalV.BASS_TENOR: (PartEnum.BASS, PartEnum.TENOR),
}
コード例 #29
0
ファイル: tools.py プロジェクト: KubbyDev/MusicBox
def midi_to_name(midi):
    return Pitch(midi).nameWithOctave
コード例 #30
0
from music21.instrument import fromString as get_instrument
from music21.clef import BassClef

timestamp = datetime.datetime.utcnow()
metadata = Metadata()
metadata.title = 'The Title'
metadata.composer = 'Jonathan Marmor'
metadata.date = timestamp.strftime('%Y/%m/%d')

score = Score()
score.insert(0, metadata)

part = Part()
parts = [part]

oboe = get_instrument('oboe')
part.insert(0, oboe)
score.insert(0, part)
score.insert(0, StaffGroup(parts))

for dur in [[1, .5], [.25], [.25, 2]]:
    pitch = Pitch(60)
    note = Note(pitch)
    duration = Duration()
    duration.fill(dur)
    note.duration = duration

    part.append(note)

score.show('musicxml', '/Applications/Sibelius 7.5.app')
コード例 #31
0
ファイル: key.py プロジェクト: arikast/music21
    def transposePitchFromC(self, p: pitch.Pitch, *, inPlace=False) -> Optional[pitch.Pitch]:
        '''
        Takes a pitch in C major and transposes it so that it has
        the same step position in the current key signature.

        >>> ks = key.KeySignature(-3)
        >>> p1 = pitch.Pitch('B')
        >>> p2 = ks.transposePitchFromC(p1)
        >>> p2.name
        'D'

        Original pitch is unchanged:

        >>> p1.name
        'B'

        >>> ks2 = key.KeySignature(2)
        >>> p2 = ks2.transposePitchFromC(p1)
        >>> p2.name
        'C#'

        For out of scale pitches the relationship still works; note also that
        original octave is preserved.

        >>> p3 = pitch.Pitch('G-4')
        >>> p4 = ks.transposePitchFromC(p3)
        >>> p4.nameWithOctave
        'B--4'

        If inPlace is True then nothing is returned and the original pitch is
        modified.

        >>> p5 = pitch.Pitch('C5')
        >>> ks.transposePitchFromC(p5, inPlace=True)
        >>> p5.nameWithOctave
        'E-5'

        New method in v6.
        '''
        transInterval = None
        transTimes = 0

        originalOctave = p.octave
        if not inPlace:
            p = copy.deepcopy(p)

        if self.sharps == 0:
            if inPlace:
                return
            else:
                return p
        elif self.sharps < 0:
            transTimes = abs(self.sharps)
            transInterval = interval.Interval('P4')
        else:
            transTimes = self.sharps
            transInterval = interval.Interval('P5')

        for i in range(transTimes):
            transInterval.transposePitch(p, inPlace=True)

        if originalOctave is not None:
            p.octave = originalOctave

        if not inPlace:
            return p
コード例 #32
0
ファイル: montreal.py プロジェクト: jonathanmarmor/montreal
    def __init__(self, ranges=False):
        score = self.score = Score()
        self.instruments = self.i = Instruments()
        self.parts = Parts(self.i)


        # Make Metadata
        timestamp = datetime.datetime.utcnow()
        metadata = Metadata()
        metadata.title = 'Early Montreal'
        metadata.composer = 'Jonathan Marmor'
        metadata.date = timestamp.strftime('%Y/%m/%d')
        score.insert(0, metadata)

        [score.insert(0, part) for part in self.parts.l]
        score.insert(0, StaffGroup(self.parts.l))

        if ranges:
            # Don't make a piece, just show the instrument ranges
            for inst, part in zip(self.instruments.l, self.parts.l):
                measure = Measure()
                measure.timeSignature = TimeSignature('4/4')
                low = Note(inst.lowest_note)
                measure.append(low)
                high = Note(inst.highest_note)
                measure.append(high)
                part.append(measure)
            return


        # 18 to 21 minutes
        piece_duration_minutes = scale(random.random(), 0, 1, 18, 21)

        # Make the "songs"
        songs = []
        total_minutes = 0
        n = 1
        while total_minutes < piece_duration_minutes:
            print 'Song {}'.format(n)
            n += 1
            song = Song(self)
            songs.append(song)
            total_minutes += song.duration_minutes

        # Make notation
        previous_duration = None
        for song in songs:
            for bar in song.bars:
                for part in bar.parts:
                    measure = Measure()
                    if bar.tempo:
                        measure.insert(0, MetronomeMark(number=bar.tempo, referent=Duration(1)))
                        measure.leftBarline = 'double'
                    if bar.duration != previous_duration:
                        ts = TimeSignature('{}/4'.format(bar.duration))
                        measure.timeSignature = ts

                    # Fix Durations
                    durations = [note['duration'] for note in part['notes']]

                    components_list = split_at_beats(durations)
                    components_list = [join_quarters(note_components) for note_components in components_list]
                    for note, components in zip(part['notes'], components_list):
                        note['durations'] = components


                    for note in part['notes']:
                        if note['pitch'] == 'rest':
                            n = Rest()
                        if isinstance(note['pitch'], list):
                            pitches = []
                            for pitch_number in note['pitch']:
                                p = Pitch(pitch_number)
                                # Force all flats
                                if p.accidental.name == 'sharp':
                                    p = p.getEnharmonic()
                                pitches.append(p)
                            n = Chord(notes=pitches)

                            # TODO add slurs
                            # TODO add glissandos
                            # TODO add -50 cent marks


                        else:
                            p = Pitch(note['pitch'])
                            # Force all flats
                            if p.accidental.name == 'sharp':
                                p = p.getEnharmonic()
                            n = Note(p)

                            # TODO add slurs
                            # TODO add glissandos
                            # TODO add -50 cent marks

                        d = Duration()
                        if note['duration'] == 0:
                            d.quarterLength = .5
                            d = d.getGraceDuration()
                        else:
                            d.fill(note['durations'])
                        n.duration = d

                        measure.append(n)

                    self.parts.d[part['instrument_name']].append(measure)
                previous_duration = bar.duration
コード例 #33
0
ファイル: voicing.py プロジェクト: napulen/romanyh
def getPitchFromString(p):
    """Cached method. Calls music21.pitch.Pitch()."""
    cachedGetPitchFromString.append(p)
    return Pitch(p)
コード例 #34
0
ファイル: movement_1.py プロジェクト: jonathanmarmor/penguin
    def __init__(self, number, piece, movement):
        self.number = number
        self.piece = piece
        self.movement = movement

        instrument_opts = piece.instruments.names[:]

        self.note_opts = {}
        for name in instrument_opts:
            self.note_opts[name] = piece.i.d[name].all_notes

        form = self.form = song_forms.choose()

        self.duration = len(form) * 4

        self.type = 'solo'
        if number % 2:
            self.type = 'ensemble'

        if self.type == 'solo':
            if len(movement.solo_ensemble_options) == 0:
                movement.solo_ensemble_options = piece.i.get_unison_ensembles(min_notes=6)
                print 'Hey, we ran out of unison ensembles! Cool!'
            solo_ensemble_hash = random.choice(movement.solo_ensemble_options.keys())
            self.soloists = movement.solo_ensemble_options[solo_ensemble_hash]['instruments']
            self.soloist_names = [s.nickname for s in self.soloists]
            self.soloists_shared_notes = movement.solo_ensemble_options[solo_ensemble_hash]['notes']
            # Remove chosen ensemble from options
            del movement.solo_ensemble_options[solo_ensemble_hash]

            # remove chosen soloists from instrument options for the song
            for soloist in self.soloist_names:
                instrument_opts.remove(soloist)

            self.accompanist_names = instrument_opts

            len_accompanists = len(self.accompanist_names)
            if len_accompanists == 2:
                ensemble_size = 2
            elif len_accompanists == 3:
                ensemble_size = random.choice([2, 3])
            elif len_accompanists == 4:
                ensemble_size = random.choice([1, 2, 3, 4])

            self.accompanist_names = random.sample(self.accompanist_names, ensemble_size)


        else:
            # who plays, who sits out?
            # ensemble_size = weighted_choice([3, 4, 5, 6], [1, 4, 5, 4])
            # self.ensemble_names = random.sample(instrument_opts, ensemble_size)

            # Everyone plays
            self.ensemble_names = instrument_opts


        # make a phrase for each unique part of the form (eg, an `a` in `abacabac`)
        unique_phrases = []
        for f in set(form):
            if self.type == 'solo':
                PhraseClass = SoloPhrase
            elif self.type == 'ensemble':
                PhraseClass = EnsemblePhrase
            unique_phrases.append(PhraseClass(piece, movement, self))

        # Copy the phrases in the order specified by form
        phrases = []
        for f in form:
            phrases.append(unique_phrases[f])

        # Render phrases as music21 objects
        for phrase in phrases:
            for part in phrase.parts:
                measure = Measure()
                if movement.first_measure:
                    ts = TimeSignature('4/4')

                    # ts.beatSequence = ts.beatSequence.subdivide(4)
                    ts.beamSequence = ts.beamSequence.subdivide(4)


                    # ts.beatSequence.partitionByList(subdivide(self.duration, 4))
                    # for i, b in enumerate(ts.beatSequence):
                    #     if b.duration.quarterLength == 4:
                    #         ts.beatSequence[i] = b.subdivide(2)
                    #         # ts.beatSequence[i][0] = b.subdivide(2)
                    #         # ts.beatSequence[i][1] = b.subdivide(2)
                    #     elif b.duration.quarterLength == 3:
                    #         ts.beatSequence[i] = b.subdivideByList([2, 1])
                    #         # ts.beatSequence[i][0] = ts.beatSequence[i].subdivide(2)
                    #     elif b.duration.quarterLength == 2:
                    #         ts.beatSequence[i] = b.subdivide(2)




                    measure.timeSignature = ts

                    # ts.getBeams()

                self.fix_durations(part['notes'])

                for note in part['notes']:
                    if note['pitch'] == 'rest':
                        n = Rest()
                    else:
                        p = Pitch(note['pitch'])
                        # Force all flats
                        if p.accidental.name == 'sharp':
                            p = p.getEnharmonic()
                        n = Note(p)

                        # TODO add slurs
                        # TODO add glissandos
                        # TODO add -50 cent marks

                    d = Duration()
                    d.fill(note['durations'])
                    n.duration = d

                    measure.append(n)

                # if len(measure.notesAndRests) > 1:
                #     measure.sliceByBeat(inPlace=True)

                # measure.makeBeams(inPlace=True)

                piece.parts.d[part['instrument_name']].append(measure)
            movement.first_measure = False