@tremolo-ui/functions 0.1.6 → 0.2.1
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/dist/index.cjs +17 -86
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +0 -80
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.ts +0 -80
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +16 -85
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/index.ts +0 -9
- package/src/math.ts +0 -43
- package/src/midi.ts +0 -21
- package/src/types.ts +0 -1
- package/src/util.ts +0 -12
package/dist/index.cjs
CHANGED
|
@@ -1,41 +1,30 @@
|
|
|
1
|
-
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
2
|
//#region src/math.ts
|
|
3
3
|
/**
|
|
4
4
|
* clamp value between min and max
|
|
5
|
-
* @category Math
|
|
6
5
|
*/
|
|
7
6
|
function clamp(value, min, max) {
|
|
8
7
|
return Math.max(min, Math.min(value, max));
|
|
9
8
|
}
|
|
10
9
|
/**
|
|
11
10
|
* Normalize the value from 0 to 1
|
|
12
|
-
* @category Math
|
|
13
11
|
*/
|
|
14
|
-
function normalizeValue(rawValue
|
|
12
|
+
function normalizeValue(rawValue, min, max, skew = 1) {
|
|
15
13
|
if (min >= max) throw new RangeError("requirements: min < max");
|
|
16
|
-
const v = clamp((rawValue
|
|
14
|
+
const v = clamp((rawValue - min) / (max - min), 0, 1);
|
|
17
15
|
return Math.pow(v, skew);
|
|
18
16
|
}
|
|
19
17
|
/**
|
|
20
18
|
* Convert normalized values back to raw values.
|
|
21
|
-
* @category Math
|
|
22
19
|
*/
|
|
23
20
|
function rawValue(normalizedValue, min, max, skew = 1) {
|
|
24
21
|
if (min >= max) throw new RangeError("requirements: min < max");
|
|
25
22
|
return min + (skew == 1 ? clamp(normalizedValue, 0, 1) : Math.exp(Math.log(clamp(normalizedValue, 0, 1)) / skew)) * (max - min);
|
|
26
23
|
}
|
|
27
|
-
/**
|
|
28
|
-
*
|
|
29
|
-
* @category Math
|
|
30
|
-
*/
|
|
31
24
|
function skewWithCenterValue(centerValue, min, max) {
|
|
32
25
|
if (!(min <= centerValue && centerValue <= max)) throw new RangeError("requirements: min <= centerValue <= max");
|
|
33
26
|
return Math.log(.5) / Math.log((centerValue - min) / (max - min));
|
|
34
27
|
}
|
|
35
|
-
/**
|
|
36
|
-
*
|
|
37
|
-
* @category Math
|
|
38
|
-
*/
|
|
39
28
|
function stepValue(value, step) {
|
|
40
29
|
if (step <= 0) throw new RangeError("requirements: step > 0");
|
|
41
30
|
const quotient = Math.floor(value / step);
|
|
@@ -44,64 +33,31 @@ function stepValue(value, step) {
|
|
|
44
33
|
const next = toFixed((quotient + 1) * step, decimalDigits);
|
|
45
34
|
return Math.abs(value - v) < Math.abs(value - next) ? v : next;
|
|
46
35
|
}
|
|
47
|
-
/**
|
|
48
|
-
*
|
|
49
|
-
* @category Math
|
|
50
|
-
*/
|
|
51
36
|
function toFixed(x, fractionDigits) {
|
|
52
37
|
return Number(x.toFixed(fractionDigits));
|
|
53
38
|
}
|
|
54
|
-
/**
|
|
55
|
-
*
|
|
56
|
-
* @category Math
|
|
57
|
-
*/
|
|
58
39
|
function integerPart(x) {
|
|
59
40
|
if (Number.isNaN(x)) return;
|
|
60
41
|
return String(x).split(".")[0];
|
|
61
42
|
}
|
|
62
|
-
/**
|
|
63
|
-
*
|
|
64
|
-
* @category Math
|
|
65
|
-
*/
|
|
66
43
|
function decimalPart(x) {
|
|
67
44
|
return String(x).split(".")[1];
|
|
68
45
|
}
|
|
69
|
-
|
|
70
|
-
*
|
|
71
|
-
* @category Math
|
|
72
|
-
*/
|
|
73
|
-
function radian(degree$1) {
|
|
74
|
-
return Math.PI * degree$1 / 180;
|
|
46
|
+
function radian(degree) {
|
|
47
|
+
return Math.PI * degree / 180;
|
|
75
48
|
}
|
|
76
|
-
|
|
77
|
-
*
|
|
78
|
-
* @category Math
|
|
79
|
-
*/
|
|
80
|
-
function degree(radian$1) {
|
|
81
|
-
return 180 * radian$1 / Math.PI;
|
|
49
|
+
function degree(radian) {
|
|
50
|
+
return 180 * radian / Math.PI;
|
|
82
51
|
}
|
|
83
|
-
/**
|
|
84
|
-
*
|
|
85
|
-
* @category Math
|
|
86
|
-
*/
|
|
87
52
|
function mapValue(value, inMin, inMax, outMin, outMax) {
|
|
88
53
|
return (value - inMin) / (inMax - inMin) * (outMax - outMin) + outMin;
|
|
89
54
|
}
|
|
90
|
-
/**
|
|
91
|
-
*
|
|
92
|
-
* @category Math
|
|
93
|
-
*/
|
|
94
55
|
function dbToGain(db) {
|
|
95
56
|
return Math.pow(10, db / 20);
|
|
96
57
|
}
|
|
97
|
-
/**
|
|
98
|
-
*
|
|
99
|
-
* @category Math
|
|
100
|
-
*/
|
|
101
58
|
function gainToDb(gain) {
|
|
102
59
|
return 20 * (Math.log(gain) / Math.LN10);
|
|
103
60
|
}
|
|
104
|
-
|
|
105
61
|
//#endregion
|
|
106
62
|
//#region src/util.ts
|
|
107
63
|
function styleHelper(value, op, influencer) {
|
|
@@ -114,30 +70,17 @@ function styleHelper(value, op, influencer) {
|
|
|
114
70
|
else if (typeof value == "number") return `${value}px`;
|
|
115
71
|
else return value;
|
|
116
72
|
}
|
|
117
|
-
/**
|
|
118
|
-
* @category Utility
|
|
119
|
-
*/
|
|
120
73
|
function isEmpty(obj) {
|
|
121
74
|
return Object.keys(obj).length == 0;
|
|
122
75
|
}
|
|
123
|
-
/**
|
|
124
|
-
* @category Utility
|
|
125
|
-
*/
|
|
126
76
|
function mod(n, m) {
|
|
127
77
|
return (n % m + m) % m;
|
|
128
78
|
}
|
|
129
|
-
/**
|
|
130
|
-
* @category Utility
|
|
131
|
-
*/
|
|
132
79
|
function xor(a = false, b = false) {
|
|
133
80
|
return (a || b) && a != b;
|
|
134
81
|
}
|
|
135
|
-
|
|
136
82
|
//#endregion
|
|
137
83
|
//#region src/midi.ts
|
|
138
|
-
/**
|
|
139
|
-
* @category MIDI
|
|
140
|
-
*/
|
|
141
84
|
const whiteKeys = [
|
|
142
85
|
"A",
|
|
143
86
|
"B",
|
|
@@ -147,9 +90,6 @@ const whiteKeys = [
|
|
|
147
90
|
"F",
|
|
148
91
|
"G"
|
|
149
92
|
];
|
|
150
|
-
/**
|
|
151
|
-
* @category MIDI
|
|
152
|
-
*/
|
|
153
93
|
const noteKeys = [
|
|
154
94
|
"C",
|
|
155
95
|
"C#",
|
|
@@ -164,11 +104,8 @@ const noteKeys = [
|
|
|
164
104
|
"A#",
|
|
165
105
|
"B"
|
|
166
106
|
];
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
*/
|
|
170
|
-
function parseNoteName(noteName$1) {
|
|
171
|
-
const m = noteName$1.match(/^([a-g])(#{0,2}|b{0,2})(-?\d+)$/i);
|
|
107
|
+
function parseNoteName(noteName) {
|
|
108
|
+
const m = noteName.match(/^([a-g])(#{0,2}|b{0,2})(-?\d+)$/i);
|
|
172
109
|
if (!m) throw new Error("Invalid note name");
|
|
173
110
|
const [, letter, accidental, octave] = m;
|
|
174
111
|
return {
|
|
@@ -179,10 +116,9 @@ function parseNoteName(noteName$1) {
|
|
|
179
116
|
}
|
|
180
117
|
/**
|
|
181
118
|
* Convert noteName to noteNumber
|
|
182
|
-
* @category MIDI
|
|
183
119
|
*/
|
|
184
|
-
function noteNumber(noteName
|
|
185
|
-
const { letter, accidental, octave } = parseNoteName(noteName
|
|
120
|
+
function noteNumber(noteName) {
|
|
121
|
+
const { letter, accidental, octave } = parseNoteName(noteName);
|
|
186
122
|
const noteIndex = noteKeys.indexOf(letter.toLocaleUpperCase());
|
|
187
123
|
const accidentalValue = (accidental[0] == "b" ? -1 : 1) * accidental.length;
|
|
188
124
|
return noteIndex + 12 * (Number(octave) + 1) + accidentalValue;
|
|
@@ -192,23 +128,20 @@ function noteNumber(noteName$1) {
|
|
|
192
128
|
* C-1 = 0
|
|
193
129
|
* G9 = 127
|
|
194
130
|
* @param noteNumber noteNumber
|
|
195
|
-
* @category MIDI
|
|
196
131
|
*/
|
|
197
|
-
function noteName(noteNumber
|
|
198
|
-
const noteIndex = mod(noteNumber
|
|
199
|
-
const octave = Math.floor(noteNumber
|
|
132
|
+
function noteName(noteNumber) {
|
|
133
|
+
const noteIndex = mod(noteNumber, 12);
|
|
134
|
+
const octave = Math.floor(noteNumber / 12) - 1;
|
|
200
135
|
return `${noteKeys[noteIndex]}${octave}`;
|
|
201
136
|
}
|
|
202
137
|
/**
|
|
203
138
|
* Convert noteNumber to noteKey
|
|
204
|
-
* @category MIDI
|
|
205
139
|
*/
|
|
206
|
-
function noteKey(noteNumber
|
|
207
|
-
return noteKeys[mod(noteNumber
|
|
140
|
+
function noteKey(noteNumber) {
|
|
141
|
+
return noteKeys[mod(noteNumber, 12)];
|
|
208
142
|
}
|
|
209
143
|
/**
|
|
210
144
|
* @param note noteNumber: 0 ~ 127 or noteName e.g. 'C3'
|
|
211
|
-
* @category MIDI
|
|
212
145
|
*/
|
|
213
146
|
function isWhiteKey(note) {
|
|
214
147
|
const n = typeof note == "string" ? noteNumber(note) : note;
|
|
@@ -216,7 +149,6 @@ function isWhiteKey(note) {
|
|
|
216
149
|
}
|
|
217
150
|
/**
|
|
218
151
|
* @param note noteNumber: 0 ~ 127 or noteName e.g. 'C3'
|
|
219
|
-
* @category MIDI
|
|
220
152
|
*/
|
|
221
153
|
function isBlackKey(note) {
|
|
222
154
|
return !isWhiteKey(note);
|
|
@@ -226,13 +158,11 @@ function isBlackKey(note) {
|
|
|
226
158
|
* @param detune [cent]
|
|
227
159
|
* @param a4 A4 frequency [Hz]
|
|
228
160
|
* @returns frequency [Hz]
|
|
229
|
-
* @category MIDI
|
|
230
161
|
*/
|
|
231
162
|
function noteToFrequency(note, detune = 0, a4 = 440) {
|
|
232
163
|
const n = typeof note == "string" ? noteNumber(note) : note;
|
|
233
164
|
return a4 / 32 * 2 ** ((n - 9 + detune / 100) / 12);
|
|
234
165
|
}
|
|
235
|
-
|
|
236
166
|
//#endregion
|
|
237
167
|
exports.clamp = clamp;
|
|
238
168
|
exports.dbToGain = dbToGain;
|
|
@@ -260,4 +190,5 @@ exports.styleHelper = styleHelper;
|
|
|
260
190
|
exports.toFixed = toFixed;
|
|
261
191
|
exports.whiteKeys = whiteKeys;
|
|
262
192
|
exports.xor = xor;
|
|
193
|
+
|
|
263
194
|
//# sourceMappingURL=index.cjs.map
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","names":["rawValue","degree","radian","noteName","noteNumber"],"sources":["../src/math.ts","../src/util.ts","../src/midi.ts"],"sourcesContent":["/**\n * clamp value between min and max\n * @category Math\n */\nexport function clamp(value: number, min: number, max: number) {\n return Math.max(min, Math.min(value, max))\n}\n\n/**\n * Normalize the value from 0 to 1\n * @category Math\n */\nexport function normalizeValue(\n rawValue: number,\n min: number,\n max: number,\n skew = 1,\n) {\n if (min >= max) throw new RangeError('requirements: min < max')\n const v = clamp((rawValue - min) / (max - min), 0, 1)\n return Math.pow(v, skew)\n}\n\n/**\n * Convert normalized values back to raw values.\n * @category Math\n */\nexport function rawValue(\n normalizedValue: number,\n min: number,\n max: number,\n skew = 1,\n) {\n if (min >= max) throw new RangeError('requirements: min < max')\n const v =\n skew == 1\n ? clamp(normalizedValue, 0, 1)\n : Math.exp(Math.log(clamp(normalizedValue, 0, 1)) / skew)\n return min + v * (max - min)\n}\n\n/**\n *\n * @category Math\n */\nexport function skewWithCenterValue(\n centerValue: number,\n min: number,\n max: number,\n) {\n if (!(min <= centerValue && centerValue <= max))\n throw new RangeError('requirements: min <= centerValue <= max')\n return Math.log(0.5) / Math.log((centerValue - min) / (max - min))\n}\n\n/**\n *\n * @category Math\n */\nexport function stepValue(value: number, step: number) {\n if (step <= 0) throw new RangeError('requirements: step > 0')\n const quotient = Math.floor(value / step)\n const decimalDigits = decimalPart(step)?.length\n const v = toFixed(quotient * step, decimalDigits)\n const next = toFixed((quotient + 1) * step, decimalDigits)\n return Math.abs(value - v) < Math.abs(value - next) ? v : next\n}\n\n/**\n *\n * @category Math\n */\nexport function toFixed(x: number, fractionDigits?: number) {\n return Number(x.toFixed(fractionDigits))\n}\n\n/**\n *\n * @category Math\n */\nexport function integerPart(x: number | string): string | undefined {\n if (Number.isNaN(x)) {\n return undefined\n }\n return String(x).split('.')[0]\n}\n\n/**\n *\n * @category Math\n */\nexport function decimalPart(x: number | string): string | undefined {\n return String(x).split('.')[1]\n}\n\n/**\n *\n * @category Math\n */\nexport function radian(degree: number) {\n return (Math.PI * degree) / 180\n}\n\n/**\n *\n * @category Math\n */\nexport function degree(radian: number) {\n return (180 * radian) / Math.PI\n}\n\n/**\n *\n * @category Math\n */\nexport function mapValue(\n value: number,\n inMin: number,\n inMax: number,\n outMin: number,\n outMax: number,\n) {\n return ((value - inMin) / (inMax - inMin)) * (outMax - outMin) + outMin\n}\n\n/**\n *\n * @category Math\n */\nexport function dbToGain(db: number) {\n return Math.pow(10, db / 20)\n}\n\n/**\n *\n * @category Math\n */\nexport function gainToDb(gain: number) {\n return 20 * (Math.log(gain) / Math.LN10)\n}\n","type Operator = '+' | '-' | '*' | '/'\n\n/**\n * @category Utility\n */\nexport function styleHelper(value: string | number): string\nexport function styleHelper(\n value: string | number,\n op: Operator,\n influencer?: number,\n): string\nexport function styleHelper(\n value: string | number,\n op?: Operator,\n influencer?: number,\n) {\n if (op && influencer) {\n if (typeof value == 'number') {\n if (op == '+') return `${value + influencer}px`\n if (op == '-') return `${value - influencer}px`\n if (op == '*') return `${value * influencer}px`\n if (op == '/') return `${value / influencer}px`\n } else {\n return `calc(${value}px ${op} ${influencer})`\n }\n } else {\n if (typeof value == 'number') {\n return `${value}px`\n } else {\n return value\n }\n }\n}\n\n/**\n * @category Utility\n */\nexport function isEmpty(obj: object) {\n return Object.keys(obj).length == 0\n}\n\n/**\n * @category Utility\n */\nexport function mod(n: number, m: number) {\n return ((n % m) + m) % m\n}\n\n/**\n * @category Utility\n */\nexport function xor(a = false, b = false) {\n return (a || b) && a != b\n}\n","import { mod } from './util'\n\n/**\n * @category MIDI\n */\nexport const whiteKeys = ['A', 'B', 'C', 'D', 'E', 'F', 'G'] as const\n\n/**\n * @category MIDI\n */\nexport type WhiteKey = (typeof whiteKeys)[number]\n\n/**\n * @category MIDI\n */\nexport const noteKeys = [\n 'C',\n 'C#',\n 'D',\n 'D#',\n 'E',\n 'F',\n 'F#',\n 'G',\n 'G#',\n 'A',\n 'A#',\n 'B',\n] as const\n\n/**\n * @category MIDI\n */\nexport type NoteKey = (typeof noteKeys)[number]\n\n/**\n * @category MIDI\n */\nexport function parseNoteName(noteName: string) {\n const m = noteName.match(/^([a-g])(#{0,2}|b{0,2})(-?\\d+)$/i)\n if (!m) throw new Error('Invalid note name')\n const [, letter, accidental, octave] = m\n return {\n letter: letter.toLocaleUpperCase() as WhiteKey,\n accidental: accidental as '#' | '##' | 'b' | 'bb' | '',\n octave: Number(octave),\n }\n}\n\n/**\n * Convert noteName to noteNumber\n * @category MIDI\n */\nexport function noteNumber(noteName: string) {\n const { letter, accidental, octave } = parseNoteName(noteName)\n const noteIndex = noteKeys.indexOf(letter.toLocaleUpperCase() as NoteKey)\n const accidentalValue = (accidental[0] == 'b' ? -1 : 1) * accidental.length\n return noteIndex + 12 * (Number(octave) + 1) + accidentalValue\n}\n\n/**\n * Convert noteNumber to noteName\n * C-1 = 0\n * G9 = 127\n * @param noteNumber noteNumber\n * @category MIDI\n */\nexport function noteName(noteNumber: number): `${NoteKey}${number}` {\n const noteIndex = mod(noteNumber, 12)\n const octave = Math.floor(noteNumber / 12) - 1\n return `${noteKeys[noteIndex]}${octave}`\n}\n\n/**\n * Convert noteNumber to noteKey\n * @category MIDI\n */\nexport function noteKey(noteNumber: number): NoteKey {\n return noteKeys[mod(noteNumber, 12)]\n}\n\n/**\n * @param note noteNumber: 0 ~ 127 or noteName e.g. 'C3'\n * @category MIDI\n */\nexport function isWhiteKey(note: number | string) {\n const n = typeof note == 'string' ? noteNumber(note) : note\n return (\n mod(n, 12) == 0 ||\n mod(n, 12) == 2 ||\n mod(n, 12) == 4 ||\n mod(n, 12) == 5 ||\n mod(n, 12) == 7 ||\n mod(n, 12) == 9 ||\n mod(n, 12) == 11\n )\n}\n\n/**\n * @param note noteNumber: 0 ~ 127 or noteName e.g. 'C3'\n * @category MIDI\n */\nexport function isBlackKey(note: number | string) {\n return !isWhiteKey(note)\n}\n\n/**\n * @param note noteNumber: 0 ~ 127 or noteName e.g. 'C3'\n * @param detune [cent]\n * @param a4 A4 frequency [Hz]\n * @returns frequency [Hz]\n * @category MIDI\n */\nexport function noteToFrequency(note: number | string, detune = 0, a4 = 440) {\n const n = typeof note == 'string' ? noteNumber(note) : note\n return (a4 / 32) * 2 ** ((n - 9 + detune / 100) / 12)\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.cjs","names":[],"sources":["../src/math.ts","../src/util.ts","../src/midi.ts"],"sourcesContent":["/**\n * clamp value between min and max\n */\nexport function clamp(value: number, min: number, max: number) {\n return Math.max(min, Math.min(value, max))\n}\n\n/**\n * Normalize the value from 0 to 1\n */\nexport function normalizeValue(\n rawValue: number,\n min: number,\n max: number,\n skew = 1,\n) {\n if (min >= max) throw new RangeError('requirements: min < max')\n const v = clamp((rawValue - min) / (max - min), 0, 1)\n return Math.pow(v, skew)\n}\n\n/**\n * Convert normalized values back to raw values.\n */\nexport function rawValue(\n normalizedValue: number,\n min: number,\n max: number,\n skew = 1,\n) {\n if (min >= max) throw new RangeError('requirements: min < max')\n const v =\n skew == 1\n ? clamp(normalizedValue, 0, 1)\n : Math.exp(Math.log(clamp(normalizedValue, 0, 1)) / skew)\n return min + v * (max - min)\n}\n\nexport function skewWithCenterValue(\n centerValue: number,\n min: number,\n max: number,\n) {\n if (!(min <= centerValue && centerValue <= max))\n throw new RangeError('requirements: min <= centerValue <= max')\n return Math.log(0.5) / Math.log((centerValue - min) / (max - min))\n}\n\nexport function stepValue(value: number, step: number) {\n if (step <= 0) throw new RangeError('requirements: step > 0')\n const quotient = Math.floor(value / step)\n const decimalDigits = decimalPart(step)?.length\n const v = toFixed(quotient * step, decimalDigits)\n const next = toFixed((quotient + 1) * step, decimalDigits)\n return Math.abs(value - v) < Math.abs(value - next) ? v : next\n}\n\nexport function toFixed(x: number, fractionDigits?: number) {\n return Number(x.toFixed(fractionDigits))\n}\n\nexport function integerPart(x: number | string): string | undefined {\n if (Number.isNaN(x)) {\n return undefined\n }\n return String(x).split('.')[0]\n}\n\nexport function decimalPart(x: number | string): string | undefined {\n return String(x).split('.')[1]\n}\n\nexport function radian(degree: number) {\n return (Math.PI * degree) / 180\n}\n\nexport function degree(radian: number) {\n return (180 * radian) / Math.PI\n}\n\nexport function mapValue(\n value: number,\n inMin: number,\n inMax: number,\n outMin: number,\n outMax: number,\n) {\n return ((value - inMin) / (inMax - inMin)) * (outMax - outMin) + outMin\n}\n\nexport function dbToGain(db: number) {\n return Math.pow(10, db / 20)\n}\n\nexport function gainToDb(gain: number) {\n return 20 * (Math.log(gain) / Math.LN10)\n}\n","type Operator = '+' | '-' | '*' | '/'\n\nexport function styleHelper(value: string | number): string\nexport function styleHelper(\n value: string | number,\n op: Operator,\n influencer?: number,\n): string\nexport function styleHelper(\n value: string | number,\n op?: Operator,\n influencer?: number,\n) {\n if (op && influencer) {\n if (typeof value == 'number') {\n if (op == '+') return `${value + influencer}px`\n if (op == '-') return `${value - influencer}px`\n if (op == '*') return `${value * influencer}px`\n if (op == '/') return `${value / influencer}px`\n } else {\n return `calc(${value}px ${op} ${influencer})`\n }\n } else {\n if (typeof value == 'number') {\n return `${value}px`\n } else {\n return value\n }\n }\n}\n\nexport function isEmpty(obj: object) {\n return Object.keys(obj).length == 0\n}\n\nexport function mod(n: number, m: number) {\n return ((n % m) + m) % m\n}\n\nexport function xor(a = false, b = false) {\n return (a || b) && a != b\n}\n","import { mod } from './util'\n\nexport const whiteKeys = ['A', 'B', 'C', 'D', 'E', 'F', 'G'] as const\n\nexport type WhiteKey = (typeof whiteKeys)[number]\n\nexport const noteKeys = [\n 'C',\n 'C#',\n 'D',\n 'D#',\n 'E',\n 'F',\n 'F#',\n 'G',\n 'G#',\n 'A',\n 'A#',\n 'B',\n] as const\n\nexport type NoteKey = (typeof noteKeys)[number]\n\nexport function parseNoteName(noteName: string) {\n const m = noteName.match(/^([a-g])(#{0,2}|b{0,2})(-?\\d+)$/i)\n if (!m) throw new Error('Invalid note name')\n const [, letter, accidental, octave] = m\n return {\n letter: letter.toLocaleUpperCase() as WhiteKey,\n accidental: accidental as '#' | '##' | 'b' | 'bb' | '',\n octave: Number(octave),\n }\n}\n\n/**\n * Convert noteName to noteNumber\n */\nexport function noteNumber(noteName: string) {\n const { letter, accidental, octave } = parseNoteName(noteName)\n const noteIndex = noteKeys.indexOf(letter.toLocaleUpperCase() as NoteKey)\n const accidentalValue = (accidental[0] == 'b' ? -1 : 1) * accidental.length\n return noteIndex + 12 * (Number(octave) + 1) + accidentalValue\n}\n\n/**\n * Convert noteNumber to noteName\n * C-1 = 0\n * G9 = 127\n * @param noteNumber noteNumber\n */\nexport function noteName(noteNumber: number): `${NoteKey}${number}` {\n const noteIndex = mod(noteNumber, 12)\n const octave = Math.floor(noteNumber / 12) - 1\n return `${noteKeys[noteIndex]}${octave}`\n}\n\n/**\n * Convert noteNumber to noteKey\n */\nexport function noteKey(noteNumber: number): NoteKey {\n return noteKeys[mod(noteNumber, 12)]\n}\n\n/**\n * @param note noteNumber: 0 ~ 127 or noteName e.g. 'C3'\n */\nexport function isWhiteKey(note: number | string) {\n const n = typeof note == 'string' ? noteNumber(note) : note\n return (\n mod(n, 12) == 0 ||\n mod(n, 12) == 2 ||\n mod(n, 12) == 4 ||\n mod(n, 12) == 5 ||\n mod(n, 12) == 7 ||\n mod(n, 12) == 9 ||\n mod(n, 12) == 11\n )\n}\n\n/**\n * @param note noteNumber: 0 ~ 127 or noteName e.g. 'C3'\n */\nexport function isBlackKey(note: number | string) {\n return !isWhiteKey(note)\n}\n\n/**\n * @param note noteNumber: 0 ~ 127 or noteName e.g. 'C3'\n * @param detune [cent]\n * @param a4 A4 frequency [Hz]\n * @returns frequency [Hz]\n */\nexport function noteToFrequency(note: number | string, detune = 0, a4 = 440) {\n const n = typeof note == 'string' ? noteNumber(note) : note\n return (a4 / 32) * 2 ** ((n - 9 + detune / 100) / 12)\n}\n"],"mappings":";;;;;AAGA,SAAgB,MAAM,OAAe,KAAa,KAAa;AAC7D,QAAO,KAAK,IAAI,KAAK,KAAK,IAAI,OAAO,IAAI,CAAC;;;;;AAM5C,SAAgB,eACd,UACA,KACA,KACA,OAAO,GACP;AACA,KAAI,OAAO,IAAK,OAAM,IAAI,WAAW,0BAA0B;CAC/D,MAAM,IAAI,OAAO,WAAW,QAAQ,MAAM,MAAM,GAAG,EAAE;AACrD,QAAO,KAAK,IAAI,GAAG,KAAK;;;;;AAM1B,SAAgB,SACd,iBACA,KACA,KACA,OAAO,GACP;AACA,KAAI,OAAO,IAAK,OAAM,IAAI,WAAW,0BAA0B;AAK/D,QAAO,OAHL,QAAQ,IACJ,MAAM,iBAAiB,GAAG,EAAE,GAC5B,KAAK,IAAI,KAAK,IAAI,MAAM,iBAAiB,GAAG,EAAE,CAAC,GAAG,KAAK,KAC3C,MAAM;;AAG1B,SAAgB,oBACd,aACA,KACA,KACA;AACA,KAAI,EAAE,OAAO,eAAe,eAAe,KACzC,OAAM,IAAI,WAAW,0CAA0C;AACjE,QAAO,KAAK,IAAI,GAAI,GAAG,KAAK,KAAK,cAAc,QAAQ,MAAM,KAAK;;AAGpE,SAAgB,UAAU,OAAe,MAAc;AACrD,KAAI,QAAQ,EAAG,OAAM,IAAI,WAAW,yBAAyB;CAC7D,MAAM,WAAW,KAAK,MAAM,QAAQ,KAAK;CACzC,MAAM,gBAAgB,YAAY,KAAK,EAAE;CACzC,MAAM,IAAI,QAAQ,WAAW,MAAM,cAAc;CACjD,MAAM,OAAO,SAAS,WAAW,KAAK,MAAM,cAAc;AAC1D,QAAO,KAAK,IAAI,QAAQ,EAAE,GAAG,KAAK,IAAI,QAAQ,KAAK,GAAG,IAAI;;AAG5D,SAAgB,QAAQ,GAAW,gBAAyB;AAC1D,QAAO,OAAO,EAAE,QAAQ,eAAe,CAAC;;AAG1C,SAAgB,YAAY,GAAwC;AAClE,KAAI,OAAO,MAAM,EAAE,CACjB;AAEF,QAAO,OAAO,EAAE,CAAC,MAAM,IAAI,CAAC;;AAG9B,SAAgB,YAAY,GAAwC;AAClE,QAAO,OAAO,EAAE,CAAC,MAAM,IAAI,CAAC;;AAG9B,SAAgB,OAAO,QAAgB;AACrC,QAAQ,KAAK,KAAK,SAAU;;AAG9B,SAAgB,OAAO,QAAgB;AACrC,QAAQ,MAAM,SAAU,KAAK;;AAG/B,SAAgB,SACd,OACA,OACA,OACA,QACA,QACA;AACA,SAAS,QAAQ,UAAU,QAAQ,UAAW,SAAS,UAAU;;AAGnE,SAAgB,SAAS,IAAY;AACnC,QAAO,KAAK,IAAI,IAAI,KAAK,GAAG;;AAG9B,SAAgB,SAAS,MAAc;AACrC,QAAO,MAAM,KAAK,IAAI,KAAK,GAAG,KAAK;;;;ACvFrC,SAAgB,YACd,OACA,IACA,YACA;AACA,KAAI,MAAM,WACR,KAAI,OAAO,SAAS,UAAU;AAC5B,MAAI,MAAM,IAAK,QAAO,GAAG,QAAQ,WAAW;AAC5C,MAAI,MAAM,IAAK,QAAO,GAAG,QAAQ,WAAW;AAC5C,MAAI,MAAM,IAAK,QAAO,GAAG,QAAQ,WAAW;AAC5C,MAAI,MAAM,IAAK,QAAO,GAAG,QAAQ,WAAW;OAE5C,QAAO,QAAQ,MAAM,KAAK,GAAG,GAAG,WAAW;UAGzC,OAAO,SAAS,SAClB,QAAO,GAAG,MAAM;KAEhB,QAAO;;AAKb,SAAgB,QAAQ,KAAa;AACnC,QAAO,OAAO,KAAK,IAAI,CAAC,UAAU;;AAGpC,SAAgB,IAAI,GAAW,GAAW;AACxC,SAAS,IAAI,IAAK,KAAK;;AAGzB,SAAgB,IAAI,IAAI,OAAO,IAAI,OAAO;AACxC,SAAQ,KAAK,MAAM,KAAK;;;;ACtC1B,MAAa,YAAY;CAAC;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CAAI;AAI5D,MAAa,WAAW;CACtB;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACD;AAID,SAAgB,cAAc,UAAkB;CAC9C,MAAM,IAAI,SAAS,MAAM,mCAAmC;AAC5D,KAAI,CAAC,EAAG,OAAM,IAAI,MAAM,oBAAoB;CAC5C,MAAM,GAAG,QAAQ,YAAY,UAAU;AACvC,QAAO;EACL,QAAQ,OAAO,mBAAmB;EACtB;EACZ,QAAQ,OAAO,OAAO;EACvB;;;;;AAMH,SAAgB,WAAW,UAAkB;CAC3C,MAAM,EAAE,QAAQ,YAAY,WAAW,cAAc,SAAS;CAC9D,MAAM,YAAY,SAAS,QAAQ,OAAO,mBAAmB,CAAY;CACzE,MAAM,mBAAmB,WAAW,MAAM,MAAM,KAAK,KAAK,WAAW;AACrE,QAAO,YAAY,MAAM,OAAO,OAAO,GAAG,KAAK;;;;;;;;AASjD,SAAgB,SAAS,YAA2C;CAClE,MAAM,YAAY,IAAI,YAAY,GAAG;CACrC,MAAM,SAAS,KAAK,MAAM,aAAa,GAAG,GAAG;AAC7C,QAAO,GAAG,SAAS,aAAa;;;;;AAMlC,SAAgB,QAAQ,YAA6B;AACnD,QAAO,SAAS,IAAI,YAAY,GAAG;;;;;AAMrC,SAAgB,WAAW,MAAuB;CAChD,MAAM,IAAI,OAAO,QAAQ,WAAW,WAAW,KAAK,GAAG;AACvD,QACE,IAAI,GAAG,GAAG,IAAI,KACd,IAAI,GAAG,GAAG,IAAI,KACd,IAAI,GAAG,GAAG,IAAI,KACd,IAAI,GAAG,GAAG,IAAI,KACd,IAAI,GAAG,GAAG,IAAI,KACd,IAAI,GAAG,GAAG,IAAI,KACd,IAAI,GAAG,GAAG,IAAI;;;;;AAOlB,SAAgB,WAAW,MAAuB;AAChD,QAAO,CAAC,WAAW,KAAK;;;;;;;;AAS1B,SAAgB,gBAAgB,MAAuB,SAAS,GAAG,KAAK,KAAK;CAC3E,MAAM,IAAI,OAAO,QAAQ,WAAW,WAAW,KAAK,GAAG;AACvD,QAAQ,KAAK,KAAM,OAAO,IAAI,IAAI,SAAS,OAAO"}
|
package/dist/index.d.cts
CHANGED
|
@@ -1,91 +1,32 @@
|
|
|
1
1
|
//#region src/math.d.ts
|
|
2
2
|
/**
|
|
3
3
|
* clamp value between min and max
|
|
4
|
-
* @category Math
|
|
5
4
|
*/
|
|
6
5
|
declare function clamp(value: number, min: number, max: number): number;
|
|
7
6
|
/**
|
|
8
7
|
* Normalize the value from 0 to 1
|
|
9
|
-
* @category Math
|
|
10
8
|
*/
|
|
11
9
|
declare function normalizeValue(rawValue: number, min: number, max: number, skew?: number): number;
|
|
12
10
|
/**
|
|
13
11
|
* Convert normalized values back to raw values.
|
|
14
|
-
* @category Math
|
|
15
12
|
*/
|
|
16
13
|
declare function rawValue(normalizedValue: number, min: number, max: number, skew?: number): number;
|
|
17
|
-
/**
|
|
18
|
-
*
|
|
19
|
-
* @category Math
|
|
20
|
-
*/
|
|
21
14
|
declare function skewWithCenterValue(centerValue: number, min: number, max: number): number;
|
|
22
|
-
/**
|
|
23
|
-
*
|
|
24
|
-
* @category Math
|
|
25
|
-
*/
|
|
26
15
|
declare function stepValue(value: number, step: number): number;
|
|
27
|
-
/**
|
|
28
|
-
*
|
|
29
|
-
* @category Math
|
|
30
|
-
*/
|
|
31
16
|
declare function toFixed(x: number, fractionDigits?: number): number;
|
|
32
|
-
/**
|
|
33
|
-
*
|
|
34
|
-
* @category Math
|
|
35
|
-
*/
|
|
36
17
|
declare function integerPart(x: number | string): string | undefined;
|
|
37
|
-
/**
|
|
38
|
-
*
|
|
39
|
-
* @category Math
|
|
40
|
-
*/
|
|
41
18
|
declare function decimalPart(x: number | string): string | undefined;
|
|
42
|
-
/**
|
|
43
|
-
*
|
|
44
|
-
* @category Math
|
|
45
|
-
*/
|
|
46
19
|
declare function radian(degree: number): number;
|
|
47
|
-
/**
|
|
48
|
-
*
|
|
49
|
-
* @category Math
|
|
50
|
-
*/
|
|
51
20
|
declare function degree(radian: number): number;
|
|
52
|
-
/**
|
|
53
|
-
*
|
|
54
|
-
* @category Math
|
|
55
|
-
*/
|
|
56
21
|
declare function mapValue(value: number, inMin: number, inMax: number, outMin: number, outMax: number): number;
|
|
57
|
-
/**
|
|
58
|
-
*
|
|
59
|
-
* @category Math
|
|
60
|
-
*/
|
|
61
22
|
declare function dbToGain(db: number): number;
|
|
62
|
-
/**
|
|
63
|
-
*
|
|
64
|
-
* @category Math
|
|
65
|
-
*/
|
|
66
23
|
declare function gainToDb(gain: number): number;
|
|
67
|
-
//# sourceMappingURL=math.d.ts.map
|
|
68
24
|
//#endregion
|
|
69
25
|
//#region src/midi.d.ts
|
|
70
|
-
/**
|
|
71
|
-
* @category MIDI
|
|
72
|
-
*/
|
|
73
26
|
declare const whiteKeys: readonly ["A", "B", "C", "D", "E", "F", "G"];
|
|
74
|
-
/**
|
|
75
|
-
* @category MIDI
|
|
76
|
-
*/
|
|
77
27
|
type WhiteKey = (typeof whiteKeys)[number];
|
|
78
|
-
/**
|
|
79
|
-
* @category MIDI
|
|
80
|
-
*/
|
|
81
28
|
declare const noteKeys: readonly ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"];
|
|
82
|
-
/**
|
|
83
|
-
* @category MIDI
|
|
84
|
-
*/
|
|
85
29
|
type NoteKey = (typeof noteKeys)[number];
|
|
86
|
-
/**
|
|
87
|
-
* @category MIDI
|
|
88
|
-
*/
|
|
89
30
|
declare function parseNoteName(noteName: string): {
|
|
90
31
|
letter: WhiteKey;
|
|
91
32
|
accidental: "#" | "##" | "b" | "bb" | "";
|
|
@@ -93,7 +34,6 @@ declare function parseNoteName(noteName: string): {
|
|
|
93
34
|
};
|
|
94
35
|
/**
|
|
95
36
|
* Convert noteName to noteNumber
|
|
96
|
-
* @category MIDI
|
|
97
37
|
*/
|
|
98
38
|
declare function noteNumber(noteName: string): number;
|
|
99
39
|
/**
|
|
@@ -101,22 +41,18 @@ declare function noteNumber(noteName: string): number;
|
|
|
101
41
|
* C-1 = 0
|
|
102
42
|
* G9 = 127
|
|
103
43
|
* @param noteNumber noteNumber
|
|
104
|
-
* @category MIDI
|
|
105
44
|
*/
|
|
106
45
|
declare function noteName(noteNumber: number): `${NoteKey}${number}`;
|
|
107
46
|
/**
|
|
108
47
|
* Convert noteNumber to noteKey
|
|
109
|
-
* @category MIDI
|
|
110
48
|
*/
|
|
111
49
|
declare function noteKey(noteNumber: number): NoteKey;
|
|
112
50
|
/**
|
|
113
51
|
* @param note noteNumber: 0 ~ 127 or noteName e.g. 'C3'
|
|
114
|
-
* @category MIDI
|
|
115
52
|
*/
|
|
116
53
|
declare function isWhiteKey(note: number | string): boolean;
|
|
117
54
|
/**
|
|
118
55
|
* @param note noteNumber: 0 ~ 127 or noteName e.g. 'C3'
|
|
119
|
-
* @category MIDI
|
|
120
56
|
*/
|
|
121
57
|
declare function isBlackKey(note: number | string): boolean;
|
|
122
58
|
/**
|
|
@@ -124,37 +60,21 @@ declare function isBlackKey(note: number | string): boolean;
|
|
|
124
60
|
* @param detune [cent]
|
|
125
61
|
* @param a4 A4 frequency [Hz]
|
|
126
62
|
* @returns frequency [Hz]
|
|
127
|
-
* @category MIDI
|
|
128
63
|
*/
|
|
129
64
|
declare function noteToFrequency(note: number | string, detune?: number, a4?: number): number;
|
|
130
|
-
//# sourceMappingURL=midi.d.ts.map
|
|
131
65
|
//#endregion
|
|
132
66
|
//#region src/types.d.ts
|
|
133
67
|
/**
|
|
134
68
|
* Options for setting the amount of keyboard and mouse wheel changes.
|
|
135
|
-
* @category Types
|
|
136
69
|
*/
|
|
137
70
|
type InputEventOption = ['normalized' | 'raw', number];
|
|
138
|
-
//# sourceMappingURL=types.d.ts.map
|
|
139
71
|
//#endregion
|
|
140
72
|
//#region src/util.d.ts
|
|
141
73
|
type Operator = '+' | '-' | '*' | '/';
|
|
142
|
-
/**
|
|
143
|
-
* @category Utility
|
|
144
|
-
*/
|
|
145
74
|
declare function styleHelper(value: string | number): string;
|
|
146
75
|
declare function styleHelper(value: string | number, op: Operator, influencer?: number): string;
|
|
147
|
-
/**
|
|
148
|
-
* @category Utility
|
|
149
|
-
*/
|
|
150
76
|
declare function isEmpty(obj: object): boolean;
|
|
151
|
-
/**
|
|
152
|
-
* @category Utility
|
|
153
|
-
*/
|
|
154
77
|
declare function mod(n: number, m: number): number;
|
|
155
|
-
/**
|
|
156
|
-
* @category Utility
|
|
157
|
-
*/
|
|
158
78
|
declare function xor(a?: boolean, b?: boolean): boolean;
|
|
159
79
|
//#endregion
|
|
160
80
|
export { type InputEventOption, type NoteKey, type WhiteKey, clamp, dbToGain, decimalPart, degree, gainToDb, integerPart, isBlackKey, isEmpty, isWhiteKey, mapValue, mod, normalizeValue, noteKey, noteKeys, noteName, noteNumber, noteToFrequency, parseNoteName, radian, rawValue, skewWithCenterValue, stepValue, styleHelper, toFixed, whiteKeys, xor };
|
package/dist/index.d.cts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.cts","names":[],"sources":["
|
|
1
|
+
{"version":3,"file":"index.d.cts","names":[],"sources":["../src/math.ts","../src/midi.ts","../src/types.ts","../src/util.ts"],"mappings":";;AAGA;;iBAAgB,KAAA,CAAM,KAAA,UAAe,GAAA,UAAa,GAAA;;;;iBAOlC,cAAA,CACd,QAAA,UACA,GAAA,UACA,GAAA,UACA,IAAA;;;AAJF;iBAcgB,QAAA,CACd,eAAA,UACA,GAAA,UACA,GAAA,UACA,IAAA;AAAA,iBAUc,mBAAA,CACd,WAAA,UACA,GAAA,UACA,GAAA;AAAA,iBAOc,SAAA,CAAU,KAAA,UAAe,IAAA;AAAA,iBASzB,OAAA,CAAQ,CAAA,UAAW,cAAA;AAAA,iBAInB,WAAA,CAAY,CAAA;AAAA,iBAOZ,WAAA,CAAY,CAAA;AAAA,iBAIZ,MAAA,CAAO,MAAA;AAAA,iBAIP,MAAA,CAAO,MAAA;AAAA,iBAIP,QAAA,CACd,KAAA,UACA,KAAA,UACA,KAAA,UACA,MAAA,UACA,MAAA;AAAA,iBAKc,QAAA,CAAS,EAAA;AAAA,iBAIT,QAAA,CAAS,IAAA;;;cC5FZ,SAAA;AAAA,KAED,QAAA,WAAmB,SAAA;AAAA,cAElB,QAAA;AAAA,KAeD,OAAA,WAAkB,QAAA;AAAA,iBAEd,aAAA,CAAc,QAAA;UAKY,QAAA;;;;;ADlB1C;;iBC2BgB,UAAA,CAAW,QAAA;;;;;;;iBAaX,QAAA,CAAS,UAAA,cAAwB,OAAA;AD1BjD;;;AAAA,iBCmCgB,OAAA,CAAQ,UAAA,WAAqB,OAAA;;;;iBAO7B,UAAA,CAAW,IAAA;;;AD5B3B;iBC4CgB,UAAA,CAAW,IAAA;;;;;;;iBAUX,eAAA,CAAgB,IAAA,mBAAuB,MAAA,WAAY,EAAA;;;;ADzFnE;;KEAY,gBAAA;;;KCHP,QAAA;AAAA,iBAEW,WAAA,CAAY,KAAA;AAAA,iBACZ,WAAA,CACd,KAAA,mBACA,EAAA,EAAI,QAAA,EACJ,UAAA;AAAA,iBAyBc,OAAA,CAAQ,GAAA;AAAA,iBAIR,GAAA,CAAI,CAAA,UAAW,CAAA;AAAA,iBAIf,GAAA,CAAI,CAAA,YAAW,CAAA"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,91 +1,32 @@
|
|
|
1
1
|
//#region src/math.d.ts
|
|
2
2
|
/**
|
|
3
3
|
* clamp value between min and max
|
|
4
|
-
* @category Math
|
|
5
4
|
*/
|
|
6
5
|
declare function clamp(value: number, min: number, max: number): number;
|
|
7
6
|
/**
|
|
8
7
|
* Normalize the value from 0 to 1
|
|
9
|
-
* @category Math
|
|
10
8
|
*/
|
|
11
9
|
declare function normalizeValue(rawValue: number, min: number, max: number, skew?: number): number;
|
|
12
10
|
/**
|
|
13
11
|
* Convert normalized values back to raw values.
|
|
14
|
-
* @category Math
|
|
15
12
|
*/
|
|
16
13
|
declare function rawValue(normalizedValue: number, min: number, max: number, skew?: number): number;
|
|
17
|
-
/**
|
|
18
|
-
*
|
|
19
|
-
* @category Math
|
|
20
|
-
*/
|
|
21
14
|
declare function skewWithCenterValue(centerValue: number, min: number, max: number): number;
|
|
22
|
-
/**
|
|
23
|
-
*
|
|
24
|
-
* @category Math
|
|
25
|
-
*/
|
|
26
15
|
declare function stepValue(value: number, step: number): number;
|
|
27
|
-
/**
|
|
28
|
-
*
|
|
29
|
-
* @category Math
|
|
30
|
-
*/
|
|
31
16
|
declare function toFixed(x: number, fractionDigits?: number): number;
|
|
32
|
-
/**
|
|
33
|
-
*
|
|
34
|
-
* @category Math
|
|
35
|
-
*/
|
|
36
17
|
declare function integerPart(x: number | string): string | undefined;
|
|
37
|
-
/**
|
|
38
|
-
*
|
|
39
|
-
* @category Math
|
|
40
|
-
*/
|
|
41
18
|
declare function decimalPart(x: number | string): string | undefined;
|
|
42
|
-
/**
|
|
43
|
-
*
|
|
44
|
-
* @category Math
|
|
45
|
-
*/
|
|
46
19
|
declare function radian(degree: number): number;
|
|
47
|
-
/**
|
|
48
|
-
*
|
|
49
|
-
* @category Math
|
|
50
|
-
*/
|
|
51
20
|
declare function degree(radian: number): number;
|
|
52
|
-
/**
|
|
53
|
-
*
|
|
54
|
-
* @category Math
|
|
55
|
-
*/
|
|
56
21
|
declare function mapValue(value: number, inMin: number, inMax: number, outMin: number, outMax: number): number;
|
|
57
|
-
/**
|
|
58
|
-
*
|
|
59
|
-
* @category Math
|
|
60
|
-
*/
|
|
61
22
|
declare function dbToGain(db: number): number;
|
|
62
|
-
/**
|
|
63
|
-
*
|
|
64
|
-
* @category Math
|
|
65
|
-
*/
|
|
66
23
|
declare function gainToDb(gain: number): number;
|
|
67
|
-
//# sourceMappingURL=math.d.ts.map
|
|
68
24
|
//#endregion
|
|
69
25
|
//#region src/midi.d.ts
|
|
70
|
-
/**
|
|
71
|
-
* @category MIDI
|
|
72
|
-
*/
|
|
73
26
|
declare const whiteKeys: readonly ["A", "B", "C", "D", "E", "F", "G"];
|
|
74
|
-
/**
|
|
75
|
-
* @category MIDI
|
|
76
|
-
*/
|
|
77
27
|
type WhiteKey = (typeof whiteKeys)[number];
|
|
78
|
-
/**
|
|
79
|
-
* @category MIDI
|
|
80
|
-
*/
|
|
81
28
|
declare const noteKeys: readonly ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"];
|
|
82
|
-
/**
|
|
83
|
-
* @category MIDI
|
|
84
|
-
*/
|
|
85
29
|
type NoteKey = (typeof noteKeys)[number];
|
|
86
|
-
/**
|
|
87
|
-
* @category MIDI
|
|
88
|
-
*/
|
|
89
30
|
declare function parseNoteName(noteName: string): {
|
|
90
31
|
letter: WhiteKey;
|
|
91
32
|
accidental: "#" | "##" | "b" | "bb" | "";
|
|
@@ -93,7 +34,6 @@ declare function parseNoteName(noteName: string): {
|
|
|
93
34
|
};
|
|
94
35
|
/**
|
|
95
36
|
* Convert noteName to noteNumber
|
|
96
|
-
* @category MIDI
|
|
97
37
|
*/
|
|
98
38
|
declare function noteNumber(noteName: string): number;
|
|
99
39
|
/**
|
|
@@ -101,22 +41,18 @@ declare function noteNumber(noteName: string): number;
|
|
|
101
41
|
* C-1 = 0
|
|
102
42
|
* G9 = 127
|
|
103
43
|
* @param noteNumber noteNumber
|
|
104
|
-
* @category MIDI
|
|
105
44
|
*/
|
|
106
45
|
declare function noteName(noteNumber: number): `${NoteKey}${number}`;
|
|
107
46
|
/**
|
|
108
47
|
* Convert noteNumber to noteKey
|
|
109
|
-
* @category MIDI
|
|
110
48
|
*/
|
|
111
49
|
declare function noteKey(noteNumber: number): NoteKey;
|
|
112
50
|
/**
|
|
113
51
|
* @param note noteNumber: 0 ~ 127 or noteName e.g. 'C3'
|
|
114
|
-
* @category MIDI
|
|
115
52
|
*/
|
|
116
53
|
declare function isWhiteKey(note: number | string): boolean;
|
|
117
54
|
/**
|
|
118
55
|
* @param note noteNumber: 0 ~ 127 or noteName e.g. 'C3'
|
|
119
|
-
* @category MIDI
|
|
120
56
|
*/
|
|
121
57
|
declare function isBlackKey(note: number | string): boolean;
|
|
122
58
|
/**
|
|
@@ -124,37 +60,21 @@ declare function isBlackKey(note: number | string): boolean;
|
|
|
124
60
|
* @param detune [cent]
|
|
125
61
|
* @param a4 A4 frequency [Hz]
|
|
126
62
|
* @returns frequency [Hz]
|
|
127
|
-
* @category MIDI
|
|
128
63
|
*/
|
|
129
64
|
declare function noteToFrequency(note: number | string, detune?: number, a4?: number): number;
|
|
130
|
-
//# sourceMappingURL=midi.d.ts.map
|
|
131
65
|
//#endregion
|
|
132
66
|
//#region src/types.d.ts
|
|
133
67
|
/**
|
|
134
68
|
* Options for setting the amount of keyboard and mouse wheel changes.
|
|
135
|
-
* @category Types
|
|
136
69
|
*/
|
|
137
70
|
type InputEventOption = ['normalized' | 'raw', number];
|
|
138
|
-
//# sourceMappingURL=types.d.ts.map
|
|
139
71
|
//#endregion
|
|
140
72
|
//#region src/util.d.ts
|
|
141
73
|
type Operator = '+' | '-' | '*' | '/';
|
|
142
|
-
/**
|
|
143
|
-
* @category Utility
|
|
144
|
-
*/
|
|
145
74
|
declare function styleHelper(value: string | number): string;
|
|
146
75
|
declare function styleHelper(value: string | number, op: Operator, influencer?: number): string;
|
|
147
|
-
/**
|
|
148
|
-
* @category Utility
|
|
149
|
-
*/
|
|
150
76
|
declare function isEmpty(obj: object): boolean;
|
|
151
|
-
/**
|
|
152
|
-
* @category Utility
|
|
153
|
-
*/
|
|
154
77
|
declare function mod(n: number, m: number): number;
|
|
155
|
-
/**
|
|
156
|
-
* @category Utility
|
|
157
|
-
*/
|
|
158
78
|
declare function xor(a?: boolean, b?: boolean): boolean;
|
|
159
79
|
//#endregion
|
|
160
80
|
export { type InputEventOption, type NoteKey, type WhiteKey, clamp, dbToGain, decimalPart, degree, gainToDb, integerPart, isBlackKey, isEmpty, isWhiteKey, mapValue, mod, normalizeValue, noteKey, noteKeys, noteName, noteNumber, noteToFrequency, parseNoteName, radian, rawValue, skewWithCenterValue, stepValue, styleHelper, toFixed, whiteKeys, xor };
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","names":[],"sources":["
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":[],"sources":["../src/math.ts","../src/midi.ts","../src/types.ts","../src/util.ts"],"mappings":";;AAGA;;iBAAgB,KAAA,CAAM,KAAA,UAAe,GAAA,UAAa,GAAA;;;;iBAOlC,cAAA,CACd,QAAA,UACA,GAAA,UACA,GAAA,UACA,IAAA;;;AAJF;iBAcgB,QAAA,CACd,eAAA,UACA,GAAA,UACA,GAAA,UACA,IAAA;AAAA,iBAUc,mBAAA,CACd,WAAA,UACA,GAAA,UACA,GAAA;AAAA,iBAOc,SAAA,CAAU,KAAA,UAAe,IAAA;AAAA,iBASzB,OAAA,CAAQ,CAAA,UAAW,cAAA;AAAA,iBAInB,WAAA,CAAY,CAAA;AAAA,iBAOZ,WAAA,CAAY,CAAA;AAAA,iBAIZ,MAAA,CAAO,MAAA;AAAA,iBAIP,MAAA,CAAO,MAAA;AAAA,iBAIP,QAAA,CACd,KAAA,UACA,KAAA,UACA,KAAA,UACA,MAAA,UACA,MAAA;AAAA,iBAKc,QAAA,CAAS,EAAA;AAAA,iBAIT,QAAA,CAAS,IAAA;;;cC5FZ,SAAA;AAAA,KAED,QAAA,WAAmB,SAAA;AAAA,cAElB,QAAA;AAAA,KAeD,OAAA,WAAkB,QAAA;AAAA,iBAEd,aAAA,CAAc,QAAA;UAKY,QAAA;;;;;ADlB1C;;iBC2BgB,UAAA,CAAW,QAAA;;;;;;;iBAaX,QAAA,CAAS,UAAA,cAAwB,OAAA;AD1BjD;;;AAAA,iBCmCgB,OAAA,CAAQ,UAAA,WAAqB,OAAA;;;;iBAO7B,UAAA,CAAW,IAAA;;;AD5B3B;iBC4CgB,UAAA,CAAW,IAAA;;;;;;;iBAUX,eAAA,CAAgB,IAAA,mBAAuB,MAAA,WAAY,EAAA;;;;ADzFnE;;KEAY,gBAAA;;;KCHP,QAAA;AAAA,iBAEW,WAAA,CAAY,KAAA;AAAA,iBACZ,WAAA,CACd,KAAA,mBACA,EAAA,EAAI,QAAA,EACJ,UAAA;AAAA,iBAyBc,OAAA,CAAQ,GAAA;AAAA,iBAIR,GAAA,CAAI,CAAA,UAAW,CAAA;AAAA,iBAIf,GAAA,CAAI,CAAA,YAAW,CAAA"}
|
package/dist/index.js
CHANGED
|
@@ -1,40 +1,29 @@
|
|
|
1
1
|
//#region src/math.ts
|
|
2
2
|
/**
|
|
3
3
|
* clamp value between min and max
|
|
4
|
-
* @category Math
|
|
5
4
|
*/
|
|
6
5
|
function clamp(value, min, max) {
|
|
7
6
|
return Math.max(min, Math.min(value, max));
|
|
8
7
|
}
|
|
9
8
|
/**
|
|
10
9
|
* Normalize the value from 0 to 1
|
|
11
|
-
* @category Math
|
|
12
10
|
*/
|
|
13
|
-
function normalizeValue(rawValue
|
|
11
|
+
function normalizeValue(rawValue, min, max, skew = 1) {
|
|
14
12
|
if (min >= max) throw new RangeError("requirements: min < max");
|
|
15
|
-
const v = clamp((rawValue
|
|
13
|
+
const v = clamp((rawValue - min) / (max - min), 0, 1);
|
|
16
14
|
return Math.pow(v, skew);
|
|
17
15
|
}
|
|
18
16
|
/**
|
|
19
17
|
* Convert normalized values back to raw values.
|
|
20
|
-
* @category Math
|
|
21
18
|
*/
|
|
22
19
|
function rawValue(normalizedValue, min, max, skew = 1) {
|
|
23
20
|
if (min >= max) throw new RangeError("requirements: min < max");
|
|
24
21
|
return min + (skew == 1 ? clamp(normalizedValue, 0, 1) : Math.exp(Math.log(clamp(normalizedValue, 0, 1)) / skew)) * (max - min);
|
|
25
22
|
}
|
|
26
|
-
/**
|
|
27
|
-
*
|
|
28
|
-
* @category Math
|
|
29
|
-
*/
|
|
30
23
|
function skewWithCenterValue(centerValue, min, max) {
|
|
31
24
|
if (!(min <= centerValue && centerValue <= max)) throw new RangeError("requirements: min <= centerValue <= max");
|
|
32
25
|
return Math.log(.5) / Math.log((centerValue - min) / (max - min));
|
|
33
26
|
}
|
|
34
|
-
/**
|
|
35
|
-
*
|
|
36
|
-
* @category Math
|
|
37
|
-
*/
|
|
38
27
|
function stepValue(value, step) {
|
|
39
28
|
if (step <= 0) throw new RangeError("requirements: step > 0");
|
|
40
29
|
const quotient = Math.floor(value / step);
|
|
@@ -43,64 +32,31 @@ function stepValue(value, step) {
|
|
|
43
32
|
const next = toFixed((quotient + 1) * step, decimalDigits);
|
|
44
33
|
return Math.abs(value - v) < Math.abs(value - next) ? v : next;
|
|
45
34
|
}
|
|
46
|
-
/**
|
|
47
|
-
*
|
|
48
|
-
* @category Math
|
|
49
|
-
*/
|
|
50
35
|
function toFixed(x, fractionDigits) {
|
|
51
36
|
return Number(x.toFixed(fractionDigits));
|
|
52
37
|
}
|
|
53
|
-
/**
|
|
54
|
-
*
|
|
55
|
-
* @category Math
|
|
56
|
-
*/
|
|
57
38
|
function integerPart(x) {
|
|
58
39
|
if (Number.isNaN(x)) return;
|
|
59
40
|
return String(x).split(".")[0];
|
|
60
41
|
}
|
|
61
|
-
/**
|
|
62
|
-
*
|
|
63
|
-
* @category Math
|
|
64
|
-
*/
|
|
65
42
|
function decimalPart(x) {
|
|
66
43
|
return String(x).split(".")[1];
|
|
67
44
|
}
|
|
68
|
-
|
|
69
|
-
*
|
|
70
|
-
* @category Math
|
|
71
|
-
*/
|
|
72
|
-
function radian(degree$1) {
|
|
73
|
-
return Math.PI * degree$1 / 180;
|
|
45
|
+
function radian(degree) {
|
|
46
|
+
return Math.PI * degree / 180;
|
|
74
47
|
}
|
|
75
|
-
|
|
76
|
-
*
|
|
77
|
-
* @category Math
|
|
78
|
-
*/
|
|
79
|
-
function degree(radian$1) {
|
|
80
|
-
return 180 * radian$1 / Math.PI;
|
|
48
|
+
function degree(radian) {
|
|
49
|
+
return 180 * radian / Math.PI;
|
|
81
50
|
}
|
|
82
|
-
/**
|
|
83
|
-
*
|
|
84
|
-
* @category Math
|
|
85
|
-
*/
|
|
86
51
|
function mapValue(value, inMin, inMax, outMin, outMax) {
|
|
87
52
|
return (value - inMin) / (inMax - inMin) * (outMax - outMin) + outMin;
|
|
88
53
|
}
|
|
89
|
-
/**
|
|
90
|
-
*
|
|
91
|
-
* @category Math
|
|
92
|
-
*/
|
|
93
54
|
function dbToGain(db) {
|
|
94
55
|
return Math.pow(10, db / 20);
|
|
95
56
|
}
|
|
96
|
-
/**
|
|
97
|
-
*
|
|
98
|
-
* @category Math
|
|
99
|
-
*/
|
|
100
57
|
function gainToDb(gain) {
|
|
101
58
|
return 20 * (Math.log(gain) / Math.LN10);
|
|
102
59
|
}
|
|
103
|
-
|
|
104
60
|
//#endregion
|
|
105
61
|
//#region src/util.ts
|
|
106
62
|
function styleHelper(value, op, influencer) {
|
|
@@ -113,30 +69,17 @@ function styleHelper(value, op, influencer) {
|
|
|
113
69
|
else if (typeof value == "number") return `${value}px`;
|
|
114
70
|
else return value;
|
|
115
71
|
}
|
|
116
|
-
/**
|
|
117
|
-
* @category Utility
|
|
118
|
-
*/
|
|
119
72
|
function isEmpty(obj) {
|
|
120
73
|
return Object.keys(obj).length == 0;
|
|
121
74
|
}
|
|
122
|
-
/**
|
|
123
|
-
* @category Utility
|
|
124
|
-
*/
|
|
125
75
|
function mod(n, m) {
|
|
126
76
|
return (n % m + m) % m;
|
|
127
77
|
}
|
|
128
|
-
/**
|
|
129
|
-
* @category Utility
|
|
130
|
-
*/
|
|
131
78
|
function xor(a = false, b = false) {
|
|
132
79
|
return (a || b) && a != b;
|
|
133
80
|
}
|
|
134
|
-
|
|
135
81
|
//#endregion
|
|
136
82
|
//#region src/midi.ts
|
|
137
|
-
/**
|
|
138
|
-
* @category MIDI
|
|
139
|
-
*/
|
|
140
83
|
const whiteKeys = [
|
|
141
84
|
"A",
|
|
142
85
|
"B",
|
|
@@ -146,9 +89,6 @@ const whiteKeys = [
|
|
|
146
89
|
"F",
|
|
147
90
|
"G"
|
|
148
91
|
];
|
|
149
|
-
/**
|
|
150
|
-
* @category MIDI
|
|
151
|
-
*/
|
|
152
92
|
const noteKeys = [
|
|
153
93
|
"C",
|
|
154
94
|
"C#",
|
|
@@ -163,11 +103,8 @@ const noteKeys = [
|
|
|
163
103
|
"A#",
|
|
164
104
|
"B"
|
|
165
105
|
];
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
*/
|
|
169
|
-
function parseNoteName(noteName$1) {
|
|
170
|
-
const m = noteName$1.match(/^([a-g])(#{0,2}|b{0,2})(-?\d+)$/i);
|
|
106
|
+
function parseNoteName(noteName) {
|
|
107
|
+
const m = noteName.match(/^([a-g])(#{0,2}|b{0,2})(-?\d+)$/i);
|
|
171
108
|
if (!m) throw new Error("Invalid note name");
|
|
172
109
|
const [, letter, accidental, octave] = m;
|
|
173
110
|
return {
|
|
@@ -178,10 +115,9 @@ function parseNoteName(noteName$1) {
|
|
|
178
115
|
}
|
|
179
116
|
/**
|
|
180
117
|
* Convert noteName to noteNumber
|
|
181
|
-
* @category MIDI
|
|
182
118
|
*/
|
|
183
|
-
function noteNumber(noteName
|
|
184
|
-
const { letter, accidental, octave } = parseNoteName(noteName
|
|
119
|
+
function noteNumber(noteName) {
|
|
120
|
+
const { letter, accidental, octave } = parseNoteName(noteName);
|
|
185
121
|
const noteIndex = noteKeys.indexOf(letter.toLocaleUpperCase());
|
|
186
122
|
const accidentalValue = (accidental[0] == "b" ? -1 : 1) * accidental.length;
|
|
187
123
|
return noteIndex + 12 * (Number(octave) + 1) + accidentalValue;
|
|
@@ -191,23 +127,20 @@ function noteNumber(noteName$1) {
|
|
|
191
127
|
* C-1 = 0
|
|
192
128
|
* G9 = 127
|
|
193
129
|
* @param noteNumber noteNumber
|
|
194
|
-
* @category MIDI
|
|
195
130
|
*/
|
|
196
|
-
function noteName(noteNumber
|
|
197
|
-
const noteIndex = mod(noteNumber
|
|
198
|
-
const octave = Math.floor(noteNumber
|
|
131
|
+
function noteName(noteNumber) {
|
|
132
|
+
const noteIndex = mod(noteNumber, 12);
|
|
133
|
+
const octave = Math.floor(noteNumber / 12) - 1;
|
|
199
134
|
return `${noteKeys[noteIndex]}${octave}`;
|
|
200
135
|
}
|
|
201
136
|
/**
|
|
202
137
|
* Convert noteNumber to noteKey
|
|
203
|
-
* @category MIDI
|
|
204
138
|
*/
|
|
205
|
-
function noteKey(noteNumber
|
|
206
|
-
return noteKeys[mod(noteNumber
|
|
139
|
+
function noteKey(noteNumber) {
|
|
140
|
+
return noteKeys[mod(noteNumber, 12)];
|
|
207
141
|
}
|
|
208
142
|
/**
|
|
209
143
|
* @param note noteNumber: 0 ~ 127 or noteName e.g. 'C3'
|
|
210
|
-
* @category MIDI
|
|
211
144
|
*/
|
|
212
145
|
function isWhiteKey(note) {
|
|
213
146
|
const n = typeof note == "string" ? noteNumber(note) : note;
|
|
@@ -215,7 +148,6 @@ function isWhiteKey(note) {
|
|
|
215
148
|
}
|
|
216
149
|
/**
|
|
217
150
|
* @param note noteNumber: 0 ~ 127 or noteName e.g. 'C3'
|
|
218
|
-
* @category MIDI
|
|
219
151
|
*/
|
|
220
152
|
function isBlackKey(note) {
|
|
221
153
|
return !isWhiteKey(note);
|
|
@@ -225,13 +157,12 @@ function isBlackKey(note) {
|
|
|
225
157
|
* @param detune [cent]
|
|
226
158
|
* @param a4 A4 frequency [Hz]
|
|
227
159
|
* @returns frequency [Hz]
|
|
228
|
-
* @category MIDI
|
|
229
160
|
*/
|
|
230
161
|
function noteToFrequency(note, detune = 0, a4 = 440) {
|
|
231
162
|
const n = typeof note == "string" ? noteNumber(note) : note;
|
|
232
163
|
return a4 / 32 * 2 ** ((n - 9 + detune / 100) / 12);
|
|
233
164
|
}
|
|
234
|
-
|
|
235
165
|
//#endregion
|
|
236
166
|
export { clamp, dbToGain, decimalPart, degree, gainToDb, integerPart, isBlackKey, isEmpty, isWhiteKey, mapValue, mod, normalizeValue, noteKey, noteKeys, noteName, noteNumber, noteToFrequency, parseNoteName, radian, rawValue, skewWithCenterValue, stepValue, styleHelper, toFixed, whiteKeys, xor };
|
|
167
|
+
|
|
237
168
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["rawValue","degree","radian","noteName","noteNumber"],"sources":["../src/math.ts","../src/util.ts","../src/midi.ts"],"sourcesContent":["/**\n * clamp value between min and max\n * @category Math\n */\nexport function clamp(value: number, min: number, max: number) {\n return Math.max(min, Math.min(value, max))\n}\n\n/**\n * Normalize the value from 0 to 1\n * @category Math\n */\nexport function normalizeValue(\n rawValue: number,\n min: number,\n max: number,\n skew = 1,\n) {\n if (min >= max) throw new RangeError('requirements: min < max')\n const v = clamp((rawValue - min) / (max - min), 0, 1)\n return Math.pow(v, skew)\n}\n\n/**\n * Convert normalized values back to raw values.\n * @category Math\n */\nexport function rawValue(\n normalizedValue: number,\n min: number,\n max: number,\n skew = 1,\n) {\n if (min >= max) throw new RangeError('requirements: min < max')\n const v =\n skew == 1\n ? clamp(normalizedValue, 0, 1)\n : Math.exp(Math.log(clamp(normalizedValue, 0, 1)) / skew)\n return min + v * (max - min)\n}\n\n/**\n *\n * @category Math\n */\nexport function skewWithCenterValue(\n centerValue: number,\n min: number,\n max: number,\n) {\n if (!(min <= centerValue && centerValue <= max))\n throw new RangeError('requirements: min <= centerValue <= max')\n return Math.log(0.5) / Math.log((centerValue - min) / (max - min))\n}\n\n/**\n *\n * @category Math\n */\nexport function stepValue(value: number, step: number) {\n if (step <= 0) throw new RangeError('requirements: step > 0')\n const quotient = Math.floor(value / step)\n const decimalDigits = decimalPart(step)?.length\n const v = toFixed(quotient * step, decimalDigits)\n const next = toFixed((quotient + 1) * step, decimalDigits)\n return Math.abs(value - v) < Math.abs(value - next) ? v : next\n}\n\n/**\n *\n * @category Math\n */\nexport function toFixed(x: number, fractionDigits?: number) {\n return Number(x.toFixed(fractionDigits))\n}\n\n/**\n *\n * @category Math\n */\nexport function integerPart(x: number | string): string | undefined {\n if (Number.isNaN(x)) {\n return undefined\n }\n return String(x).split('.')[0]\n}\n\n/**\n *\n * @category Math\n */\nexport function decimalPart(x: number | string): string | undefined {\n return String(x).split('.')[1]\n}\n\n/**\n *\n * @category Math\n */\nexport function radian(degree: number) {\n return (Math.PI * degree) / 180\n}\n\n/**\n *\n * @category Math\n */\nexport function degree(radian: number) {\n return (180 * radian) / Math.PI\n}\n\n/**\n *\n * @category Math\n */\nexport function mapValue(\n value: number,\n inMin: number,\n inMax: number,\n outMin: number,\n outMax: number,\n) {\n return ((value - inMin) / (inMax - inMin)) * (outMax - outMin) + outMin\n}\n\n/**\n *\n * @category Math\n */\nexport function dbToGain(db: number) {\n return Math.pow(10, db / 20)\n}\n\n/**\n *\n * @category Math\n */\nexport function gainToDb(gain: number) {\n return 20 * (Math.log(gain) / Math.LN10)\n}\n","type Operator = '+' | '-' | '*' | '/'\n\n/**\n * @category Utility\n */\nexport function styleHelper(value: string | number): string\nexport function styleHelper(\n value: string | number,\n op: Operator,\n influencer?: number,\n): string\nexport function styleHelper(\n value: string | number,\n op?: Operator,\n influencer?: number,\n) {\n if (op && influencer) {\n if (typeof value == 'number') {\n if (op == '+') return `${value + influencer}px`\n if (op == '-') return `${value - influencer}px`\n if (op == '*') return `${value * influencer}px`\n if (op == '/') return `${value / influencer}px`\n } else {\n return `calc(${value}px ${op} ${influencer})`\n }\n } else {\n if (typeof value == 'number') {\n return `${value}px`\n } else {\n return value\n }\n }\n}\n\n/**\n * @category Utility\n */\nexport function isEmpty(obj: object) {\n return Object.keys(obj).length == 0\n}\n\n/**\n * @category Utility\n */\nexport function mod(n: number, m: number) {\n return ((n % m) + m) % m\n}\n\n/**\n * @category Utility\n */\nexport function xor(a = false, b = false) {\n return (a || b) && a != b\n}\n","import { mod } from './util'\n\n/**\n * @category MIDI\n */\nexport const whiteKeys = ['A', 'B', 'C', 'D', 'E', 'F', 'G'] as const\n\n/**\n * @category MIDI\n */\nexport type WhiteKey = (typeof whiteKeys)[number]\n\n/**\n * @category MIDI\n */\nexport const noteKeys = [\n 'C',\n 'C#',\n 'D',\n 'D#',\n 'E',\n 'F',\n 'F#',\n 'G',\n 'G#',\n 'A',\n 'A#',\n 'B',\n] as const\n\n/**\n * @category MIDI\n */\nexport type NoteKey = (typeof noteKeys)[number]\n\n/**\n * @category MIDI\n */\nexport function parseNoteName(noteName: string) {\n const m = noteName.match(/^([a-g])(#{0,2}|b{0,2})(-?\\d+)$/i)\n if (!m) throw new Error('Invalid note name')\n const [, letter, accidental, octave] = m\n return {\n letter: letter.toLocaleUpperCase() as WhiteKey,\n accidental: accidental as '#' | '##' | 'b' | 'bb' | '',\n octave: Number(octave),\n }\n}\n\n/**\n * Convert noteName to noteNumber\n * @category MIDI\n */\nexport function noteNumber(noteName: string) {\n const { letter, accidental, octave } = parseNoteName(noteName)\n const noteIndex = noteKeys.indexOf(letter.toLocaleUpperCase() as NoteKey)\n const accidentalValue = (accidental[0] == 'b' ? -1 : 1) * accidental.length\n return noteIndex + 12 * (Number(octave) + 1) + accidentalValue\n}\n\n/**\n * Convert noteNumber to noteName\n * C-1 = 0\n * G9 = 127\n * @param noteNumber noteNumber\n * @category MIDI\n */\nexport function noteName(noteNumber: number): `${NoteKey}${number}` {\n const noteIndex = mod(noteNumber, 12)\n const octave = Math.floor(noteNumber / 12) - 1\n return `${noteKeys[noteIndex]}${octave}`\n}\n\n/**\n * Convert noteNumber to noteKey\n * @category MIDI\n */\nexport function noteKey(noteNumber: number): NoteKey {\n return noteKeys[mod(noteNumber, 12)]\n}\n\n/**\n * @param note noteNumber: 0 ~ 127 or noteName e.g. 'C3'\n * @category MIDI\n */\nexport function isWhiteKey(note: number | string) {\n const n = typeof note == 'string' ? noteNumber(note) : note\n return (\n mod(n, 12) == 0 ||\n mod(n, 12) == 2 ||\n mod(n, 12) == 4 ||\n mod(n, 12) == 5 ||\n mod(n, 12) == 7 ||\n mod(n, 12) == 9 ||\n mod(n, 12) == 11\n )\n}\n\n/**\n * @param note noteNumber: 0 ~ 127 or noteName e.g. 'C3'\n * @category MIDI\n */\nexport function isBlackKey(note: number | string) {\n return !isWhiteKey(note)\n}\n\n/**\n * @param note noteNumber: 0 ~ 127 or noteName e.g. 'C3'\n * @param detune [cent]\n * @param a4 A4 frequency [Hz]\n * @returns frequency [Hz]\n * @category MIDI\n */\nexport function noteToFrequency(note: number | string, detune = 0, a4 = 440) {\n const n = typeof note == 'string' ? noteNumber(note) : note\n return (a4 / 32) * 2 ** ((n - 9 + detune / 100) / 12)\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../src/math.ts","../src/util.ts","../src/midi.ts"],"sourcesContent":["/**\n * clamp value between min and max\n */\nexport function clamp(value: number, min: number, max: number) {\n return Math.max(min, Math.min(value, max))\n}\n\n/**\n * Normalize the value from 0 to 1\n */\nexport function normalizeValue(\n rawValue: number,\n min: number,\n max: number,\n skew = 1,\n) {\n if (min >= max) throw new RangeError('requirements: min < max')\n const v = clamp((rawValue - min) / (max - min), 0, 1)\n return Math.pow(v, skew)\n}\n\n/**\n * Convert normalized values back to raw values.\n */\nexport function rawValue(\n normalizedValue: number,\n min: number,\n max: number,\n skew = 1,\n) {\n if (min >= max) throw new RangeError('requirements: min < max')\n const v =\n skew == 1\n ? clamp(normalizedValue, 0, 1)\n : Math.exp(Math.log(clamp(normalizedValue, 0, 1)) / skew)\n return min + v * (max - min)\n}\n\nexport function skewWithCenterValue(\n centerValue: number,\n min: number,\n max: number,\n) {\n if (!(min <= centerValue && centerValue <= max))\n throw new RangeError('requirements: min <= centerValue <= max')\n return Math.log(0.5) / Math.log((centerValue - min) / (max - min))\n}\n\nexport function stepValue(value: number, step: number) {\n if (step <= 0) throw new RangeError('requirements: step > 0')\n const quotient = Math.floor(value / step)\n const decimalDigits = decimalPart(step)?.length\n const v = toFixed(quotient * step, decimalDigits)\n const next = toFixed((quotient + 1) * step, decimalDigits)\n return Math.abs(value - v) < Math.abs(value - next) ? v : next\n}\n\nexport function toFixed(x: number, fractionDigits?: number) {\n return Number(x.toFixed(fractionDigits))\n}\n\nexport function integerPart(x: number | string): string | undefined {\n if (Number.isNaN(x)) {\n return undefined\n }\n return String(x).split('.')[0]\n}\n\nexport function decimalPart(x: number | string): string | undefined {\n return String(x).split('.')[1]\n}\n\nexport function radian(degree: number) {\n return (Math.PI * degree) / 180\n}\n\nexport function degree(radian: number) {\n return (180 * radian) / Math.PI\n}\n\nexport function mapValue(\n value: number,\n inMin: number,\n inMax: number,\n outMin: number,\n outMax: number,\n) {\n return ((value - inMin) / (inMax - inMin)) * (outMax - outMin) + outMin\n}\n\nexport function dbToGain(db: number) {\n return Math.pow(10, db / 20)\n}\n\nexport function gainToDb(gain: number) {\n return 20 * (Math.log(gain) / Math.LN10)\n}\n","type Operator = '+' | '-' | '*' | '/'\n\nexport function styleHelper(value: string | number): string\nexport function styleHelper(\n value: string | number,\n op: Operator,\n influencer?: number,\n): string\nexport function styleHelper(\n value: string | number,\n op?: Operator,\n influencer?: number,\n) {\n if (op && influencer) {\n if (typeof value == 'number') {\n if (op == '+') return `${value + influencer}px`\n if (op == '-') return `${value - influencer}px`\n if (op == '*') return `${value * influencer}px`\n if (op == '/') return `${value / influencer}px`\n } else {\n return `calc(${value}px ${op} ${influencer})`\n }\n } else {\n if (typeof value == 'number') {\n return `${value}px`\n } else {\n return value\n }\n }\n}\n\nexport function isEmpty(obj: object) {\n return Object.keys(obj).length == 0\n}\n\nexport function mod(n: number, m: number) {\n return ((n % m) + m) % m\n}\n\nexport function xor(a = false, b = false) {\n return (a || b) && a != b\n}\n","import { mod } from './util'\n\nexport const whiteKeys = ['A', 'B', 'C', 'D', 'E', 'F', 'G'] as const\n\nexport type WhiteKey = (typeof whiteKeys)[number]\n\nexport const noteKeys = [\n 'C',\n 'C#',\n 'D',\n 'D#',\n 'E',\n 'F',\n 'F#',\n 'G',\n 'G#',\n 'A',\n 'A#',\n 'B',\n] as const\n\nexport type NoteKey = (typeof noteKeys)[number]\n\nexport function parseNoteName(noteName: string) {\n const m = noteName.match(/^([a-g])(#{0,2}|b{0,2})(-?\\d+)$/i)\n if (!m) throw new Error('Invalid note name')\n const [, letter, accidental, octave] = m\n return {\n letter: letter.toLocaleUpperCase() as WhiteKey,\n accidental: accidental as '#' | '##' | 'b' | 'bb' | '',\n octave: Number(octave),\n }\n}\n\n/**\n * Convert noteName to noteNumber\n */\nexport function noteNumber(noteName: string) {\n const { letter, accidental, octave } = parseNoteName(noteName)\n const noteIndex = noteKeys.indexOf(letter.toLocaleUpperCase() as NoteKey)\n const accidentalValue = (accidental[0] == 'b' ? -1 : 1) * accidental.length\n return noteIndex + 12 * (Number(octave) + 1) + accidentalValue\n}\n\n/**\n * Convert noteNumber to noteName\n * C-1 = 0\n * G9 = 127\n * @param noteNumber noteNumber\n */\nexport function noteName(noteNumber: number): `${NoteKey}${number}` {\n const noteIndex = mod(noteNumber, 12)\n const octave = Math.floor(noteNumber / 12) - 1\n return `${noteKeys[noteIndex]}${octave}`\n}\n\n/**\n * Convert noteNumber to noteKey\n */\nexport function noteKey(noteNumber: number): NoteKey {\n return noteKeys[mod(noteNumber, 12)]\n}\n\n/**\n * @param note noteNumber: 0 ~ 127 or noteName e.g. 'C3'\n */\nexport function isWhiteKey(note: number | string) {\n const n = typeof note == 'string' ? noteNumber(note) : note\n return (\n mod(n, 12) == 0 ||\n mod(n, 12) == 2 ||\n mod(n, 12) == 4 ||\n mod(n, 12) == 5 ||\n mod(n, 12) == 7 ||\n mod(n, 12) == 9 ||\n mod(n, 12) == 11\n )\n}\n\n/**\n * @param note noteNumber: 0 ~ 127 or noteName e.g. 'C3'\n */\nexport function isBlackKey(note: number | string) {\n return !isWhiteKey(note)\n}\n\n/**\n * @param note noteNumber: 0 ~ 127 or noteName e.g. 'C3'\n * @param detune [cent]\n * @param a4 A4 frequency [Hz]\n * @returns frequency [Hz]\n */\nexport function noteToFrequency(note: number | string, detune = 0, a4 = 440) {\n const n = typeof note == 'string' ? noteNumber(note) : note\n return (a4 / 32) * 2 ** ((n - 9 + detune / 100) / 12)\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED
package/src/index.ts
CHANGED
package/src/math.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* clamp value between min and max
|
|
3
|
-
* @category Math
|
|
4
3
|
*/
|
|
5
4
|
export function clamp(value: number, min: number, max: number) {
|
|
6
5
|
return Math.max(min, Math.min(value, max))
|
|
@@ -8,7 +7,6 @@ export function clamp(value: number, min: number, max: number) {
|
|
|
8
7
|
|
|
9
8
|
/**
|
|
10
9
|
* Normalize the value from 0 to 1
|
|
11
|
-
* @category Math
|
|
12
10
|
*/
|
|
13
11
|
export function normalizeValue(
|
|
14
12
|
rawValue: number,
|
|
@@ -23,7 +21,6 @@ export function normalizeValue(
|
|
|
23
21
|
|
|
24
22
|
/**
|
|
25
23
|
* Convert normalized values back to raw values.
|
|
26
|
-
* @category Math
|
|
27
24
|
*/
|
|
28
25
|
export function rawValue(
|
|
29
26
|
normalizedValue: number,
|
|
@@ -39,10 +36,6 @@ export function rawValue(
|
|
|
39
36
|
return min + v * (max - min)
|
|
40
37
|
}
|
|
41
38
|
|
|
42
|
-
/**
|
|
43
|
-
*
|
|
44
|
-
* @category Math
|
|
45
|
-
*/
|
|
46
39
|
export function skewWithCenterValue(
|
|
47
40
|
centerValue: number,
|
|
48
41
|
min: number,
|
|
@@ -53,10 +46,6 @@ export function skewWithCenterValue(
|
|
|
53
46
|
return Math.log(0.5) / Math.log((centerValue - min) / (max - min))
|
|
54
47
|
}
|
|
55
48
|
|
|
56
|
-
/**
|
|
57
|
-
*
|
|
58
|
-
* @category Math
|
|
59
|
-
*/
|
|
60
49
|
export function stepValue(value: number, step: number) {
|
|
61
50
|
if (step <= 0) throw new RangeError('requirements: step > 0')
|
|
62
51
|
const quotient = Math.floor(value / step)
|
|
@@ -66,18 +55,10 @@ export function stepValue(value: number, step: number) {
|
|
|
66
55
|
return Math.abs(value - v) < Math.abs(value - next) ? v : next
|
|
67
56
|
}
|
|
68
57
|
|
|
69
|
-
/**
|
|
70
|
-
*
|
|
71
|
-
* @category Math
|
|
72
|
-
*/
|
|
73
58
|
export function toFixed(x: number, fractionDigits?: number) {
|
|
74
59
|
return Number(x.toFixed(fractionDigits))
|
|
75
60
|
}
|
|
76
61
|
|
|
77
|
-
/**
|
|
78
|
-
*
|
|
79
|
-
* @category Math
|
|
80
|
-
*/
|
|
81
62
|
export function integerPart(x: number | string): string | undefined {
|
|
82
63
|
if (Number.isNaN(x)) {
|
|
83
64
|
return undefined
|
|
@@ -85,34 +66,18 @@ export function integerPart(x: number | string): string | undefined {
|
|
|
85
66
|
return String(x).split('.')[0]
|
|
86
67
|
}
|
|
87
68
|
|
|
88
|
-
/**
|
|
89
|
-
*
|
|
90
|
-
* @category Math
|
|
91
|
-
*/
|
|
92
69
|
export function decimalPart(x: number | string): string | undefined {
|
|
93
70
|
return String(x).split('.')[1]
|
|
94
71
|
}
|
|
95
72
|
|
|
96
|
-
/**
|
|
97
|
-
*
|
|
98
|
-
* @category Math
|
|
99
|
-
*/
|
|
100
73
|
export function radian(degree: number) {
|
|
101
74
|
return (Math.PI * degree) / 180
|
|
102
75
|
}
|
|
103
76
|
|
|
104
|
-
/**
|
|
105
|
-
*
|
|
106
|
-
* @category Math
|
|
107
|
-
*/
|
|
108
77
|
export function degree(radian: number) {
|
|
109
78
|
return (180 * radian) / Math.PI
|
|
110
79
|
}
|
|
111
80
|
|
|
112
|
-
/**
|
|
113
|
-
*
|
|
114
|
-
* @category Math
|
|
115
|
-
*/
|
|
116
81
|
export function mapValue(
|
|
117
82
|
value: number,
|
|
118
83
|
inMin: number,
|
|
@@ -123,18 +88,10 @@ export function mapValue(
|
|
|
123
88
|
return ((value - inMin) / (inMax - inMin)) * (outMax - outMin) + outMin
|
|
124
89
|
}
|
|
125
90
|
|
|
126
|
-
/**
|
|
127
|
-
*
|
|
128
|
-
* @category Math
|
|
129
|
-
*/
|
|
130
91
|
export function dbToGain(db: number) {
|
|
131
92
|
return Math.pow(10, db / 20)
|
|
132
93
|
}
|
|
133
94
|
|
|
134
|
-
/**
|
|
135
|
-
*
|
|
136
|
-
* @category Math
|
|
137
|
-
*/
|
|
138
95
|
export function gainToDb(gain: number) {
|
|
139
96
|
return 20 * (Math.log(gain) / Math.LN10)
|
|
140
97
|
}
|
package/src/midi.ts
CHANGED
|
@@ -1,18 +1,9 @@
|
|
|
1
1
|
import { mod } from './util'
|
|
2
2
|
|
|
3
|
-
/**
|
|
4
|
-
* @category MIDI
|
|
5
|
-
*/
|
|
6
3
|
export const whiteKeys = ['A', 'B', 'C', 'D', 'E', 'F', 'G'] as const
|
|
7
4
|
|
|
8
|
-
/**
|
|
9
|
-
* @category MIDI
|
|
10
|
-
*/
|
|
11
5
|
export type WhiteKey = (typeof whiteKeys)[number]
|
|
12
6
|
|
|
13
|
-
/**
|
|
14
|
-
* @category MIDI
|
|
15
|
-
*/
|
|
16
7
|
export const noteKeys = [
|
|
17
8
|
'C',
|
|
18
9
|
'C#',
|
|
@@ -28,14 +19,8 @@ export const noteKeys = [
|
|
|
28
19
|
'B',
|
|
29
20
|
] as const
|
|
30
21
|
|
|
31
|
-
/**
|
|
32
|
-
* @category MIDI
|
|
33
|
-
*/
|
|
34
22
|
export type NoteKey = (typeof noteKeys)[number]
|
|
35
23
|
|
|
36
|
-
/**
|
|
37
|
-
* @category MIDI
|
|
38
|
-
*/
|
|
39
24
|
export function parseNoteName(noteName: string) {
|
|
40
25
|
const m = noteName.match(/^([a-g])(#{0,2}|b{0,2})(-?\d+)$/i)
|
|
41
26
|
if (!m) throw new Error('Invalid note name')
|
|
@@ -49,7 +34,6 @@ export function parseNoteName(noteName: string) {
|
|
|
49
34
|
|
|
50
35
|
/**
|
|
51
36
|
* Convert noteName to noteNumber
|
|
52
|
-
* @category MIDI
|
|
53
37
|
*/
|
|
54
38
|
export function noteNumber(noteName: string) {
|
|
55
39
|
const { letter, accidental, octave } = parseNoteName(noteName)
|
|
@@ -63,7 +47,6 @@ export function noteNumber(noteName: string) {
|
|
|
63
47
|
* C-1 = 0
|
|
64
48
|
* G9 = 127
|
|
65
49
|
* @param noteNumber noteNumber
|
|
66
|
-
* @category MIDI
|
|
67
50
|
*/
|
|
68
51
|
export function noteName(noteNumber: number): `${NoteKey}${number}` {
|
|
69
52
|
const noteIndex = mod(noteNumber, 12)
|
|
@@ -73,7 +56,6 @@ export function noteName(noteNumber: number): `${NoteKey}${number}` {
|
|
|
73
56
|
|
|
74
57
|
/**
|
|
75
58
|
* Convert noteNumber to noteKey
|
|
76
|
-
* @category MIDI
|
|
77
59
|
*/
|
|
78
60
|
export function noteKey(noteNumber: number): NoteKey {
|
|
79
61
|
return noteKeys[mod(noteNumber, 12)]
|
|
@@ -81,7 +63,6 @@ export function noteKey(noteNumber: number): NoteKey {
|
|
|
81
63
|
|
|
82
64
|
/**
|
|
83
65
|
* @param note noteNumber: 0 ~ 127 or noteName e.g. 'C3'
|
|
84
|
-
* @category MIDI
|
|
85
66
|
*/
|
|
86
67
|
export function isWhiteKey(note: number | string) {
|
|
87
68
|
const n = typeof note == 'string' ? noteNumber(note) : note
|
|
@@ -98,7 +79,6 @@ export function isWhiteKey(note: number | string) {
|
|
|
98
79
|
|
|
99
80
|
/**
|
|
100
81
|
* @param note noteNumber: 0 ~ 127 or noteName e.g. 'C3'
|
|
101
|
-
* @category MIDI
|
|
102
82
|
*/
|
|
103
83
|
export function isBlackKey(note: number | string) {
|
|
104
84
|
return !isWhiteKey(note)
|
|
@@ -109,7 +89,6 @@ export function isBlackKey(note: number | string) {
|
|
|
109
89
|
* @param detune [cent]
|
|
110
90
|
* @param a4 A4 frequency [Hz]
|
|
111
91
|
* @returns frequency [Hz]
|
|
112
|
-
* @category MIDI
|
|
113
92
|
*/
|
|
114
93
|
export function noteToFrequency(note: number | string, detune = 0, a4 = 440) {
|
|
115
94
|
const n = typeof note == 'string' ? noteNumber(note) : note
|
package/src/types.ts
CHANGED
package/src/util.ts
CHANGED
|
@@ -1,8 +1,5 @@
|
|
|
1
1
|
type Operator = '+' | '-' | '*' | '/'
|
|
2
2
|
|
|
3
|
-
/**
|
|
4
|
-
* @category Utility
|
|
5
|
-
*/
|
|
6
3
|
export function styleHelper(value: string | number): string
|
|
7
4
|
export function styleHelper(
|
|
8
5
|
value: string | number,
|
|
@@ -32,23 +29,14 @@ export function styleHelper(
|
|
|
32
29
|
}
|
|
33
30
|
}
|
|
34
31
|
|
|
35
|
-
/**
|
|
36
|
-
* @category Utility
|
|
37
|
-
*/
|
|
38
32
|
export function isEmpty(obj: object) {
|
|
39
33
|
return Object.keys(obj).length == 0
|
|
40
34
|
}
|
|
41
35
|
|
|
42
|
-
/**
|
|
43
|
-
* @category Utility
|
|
44
|
-
*/
|
|
45
36
|
export function mod(n: number, m: number) {
|
|
46
37
|
return ((n % m) + m) % m
|
|
47
38
|
}
|
|
48
39
|
|
|
49
|
-
/**
|
|
50
|
-
* @category Utility
|
|
51
|
-
*/
|
|
52
40
|
export function xor(a = false, b = false) {
|
|
53
41
|
return (a || b) && a != b
|
|
54
42
|
}
|