@audio/mir-tonnetz 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +29 -0
- package/tonnetz.js +28 -0
package/package.json
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@audio/mir-tonnetz",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Tonal centroid (Tonnetz) — 6-dim interval-circle projection of chroma (Harte 2006)",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"sideEffects": false,
|
|
7
|
+
"main": "tonnetz.js",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": "./tonnetz.js",
|
|
10
|
+
"./package.json": "./package.json"
|
|
11
|
+
},
|
|
12
|
+
"files": [
|
|
13
|
+
"tonnetz.js"
|
|
14
|
+
],
|
|
15
|
+
"keywords": [
|
|
16
|
+
"audio",
|
|
17
|
+
"dsp",
|
|
18
|
+
"mir",
|
|
19
|
+
"tonnetz"
|
|
20
|
+
],
|
|
21
|
+
"license": "MIT",
|
|
22
|
+
"author": "Dmitry Iv. <dfcreative@gmail.com>",
|
|
23
|
+
"engines": {
|
|
24
|
+
"node": ">=18"
|
|
25
|
+
},
|
|
26
|
+
"publishConfig": {
|
|
27
|
+
"access": "public"
|
|
28
|
+
}
|
|
29
|
+
}
|
package/tonnetz.js
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
// Tonal centroid (Tonnetz) — project 12-bin chroma onto three interval circles:
|
|
2
|
+
// fifths (r=1), minor thirds (r=1), major thirds (r=0.5) → 6-dim harmonic space.
|
|
3
|
+
// Harte, Sandler & Gasser, "Detecting harmonic change in musical audio", 2006.
|
|
4
|
+
|
|
5
|
+
const CIRCLES = [
|
|
6
|
+
[7 * Math.PI / 6, 1], // fifths
|
|
7
|
+
[3 * Math.PI / 2, 1], // minor thirds
|
|
8
|
+
[2 * Math.PI / 3, 0.5], // major thirds
|
|
9
|
+
]
|
|
10
|
+
|
|
11
|
+
export default function tonnetz (chroma) {
|
|
12
|
+
let sum = 0
|
|
13
|
+
for (let k = 0; k < 12; k++) sum += chroma[k]
|
|
14
|
+
let out = new Float32Array(6)
|
|
15
|
+
if (sum <= 0) return out
|
|
16
|
+
for (let j = 0; j < 3; j++) {
|
|
17
|
+
let [w, r] = CIRCLES[j]
|
|
18
|
+
let s = 0, c = 0
|
|
19
|
+
for (let k = 0; k < 12; k++) {
|
|
20
|
+
let v = chroma[k] / sum
|
|
21
|
+
s += r * Math.sin(w * k) * v
|
|
22
|
+
c += r * Math.cos(w * k) * v
|
|
23
|
+
}
|
|
24
|
+
out[2 * j] = s
|
|
25
|
+
out[2 * j + 1] = c
|
|
26
|
+
}
|
|
27
|
+
return out
|
|
28
|
+
}
|