npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

rhythmicon-rhythm

v0.3.0

Published

Analyze and compute rhythmic patterns

Readme

rhythmicon-rhythm

NPM Version

Analyze and compute rhythmic patterns

This Node package implements class Rhythm to store, analyze and manipulate rhythms.

Table of Contents

Background

Class Rhythm implements a simplified model of musical rhythms. Every rhythm is an array of pulses, each being either a beat (value 1) or a rest (value 0). For instance the tresillo rhythm is array [1,0,0,1,0,0,1,0]. A rhythm can also be encoded as pattern string (x--x--x-) and as durations (array [3,3,2] or string 3+3+2). Rhythms can further be:

Related works

  • rhythmicon-vue is a JavaScript library of Vue components to display and interact with rhythmic patterns
  • rhythmicon further contains a collection of rhythms and a web application to analyze and modify rhythmic patterns
  • tonal is a JavaScript library for tonal elements of music (note, intervals, chords, scales, modes, keys). The library also contains the limited class @tonaljs/rhythm-pattern for rhythmic patterns.

Install

This package comes as single file without dependencies.

npm install rhythmicon-rhythm

Usage

import Rhythm from "rhythmicon-rhythm"

const r = new Rhytm("x--x--x-")

console.log(`Rhythm has ${r.beats()} in ${r.length} pulses) 

Rhythm

This is a subclass of Array so all of its properties and methods can be used. Please make sure the Array will contain only 0 and 1 elements when using low-level Array methods.

Constructors

new

The constructor creates a new Rhythm object like new Array. If passed a single string or Array argument, this argument is used to build the rhythm from.

new Rhyth("x--x--x-")
new Rhythm("|RL-RRL--|")
new Rhyth([1,0,0,1,0,0,1,0])
new Rhyth("A","_","_","+","_","_","B","_")

Rhythm(n) // empty rhythm of length n

clone

This instance method returns a copy of the Rhythm instance.

Factory methods

fromPattern(pattern)

Generates a Rhythm from a pattern string.

fromDurations(durations)

Generates a rhythm from an Array or string of durations.

euclidean(beats, pulses)

Generates an euclidean rhythm with beats number of beats in pulses number of pulses.

Accessor methods

The following ("member const") methods don't modify instances.

beats()

Get the number of beats in this rhythm.

beatPulses()

Get an array of index numbers of beats in this rhythm.

first()

Get the position the the first beat, or undefined if the rhythm is empty.

rhythm.first() === rhythm.beatPulses()[0]

empty()

Get whether the rhytm contains no beats.

durations()

Return an array of durations between beats, starting with the first beat.

divisor()

Get greatest common divisor of all durations. Returns 1 if the rhythm cannot be deflated or if the first pulse is not a beat. Returns the length of the rhytm for an empty rhythm.

repetitions()

Get number of repetitions.

shuffled()

Check whether the rhythm is shuffled. That is the pulses can be organized in groups of three pulses where the second pulse of each group is a rest.

Rhythm.fromPattern("x--x-x").shuffled() // true
Rhythm.fromPattern("xx-x-x").shuffled() // false

odd()

Check whether the rhythm is odd (cannot be split at beats into two parts of equal length).

core()

Check whether the rhythm is normalized to its core rhythm.

rotations()

Calculate all rotations by pulse. Returns a Set of pattern strings.

beatRotations()

Calculate all rotations by beat. Returns a Set of pattern strings.

toString()

Stringify the rhythm with "x" for beat and "-" for rest.

toDurationString(sep)

Stringify the durations of the beat, separated by sep (+ by default) and preceded by more of this character if the first pulse is not a beat.

Comparator methods

compare(rhythm)

Compare two rhythms, first by length, then lexicographically by its durations. The argument is parsed if it is no Rhythm object.

equivalent(rhythm)

Check whether this rhythm is equivalent to another, possibly under rotation. The argument is parsed if it is no Rhythm object.

equals(rhythm)

Whether the rythm is equal to another rythm (same length, same pulses). The argument is parsed if it is no Rhythm object.

rotation(rhythm)

Get the rotation number if this rhythm is equivalent to another, or undefined otherwise.

Modifying methods

beat(...durations)

Add one or more beats with given duration(s) or one pulse if no parameter is given.

rest(duration)

Add a rest with given duration in pulses.

replace(...rhythm)

Change the rhytm in-place. Takes same arguments as the constructor, except a single number is read is one pulse instead of a number of pulses.

deflate(divisor)

Deflate the rhythm if it has a divisor > 1. The optional parameter must be a prime of the divisor.

inflate(n)

Inflate the rhythm. Each pulse is replaced by n pulses with default n=2.

repeat(n)

Repeat the rhythm n times (default 2 to duplicate it).

cut(n)

Reduce the rhythm by removal of all repetitions or to a smaller number n of repetitions. Does nothing if n is larger than repetitions().

cut(n) results in the same as cut().repeat(n)

Rhythm.fromPattern("x-x-x-x-").cut()  // => Rhythm[1,0]
Rhythm.fromPattern("x-x-x-x-").cut(1) // => Rhythm[1,0,1,0]
Rhythm.fromPattern("x-x-x-x-").cut(2) // => Rhythm[1,0,1,0]
Rhythm.fromPattern("x-x-x-x-").cut(3) // => Rhythm[1,0,1,0,1,0]

complement()

Convert rhythm into its complement by swapping beats and rests.

shuffle()

If the rhythm can be grouped into groups of two pulses, each of these groups is replaced by three pulses, the second one being a rest.

Rhythm.fromPattern("x-xx").shuffle() // => "x--x-x"

unshuffle()

Remove the middle rest of each triple group if the rhythm is shuffled. Does nothing otherwise.

rotate(pulses)

Rotate the rhythm pulses number of pulses to the right (1 by default), or to the left if pulses is negative.

Rhythm.fromPattern("x--x-").rotate(1) // => Rhythm[0,1,0,0,1]

rotateBeats(beats)

Rotate the rhythm one or more beats to the right.

If the first pulse is not a beat, the rhythm is first rotated to do so, so rotation by zero beats will rotate the first beat to the first pulse.

normalize()

Normalize to a core rhythm by rotating, deflation, and cutting repetitions.

Static methods

isBeat(value)

Return whether a variable is read as beat. This is true for every true value except for the characters space, underscore, dot, and minus.

isDurationsString(str)

Return whether a string specifies a rhythm in form of durations with optional rotation.

if (Rhythm.isDurationString(s)) {
  rhythm = Rhythm.fromDurations(s)
}

parse(...rhythm)

Read a string, an Array, or a list of values as rhythm and returns an Array of pulses.

Maintainers

Contributing

Contributions are welcome! Best use the rhythmicon issue tracker for questions, bug reports, and/or feature requests!

License

MIT license