Polyrhythm Alignment Calculator
A polyrhythm becomes much easier to read, program, and rehearse when both parts are placed on one exact pulse grid.
Run — free
Enter the number of evenly spaced attacks in each rhythm, such as three and four, and this calculator finds the smallest shared subdivision grid. It also lists every attack position for both parts, marks their coincidences, and shows whether they meet anywhere inside the cycle or only at its boundaries.
Turn two rhythmic counts into one shared cycle
Treat both numbers as attack counts spread evenly across the same span of musical time. For three against four, one performer divides the cycle into three equal spaces while the other divides it into four. Those individual divisions do not land on the same intermediate marks, so the calculator constructs a finer grid that can represent both without rounding. The smallest possible grid is the least common multiple of the two counts. Three against four therefore needs twelve subdivisions: the three-part rhythm attacks every four grid pulses, and the four-part rhythm attacks every three. The returned position lists begin at zero and include the ending boundary, making the entire cycle explicit. This convention works well for notation planning, sequencer steps, drum-machine programming, and rehearsal diagrams. The ending position is the start of the next repeated cycle, not an extra attack that must be played twice. Read the ratio as a relationship within one common duration, rather than as two independent tempos or two unrelated bar lengths.
Understand alignment points and internal coincidences
The greatest common divisor reveals how many equal regions of the cycle share boundaries. If the two counts are coprime, as three and four are, their only coincidences are the beginning and end of the common cycle. If they share a factor, they also meet inside it. Four against six has a greatest common divisor of two, so both patterns attack together halfway through the cycle as well as at its boundaries. The calculator reports alignment positions in common-grid pulses and separately counts internal alignments, excluding the opening and closing boundaries. Its alignment interval is the constant distance between simultaneous attacks on that grid. This is useful when deciding where to place accents, conducting cues, phrase markers, or synchronization events. It also prevents a common misunderstanding: the least common multiple sizes the notation grid, while the greatest common divisor controls repeated coincidences inside the cycle. Both values matter, but they answer different musical questions. The explicit positions let you verify the result rather than relying on a ratio label alone.
Apply the grid in notation, practice, and production
To notate the result, imagine the reported grid subdivisions as equal ticks across one shared beat, bar, or phrase. Place attacks for the first part at every rhythm_a_step ticks and attacks for the second at every rhythm_b_step ticks. You can scale the drawing visually without changing those integer relationships. During practice, count or tap the fine grid slowly, accenting the positions belonging to each rhythm until each layer feels independent. In a digital audio workstation, use the same positions as step indices, remembering that the final boundary belongs to the following loop iteration. For MIDI or code, multiply every returned position by a chosen tick duration; because all positions are integers, no timing drift is introduced by fractional rounding. The calculation describes ideal, evenly spaced cross-rhythms and does not infer swing, tuplets with unequal spacing, tempo, meter, note spelling, or expressive microtiming. Those choices remain musical decisions. The API price is $0.002 per calculation, while the deterministic method ensures the same two input counts always produce the same grid and alignment map.
What you can do with it
Notate three against four
Find the twelve-pulse common grid and place both tuplet streams at exact integer positions.
Program a cross-rhythm loop
Convert two attack counts into sequencer steps without accumulating fractional timing errors.
Plan rehearsal accents
Identify simultaneous attacks and use them as reliable cues while musicians learn independent layers.
FAQ
What does the common pulse grid mean?
It is the smallest number of equal subdivisions that can place every attack from both rhythms on integer positions.
When do three against four line up?
They coincide at the start and at the end of the shared twelve-subdivision cycle, with no internal coincidence.
Why is the final position included in both attack lists?
It shows the cycle boundary where the patterns realign. In a repeating loop, that point is also the next cycle's zero.
Does this calculate tempo or note duration?
No. It calculates exact proportional positions within a shared cycle; you choose the cycle's real duration and notation.
Can the rhythms align inside the cycle?
Yes. They have internal alignments when their attack counts share a divisor greater than one, as four and six do.
How much does an API calculation cost?
Each API calculation costs $0.002.
For developers — API access
Everything on this page is available programmatically. This section is for teams who want to wire it into their own systems; everyone else can just use the tool above.
API endpoint
Prefer to automate it? One authenticated POST creates the task; the result comes back by webhook or a signed link. The same capability also runs here on the web, by email and from Telegram — and soon from our app too.
Call it from your stack
curl -X POST https://api.kit.forhosting.com/hobby/music-polyrhythm-alignment \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"rhythm_a":3,"rhythm_b":4}'const res = await fetch("https://api.kit.forhosting.com/hobby/music-polyrhythm-alignment", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"rhythm_a": 3,
"rhythm_b": 4
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/hobby/music-polyrhythm-alignment",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"rhythm_a": 3,
"rhythm_b": 4
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/hobby/music-polyrhythm-alignment", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"rhythm_a":3,"rhythm_b":4}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"rhythm_a":3,"rhythm_b":4}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/hobby/music-polyrhythm-alignment", body)
req.Header.Set("Authorization", "Bearer "+os.Getenv("KIT_KEY"))
req.Header.Set("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)Example request
{
"rhythm_a": 3,
"rhythm_b": 4
}Example response
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "hobby.music_polyrhythm_alignment",
"status": "queued",
"_links": {
"result": "/tasks/tsk_…/result"
}
}The API is asynchronous: the call returns a task_id immediately and the result arrives by webhook. Polling is capped at 1 req/s per task.
Pricing
Published price — no tokens, no invented credits. A failed task is never charged.
Errors
| HTTP | Code | Meaning |
|---|---|---|
401 | unauthorized | Missing or invalid API key. |
402 | insufficient_balance | Your balance doesn't cover the task price. |
404 | unknown_type | That task type doesn't exist. |
429 | rate_limited | Too many requests. Use the webhook instead of polling. |