Public
Edited
May 16, 2023
Importers
Insert cell
# Harmonic Series (WIP)
Easy-to-use JS tools for the harmonic series in music specifically, and progressions more generally.

Inputs:
- a = first term of progression
- n = number of terms in progression
- d = common difference
- p = precision level for rounding

Insert cell
Insert cell
viewof demoHz = Inputs.range([20, 10000], {label: "Frequency (Hz):", step: 1, value: 110})
Insert cell
demoNotes = d3.cross([demoHz],harmonicProgression(1,10,1,3))
Insert cell
harmonicFinder = (a, n, d) => {
// a = first term of progression
// n = number of terms in progression
// d = common difference
return 1/(a+(n-1)*d)
}
Insert cell
harmonicFinder(1,2,3)
Insert cell
harmonicSum = (n) => {
// sums harmonic series until nth term
// by Surbhi Tyagi 2022
var s = 0
for (var i=1; i<=n; i++){s=s+1/i}
return s
}
Insert cell
harmonicSum(5)
Insert cell
harmonicProgression = (a, n, d, p) => {
// a = first term of progression
// n = number of terms in progression
// d = common difference
// p = precision

// when d=1: 1/2, 1/3, 1/4, 1/5...
// when d=2: 1/2, 1/4, 1/6, 1/8...
var arr = []
for (var i=1; i<=n; i++){
var s = (1/(a+(i-1)*d))
arr.push(round(s,p))
}
return arr
}
Insert cell
harmonicProgression(1,10,1,3)
Insert cell
// octaves

geometricProgression = (a, n, d, p) => {
// a = first term of progression
// n = number of terms in progression
// d = common difference
// p = precision

// when d=2: 1/2, 1/4, 1/8, 1/16...
// when d=3: 1/2, 1/6, 1/18, 1/54...
var arr = []
for (var i=1; i<=n; i++){
var g = 1/(a*(d**(i-1)))
arr.push(round(g,p))
}
return arr
}
Insert cell
geometricProgression(2,10,2,3)
Insert cell
// payItForward
// returns a straightforward or reciprocal progression
// requires round

payItForward = (a,n,d,p,t) => {
// a = first term of progression
// n = number of terms in progression
// d = common difference
// p = precision
// t = type
// types: "r" for arithmetic, "h" for harmonic (1/arithmetic)
// "g" for geometric, "gr" for 1/geometric
var arr = []
for (var i=1; i<=n; i++){
var r = a+(i-1)*d
var h = 1/r
var g = a*(d**(i-1))
var gr = 1/g
switch(t){
case "r": arr.push(round(r,p)); break;
case "h": arr.push(round(h,p)); break;
case "g": arr.push(round(g,p)); break;
case "gr": arr.push(round(gr,p)); break;
default:
console.log(`Type of progression required`);
}
}
return arr
}
Insert cell
payItForward(1,10,2,3,"h")
Insert cell
// WIP
harmonicRatios = (a,n,d,p) => {
// a = first term of progression
// n = number of terms in progression
// d = common difference
// p = precision
// requires round
var arr = []

// ordinal indicators by Tomas Langkass 2016
// https://stackoverflow.com/questions/13627308/add-st-nd-rd-and-th-ordinal-suffix-to-a-number
function nth(n){return["st","nd","rd"][((n+90)%100-10)%10-1]||"th"}

for (var i=1; i<=n; i++){
var s = (1/(a+(i-1)*d))
var r = 1 + "/" + (a+(i-1)*d)
var o = i + nth(i) + " harmonic of n+" + d
arr.push({Fraction: round(s,p), Ratio: r, Notes: o})
}
return arr
}
Insert cell
musicalHarmonics(1,125)
Insert cell
Insert cell
Insert cell
// musicalHarmonics
// divides every whole number between min...max by the closest power of 2
// returns an array of objects similar to Quartermaster
// requires ratioToCents, ratioToSavarts, round

musicalHarmonics = (min,max) => {
var arr = []

for (var i=min; i<=max; i++){
var p = blpo2(i)
var r = i + "/" + p
var o = i + nth(i) + " harmonic"
var c = Math.abs(round(ratioToCents(i/p),3))
var sv = Math.abs(round(ratioToSavarts(i/p),3))
var viz = [{Blue: c, Pink: 1200-c}]
arr.push({Fraction: round(i/p,3), Ratio: r, Cents: c, Savarts: sv, Notes: o, Viz: viz})
}
return arr
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more