Пример #1
0
 def _get_sounding_pitches(self):
     if "sounding pitch" in inspect(self).indicators(str):
         return self.written_pitches
     else:
         instrument = self._get_effective(instruments.Instrument)
         if instrument:
             sounding_pitch = instrument.middle_c_sounding_pitch
         else:
             sounding_pitch = abjad_pitch.NamedPitch("C4")
         interval = abjad_pitch.NamedPitch("C4") - sounding_pitch
         sounding_pitches = [
             interval.transpose(pitch) for pitch in self.written_pitches
         ]
         return tuple(sounding_pitches)
Пример #2
0
 def _to_relative_octave(self, pitch, reference):
     if pitch.pitch_class.number > reference.pitch_class.number:
         pair = (pitch.pitch_class.name, reference.octave.number)
         up_pitch = abjad_pitch.NamedPitch(pair)
         pair = (pitch.pitch_class.name, reference.octave.number - 1)
         down_pitch = abjad_pitch.NamedPitch(pair)
         up_octave = up_pitch.octave.number
         down_octave = down_pitch.octave.number
     else:
         pair = (pitch.pitch_class.name, reference.octave.number + 1)
         up_pitch = abjad_pitch.NamedPitch(pair)
         pair = (pitch.pitch_class.name, reference.octave.number)
         down_pitch = abjad_pitch.NamedPitch(pair)
         up_octave = up_pitch.octave.number
         down_octave = down_pitch.octave.number
     if abs(
             float(up_pitch._get_diatonic_pitch_number()) -
             float(reference._get_diatonic_pitch_number())) < abs(
                 float(down_pitch._get_diatonic_pitch_number()) -
                 float(reference._get_diatonic_pitch_number())):
         pair = (
             up_pitch.pitch_class.name,
             up_octave + pitch.octave.number - 3,
         )
         pitch = abjad_pitch.NamedPitch(pair)
     else:
         pair = (
             down_pitch.pitch_class.name,
             down_octave + pitch.octave.number - 3,
         )
         pitch = abjad_pitch.NamedPitch(pair)
     return pitch
Пример #3
0
 def recurse(music):
     key_signatures = music._get_indicators(
         abjad_indicators.KeySignature)
     if key_signatures:
         for x in key_signatures:
             tonic = abjad_pitch.NamedPitch((x.tonic.name, 4))
             # TODO: cheating to assign to a read-only property
             x._tonic = abjad_parser.LilyPondParser._transpose_enharmonically(
                 from_pitch, to_pitch, tonic).pitch_class
     if isinstance(music, core.Note):
         music.written_pitch = abjad_parser.LilyPondParser._transpose_enharmonically(
             from_pitch, to_pitch, music.written_pitch)
     elif isinstance(music, core.Chord):
         for note_head in music.note_heads:
             note_head.written_pitch = abjad_parser.LilyPondParser._transpose_enharmonically(
                 from_pitch, to_pitch, note_head.written_pitch)
     elif isinstance(music, core.Container):
         for x in music:
             recurse(x)
Пример #4
0
 def p_pitch__PITCHNAME__commas(self, p):
     """
     pitch : PITCHNAME commas
     """
     p[0] = abjad_pitch.NamedPitch(str(p[1]) + ',' * p[2])
Пример #5
0
 def p_pitch__PITCHNAME__apostrophes(self, p):
     """
     pitch : PITCHNAME apostrophes
     """
     p[0] = abjad_pitch.NamedPitch(str(p[1]) + "'" * p[2])
Пример #6
0
 def p_pitch__PITCHNAME(self, p):
     """
     pitch : PITCHNAME
     """
     p[0] = abjad_pitch.NamedPitch(str(p[1]))
Пример #7
0
    def __init__(
        self, *arguments, multiplier: typings.DurationTyping = None, tag: Tag = None,
    ) -> None:
        from abjad.ly import drums
        from .Note import Note

        assert len(arguments) in (0, 1, 2)
        self._note_heads = NoteHeadList(client=self)
        if len(arguments) == 1 and isinstance(arguments[0], str):
            string = f"{{ {arguments[0]} }}"
            parsed = parse(string)
            assert len(parsed) == 1 and isinstance(parsed[0], Leaf)
            arguments = tuple([parsed[0]])
        are_cautionary: typing.List[typing.Optional[bool]] = []
        are_forced: typing.List[typing.Optional[bool]] = []
        are_parenthesized: typing.List[typing.Optional[bool]] = []
        if len(arguments) == 1 and isinstance(arguments[0], Leaf):
            leaf = arguments[0]
            written_pitches = []
            written_duration = leaf.written_duration
            if multiplier is None:
                multiplier = leaf.multiplier
            # TODO: move to dedicated from_note() constructor:
            if isinstance(leaf, Note) and leaf.note_head is not None:
                written_pitches.append(leaf.note_head.written_pitch)
                are_cautionary = [leaf.note_head.is_cautionary]
                are_forced = [leaf.note_head.is_forced]
                are_parenthesized = [leaf.note_head.is_parenthesized]
            elif isinstance(leaf, Chord):
                written_pitches.extend(x.written_pitch for x in leaf.note_heads)
                are_cautionary = [x.is_cautionary for x in leaf.note_heads]
                are_forced = [x.is_forced for x in leaf.note_heads]
                are_parenthesized = [x.is_parenthesized for x in leaf.note_heads]
        # TODO: move to dedicated constructor:
        elif len(arguments) == 2:
            written_pitches, written_duration = arguments
            if isinstance(written_pitches, str):
                written_pitches = [x for x in written_pitches.split() if x]
            elif isinstance(written_pitches, type(self)):
                written_pitches = written_pitches.written_pitches
        elif len(arguments) == 0:
            written_pitches = [abjad_pitch.NamedPitch(_) for _ in [0, 4, 7]]
            written_duration = Duration(1, 4)
        else:
            raise ValueError(f"can not initialize chord from {arguments!r}.")
        Leaf.__init__(self, written_duration, multiplier=multiplier, tag=tag)
        if not are_cautionary:
            are_cautionary = [None] * len(written_pitches)
        if not are_forced:
            are_forced = [None] * len(written_pitches)
        if not are_parenthesized:
            are_parenthesized = [None] * len(written_pitches)
        for written_pitch, is_cautionary, is_forced, is_parenthesized in zip(
            written_pitches, are_cautionary, are_forced, are_parenthesized
        ):
            if not is_cautionary:
                is_cautionary = None
            if not is_forced:
                is_forced = None
            if not is_parenthesized:
                is_parenthesized = None
            if written_pitch not in drums:
                note_head = NoteHead(
                    written_pitch=written_pitch,
                    is_cautionary=is_cautionary,
                    is_forced=is_forced,
                    is_parenthesized=is_parenthesized,
                )
            else:
                assert isinstance(written_pitch, str), repr(written_pitch)
                note_head = DrumNoteHead(
                    written_pitch=written_pitch,
                    is_cautionary=is_cautionary,
                    is_forced=is_forced,
                    is_parenthesized=is_parenthesized,
                )
            self._note_heads.append(note_head)
        if len(arguments) == 1 and isinstance(arguments[0], Leaf):
            self._copy_override_and_set_from_leaf(arguments[0])
Пример #8
0
    def _transpose_enharmonically(pitch_a, pitch_b, pitch_c):
        """
        Transpose ``pitch_c`` by the distance between ``pitch_b``
        and ``pitch_a1``.

        This function was reverse-engineered from LilyPond's source code.

        Returns named pitch.
        """

        def normalize_alteration(step, alteration):
            while 2.0 < alteration:
                alteration -= step_size(step)
                step += 1.0
            while alteration < -2.0:
                step -= 1.0
                alteration += step_size(step)
            return step, alteration

        def normalize_octave(octave, step):
            normalized_step = step % len(scale)
            octave += (step - normalized_step) / len(scale)
            return octave, normalized_step

        def step_size(step):
            normalized_step = step % len(scale)
            if normalized_step == 6:
                return 1.0  # b to c
            return scale[normalized_step + 1] - scale[normalized_step]

        if not isinstance(pitch_a, abjad_pitch.NamedPitch):
            pitch_a = abjad_pitch.NamedPitch(pitch_a)
        if not isinstance(pitch_b, abjad_pitch.NamedPitch):
            pitch_b = abjad_pitch.NamedPitch(pitch_b)
        if not isinstance(pitch_c, abjad_pitch.NamedPitch):
            pitch_c = abjad_pitch.NamedPitch(pitch_c)
        scale = [0.0, 2.0, 4.0, 5.0, 7.0, 9.0, 11.0]
        a_oct, a_step = (
            pitch_a.octave.number,
            pitch_a._get_diatonic_pc_number(),
        )
        b_oct, b_step = (
            pitch_b.octave.number,
            pitch_b._get_diatonic_pc_number(),
        )
        c_oct, c_step, c_alt = (
            pitch_c.octave.number,
            pitch_c._get_diatonic_pc_number(),
            pitch_c.accidental.semitones,
        )
        d_oct, d_step, d_tones = (
            b_oct - a_oct,
            b_step - a_step,
            float(pitch_b.number) - float(pitch_a.number),
        )
        tmp_alt = float(pitch_c.number) + d_tones
        # print 'TMP_ALT: %f' % tmp_alt
        new_oct = c_oct + d_oct
        new_step = c_step + d_step
        new_alt = c_alt
        # print 'NEW:', new_oct, new_step, new_alt
        new_step, new_alt = normalize_alteration(new_step, new_alt)
        new_oct, new_step = normalize_octave(new_oct, new_step)
        # print 'NEW(norm):', new_oct, new_step, new_alt
        octave_ticks = str(abjad_pitch.Octave(new_oct))
        pitch_class_name = abjad_pitch.constants._diatonic_pc_number_to_diatonic_pc_name[
            new_step % 7
        ]
        # pitch_class_name = str(abjad_pitch.NamedDiatonicPitchClass(
        #    int(new_step)))
        accidental = str(abjad_pitch.Accidental(new_alt))
        tmp_pitch = abjad_pitch.NamedPitch(pitch_class_name + accidental + octave_ticks)
        # print 'TMP(pitch): %r' % tmp_pitch
        new_alt += tmp_alt - float(tmp_pitch.number)
        # print 'NEW(alt): %f' % new_alt
        new_step, new_alt = normalize_alteration(new_step, new_alt)
        new_oct, new_step = normalize_octave(new_oct, new_step)
        # print 'NEW(norm):', new_oct, new_step, new_alt
        octave_ticks = str(abjad_pitch.Octave(new_oct))
        # pitch_class_name = str(abjad_pitch.NamedDiatonicPitchClass(
        #    int(new_step)))
        pitch_class_name = abjad_pitch.constants._diatonic_pc_number_to_diatonic_pc_name[
            new_step % 7
        ]
        accidental = str(abjad_pitch.Accidental(new_alt))
        return abjad_pitch.NamedPitch(pitch_class_name + accidental + octave_ticks)