Case Study II: Jazz Rhythmic Patterns

Case Study II: Jazz Rhythmic Patterns#

Jazz Rhythmic Patterns is structurally smaller than the other projects, but it is useful for a technical report because it shows a different kind of musical abstraction. Instead of generating a large score from many interlocking parameters, it defines a small library of one-measure rhythmic cells. Those cells can be repeated, rendered, and reused in other contexts.

This package works as a compositional vocabulary source. It also works as a simple example of how musical ideas can be encoded as reusable Python functions. Each pattern returns a short list of notes and rests. The score builder then places several staves one under another so the patterns can be compared visually.

Download#

Format

Link

PDF

jazz-rhythms.pdf

LilyPond

jazz-rhythms.ly

MIDI

jazz-rhythms.midi

WAV

Not published for this score

Listen#

Note

A WAV player is not available for this score yet. Audio support for this case study is planned.

Score Preview#

First page preview of Jazz Rhythmic Patterns

The pattern functions are intentionally small:

One of the reusable rhythm cells in the jazz rhythm package.#
def charleston():
    """Return a one-measure Charleston rhythm."""
    return [
        abjad.Note("c'4."),
        abjad.Note("c'8"),
        abjad.Rest("r4"),
        abjad.Rest("r4"),
    ]

The score layer is equally direct:

Assembly of the jazz rhythm comparison score.#
def build_lilypond_file():
    """Build the LilyPond file for the jazz rhythm score."""
    score = abjad.Score([], name="Score")
    score.append(_make_staff("Charleston Staff", "Charleston", rhythms.charleston))
    score.append(
        _make_staff(
            "Charleston Extended Staff",
            "Charleston Extended (and of 4)",
            rhythms.charleston_extended,
        )
    )
    score.append(
        _make_staff(
            "Anticipation Staff",
            "Anticipation (push to 1)",
            rhythms.anticipation,
        )
    )
    score.append(_make_staff("Two Beat Staff", "Two Beat Comping", rhythms.two_beat))
    score.append(
        _make_staff(
            "Syncopated Staff",
            "Syncopated (off-beats)",
            rhythms.syncopated,
        )
    )
    score.append(
        _make_lyric_staff(
            "Swing Two Four Staff",
            "Swing on 2 and 4",
            rhythms.swing_two_four,
            "doodle LA doodle LA",
        )
    )

    header_block = abjad.Block(name="header")
    header_block.items.append(rf'title = "{TITLE}"')
    header_block.items.append(rf'composer = "{COMPOSER}"')
    header_block.items.append(r"tagline = ##f")

    layout_block = abjad.Block(name="layout")
    layout_block.items.append(r"indent = 2.0\cm")
    layout_block.items.append(
        r"""
        \context {
            \Score
            \override VerticalAxisGroup.default-staff-staff-spacing.basic-distance = #14
            \override VerticalAxisGroup.default-staff-staff-spacing.minimum-distance = #10
            \override VerticalAxisGroup.default-staff-staff-spacing.padding = #3
        }
        """
    )

    midi_block = abjad.Block(name="midi")

    score_block = abjad.Block(name="score")
    score_block.items.append(score)
    score_block.items.append(layout_block)
    score_block.items.append(midi_block)

    return abjad.LilyPondFile(items=[header_block, score_block])

This package matters because it shows that the repository does not only support finished scores and large generators. It also supports smaller compositional tools. In a technical report, that helps show the full range of the codebase.