total-serialism
Advanced tools
Comparing version 2.5.0 to 2.6.0
@@ -28,7 +28,7 @@ # Algorithmic | ||
Generate a euclidean rhythm evenly spacing n-beats amongst n-steps.Inspired by Godfried Toussaints famous paper "The Euclidean Algorithm Generates Traditional Musical Rhythms". | ||
Generate a euclidean rhythm evenly spacing n-hits amongst n-steps. Inspired by Godfried Toussaints famous paper "The Euclidean Algorithm Generates Traditional Musical Rhythms". | ||
**arguments** | ||
- {Int+} -> length of array (optional, default=8) | ||
- {Int+} -> beats (optional, default=4) | ||
- {Int+/Array} -> length of array (optional, default=8, uses length of Array if input) | ||
- {Int+/Array} -> hits (optional, default=4, uses length of Array if input) | ||
- {Int} -> rotate (optional, default=0) | ||
@@ -44,11 +44,11 @@ | ||
<iframe src="https://editor.p5js.org/tmhglnd/embed/xS8sKejzG" width="100%" height="250px" frameBorder="0" scrolling="no"></iframe> | ||
<!-- <iframe src="https://editor.p5js.org/tmhglnd/embed/xS8sKejzG" width="100%" height="250px" frameBorder="0" scrolling="no"></iframe> --> | ||
## fastEuclid | ||
A fast euclidean rhythm algorithm. Uses the downsampling of a line drawn between two points in a 2-dimensional grid to divide the squares into an evenly distributed amount of steps. Generates correct distribution, but the distribution may differ a bit from the recursive method `euclid()` above. | ||
A fast euclidean rhythm algorithm. Uses the downsampling of a line drawn between two points in a 2-dimensional grid to divide the squares into an evenly distributed amount of steps. Generates correct distribution, but the rotation/order may differ a bit from the recursive `euclid()` method above. | ||
**arguments** | ||
- {Int} -> steps (optional, default=8) | ||
- {Int} -> beats (optional, default=4) | ||
- {Int+/Array} -> length of array (optional, default=8, uses length of Array if input) | ||
- {Int+/Array} -> hits (optional, default=4, uses length of Array if input) | ||
- {Int} -> rotate (optional, default=0) | ||
@@ -81,3 +81,3 @@ | ||
<iframe src="https://editor.p5js.org/tmhglnd/embed/2iav0oh9K" width="100%" height="250px" frameBorder="0" scrolling="no"></iframe> | ||
<!-- <iframe src="https://editor.p5js.org/tmhglnd/embed/2iav0oh9K" width="100%" height="250px" frameBorder="0" scrolling="no"></iframe> --> | ||
@@ -122,3 +122,3 @@ - [Learn hex beats by Steven Yi](https://kunstmusik.github.io/learn-hex-beats/) | ||
<iframe src="https://editor.p5js.org/tmhglnd/embed/1jFaQ3vuG" width="100%" height="250px" frameBorder="0" scrolling="no"></iframe> | ||
<!-- <iframe src="https://editor.p5js.org/tmhglnd/embed/1jFaQ3vuG" width="100%" height="250px" frameBorder="0" scrolling="no"></iframe> --> | ||
@@ -139,3 +139,3 @@ ```js | ||
<iframe src="https://editor.p5js.org/tmhglnd/embed/_X0duWOvn" width="100%" height="250px" frameBorder="0" scrolling="no"></iframe> | ||
<!-- <iframe src="https://editor.p5js.org/tmhglnd/embed/_X0duWOvn" width="100%" height="250px" frameBorder="0" scrolling="no"></iframe> --> | ||
@@ -268,3 +268,3 @@ ## cellular automaton | ||
<iframe src="https://editor.p5js.org/tmhglnd/embed/5dICbZv7b" width="100%" height="250px" frameBorder="0" scrolling="no"></iframe> | ||
<!-- <iframe src="https://editor.p5js.org/tmhglnd/embed/5dICbZv7b" width="100%" height="250px" frameBorder="0" scrolling="no"></iframe> --> | ||
@@ -289,3 +289,3 @@ ## pisano | ||
<iframe src="https://editor.p5js.org/tmhglnd/embed/gputPJXWN" width="100%" height="250px" frameBorder="0" scrolling="no"></iframe> | ||
<!-- <iframe src="https://editor.p5js.org/tmhglnd/embed/gputPJXWN" width="100%" height="250px" frameBorder="0" scrolling="no"></iframe> --> | ||
@@ -334,3 +334,3 @@ ## pell | ||
**arguments** | ||
- {Int+} -> size the length of the resulting Meldoy's steps (default=16) | ||
- {Int+/Array} -> output length of the Meldoy's steps (default=16, uses length of Array if input) | ||
- {Array} -> seed the sequence's first two steps (defaults = [0, 1]) | ||
@@ -337,0 +337,0 @@ - {Int} -> offset from which the sequence starts |
@@ -31,3 +31,3 @@ | ||
**arguments** | ||
- {Int+} -> Length of array | ||
- {Int+/Array} -> Length of output array (uses length of Array if input) | ||
- {Number} -> Low value (optional, default=0) | ||
@@ -67,3 +67,3 @@ - {Number} -> High value (exclusive, optional, default=length) | ||
**arguments** | ||
- {Int+} -> Length of array | ||
- {Int+/Array} -> Length of output array (uses length of Array if input) | ||
- {Number} -> Low value (optional) | ||
@@ -102,3 +102,3 @@ - {Number} -> High value (inclusive, optional) | ||
**arguments** | ||
- {Int+} -> Length of array | ||
- {Int+/Array} -> Length of output array (uses length of Array if input) | ||
- {Number} -> Low value (optional, default=0) | ||
@@ -124,3 +124,3 @@ - {Number} -> High value (exclusive, optional, default=length) | ||
**arguments** | ||
- {Int+} -> Length of array | ||
- {Int+/Array} -> Length of output array (uses length of Array if input) | ||
- {Number} -> Low value (optional) | ||
@@ -167,3 +167,3 @@ - {Number} -> High value (inclusive, optional) | ||
**arguments** | ||
- {Int+} -> Length of array | ||
- {Int+/Array} -> Length of output array (uses length of Array if input) | ||
- {Number} -> Periods of (co)sine-wave (optional, default=1) | ||
@@ -212,3 +212,3 @@ - {Number} -> Low range of values (optional, default=0) | ||
**arguments** | ||
- {Int+} -> Length of array | ||
- {Int+/Array} -> Length of output array (uses length of Array if input) | ||
- {Number} -> Periods of (co)sine-wave (optional, default=1) | ||
@@ -268,3 +268,3 @@ - {Number} -> Low range of values (optional, default=-1) | ||
**arguments** | ||
- {Int} -> Length of output array (resolution) | ||
- {Int+/Array} -> Length of output array (uses length of Array if input) | ||
- {Number/Array} -> Periods of the wave (option, default=1) | ||
@@ -321,3 +321,3 @@ - {Number} -> Low range of values (optional, default=-1) | ||
**arguments** | ||
- {Int} -> Length of output array (resolution) | ||
- {Int+/Array} -> Length of output array (uses length of Array if input) | ||
- {Number/Array} -> Periods of the wave (option, default=1) | ||
@@ -324,0 +324,0 @@ - {Number} -> Low range of values (optional, default=0) |
@@ -27,2 +27,3 @@ # Utility | ||
- [toArray](#toArray) | ||
- [size](#size) | ||
- [sum](#sum) | ||
@@ -159,3 +160,3 @@ - [minimum](#minimum) | ||
// Alias: mix | ||
// Alias: mix() | ||
``` | ||
@@ -185,5 +186,29 @@ | ||
## size | ||
Return the length/size of an array if the argument is an array. If the argument is a number return the number as a positive integer greater than 0. If the argument is not a number return 1. The method can be used to input arrays as arguments for other functions | ||
**arguments** | ||
- @param {Value/Array} -> input value to check | ||
- @return {Int} -> the array length | ||
```js | ||
Util.size([5, 7, 3, 2, 9]); | ||
//=> 5 | ||
Util.size(8); | ||
//=> 8 | ||
Util.size(3.1415); | ||
//=> 3 | ||
Util.size('foo'); | ||
//=> 1 | ||
// Alias: length() | ||
``` | ||
# Arithmetic | ||
Basic arithmetic methods that accept n-dimensional arrays in both arguments. Outputlength is always the length of the longest list. | ||
Basic arithmetic methods that accept n-dimensional arrays in both arguments. Outputlength is always the length of the longest list. Values that are `NaN` will be returned as `0` | ||
@@ -211,2 +236,4 @@ ## add | ||
//=> [ -9, [ -18, -27, -38 ] ] | ||
// Alias: sub() | ||
``` | ||
@@ -223,2 +250,4 @@ | ||
//=> [ 10, [ 40, 90, 80 ] ] | ||
// Alias: mul(), mult() | ||
``` | ||
@@ -235,2 +264,4 @@ | ||
//=> [ 0.1, [ 0.1, 0.1, 0.05 ] ] | ||
// Alias: div() | ||
``` | ||
@@ -276,3 +307,3 @@ | ||
Return the sum of all values in an array. Ignores all non-numeric values. | ||
Return the sum of all values in an array. Ignores all non-numeric values. Works with n-dimensional arrays. | ||
@@ -285,2 +316,5 @@ ```js | ||
//=> 43 | ||
Util.sum([1, 2, [3, 4, [5, 6], 7], 8]); | ||
//=> 36 | ||
``` | ||
@@ -325,3 +359,3 @@ | ||
- {Number/Array} -> input values | ||
- {Int/Array} -> normailzed values | ||
- {Int/Array} -> normalized values | ||
@@ -333,6 +367,28 @@ ```js | ||
// works with n-dimensional arrays | ||
Util.normalize([5, [12, [4, 17]], 3, 1]); | ||
Util.norm([5, [12, [4, 17]], 3, 1]); | ||
//=> [ 0.25, [ 0.6875, [ 0.1875, 1 ] ], 0.125, 0 ] | ||
// Alias: norm() | ||
``` | ||
## signedNormalize | ||
Signed Normalize all the values in an array between -1. and 1. | ||
The highest value will be 1, the lowest value will be -1. | ||
**arguments** | ||
- {Number/Array} -> input values | ||
- {Int/Array} -> signed normalized values | ||
```js | ||
Util.signedNormalize([0, 1, 2, 3, 4]); | ||
//=> [ -1, -0.75, -0.25, 0, 1 ] | ||
// works with n-dimensional arrays | ||
Util.snorm([5, [12, [4, 17]], 3, 1]); | ||
//=> [ -0.5, [ 0.375, [ -0.625, 1 ] ], -0.75, -1 ] | ||
// Alias: snorm() | ||
``` | ||
## flatten | ||
@@ -339,0 +395,0 @@ |
{ | ||
"name": "total-serialism", | ||
"version": "2.5.0", | ||
"version": "2.6.0", | ||
"description": "A set of methods for the generation and transformation of number sequences useful in algorithmic composition", | ||
@@ -5,0 +5,0 @@ "main": "index.js", |
@@ -205,6 +205,8 @@ # Total Serialism | ||
const Srl = require('total-serialism'); | ||
// subset of library | ||
const Gen = require('total-serialism').Generative; | ||
// specific method from one of the libraries | ||
const { random, drunk } = require('total-serialism').Stochastic; | ||
// specific methods | ||
const { spread, fill } = require('total-serialism').Generative; | ||
``` | ||
@@ -256,3 +258,7 @@ | ||
```js | ||
const Serialism = require('total-serialism'); | ||
const TS = require('total-serialism'); | ||
// function calls look like: | ||
TS.Generative.spread(4); | ||
TS.Stochastic.random(4); | ||
``` | ||
@@ -267,4 +273,44 @@ Or an individual section | ||
const Util = require('total-serialism').Utility; | ||
// function calls look like: | ||
Gen.spread(4); | ||
Rand.random(4); | ||
``` | ||
Or an individual function | ||
```js | ||
const { spread } = require('total-serialism').Generative; | ||
const { random } = require('total-serialism').Stochastic; | ||
// function calls look like: | ||
spread(4); | ||
random(4); | ||
``` | ||
It's also possible to expose entire subsets to the main package | ||
```js | ||
// expose multiple sub-libraries to the main package with | ||
const TS = require('total-serialism'); | ||
Object.assign(TS, TS.Generative, TS.Stochastic); | ||
// function calls look like: | ||
TS.spread(4); | ||
TS.random(4); | ||
``` | ||
Or expose entire subsets to the global namespace. (not recommended, this can lead to name collisions with other functions/packages) | ||
```js | ||
// expose multiple sub-libraries to the global scope | ||
const TS = require('total-serialism'); | ||
Object.assign(globalThis, TS.Generative, TS.Stochastic); | ||
// function calls look like: | ||
spread(4); | ||
random(4); | ||
// etc... | ||
``` | ||
# 🎮 In Action | ||
@@ -271,0 +317,0 @@ |
@@ -12,6 +12,7 @@ //========================================================================== | ||
// - spread-methods inspired by Max8's MC functions spread and spreadinclusive | ||
// - cosine/sine array generation inspired by workshop by Steven Yi at ICLC | ||
//========================================================================== | ||
// const Util = require('./utility.js'); | ||
const { map, flatten, toArray } = require('./utility'); | ||
const { map, flatten, toArray, size, TWO_PI } = require('./utility'); | ||
@@ -35,4 +36,4 @@ // Generate a list of n-length starting at one value | ||
lo = Math.min(lo, hi); | ||
// len is minimum of 1 | ||
len = Math.max(1, len); | ||
// len is minimum of 1 or length of array | ||
len = size(len); | ||
if (len === 1){ return [0]; } | ||
@@ -56,3 +57,3 @@ // stepsize | ||
// | ||
function spread(len, lo=len, hi){ | ||
function spread(len, lo=size(len), hi){ | ||
let arr = spreadFloat(len, lo, hi); | ||
@@ -79,3 +80,4 @@ return arr.map(v => Math.floor(Number(v.toPrecision(15)))); | ||
// len is minimum of 1 | ||
len = Math.max(1, len); | ||
len = size(len); | ||
// len = Math.max(1, len); | ||
if (len === 1){ return [0]; } | ||
@@ -98,3 +100,3 @@ // generate array | ||
// | ||
function spreadExp(len, lo=len, hi, exp){ | ||
function spreadExp(len, lo=size(len), hi, exp){ | ||
let arr = spreadExpFloat(len, lo, hi, exp); | ||
@@ -121,3 +123,4 @@ return arr.map(v => Math.floor(Number(v.toPrecision(15)))); | ||
// len is minimum of 1 | ||
len = Math.max(1, len); | ||
len = size(len); | ||
// len = Math.max(1, len); | ||
if (len === 1){ return [0]; } | ||
@@ -141,3 +144,3 @@ // stepsize | ||
// | ||
function spreadInclusive(len, lo=len, hi){ | ||
function spreadInclusive(len, lo=size(len), hi){ | ||
var arr = spreadInclusiveFloat(len, lo, hi); | ||
@@ -165,3 +168,4 @@ return arr.map(v => Math.floor(Number(v.toPrecision(15)))); | ||
// len is minimum of 1 | ||
len = Math.max(1, len); | ||
len = size(len); | ||
// len = Math.max(1, len); | ||
// generate array | ||
@@ -183,3 +187,3 @@ let arr = []; | ||
// | ||
function spreadInclusiveExp(len, lo=len, hi, exp){ | ||
function spreadInclusiveExp(len, lo=size(len), hi, exp){ | ||
var arr = spreadInclusiveExpFloat(len, lo, hi, exp); | ||
@@ -232,2 +236,3 @@ return arr.map(v => Math.floor(Number(v.toPrecision(15)))); | ||
function sineFloat(len=1, periods=1, lo, hi, phase=0){ | ||
// if no range specified | ||
if (lo === undefined){ lo = -1; hi = 1; } | ||
@@ -237,3 +242,3 @@ else if (hi === undefined){ hi = lo, lo = 0; } | ||
periods = toArray(periods); | ||
// if no range specified | ||
// if (lo === undefined){ lo = -1; hi = 1; } | ||
@@ -244,11 +249,13 @@ // swap if lo > hi | ||
// array length minimum of 1 | ||
len = Math.max(1, len); | ||
len = size(len); | ||
// len = Math.max(1, len); | ||
let arr = []; | ||
let twoPI = Math.PI * 2.0; | ||
// let twoPI = Math.PI * 2.0; | ||
// let a = Math.PI * 2.0 * periods / len; | ||
let p = Math.PI * phase * 2.0; | ||
// let p = Math.PI * phase * 2.0; | ||
let p = TWO_PI * phase; | ||
for (let i=0; i<len; i++){ | ||
// arr[i] = Math.sin(a * i + p); | ||
let a = twoPI * periods[i % periods.length] / len; | ||
let a = TWO_PI * periods[i % periods.length] / len; | ||
arr[i] = Math.sin(a * i + p); | ||
@@ -317,3 +324,4 @@ } | ||
// array length minimum of 1 | ||
len = Math.max(1, len); | ||
len = size(len); | ||
// len = Math.max(1, len); | ||
let arr = []; | ||
@@ -356,3 +364,4 @@ | ||
// array length minimum of 1 | ||
len = Math.max(1, len); | ||
len = size(len); | ||
// len = Math.max(1, len); | ||
let arr = []; | ||
@@ -388,2 +397,3 @@ | ||
function binary(...a){ | ||
// if no arguments return else flatten array to 1 dimension | ||
if (!a.length) { return [0]; } | ||
@@ -397,3 +407,5 @@ a = flatten(a); | ||
} else { | ||
// make the value into a whole number | ||
let v = Math.floor(Math.max(a[i], 0)); | ||
// convert the number to binary string, split, convert to numbers | ||
arr = arr.concat(v.toString(2).split('').map((x) => Number(x))); | ||
@@ -416,2 +428,3 @@ } | ||
function spacing(...a){ | ||
// if no arguments return else flatten array to 1 dimension | ||
if (!a.length) { return [0]; } | ||
@@ -423,4 +436,6 @@ a = flatten(a); | ||
if (isNaN(a[i]) || a[i] < 1){ | ||
// if no number or less than 1 append 0 | ||
arr = arr.concat(0); | ||
} else { | ||
// for every integer push a 1 followed by 0's | ||
for (let j=0; j<Math.floor(a[i]); j++){ | ||
@@ -427,0 +442,0 @@ arr.push(!j ? 1 : 0); |
@@ -27,3 +27,3 @@ //============================================================================== | ||
const { mod } = require('./utility'); | ||
const { mod, size } = require('./utility'); | ||
const { rotate } = require('./transform'); | ||
@@ -47,3 +47,3 @@ const BigNumber = require('bignumber.js'); | ||
let a = []; | ||
for (let i in hex){ | ||
for (let i=0; i<hex.length; i++){ | ||
let binary = parseInt("0x"+hex[i]).toString(2); | ||
@@ -57,2 +57,3 @@ binary = isNaN(binary)? '0000' : binary; | ||
exports.hexBeat = hexBeat; | ||
exports.hex = hexBeat; | ||
@@ -74,2 +75,5 @@ // A fast euclidean rhythm algorithm | ||
let d = -1; | ||
// steps/hits is minimum of 1 or array length | ||
s = size(s); | ||
h = size(h); | ||
@@ -86,2 +90,3 @@ for (let i=0; i<s; i++){ | ||
} | ||
exports.fastEuclidean = fastEuclid; | ||
exports.fastEuclid = fastEuclid; | ||
@@ -102,2 +107,6 @@ | ||
function euclid(steps=8, beats=4, rot=0){ | ||
// steps/hits is minimum of 1 or array length | ||
steps = size(steps); | ||
beats = size(beats); | ||
pattern = []; | ||
@@ -122,2 +131,3 @@ counts = []; | ||
} | ||
exports.euclidean = euclid; | ||
exports.euclid = euclid; | ||
@@ -332,2 +342,3 @@ | ||
} | ||
exports.pisanoPeriod = pisano; | ||
exports.pisano = pisano; | ||
@@ -434,4 +445,4 @@ | ||
// | ||
function infinitySeries(size=16, seed=[0,1], offset=0){ | ||
size = Math.max(1, size); | ||
function infinitySeries(len=16, seed=[0,1], offset=0){ | ||
len = size(len); | ||
let root = seed[0]; | ||
@@ -441,3 +452,3 @@ let step1 = seed[1]; | ||
let steps = Array.from(new Array(size), (n, i) => i + offset).map(step => { | ||
let steps = Array.from(new Array(len), (n, i) => i + offset).map(step => { | ||
return root + (norgardInteger(step) * seedInterval); | ||
@@ -444,0 +455,0 @@ }); |
@@ -17,3 +17,3 @@ //======================================================================= | ||
const { spread } = require('./gen-basic.js'); | ||
const { fold } = require('./utility'); | ||
const { fold, size, toArray } = require('./utility'); | ||
const { change } = require('./statistic'); | ||
@@ -68,5 +68,5 @@ | ||
// len is positive and minimum of 1 | ||
len = Math.max(1, len); | ||
var arr = new Array(len); | ||
len = size(len); | ||
var arr = []; | ||
for (var i=0; i<len; i++){ | ||
@@ -88,3 +88,3 @@ arr[i] = (rng() * (hi - lo)) + lo; | ||
// | ||
function random(len=1, lo=2, hi=0){ | ||
function random(len=1, lo=12, hi=0){ | ||
var arr = randomFloat(len, lo, hi); | ||
@@ -112,5 +112,7 @@ return arr.map(v => Math.floor(v)); | ||
p = (!p)? (lo+hi)/2 : p; | ||
// len is positive and minimum of 1 | ||
len = size(len); | ||
var arr = []; | ||
for (var i=0; i<Math.max(1,len); i++){ | ||
for (var i=0; i<len; i++){ | ||
// direction of next random number (+ / -) | ||
@@ -129,2 +131,3 @@ var dir = (rng() > 0.5) * 2 - 1; | ||
exports.drunkFloat = drunkFloat; | ||
exports.drunkF = drunkFloat; | ||
exports.walkFloat = drunkFloat; | ||
@@ -186,4 +189,5 @@ | ||
let arr = []; | ||
// limit list length | ||
len = Math.max(1, len); | ||
// set list length to minimum of 1 | ||
len = size(len); | ||
// swap if lo > hi | ||
@@ -221,2 +225,3 @@ if (min > max){ var t=min, min=max; max=t; } | ||
function shuffle(a=[0]){ | ||
// slice array to avoid changing the original array | ||
var arr = a.slice(); | ||
@@ -242,2 +247,3 @@ for (var i=arr.length-1; i>0; i-=1) { | ||
exports.twelveTone = twelveTone; | ||
exports.toneRow = twelveTone; | ||
@@ -273,6 +279,8 @@ // Generate a list of unique random integer values between a | ||
// if a is no Array make it an array | ||
a = (!Array.isArray(a))? [a] : a; | ||
a = toArray(a); | ||
// set the size to minimum of 1 or based on array length | ||
len = size(len); | ||
var arr = []; | ||
for (var i=0; i<Math.max(1,len); i++){ | ||
for (var i=0; i<len; i++){ | ||
arr.push(a[Math.floor(rng()*a.length)]); | ||
@@ -295,4 +303,7 @@ } | ||
function pick(len=1, a=[0, 1]){ | ||
// set the size to minimum of 1 or based on array length | ||
len = size(len); | ||
// fill the jar with the input | ||
var jar = (!Array.isArray(a))? [a] : a; | ||
if (jar.length < 2){ | ||
@@ -305,3 +316,3 @@ return new Array(len).fill(jar[0]); | ||
var v, p, arr = []; | ||
for (var i=0; i<Math.max(1,len); i++){ | ||
for (var i=0; i<len; i++){ | ||
v = s.pop(); | ||
@@ -332,8 +343,10 @@ if (v === undefined){ | ||
// | ||
function expand(a=[0, 0], l=1){ | ||
a = (Array.isArray(a))? a : [a]; | ||
function expand(a=[0, 0], l=0){ | ||
a = toArray(a); | ||
l = size(l); | ||
// return a if output length is smaller/equal then input array | ||
if (l <= a.length){ return a; } | ||
// get the differences and pick the expansion options | ||
let p = change(a); | ||
let chg = pick(l-a.length, p); | ||
// console.log(chg); | ||
// empty output array and axiom for output | ||
@@ -340,0 +353,0 @@ let arr = a.slice(); |
@@ -23,3 +23,3 @@ //======================================================================= | ||
const { sort } = require('./statistic'); | ||
const { flatten, add, max, min, lerp, toArray } = require('./utility'); | ||
const { flatten, add, max, min, lerp, toArray, size } = require('./utility'); | ||
@@ -122,2 +122,4 @@ // Duplicate an array multiple times, | ||
a = toArray(a); | ||
length = size(length); | ||
let len = length - a.length; | ||
@@ -309,2 +311,3 @@ if (len < 1) { | ||
exports.palindrome = palindrome; | ||
exports.palin = palindrome; | ||
exports.mirror = palindrome; | ||
@@ -459,2 +462,3 @@ | ||
if (len < 2){ return a; } | ||
len = size(len); | ||
@@ -461,0 +465,0 @@ let arr = []; |
@@ -72,3 +72,3 @@ //============================================================================== | ||
// @param {Number} -> the tempo in Beats/Minute (BPM) | ||
// @return {Void} | ||
// @return {Number} -> the tempo in Beats/Minute (BPM) | ||
// | ||
@@ -81,2 +81,3 @@ function setTempo(t=100){ | ||
notation.measureInMs = 60000.0 / notation.bpm * 4; | ||
return getTempo(); | ||
} | ||
@@ -88,3 +89,3 @@ exports.setTempo = setTempo; | ||
// | ||
// @return -> tempo in Beats/Minute (BPM) | ||
// @return {Number} -> tempo in Beats/Minute (BPM) | ||
// | ||
@@ -101,3 +102,3 @@ function getTempo(){ | ||
// @param {Int/String} -> root of the scale (optional, default=c) | ||
// @return {Void} | ||
// @return {Object} -> the scale, root and rootInt | ||
// | ||
@@ -110,2 +111,3 @@ function setScale(s="chromatic", r){ | ||
} | ||
return getScale(); | ||
} | ||
@@ -117,3 +119,2 @@ exports.setScale = setScale; | ||
// @return {Object} -> the scale, root and rootInt | ||
// @return {Void} | ||
// | ||
@@ -133,3 +134,3 @@ function getScale(){ | ||
// @param {Int/String} -> root of the scale (optional, default=c) | ||
// @return {Void} | ||
// @return {Object} -> the scale, root and rootInt | ||
// | ||
@@ -153,2 +154,3 @@ function setRoot(r='c'){ | ||
} | ||
return getScale(); | ||
} | ||
@@ -160,3 +162,2 @@ exports.setRoot = setRoot; | ||
// @return {Object} -> the scale and root | ||
// @return {Void} | ||
// | ||
@@ -235,11 +236,16 @@ function getRoot(){ | ||
// With default equal temperament tuning A4 = 440 Hz | ||
// Adjust the tuning with optional second argument | ||
// Adjust the amount of notes per octave (12-TET, 5-TET) with third argument | ||
// Adjust the center c4 midi value with optional fourth argument | ||
// | ||
// @param {Number/Array} -> midi values to convert | ||
// @param {Number} -> tuning | ||
// @param {Number} -> octave division | ||
// @return {Number/Array} -> frequency in Hz | ||
// | ||
function midiToFreq(a=48){ | ||
function midiToFreq(a=48, t=440, n=12, c=69){ | ||
if (!Array.isArray(a)){ | ||
return Math.pow(2, (a - 69) / 12) * 440; | ||
return Math.pow(2, (a - c) / n) * t; | ||
} | ||
return a.map(x => midiToFreq(x)); | ||
return a.map(x => midiToFreq(x, t, n, c)); | ||
} | ||
@@ -246,0 +252,0 @@ exports.midiToFreq = midiToFreq; |
@@ -31,2 +31,21 @@ //==================================================================== | ||
// Return the length/size of an array if the argument is an array | ||
// if argument is a number return the number as integer | ||
// if argument is not a number return 1 | ||
// The method can be used to input arrays as arguments for other functions | ||
// | ||
// @param {Value/Array} -> input value to check | ||
// @return {Int} -> the array length | ||
// | ||
function length(a){ | ||
if (Array.isArray(a)){ | ||
// return array length if argument is array | ||
return a.length; | ||
} | ||
// else return 1 if NaN or positive integer if Number | ||
return isNaN(a) ? 1 : Math.max(1, Math.floor(a)); | ||
} | ||
exports.length = length; | ||
exports.size = length; | ||
// Wrap a value between a low and high range | ||
@@ -299,9 +318,11 @@ // Similar to mod, expect the low range is also adjustable | ||
// Ignore all non numeric values | ||
// Works with multidimensional arrays by flattening first | ||
// | ||
// @param {Array} -> input array | ||
// @return {Number} -> summed array | ||
// | ||
function sum(a=[0]){ | ||
let s = 0; | ||
toArray(a).forEach((v) => { | ||
s += isNaN(v)? 0 : v; | ||
flatten(toArray(a)).forEach((v) => { | ||
s += isNaN(v) ? 0 : v; | ||
}); | ||
@@ -340,3 +361,4 @@ return s; | ||
// @param {Number/Array} -> input values | ||
// @return {Int/Array} -> normailzed values | ||
// @return {Number/Array} -> normalized values | ||
// | ||
function normalize(a=[0]){ | ||
@@ -354,2 +376,14 @@ // get minimum and maximum | ||
// Signed Normalize all the values in an array between -1. and 1. | ||
// The highest value will be 1, the lowest value will be -1. | ||
// | ||
// @param {Number/Array} -> input values | ||
// @return {Number/Array} -> signed normalized values | ||
// | ||
function signedNormalize(a=[0]){ | ||
return subtract(multiply(normalize(a), 2), 1); | ||
} | ||
exports.signedNormalize = signedNormalize; | ||
exports.snorm = signedNormalize; | ||
// Plot an array of values to the console in the form of an | ||
@@ -356,0 +390,0 @@ // ascii chart and return chart from function. If you just want the |
@@ -68,2 +68,5 @@ | ||
}); | ||
test("Gen.spread([1,2,3,4,5,6])", () => { | ||
expect(Gen.spread([1,2,3,4,5,6])).toStrictEqual([0, 1, 2, 3, 4, 5]); | ||
}); | ||
test("Gen.spread(6, 12)", () => { | ||
@@ -85,2 +88,5 @@ expect(Gen.spread(6, 12)).toStrictEqual([0, 2, 4, 6, 8, 10]); | ||
}); | ||
test("Gen.spreadFloat([1,2,3,4])", () => { | ||
expect(Gen.spreadFloat([1,2,3,4])).toStrictEqual([0, 0.25, 0.5, 0.75]); | ||
}); | ||
test("Gen.spreadFloat(4, 2)", () => { | ||
@@ -99,2 +105,5 @@ expect(Gen.spreadFloat(4, 2)).toStrictEqual([0, 0.5, 1, 1.5]); | ||
}); | ||
test("Gen.spreadInc([1,2,3,4,5,6])", () => { | ||
expect(Gen.spreadInc([1,2,3,4,5,6])).toStrictEqual([0, 1, 2, 3, 4, 6]); | ||
}); | ||
test("Gen.spreadInc(6, 12)", () => { | ||
@@ -116,2 +125,5 @@ expect(Gen.spreadInc(6, 12)).toStrictEqual([0, 2, 4, 7, 9, 12]); | ||
}); | ||
test("Gen.spreadIncF([1,2,3,4,5])", () => { | ||
expect(Gen.spreadIncF([1,2,3,4,5])).toStrictEqual([0, 0.25, 0.5, 0.75, 1]); | ||
}); | ||
test("Gen.spreadIncF(5, 2)", () => { | ||
@@ -127,2 +139,5 @@ expect(Gen.spreadIncF(5, 2)).toStrictEqual([0, 0.5, 1, 1.5, 2]); | ||
}); | ||
test("Gen.spreadExp(new Array(10), 0, 10, 2)", () => { | ||
expect(Gen.spreadExp(new Array(10), 0, 10, 2)).toStrictEqual([0, 0, 0, 0, 1, 2, 3, 4, 6, 8]); | ||
}); | ||
test("Gen.spreadIncExp(10, 0, 10, 2)", () => { | ||
@@ -137,2 +152,5 @@ expect(Gen.spreadIncExp(10, 0, 10, 2)).toStrictEqual([0, 0, 0, 1, 1, 3, 4, 6, 7, 10]); | ||
}); | ||
test("Gen.spreadIncExpF(new Array(12), 0, 10, 0.5)", () => { | ||
expect(Gen.spreadIncExpF(new Array(12), 0, 10, 0.5)).toStrictEqual([0, 3.0151134457776365, 4.264014327112209, 5.222329678670935, 6.030226891555273, 6.74199862463242, 7.385489458759964, 7.977240352174656, 8.528028654224418, 9.04534033733291, 9.534625892455924, 10]); | ||
}); | ||
@@ -155,2 +173,5 @@ test("Gen.fill()", () => { | ||
}) | ||
test("Gen.sine(Array(8), 1, -5, 5)", () => { | ||
expect(Gen.sine(Array(8), 1, -5, 5)).toStrictEqual([0, 3, 5, 3, 0, -3, -5, -3,]); | ||
}) | ||
test("Gen.cos(30, Gen.sinF(30, 2), -5, 5)", () => { | ||
@@ -163,2 +184,5 @@ expect(Gen.cosine(8, Gen.sinF(8, 2), -5, 5)).toStrictEqual([ 5, 3, 5, -3, 5, -3, 5, 3,]); | ||
}); | ||
test("Gen.saw(Array(8), 8.5)", () => { | ||
expect(Gen.saw(Array(8), 8.5)).toStrictEqual([ 0, 0, 1, 2, 3, 3, 4, 5,]); | ||
}); | ||
test("Gen.sawF(8, 2.5)", () => { | ||
@@ -174,2 +198,5 @@ expect(Gen.sawF(8, 2.5)).toStrictEqual([ -1, -0.375, 0.25, 0.875, -0.5, 0.125, 0.75, -0.625,]); | ||
}); | ||
test("Gen.square(Array(8), 3, 0, 12, 0.8)", () => { | ||
expect(Gen.square(Array(8), 3, 0, 12, 0.8)).toStrictEqual([12, 12, 12, 12, 12, 0, 12, 12]); | ||
}); | ||
test("Gen.squareF(8, 4, 0, 1, 0.2)", () => { | ||
@@ -216,2 +243,5 @@ expect(Gen.squareF(8, 4, 0, 1, 0.2)).toStrictEqual([1, 0, 1, 0, 1, 0, 1, 0]); | ||
}); | ||
test("Algo.euclid(Array(8), Array(5))", () => { | ||
expect(Algo.euclid(Array(8), Array(5))).toStrictEqual([1, 0, 1, 1, 0, 1, 1, 0]); | ||
}); | ||
test("Algo.euclid(8, 3, 1)", () => { | ||
@@ -227,2 +257,5 @@ expect(Algo.euclid(8, 3, 1)).toStrictEqual([ 0, 1, 0, 0, 1, 0, 0, 1]) | ||
}); | ||
test("Algo.fastEuclid(Array(8), Array(5))", () => { | ||
expect(Algo.fastEuclid(Array(8), Array(5))).toStrictEqual([ 1, 0, 1, 0, 1, 1, 0, 1 ]); | ||
}); | ||
test("Algo.fastEuclid(8, 3, 1)", () => { | ||
@@ -346,2 +379,5 @@ expect(Algo.fastEuclid(8, 3, 1)).toStrictEqual([ 0, 1, 0, 0, 1, 0, 0, 1 ]); | ||
}); | ||
// test("Algo.pisano(Array(7))", () => { | ||
// expect(Algo.pisano(Array(7))).toStrictEqual([ 0, 1, 1, 2, 3, 5, 1, 6, 0, 6, 6, 5, 4, 2, 6, 1 ]); | ||
// }); | ||
test("Algo.pisano(4, 10)", () => { | ||
@@ -375,2 +411,5 @@ expect(Algo.pisano(4, 10)).toStrictEqual([ 0, 1, 1, 2, 3, 1, 0, 1, 1, 2 ]); | ||
}); | ||
test('Algo.infinitySeries(Array(16), [0, 3])', () => { | ||
expect(Algo.infinitySeries(Array(16), [0, 3])).toStrictEqual([ 0, 3, -3, 6, 3, 0, -6, 9, -3, 6, 0, 3, 6, -3, -9, 12]); | ||
}); | ||
test('Algo.infSeries(8, [0, 1], 120)', () => { | ||
@@ -414,2 +453,6 @@ expect(Algo.infinitySeries(8, [0, 1], 120)).toStrictEqual([ -4, 5, 3, -2, 5, -4, -6, 7]); | ||
}); | ||
test("Rand.random([1,2,3,4,5], 2)", () => { | ||
Rand.seed(4827); | ||
expect(Rand.random([1,2,3,4,5], 2)).toStrictEqual([ 1, 0, 1, 1, 0 ]); | ||
}); | ||
@@ -434,2 +477,6 @@ test("Rand.random(5, 2)", () => { | ||
}); | ||
test("Rand.drunkFloat([1,2,3,4,5])", () => { | ||
Rand.seed(1618); | ||
expect(Rand.drunkFloat([1,2,3,4,5])).toStrictEqual([ 0.49305378228860675, 0.4599542055791346, 0.8460817983354717, 0.9639116027672727, 0.4009600948886277 ]); | ||
}); | ||
@@ -444,3 +491,12 @@ test("Rand.coin(5)", () => { | ||
}); | ||
test("Rand.coin([1,2,3,4,5])", () => { | ||
Rand.seed(3141); | ||
expect(Rand.coin([1,2,3,4,5])).toStrictEqual([ 0, 1, 0, 0, 1 ]); | ||
}); | ||
test("Rand.dice([1,2,3,4,5])", () => { | ||
expect(Rand.dice([1,2,3,4,5])).toStrictEqual([ 3, 6, 6, 4, 3 ]); | ||
}); | ||
test("Rand.shuffle()", () => { | ||
@@ -469,2 +525,6 @@ expect(Rand.shuffle()).toStrictEqual([0]); | ||
}); | ||
test("Rand.clave([1,2,3,4,5,6,7,8])", () => { | ||
Rand.seed(7483); | ||
expect(Rand.clave([1,2,3,4,5,6,7,8])).toStrictEqual([ 1, 0, 1, 0, 0, 1, 0, 1]); | ||
}); | ||
test("Rand.clave(5)", () => { | ||
@@ -484,2 +544,6 @@ expect(Rand.clave(5)).toStrictEqual([ 1, 0, 0, 1, 0 ]); | ||
}); | ||
test('Rand.urn([1,2,3,4,5])', () => { | ||
Rand.seed(7563); | ||
expect(Rand.urn([1,2,3,4,5])).toStrictEqual([ 5, 8, 3, 1, 7 ]); | ||
}); | ||
test('Rand.urn(10, 5)', () => { | ||
@@ -496,2 +560,6 @@ expect(Rand.urn(10, 5)).toStrictEqual([ 3, 0, 2, 1, 4, 2, 4, 3, 1, 0 ]); | ||
}); | ||
test("Rand.choose([1,2,3,4,5], [0, 1, 2, 3, 5, 8])", () => { | ||
Rand.seed(9351); | ||
expect(Rand.choose([1,2,3,4,5], [0, 1, 2, 3, 5, 8])).toStrictEqual([ 3, 5, 2, 5, 3 ]); | ||
}); | ||
test("Rand.choose(5, ['c', 'e', 'g'])", () => { | ||
@@ -505,2 +573,6 @@ expect(Rand.choose(5, ['c', 'e', 'g'])).toStrictEqual([ 'g', 'g', 'e', 'c', 'g' ]); | ||
}); | ||
test("Rand.pick([1,2,3,4,5], [0, 1, 2, 3, 5, 8])", () => { | ||
Rand.seed(9351); | ||
expect(Rand.pick([1,2,3,4,5], [0, 1, 2, 3, 5, 8])).toStrictEqual([ 3, 8, 1, 2, 5 ]); | ||
}); | ||
test("Rand.pick(5, ['c', 'e', ['g', 'd']])", () => { | ||
@@ -518,2 +590,8 @@ expect(Rand.pick(5, ['c', 'e', ['g', 'd']])).toStrictEqual([ [ 'g', 'd' ], 'e', 'c', 'e', 'c' ]); | ||
}); | ||
test("Rand.expand([0, 7, 3, 5, 0, -1], Gen.spread(10))", () => { | ||
let arr = [0, 7, 3, 5, 0, -1]; | ||
let arr2 = Gen.spread(10); | ||
Rand.seed(3141); | ||
expect(Rand.expand(arr, arr2)).toStrictEqual([ 0, 7, 3, 5, 0, -1, 6, 8, 7, 2 ]); | ||
}); | ||
} | ||
@@ -571,2 +649,5 @@ | ||
}); | ||
test("Mod.pad([3, 7, 12], Array(8))", () => { | ||
expect(Mod.pad([3, 7, 12], Array(8))).toStrictEqual([ 3, 7, 12, 0, 0, 0, 0, 0 ]); | ||
}); | ||
test("Mod.pad(['c', 'f', 'g'], 8, '-', 4)", () => { | ||
@@ -723,2 +804,5 @@ expect(Mod.pad(['c', 'f', 'g'], 8, '-', 4)).toStrictEqual([ '-', '-', '-', '-', 'c', 'f', 'g', '-' ]); | ||
}); | ||
test("Mod.stretch([0, 12, 3, 7], Array(9))", () => { | ||
expect(Mod.stretch([0, 12, 3, 7], Array(9))).toStrictEqual([ 0, 4.5, 9, 10.875, 7.5, 4.125, 4, 5.5, 7 ]); | ||
}); | ||
@@ -1259,2 +1343,21 @@ test("Mod.stretch([0, 12, 3, 7], 9, 'none')", () => { | ||
test("Util.length()", () => { | ||
expect(Util.length()).toStrictEqual(1); | ||
}); | ||
test("Util.length([1, 2, 3, 4, 5])", () => { | ||
expect(Util.length([1, 2, 3, 4, 5])).toStrictEqual(5); | ||
}); | ||
test("Util.size(8)", () => { | ||
expect(Util.size(8)).toStrictEqual(8); | ||
}); | ||
test("Util.size(Math.PI)", () => { | ||
expect(Util.size(Math.PI)).toStrictEqual(3); | ||
}); | ||
test("Util.size(-Math.PI)", () => { | ||
expect(Util.size(-Math.PI)).toStrictEqual(1); | ||
}); | ||
test("Util.size('foo')", () => { | ||
expect(Util.size('foo')).toStrictEqual(1); | ||
}); | ||
test("Util.sum([1, 2, 3, 4])", () => { | ||
@@ -1266,2 +1369,5 @@ expect(Util.sum([1, 2, 3, 4])).toStrictEqual(10); | ||
}); | ||
test("Util.sum([1,2,[3,4,[5,6],7],8])", () => { | ||
expect(Util.sum([1,2,[3,4,[5,6],7],8])).toStrictEqual(36); | ||
}); | ||
@@ -1290,2 +1396,8 @@ test("Util.trunc()", () => { | ||
}); | ||
test("Util.snorm([0, 3, 9, 12, 24])", () => { | ||
expect(Util.snorm([0, 3, 9, 12, 24])).toStrictEqual([ -1, -0.75, -0.25, 0, 1 ]); | ||
}); | ||
test("Util.snorm([5, [12, [4, 17]], 3, 1])", () => { | ||
expect(Util.snorm([5, [12, [4, 17]], 3, 1])).toStrictEqual([ -0.5, [ 0.375, [ -0.625, 1 ] ], -0.75, -1 ]); | ||
}); | ||
@@ -1292,0 +1404,0 @@ test("Util.map()", () => { |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
12714017
40906
420