Skip to content

Music: a tala goes round

Music: a tala goes round

Run it here, in your browser

A tala is a cycle of beats that comes round again and again. Here the bols sit round a circle, and the beat playing now glows. The sam, beat 1, is marked X, and a wave is marked 0. Keys 1 to 6 pick a tala. (This one uses real time, so the picture changes from run to run.)

How it works

  • A tala is a repeating pattern of beats. The beats fall in groups called vibhags. You clap at the start of some groups (tali) and wave at the start of others (khali). Beat 1 is the sam, where the cycle begins and lands. A bol is the syllable a tabla player says for one beat, and the theka is the whole pattern of bols.
  • f.talas() lists the six talas. f.tala_info(name) gives .beats, .vibhag, .tali, .khali, .sam and .bols.
  • f.tala(info.name, tempo=TEMPO) makes one cycle with simple drum sounds. choose() stops the old cycle, makes a new one and loops it.
  • Each frame, cycle.current_time() divided by the length of a beat says which beat is playing.
  • Each bol sits at an angle on the circle, found with math.cos() and math.sin(). The beat that is playing glows gold.
  • marks() decides the sign over each beat: X for the sam, 0 for a wave and 2, 3, ... for the other claps. key_pressed() reads the keys 1 to 6.

Make it yours

  • Change TEMPO. A bigger number is faster.
  • Start with another tala: change choose(0) in setup() to choose(2).
  • Change the colour of the glow, f.fill(255, 200, 80, 90), or its size, 64.
  • Print the bols when a tala is chosen: add print(info.bols) to the end of choose().
  • Change the radius 150 of the circle. It is used for both x and y in draw().

The code

Copy it into a file and run it.

"""Music: a tala goes round

A tala is a cycle of beats that comes round again and again. Here the bols sit round a circle,
and the beat playing now glows. The sam, beat 1, is marked X, and a wave is marked 0. Keys 1 to
6 pick a tala.

How it works:
- A tala is a repeating pattern of beats. The beats fall in groups called vibhags. You clap at the
  start of some groups (tali) and wave at the start of others (khali). Beat 1 is the sam, where
  the cycle begins and lands. A bol is the syllable a tabla player says for one beat, and the
  theka is the whole pattern of bols.
- f.talas() lists the six talas. f.tala_info(name) gives .beats, .vibhag, .tali, .khali, .sam
  and .bols.
- f.tala(info.name, tempo=TEMPO) makes one cycle with simple drum sounds. choose() stops the old
  cycle, makes a new one and loops it.
- Each frame, cycle.current_time() divided by the length of a beat says which beat is playing.
- Each bol sits at an angle on the circle, found with math.cos() and math.sin(). The beat that
  is playing glows gold.
- marks() decides the sign over each beat: X for the sam, 0 for a wave and 2, 3, ... for the other
  claps. key_pressed() reads the keys 1 to 6.

Make it yours:
- Change TEMPO. A bigger number is faster.
- Start with another tala: change choose(0) in setup() to choose(2).
- Change the colour of the glow, f.fill(255, 200, 80, 90), or its size, 64.
- Print the bols when a tala is chosen: add print(info.bols) to the end of choose().
- Change the radius 150 of the circle. It is used for both x and y in draw().
"""
# gallery: time-dependent
import math

import funground as f

TEMPO = 80
NAMES = f.talas()
info = None
cycle = None


def choose(index):
    global info, cycle
    if cycle:
        cycle.stop()
    info = f.tala_info(NAMES[index])
    cycle = f.tala(info.name, tempo=TEMPO)
    cycle.loop()


def setup():
    f.size(560, 480)
    choose(0)


def key_pressed():
    if f.key and f.key in "123456":
        choose(int(f.key) - 1)


def marks():
    """The sign over each beat: X for the sam, 0 for a wave, 2, 3, ... for the other claps."""
    out = {}
    clap = 2
    for beat in sorted(info.tali + info.khali):
        if beat == info.sam:
            out[beat] = "X 0" if beat in info.khali else "X"
        elif beat in info.khali:
            out[beat] = "0"
        else:
            out[beat] = str(clap)
            clap += 1
    return out


def draw():
    f.background("#10202a")
    now = int(cycle.current_time() / (60 / TEMPO)) % info.beats + 1
    signs = marks()
    waved = set()                     # the beats of each vibhag that starts with a wave
    start = 1
    for size in info.vibhag:
        if start in info.khali:
            waved.update(range(start, start + size))
        start += size
    f.text_align("center", "center")
    for beat, bol in enumerate(info.bols, start=1):
        angle = math.radians(360 * (beat - 1) / info.beats - 90)
        x = 280 + 150 * math.cos(angle)
        y = 230 + 150 * math.sin(angle)
        f.no_stroke()
        if beat == now:
            f.fill(255, 200, 80, 90)
            f.circle(x, y, 64)
        f.fill("gold" if beat == now else "#7fa6b8" if beat in waved else "#e0f0f0")
        f.text_size(17 if len(bol) < 6 else 12)
        f.text(bol, x, y)
        if beat in signs:
            f.fill("tomato" if beat == info.sam else "#7fd0c0")
            f.text_size(15)
            f.text(signs[beat], 280 + 196 * math.cos(angle), 230 + 196 * math.sin(angle))

    f.fill("white")
    f.text_size(28)
    f.text(info.name, 280, 218)
    f.text_size(15)
    f.text(f"{info.beats} beats: {' + '.join(map(str, info.vibhag))}", 280, 248)
    f.fill("#7fa6b8")
    f.text_size(13)
    f.text("keys:  " + "   ".join(f"{i + 1} {n}" for i, n in enumerate(NAMES)), 280, 462)


f.run()

View on GitHub ยท Back to the gallery