taktmuster
v1.2.0
Published
A project for generating and visualizing musical patterns
Readme
Taktmuster
taktmuster generates metrical patterns as both:
- a discrete accent sequence like
4,1,2,1,3,1,2,1 - a continuous curve you can iterate with
getNext()
The project started as an experimental study around meter, curves, and pulse hierarchies. The current refactor keeps that idea, but reduces the API to a small deterministic core:
Taktmusterbuilds the pattern and curveMetronomeextendsTaktmuster- every
getNext()result includestimeoutMillis
Background
The library treats rhythm as layered structure.
- Phrase layer: the whole span across all measures
- Measure layer: the first beat of each measure
- Group layer: internal beat groups such as
2+2inside4/4 - Beat layer: the regular pulse grid
- Subdivision layers: smaller internal steps when
pulsePerQuarteris higher
This lets one object answer two different questions:
- “What is the accent pattern?”
- “What is the next timed curve sample?”
Modes
Taktmuster supports named strategies through type.
type: "balanced"
This is the default modern mode.
- Uses phrase, measure, group, beat, and subdivision layers together
- Produces a smoother normalized curve
- Best for continuous modulation, visualization, and richer pulse density
Think of balanced as the more even, modern mathematical model.
type: "classic"
This mode is closer to the older metric hierarchy idea.
- Builds accents from larger spans down to smaller spans
- Keeps the hierarchy coarser
- Produces stronger top-level accents with fewer internal layers
Think of classic as the more traditional accent-tree model.
Important: for some meters, the discrete beat pattern can be the same in classic and balanced, while the continuous curve is still different. The main difference is in how the curve layers are built.
Install
npm installUsage
import { Taktmuster, Metronome } from 'taktmuster';
const tm = new Taktmuster({
tempo: 120,
pulsePerQuarter: 4,
taktCnt: 2,
zaehler: 4,
nenner: 4,
type: 'classic',
curveType: 'cos'
});
console.log(tm.getTaktMuster());
// [4, 1, 2, 1, 3, 1, 2, 1]
const step = tm.getNext();
console.log(step);Example getNext() payload:
{
index: 0,
cycle: 0,
mode: 'classic',
beatIndex: 0,
stepInBeat: 0,
patternValue: 4,
waveformValue: 1,
taktValue: 1,
metricStrength: 2.36,
timeoutMillis: 125,
newCycle: false
}Discrete Patterns
Use getTaktMuster() when you want the accent numbers directly.
new Taktmuster({
taktCnt: 2,
zaehler: 4,
nenner: 4,
type: 'classic'
}).getTaktMuster();
// [4, 1, 2, 1, 3, 1, 2, 1]
new Taktmuster({
taktCnt: 2,
zaehler: 3,
nenner: 4,
type: 'classic'
}).getTaktMuster();
// [3, 1, 1, 2, 1, 1]Timed Iteration
getNext() returns the next sample and timeoutMillis.
const tm = new Taktmuster({
tempo: 96,
pulsePerQuarter: 4,
taktCnt: 2,
zaehler: 7,
nenner: 8,
type: 'balanced'
});
const next = tm.getNext();
console.log(next.timeoutMillis);If you want automatic scheduling:
const stop = tm.notifyNext((step) => {
console.log(step.index, step.timeoutMillis, step.patternValue);
});
// later
stop();Metronome extends Taktmuster, so it can be used directly or mirror another instance:
const source = new Taktmuster({ taktCnt: 2, zaehler: 4, nenner: 4, type: 'classic' });
const metronome = new Metronome();
metronome.setTaktmuster(source);API
new Taktmuster(options)
Main options:
tempo: BPM, default120pulsePerQuarter: pulses per quarter note, default1taktCnt: number of measures, default1zaehler: numerator, default4nenner: denominator, default4type:balancedorclassiccurveType:cos,sin, ortoggleswing: alternating timing offset from-0.45to0.45depth: optional subdivision depth override
Main methods:
setTempo(tempo, pulsePerQuarter)setTakt(taktCnt, zaehler, nenner, curveType)setType(type)getCurve()getTaktMuster()getNext()getNextTimeout()notifyNext(callback, { immediate })start(callback)stop()reset()at(index)
Iteration Script
To inspect modes side by side, run:
npm run test:iterateThat script prints:
- the discrete pattern
- the first timed steps from
getNext() - a side-by-side comparison of
balancedandclassic
Development
npm test
npm run test:iterate
npm run webpack:build
node index.node.js