@tspro/web-music-score 4.0.0 → 4.1.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/CHANGELOG.md +19 -0
- package/README.md +18 -9
- package/dist/audio/index.d.mts +40 -1
- package/dist/audio/index.d.ts +40 -1
- package/dist/audio/index.js +1 -1
- package/dist/audio/index.mjs +2 -2
- package/dist/audio-cg/index.d.mts +3 -0
- package/dist/audio-cg/index.d.ts +3 -0
- package/dist/audio-cg/index.js +1 -1
- package/dist/audio-cg/index.mjs +2 -2
- package/dist/{chunk-D643HZHM.mjs → chunk-MHNTJ6FU.mjs} +2 -2
- package/dist/core/index.d.mts +12 -0
- package/dist/core/index.d.ts +12 -0
- package/dist/core/index.js +3 -2
- package/dist/core/index.mjs +4 -3
- package/dist/guitar-CaZJDA05.d.ts +35 -0
- package/dist/guitar-DdexKdN6.d.mts +35 -0
- package/dist/iife/index.global.js +11 -11
- package/dist/{interface-XoKiryoV.d.mts → music-objects-DIaqNPjs.d.mts} +616 -114
- package/dist/{interface-7k8qGG44.d.ts → music-objects-xJJNlFwK.d.ts} +616 -114
- package/dist/note-eA2xPPiG.d.mts +294 -0
- package/dist/note-eA2xPPiG.d.ts +294 -0
- package/dist/pieces/index.d.mts +22 -3
- package/dist/pieces/index.d.ts +22 -3
- package/dist/pieces/index.js +5 -2
- package/dist/pieces/index.mjs +6 -3
- package/dist/react-ui/index.d.mts +166 -17
- package/dist/react-ui/index.d.ts +166 -17
- package/dist/react-ui/index.js +78 -1
- package/dist/react-ui/index.mjs +79 -2
- package/dist/scale-DQNA-YLD.d.ts +230 -0
- package/dist/scale-bnD0WnMV.d.mts +230 -0
- package/dist/score/index.d.mts +315 -47
- package/dist/score/index.d.ts +315 -47
- package/dist/score/index.js +684 -173
- package/dist/score/index.mjs +683 -174
- package/dist/tempo-Bp1UzsrZ.d.ts +399 -0
- package/dist/tempo-S85Q7uJA.d.mts +399 -0
- package/dist/theory/index.d.mts +29 -13
- package/dist/theory/index.d.ts +29 -13
- package/dist/theory/index.js +433 -42
- package/dist/theory/index.mjs +432 -43
- package/package.json +3 -2
- package/dist/guitar-DggbM2UL.d.mts +0 -17
- package/dist/guitar-cNmE-EvH.d.ts +0 -17
- package/dist/note-BFa43I86.d.mts +0 -85
- package/dist/note-CcVdUFqS.d.ts +0 -85
- package/dist/scale-C2pCNxdE.d.mts +0 -75
- package/dist/scale-CvPbJvfN.d.ts +0 -75
- package/dist/tempo-BAYoZ_Li.d.mts +0 -187
- package/dist/tempo-r2sb6Ku2.d.ts +0 -187
package/dist/theory/index.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
/* WebMusicScore v4.
|
|
1
|
+
/* WebMusicScore v4.1.0 | (c) 2023 PahkaSoft | MIT License | Includes: Tone.js (MIT License) */
|
|
2
2
|
import {
|
|
3
3
|
__publicField
|
|
4
|
-
} from "../chunk-
|
|
4
|
+
} from "../chunk-MHNTJ6FU.mjs";
|
|
5
5
|
|
|
6
6
|
// src/theory/chord.ts
|
|
7
7
|
import { Utils as Utils6 } from "@tspro/ts-utils-lib";
|
|
@@ -65,8 +65,11 @@ var DiatonicToChromaticMap = [0, 2, 4, 5, 7, 9, 11];
|
|
|
65
65
|
var NoteNameRegex = /^([A-G])((?:bb|𝄫|♭|b|#|♯|x|𝄪)?)?(-?\d+)?$/;
|
|
66
66
|
var _Note = class _Note {
|
|
67
67
|
constructor(arg, accidental, octave) {
|
|
68
|
+
/** Diatonic class */
|
|
68
69
|
__publicField(this, "diatonicClass");
|
|
70
|
+
/** Accidental. */
|
|
69
71
|
__publicField(this, "accidental");
|
|
72
|
+
/** Octave. */
|
|
70
73
|
__publicField(this, "octave");
|
|
71
74
|
if (typeof arg === "number" && typeof accidental === "number" && octave === void 0) {
|
|
72
75
|
_Note.validateDiatonicId(arg);
|
|
@@ -85,21 +88,32 @@ var _Note = class _Note {
|
|
|
85
88
|
throw new MusicError2(MusicErrorType2.Note, `Invalid args: ${arg}, ${accidental}, ${octave}`);
|
|
86
89
|
}
|
|
87
90
|
}
|
|
91
|
+
/** Diatonic id getter. */
|
|
88
92
|
get diatonicId() {
|
|
89
93
|
return _Note.getDiatonicIdInOctave(this.diatonicClass, this.octave);
|
|
90
94
|
}
|
|
95
|
+
/** Chromatic id getter. */
|
|
91
96
|
get chromaticId() {
|
|
92
97
|
return _Note.getChromaticIdInOctave(DiatonicToChromaticMap[this.diatonicClass] + this.accidental, this.octave);
|
|
93
98
|
}
|
|
99
|
+
/** Midi number getter (implemented same as chromatic id). */
|
|
94
100
|
get midiNumber() {
|
|
95
101
|
return this.chromaticId;
|
|
96
102
|
}
|
|
103
|
+
/** Chromatic class getter. */
|
|
97
104
|
get chromaticClass() {
|
|
98
105
|
return _Note.getChromaticClass(DiatonicToChromaticMap[this.diatonicClass] + this.accidental);
|
|
99
106
|
}
|
|
107
|
+
/** Note letter getter. */
|
|
100
108
|
get noteLetter() {
|
|
101
109
|
return NoteLetters[this.diatonicClass];
|
|
102
110
|
}
|
|
111
|
+
/**
|
|
112
|
+
* Format note to string presentation.
|
|
113
|
+
* @param pitchNotation - Pitchy notation.
|
|
114
|
+
* @param symbolSet - Symbol set.
|
|
115
|
+
* @returns - String presentation of note.
|
|
116
|
+
*/
|
|
103
117
|
format(pitchNotation, symbolSet) {
|
|
104
118
|
let { noteLetter, octave } = this;
|
|
105
119
|
let accidentalSymbol = _Note.getAccidentalSymbol(this.accidental, symbolSet);
|
|
@@ -113,11 +127,21 @@ var _Note = class _Note {
|
|
|
113
127
|
return noteLetter + accidentalSymbol + octave;
|
|
114
128
|
}
|
|
115
129
|
}
|
|
130
|
+
/**
|
|
131
|
+
* Format note to string presentation without octave number.
|
|
132
|
+
* @param symbolSet - Symbol set.
|
|
133
|
+
* @returns - String presentation of note without octave number.
|
|
134
|
+
*/
|
|
116
135
|
formatOmitOctave(symbolSet) {
|
|
117
136
|
let noteLetter = NoteLetters[this.diatonicClass];
|
|
118
137
|
let accidental = _Note.getAccidentalSymbol(this.accidental, symbolSet);
|
|
119
138
|
return noteLetter + accidental;
|
|
120
139
|
}
|
|
140
|
+
/**
|
|
141
|
+
* Get note.
|
|
142
|
+
* @param noteName - Note name (e.g. "C4").
|
|
143
|
+
* @returns - Note.
|
|
144
|
+
*/
|
|
121
145
|
static getNote(noteName) {
|
|
122
146
|
let note = this.noteByNameCache.get(noteName);
|
|
123
147
|
if (note === void 0) {
|
|
@@ -133,6 +157,11 @@ var _Note = class _Note {
|
|
|
133
157
|
}
|
|
134
158
|
return note;
|
|
135
159
|
}
|
|
160
|
+
/**
|
|
161
|
+
* Get chromatic note. There are number of alternatives, this function uses simple logic to choose one.
|
|
162
|
+
* @param chromaticId - Chromatic id.
|
|
163
|
+
* @returns - Note.
|
|
164
|
+
*/
|
|
136
165
|
static getChromaticNote(chromaticId) {
|
|
137
166
|
let note = this.chromaticNoteCache.get(chromaticId);
|
|
138
167
|
if (note === void 0) {
|
|
@@ -159,21 +188,54 @@ var _Note = class _Note {
|
|
|
159
188
|
throw new MusicError2(MusicErrorType2.Note, `Invalid arg: ${arg}`);
|
|
160
189
|
}
|
|
161
190
|
}
|
|
191
|
+
/**
|
|
192
|
+
* Get octave from diatonic id.
|
|
193
|
+
* @param diatonicId - Diatonic id.
|
|
194
|
+
* @returns - Octave.
|
|
195
|
+
*/
|
|
162
196
|
static getOctaveFromDiatonicId(diatonicId) {
|
|
163
197
|
return Math.floor((diatonicId - C0_diatonicId) / 7);
|
|
164
198
|
}
|
|
199
|
+
/**
|
|
200
|
+
* Get diatonic id in given octave (transposes diatonic id to given octave).
|
|
201
|
+
* @param diatonicId - Original diatonic id.
|
|
202
|
+
* @param octave - Octave.
|
|
203
|
+
* @returns - Transposed diatonic id.
|
|
204
|
+
*/
|
|
165
205
|
static getDiatonicIdInOctave(diatonicId, octave) {
|
|
166
206
|
return _Note.getDiatonicClass(diatonicId) + octave * 7 + C0_diatonicId;
|
|
167
207
|
}
|
|
208
|
+
/**
|
|
209
|
+
* Get chromatic class from chromatic id.
|
|
210
|
+
* @param chromaticId - Chromatic id.
|
|
211
|
+
* @returns - Chromatic class.
|
|
212
|
+
*/
|
|
168
213
|
static getChromaticClass(chromaticId) {
|
|
169
214
|
return mod(chromaticId, 12);
|
|
170
215
|
}
|
|
216
|
+
/**
|
|
217
|
+
* Get octave from chromatic id.
|
|
218
|
+
* @param chromaticId - Chromatic id.
|
|
219
|
+
* @returns - Octave.
|
|
220
|
+
*/
|
|
171
221
|
static getOctaveFromChromaticId(chromaticId) {
|
|
172
222
|
return Math.floor((chromaticId - C0_chromaticId) / 12);
|
|
173
223
|
}
|
|
224
|
+
/**
|
|
225
|
+
* Get chromatic id in given octave (transposes chromatic id to given octave).
|
|
226
|
+
* @param chromaticId - Original chromatic id.
|
|
227
|
+
* @param octave - Octave.
|
|
228
|
+
* @returns - Transpose chromatic id.
|
|
229
|
+
*/
|
|
174
230
|
static getChromaticIdInOctave(chromaticId, octave) {
|
|
175
231
|
return _Note.getChromaticClass(chromaticId) + octave * 12 + C0_chromaticId;
|
|
176
232
|
}
|
|
233
|
+
/**
|
|
234
|
+
* Test if given two notes are equal.
|
|
235
|
+
* @param a - Note a.
|
|
236
|
+
* @param b - Note b.
|
|
237
|
+
* @returns - True/false.
|
|
238
|
+
*/
|
|
177
239
|
static equals(a, b) {
|
|
178
240
|
if (a == null && b == null) {
|
|
179
241
|
return true;
|
|
@@ -183,6 +245,12 @@ var _Note = class _Note {
|
|
|
183
245
|
return a === b || a.diatonicId === b.diatonicId && a.accidental === b.accidental;
|
|
184
246
|
}
|
|
185
247
|
}
|
|
248
|
+
/**
|
|
249
|
+
* Replace accidental symbols in given string to givn symbol set (ascii/unicode).
|
|
250
|
+
* @param str - String to replace.
|
|
251
|
+
* @param symbolSet - Symbol set.
|
|
252
|
+
* @returns - String with updated accidental symbols.
|
|
253
|
+
*/
|
|
186
254
|
static replaceAccidentalSymbols(str, symbolSet) {
|
|
187
255
|
if (symbolSet === 1 /* Unicode */) {
|
|
188
256
|
return str.replace("bb", "\u{1D12B}").replace("b", "\u266D").replace("#", "\u266F").replace("x", "\u{1D12A}");
|
|
@@ -190,9 +258,19 @@ var _Note = class _Note {
|
|
|
190
258
|
return str.replace("\u{1D12B}", "bb").replace("\u266D", "b").replace("\u266F", "#").replace("\u{1D12A}", "x");
|
|
191
259
|
}
|
|
192
260
|
}
|
|
261
|
+
/**
|
|
262
|
+
* Test if given string is valid note name.
|
|
263
|
+
* @param noteName - Note name to validate.
|
|
264
|
+
* @returns - True/false.
|
|
265
|
+
*/
|
|
193
266
|
static isValidNoteName(noteName) {
|
|
194
267
|
return NoteNameRegex.test(noteName);
|
|
195
268
|
}
|
|
269
|
+
/**
|
|
270
|
+
* Parse note name string to note props.
|
|
271
|
+
* @param noteName - Note name to parse.
|
|
272
|
+
* @returns - Parsed note props or undefined if parsing error.
|
|
273
|
+
*/
|
|
196
274
|
static parseNote(noteName) {
|
|
197
275
|
var _a;
|
|
198
276
|
let m = NoteNameRegex.exec(noteName);
|
|
@@ -206,6 +284,12 @@ var _Note = class _Note {
|
|
|
206
284
|
let octave = octaveStr ? _Note.validateOctave(+octaveStr) : void 0;
|
|
207
285
|
return { noteLetter, accidental, octave };
|
|
208
286
|
}
|
|
287
|
+
/**
|
|
288
|
+
* Get scientific note name from given note name.
|
|
289
|
+
* @param noteName - Note name.
|
|
290
|
+
* @param symbolSet - Symbol set (ascii/unicode) for scientific note name.
|
|
291
|
+
* @returns - Scientific note name.
|
|
292
|
+
*/
|
|
209
293
|
static getScientificNoteName(noteName, symbolSet) {
|
|
210
294
|
let p = _Note.parseNote(noteName);
|
|
211
295
|
if (!p) {
|
|
@@ -214,9 +298,20 @@ var _Note = class _Note {
|
|
|
214
298
|
let { noteLetter, accidental, octave } = p;
|
|
215
299
|
return noteLetter + _Note.getAccidentalSymbol(accidental, symbolSet) + (octave != null ? octave : "");
|
|
216
300
|
}
|
|
301
|
+
/**
|
|
302
|
+
* Get symbol of given accidental in given symbol set (ascii/unicide).
|
|
303
|
+
* @param accidental - Accidental.
|
|
304
|
+
* @param symbolsSet - Symbol set.
|
|
305
|
+
* @returns - Accidental symbol or undefined (invalid accidental).
|
|
306
|
+
*/
|
|
217
307
|
static getAccidentalSymbol(accidental, symbolsSet) {
|
|
218
308
|
return symbolsSet === 1 /* Unicode */ ? AccidentalUnicodeSymbolMap.get(accidental) : AccidentalAsciiSymbolMap.get(accidental);
|
|
219
309
|
}
|
|
310
|
+
/**
|
|
311
|
+
* Get accidental value from given accidental symbol.
|
|
312
|
+
* @param accidentalSymbol - Accidental symbol (e.g. "#").
|
|
313
|
+
* @returns - Accidental vlaue.
|
|
314
|
+
*/
|
|
220
315
|
static getAccidental(accidentalSymbol) {
|
|
221
316
|
let accidental = AccidentalMap.get(accidentalSymbol);
|
|
222
317
|
if (accidental === void 0) {
|
|
@@ -224,15 +319,32 @@ var _Note = class _Note {
|
|
|
224
319
|
}
|
|
225
320
|
return accidental;
|
|
226
321
|
}
|
|
322
|
+
/**
|
|
323
|
+
* Get note letter from given diatonic id.
|
|
324
|
+
* @param diatonicId - Diatonic id.
|
|
325
|
+
* @returns - Note letter.
|
|
326
|
+
*/
|
|
227
327
|
static getNoteLetter(diatonicId) {
|
|
228
328
|
return NoteLetters[_Note.getDiatonicClass(diatonicId)];
|
|
229
329
|
}
|
|
330
|
+
/**
|
|
331
|
+
* Find next lowest possible diatonic id that is above given bottom level.
|
|
332
|
+
* @param diatonicId - Diatonic id to begin with.
|
|
333
|
+
* @param bottomDiatonicId - Bottom diatonic id.
|
|
334
|
+
* @param addOctaveIfEqual - If true then add one octave if diatonic id would equal to bottom diatonic id.
|
|
335
|
+
* @returns - Diatonic id.
|
|
336
|
+
*/
|
|
230
337
|
static findNextDiatonicIdAbove(diatonicId, bottomDiatonicId, addOctaveIfEqual) {
|
|
231
338
|
let diatonicClass = _Note.getDiatonicClass(diatonicId);
|
|
232
339
|
let bottomDiatonicClass = _Note.getDiatonicClass(bottomDiatonicId);
|
|
233
340
|
let addOctave = addOctaveIfEqual ? diatonicClass <= bottomDiatonicClass ? 1 : 0 : diatonicClass < bottomDiatonicClass ? 1 : 0;
|
|
234
341
|
return _Note.getDiatonicIdInOctave(diatonicClass, _Note.getOctaveFromDiatonicId(bottomDiatonicId) + addOctave);
|
|
235
342
|
}
|
|
343
|
+
/**
|
|
344
|
+
* Validate if given argument is diatonic id.
|
|
345
|
+
* @param diatonicId - Diatonic id to validate.
|
|
346
|
+
* @returns - Valid diatonic id or throws.
|
|
347
|
+
*/
|
|
236
348
|
static validateDiatonicId(diatonicId) {
|
|
237
349
|
if (Utils2.Is.isInteger(diatonicId)) {
|
|
238
350
|
return diatonicId;
|
|
@@ -240,13 +352,23 @@ var _Note = class _Note {
|
|
|
240
352
|
throw new MusicError2(MusicErrorType2.Note, `Invalid diatonicId: ${diatonicId}`);
|
|
241
353
|
}
|
|
242
354
|
}
|
|
355
|
+
/**
|
|
356
|
+
* Validate if given argument is diatonic class.
|
|
357
|
+
* @param diatonicClass - Diatonic class to validate.
|
|
358
|
+
* @returns - Valid diatonic class or throws.
|
|
359
|
+
*/
|
|
243
360
|
static validateDiatonicClass(diatonicClass) {
|
|
244
|
-
if (Utils2.Is.
|
|
361
|
+
if (Utils2.Is.isIntegerBetween(diatonicClass, 0, 6)) {
|
|
245
362
|
return diatonicClass;
|
|
246
363
|
} else {
|
|
247
364
|
throw new MusicError2(MusicErrorType2.Note, `Invalid diatonicClass: ${diatonicClass}`);
|
|
248
365
|
}
|
|
249
366
|
}
|
|
367
|
+
/**
|
|
368
|
+
* Validate if given argument is chromatic id.
|
|
369
|
+
* @param chromaticId - Chromatic id to validate.
|
|
370
|
+
* @returns - Valid chromatic id, or throws.
|
|
371
|
+
*/
|
|
250
372
|
static validateChromaticId(chromaticId) {
|
|
251
373
|
if (Utils2.Is.isInteger(chromaticId)) {
|
|
252
374
|
return chromaticId;
|
|
@@ -254,20 +376,35 @@ var _Note = class _Note {
|
|
|
254
376
|
throw new MusicError2(MusicErrorType2.Note, `Invalid chromaticId: ${chromaticId}`);
|
|
255
377
|
}
|
|
256
378
|
}
|
|
379
|
+
/**
|
|
380
|
+
* Validate if given argument is chromatic class.
|
|
381
|
+
* @param chromaticClass - Chromatic class to validate.
|
|
382
|
+
* @returns - Valid chromatic class, or throws.
|
|
383
|
+
*/
|
|
257
384
|
static validatechromaticClass(chromaticClass) {
|
|
258
|
-
if (Utils2.Is.
|
|
385
|
+
if (Utils2.Is.isIntegerBetween(chromaticClass, 0, 11)) {
|
|
259
386
|
return chromaticClass;
|
|
260
387
|
} else {
|
|
261
388
|
throw new MusicError2(MusicErrorType2.Note, `Invalid chromaticClass: ${chromaticClass}`);
|
|
262
389
|
}
|
|
263
390
|
}
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
391
|
+
/**
|
|
392
|
+
* Validate if given argument if note letter.
|
|
393
|
+
* @param noteLetter - Note letter to validate.
|
|
394
|
+
* @returns - Valid note letter or throws.
|
|
395
|
+
*/
|
|
396
|
+
static validateNoteLetter(noteLetter) {
|
|
397
|
+
if (NoteLetters.some((n) => n === noteLetter)) {
|
|
398
|
+
return noteLetter;
|
|
267
399
|
} else {
|
|
268
|
-
throw new MusicError2(MusicErrorType2.Note, `Invalid note: ${
|
|
400
|
+
throw new MusicError2(MusicErrorType2.Note, `Invalid note: ${noteLetter}`);
|
|
269
401
|
}
|
|
270
402
|
}
|
|
403
|
+
/**
|
|
404
|
+
* Validate if given argument is octave.
|
|
405
|
+
* @param octave - Octave to validate.
|
|
406
|
+
* @returns - Valid octave or throws.
|
|
407
|
+
*/
|
|
271
408
|
static validateOctave(octave) {
|
|
272
409
|
if (Utils2.Is.isInteger(octave)) {
|
|
273
410
|
return octave;
|
|
@@ -275,8 +412,13 @@ var _Note = class _Note {
|
|
|
275
412
|
throw new MusicError2(MusicErrorType2.Note, `Invalid octave: ${octave}`);
|
|
276
413
|
}
|
|
277
414
|
}
|
|
415
|
+
/**
|
|
416
|
+
* Validate if given argument is valid accidental.
|
|
417
|
+
* @param acc - Accidental to validate.
|
|
418
|
+
* @returns - Valid accidental or thorws.
|
|
419
|
+
*/
|
|
278
420
|
static validateAccidental(acc) {
|
|
279
|
-
if (Utils2.Is.
|
|
421
|
+
if (Utils2.Is.isIntegerBetween(acc, -2, 2)) {
|
|
280
422
|
return acc;
|
|
281
423
|
} else {
|
|
282
424
|
throw new MusicError2(MusicErrorType2.Note, `Invalid accidental: ${acc}`);
|
|
@@ -304,6 +446,12 @@ var _Note = class _Note {
|
|
|
304
446
|
});
|
|
305
447
|
return uniqueSet;
|
|
306
448
|
}
|
|
449
|
+
/**
|
|
450
|
+
* Function to compare two notes using diatonic id and accidental properties of notes.
|
|
451
|
+
* @param a - Note a.
|
|
452
|
+
* @param b - Note b.
|
|
453
|
+
* @returns - -1, 0 or 1.
|
|
454
|
+
*/
|
|
307
455
|
static compareFunc(a, b) {
|
|
308
456
|
if (a.diatonicId < b.diatonicId) {
|
|
309
457
|
return -1;
|
|
@@ -425,6 +573,10 @@ var _KeySignature = class _KeySignature {
|
|
|
425
573
|
}
|
|
426
574
|
this.orderedAccidentedNotes = flats.length > 0 ? flats : sharps;
|
|
427
575
|
}
|
|
576
|
+
/**
|
|
577
|
+
* Get accidental type sharps, flats, or natural (without accidentals).
|
|
578
|
+
* @returns - Accidental type.
|
|
579
|
+
*/
|
|
428
580
|
getAccidentalType() {
|
|
429
581
|
if (this.orderedAccidentedNotes.length === 0) {
|
|
430
582
|
return 0 /* Natural */;
|
|
@@ -434,23 +586,40 @@ var _KeySignature = class _KeySignature {
|
|
|
434
586
|
return 2 /* Sharps */;
|
|
435
587
|
}
|
|
436
588
|
}
|
|
589
|
+
/**
|
|
590
|
+
* Get natural scale notes of this key signature, natural scale has 7 steps (e.g. Major scale: W, W, H, W, W, W, H).
|
|
591
|
+
* @returns - Array of notes.
|
|
592
|
+
*/
|
|
437
593
|
getNaturalScaleNotes() {
|
|
438
594
|
return this.naturalScaleNotes;
|
|
439
595
|
}
|
|
596
|
+
/**
|
|
597
|
+
* Get accidental for given diatonic id.
|
|
598
|
+
* @param diatonicId - Diatonic id.
|
|
599
|
+
* @returns - Accidental -2, -1, 0, 1 or 2.
|
|
600
|
+
*/
|
|
440
601
|
getAccidental(diatonicId) {
|
|
441
602
|
var _a;
|
|
442
603
|
return (_a = this.accidentalByDiatonicClass[Note.getDiatonicClass(diatonicId)]) != null ? _a : 0;
|
|
443
604
|
}
|
|
605
|
+
/**
|
|
606
|
+
* Get number of accidentals this key signature has.
|
|
607
|
+
* @returns - Number of accidentals.
|
|
608
|
+
*/
|
|
444
609
|
getNumAccidentals() {
|
|
445
610
|
return this.orderedAccidentedNotes.length;
|
|
446
611
|
}
|
|
612
|
+
/**
|
|
613
|
+
* Get accidental notes in correct order.
|
|
614
|
+
* @returns - Array of accidental notes.
|
|
615
|
+
*/
|
|
447
616
|
getOrderedAccidentalNotes() {
|
|
448
617
|
return this.orderedAccidentedNotes;
|
|
449
618
|
}
|
|
450
619
|
/**
|
|
451
|
-
*
|
|
452
|
-
* @param degree - number 1
|
|
453
|
-
* @returns
|
|
620
|
+
* Get note of key signature by degree value.
|
|
621
|
+
* @param degree - Degree number in range [1, 7] or string e.g "b5" or "#4".
|
|
622
|
+
* @returns - Note.
|
|
454
623
|
*/
|
|
455
624
|
getNoteByDegree(degree) {
|
|
456
625
|
let { deg, acc } = parseDegree(degree);
|
|
@@ -461,6 +630,12 @@ var _KeySignature = class _KeySignature {
|
|
|
461
630
|
return new Note(note.diatonicId, note.accidental + acc);
|
|
462
631
|
}
|
|
463
632
|
}
|
|
633
|
+
/**
|
|
634
|
+
* Test equality of given key signatures.
|
|
635
|
+
* @param a - Key signature a.
|
|
636
|
+
* @param b - Key signature b.
|
|
637
|
+
* @returns - True/false.
|
|
638
|
+
*/
|
|
464
639
|
static equals(a, b) {
|
|
465
640
|
if (a == null && b == null) {
|
|
466
641
|
return true;
|
|
@@ -598,9 +773,13 @@ var Interval = class _Interval {
|
|
|
598
773
|
constructor(note1, note2) {
|
|
599
774
|
this.note1 = note1;
|
|
600
775
|
this.note2 = note2;
|
|
776
|
+
/** Interval direction. */
|
|
601
777
|
__publicField(this, "direction");
|
|
778
|
+
/** Number of semitones. */
|
|
602
779
|
__publicField(this, "semitones");
|
|
780
|
+
/** Interval quantity. */
|
|
603
781
|
__publicField(this, "quantity");
|
|
782
|
+
/** Interval quality. */
|
|
604
783
|
__publicField(this, "quality");
|
|
605
784
|
if (note2.diatonicId >= note1.diatonicId) {
|
|
606
785
|
this.direction = note2.diatonicId === note1.diatonicId ? "Unison" : "Ascending";
|
|
@@ -618,6 +797,12 @@ var Interval = class _Interval {
|
|
|
618
797
|
throw new InvalidIntervalException("Unknown interval quality");
|
|
619
798
|
}
|
|
620
799
|
}
|
|
800
|
+
/**
|
|
801
|
+
* Get interval between given two notes.
|
|
802
|
+
* @param note1 - First note.
|
|
803
|
+
* @param note2 - Second note.
|
|
804
|
+
* @returns - Interval if valid, or undefined.
|
|
805
|
+
*/
|
|
621
806
|
static get(note1, note2) {
|
|
622
807
|
try {
|
|
623
808
|
return new _Interval(note1, note2);
|
|
@@ -629,12 +814,20 @@ var Interval = class _Interval {
|
|
|
629
814
|
}
|
|
630
815
|
}
|
|
631
816
|
}
|
|
817
|
+
/**
|
|
818
|
+
* Get string presentation of interval (e.g. "Descending Major 2").
|
|
819
|
+
* @returns - Interval string.
|
|
820
|
+
*/
|
|
632
821
|
toString() {
|
|
633
822
|
let direction = this.direction === "Unison" ? "" : this.direction + " ";
|
|
634
823
|
let quality = this.quality + " ";
|
|
635
824
|
let quantity = this.direction === "Unison" ? "Unison" : formatQuantity(this.quantity);
|
|
636
825
|
return direction + quality + quantity;
|
|
637
826
|
}
|
|
827
|
+
/**
|
|
828
|
+
* Get abbrevated string presentation of interval (e.g. "↓M2").
|
|
829
|
+
* @returns - Interval abbrevated string.
|
|
830
|
+
*/
|
|
638
831
|
toAbbrString() {
|
|
639
832
|
var _a;
|
|
640
833
|
let direction = this.direction === "Descending" ? "\u2193" : "";
|
|
@@ -729,12 +922,20 @@ function getMode(scaleType) {
|
|
|
729
922
|
}
|
|
730
923
|
}
|
|
731
924
|
var Scale = class extends KeySignature {
|
|
925
|
+
/**
|
|
926
|
+
* Create nev scale object instance.
|
|
927
|
+
* @param tonic - Tonic (e.g. "C" in "C Major").
|
|
928
|
+
* @param scaleType - Scale typo ("e.g. "Major" in "C Major").
|
|
929
|
+
*/
|
|
732
930
|
constructor(tonic, scaleType) {
|
|
733
931
|
super(tonic, getMode(scaleType));
|
|
734
932
|
this.tonic = tonic;
|
|
735
933
|
this.scaleType = scaleType;
|
|
934
|
+
/** Degrees of scale notes. */
|
|
736
935
|
__publicField(this, "scaleDegrees");
|
|
936
|
+
/** Scale notes. */
|
|
737
937
|
__publicField(this, "scaleNotes");
|
|
938
|
+
/** Degrees (or undefined) of chromatic classes. */
|
|
738
939
|
__publicField(this, "chromaticClassDegree");
|
|
739
940
|
__publicField(this, "preferredChromaticNoteCache", /* @__PURE__ */ new Map());
|
|
740
941
|
switch (scaleType) {
|
|
@@ -766,6 +967,12 @@ var Scale = class extends KeySignature {
|
|
|
766
967
|
return id >= 0 ? this.scaleDegrees[id] : void 0;
|
|
767
968
|
});
|
|
768
969
|
}
|
|
970
|
+
/**
|
|
971
|
+
* Compare if two scales equals.
|
|
972
|
+
* @param a - Scale a.
|
|
973
|
+
* @param b - Scale b.
|
|
974
|
+
* @returns - Boolean equality of given scales.
|
|
975
|
+
*/
|
|
769
976
|
static equals(a, b) {
|
|
770
977
|
if (a == null && b == null) {
|
|
771
978
|
return true;
|
|
@@ -775,6 +982,11 @@ var Scale = class extends KeySignature {
|
|
|
775
982
|
return a === b || a.getScaleName() === b.getScaleName();
|
|
776
983
|
}
|
|
777
984
|
}
|
|
985
|
+
/**
|
|
986
|
+
* Get scale name.
|
|
987
|
+
* @param symbolSet - Symbol set to format scale name in ascii or unicode.
|
|
988
|
+
* @returns - Scale name string.
|
|
989
|
+
*/
|
|
778
990
|
getScaleName(symbolSet) {
|
|
779
991
|
switch (symbolSet) {
|
|
780
992
|
case 1 /* Unicode */:
|
|
@@ -783,6 +995,12 @@ var Scale = class extends KeySignature {
|
|
|
783
995
|
return this.tonic + " " + this.scaleType;
|
|
784
996
|
}
|
|
785
997
|
}
|
|
998
|
+
/**
|
|
999
|
+
* Get scale notes.
|
|
1000
|
+
* @param bottomNote - Computed scale notes begin no lower than this note.
|
|
1001
|
+
* @param numOctaves - How many octaves?
|
|
1002
|
+
* @returns - Array of scale notes.
|
|
1003
|
+
*/
|
|
786
1004
|
getScaleNotes(bottomNote, numOctaves) {
|
|
787
1005
|
if (!Utils5.Is.isIntegerGte(numOctaves, 1)) {
|
|
788
1006
|
throw new MusicError5(MusicErrorType5.Scale, `Invalid numOctaves: ${numOctaves}`);
|
|
@@ -798,9 +1016,17 @@ var Scale = class extends KeySignature {
|
|
|
798
1016
|
return new Note(diatonicId, note.accidental);
|
|
799
1017
|
});
|
|
800
1018
|
}
|
|
1019
|
+
/**
|
|
1020
|
+
* Get scale overview (e.g. "C - D - E - F - G - A - B" for "C Major" scale).
|
|
1021
|
+
* @returns - Scale overview string.
|
|
1022
|
+
*/
|
|
801
1023
|
getScaleOverview() {
|
|
802
1024
|
return this.getScaleNotes("C4", 1).map((note) => note.formatOmitOctave(1 /* Unicode */)).join(" - ");
|
|
803
1025
|
}
|
|
1026
|
+
/**
|
|
1027
|
+
* Get scale steps, array of 1 (half step) and 2 (whole step), (e.g. [2, 2, 1, 2, 2, 2, 1] for Major scale).
|
|
1028
|
+
* @returns - Array of scale steps.
|
|
1029
|
+
*/
|
|
804
1030
|
getScaleSteps() {
|
|
805
1031
|
let chromaticIds = this.getScaleNotes("C4", 1).map((note) => note.chromaticId);
|
|
806
1032
|
let steps = [];
|
|
@@ -809,15 +1035,34 @@ var Scale = class extends KeySignature {
|
|
|
809
1035
|
}
|
|
810
1036
|
return steps;
|
|
811
1037
|
}
|
|
1038
|
+
/**
|
|
1039
|
+
* Get scale steps string presentation, array of "H" (half step) and "W" (whole step), (e.g. ["W", "W", "H", "W", "W", "W", "H"] for Major scale).
|
|
1040
|
+
* @returns - Array of scale steps string presentation.
|
|
1041
|
+
*/
|
|
812
1042
|
getScaleStringSteps() {
|
|
813
1043
|
return this.getScaleSteps().map((step) => step === 1 ? "H" : step === 2 ? "W" : step.toString() + "H");
|
|
814
1044
|
}
|
|
1045
|
+
/**
|
|
1046
|
+
* Test if given note is scale note.
|
|
1047
|
+
* @param note - Note to test.
|
|
1048
|
+
* @returns - True/false.
|
|
1049
|
+
*/
|
|
815
1050
|
isScaleNote(note) {
|
|
816
1051
|
return this.chromaticClassDegree[note.chromaticClass] !== void 0;
|
|
817
1052
|
}
|
|
1053
|
+
/**
|
|
1054
|
+
* Test if given note is scale root note.
|
|
1055
|
+
* @param note - Note to test.
|
|
1056
|
+
* @returns - True/false.
|
|
1057
|
+
*/
|
|
818
1058
|
isScaleRootNote(note) {
|
|
819
1059
|
return String(this.chromaticClassDegree[note.chromaticClass]) === "1";
|
|
820
1060
|
}
|
|
1061
|
+
/**
|
|
1062
|
+
* Get interval value between scale root note and given note.
|
|
1063
|
+
* @param note - Note.
|
|
1064
|
+
* @returns - Interval.
|
|
1065
|
+
*/
|
|
821
1066
|
getIntervalFromRootNote(note) {
|
|
822
1067
|
let rootNote = this.getScaleNotes("C0", 1)[0];
|
|
823
1068
|
while (note.chromaticId >= rootNote.chromaticId + 12) {
|
|
@@ -833,6 +1078,11 @@ var Scale = class extends KeySignature {
|
|
|
833
1078
|
return interval;
|
|
834
1079
|
}
|
|
835
1080
|
}
|
|
1081
|
+
/**
|
|
1082
|
+
* Get preferred chromatic note from given chromatic id.
|
|
1083
|
+
* @param chromaticId - Chromatic id.
|
|
1084
|
+
* @returns - Note.
|
|
1085
|
+
*/
|
|
836
1086
|
getPreferredChromaticNote(chromaticId) {
|
|
837
1087
|
Note.validateChromaticId(chromaticId);
|
|
838
1088
|
let note = this.preferredChromaticNoteCache.get(chromaticId);
|
|
@@ -875,6 +1125,10 @@ var Scale = class extends KeySignature {
|
|
|
875
1125
|
}
|
|
876
1126
|
};
|
|
877
1127
|
var ScaleFactory = class {
|
|
1128
|
+
/**
|
|
1129
|
+
* Create new scale factory object instance.
|
|
1130
|
+
* @param type - Scale type.
|
|
1131
|
+
*/
|
|
878
1132
|
constructor(type) {
|
|
879
1133
|
this.type = type;
|
|
880
1134
|
__publicField(this, "tonicList", []);
|
|
@@ -920,15 +1174,32 @@ var ScaleFactory = class {
|
|
|
920
1174
|
...flatScales.sort(SortByAccidentalCountFunc).map((scale) => scale.tonic)
|
|
921
1175
|
];
|
|
922
1176
|
}
|
|
1177
|
+
/**
|
|
1178
|
+
* Get list of tonics (e.g. "C", "C#", ... for Major scale type).
|
|
1179
|
+
* @returns - Array of tonics.
|
|
1180
|
+
*/
|
|
923
1181
|
getTonicList() {
|
|
924
1182
|
return this.tonicList;
|
|
925
1183
|
}
|
|
1184
|
+
/**
|
|
1185
|
+
* Get default tonic.
|
|
1186
|
+
* @returns - Default tonic.
|
|
1187
|
+
*/
|
|
926
1188
|
getDefaultTonic() {
|
|
927
1189
|
return this.tonicList[0];
|
|
928
1190
|
}
|
|
1191
|
+
/**
|
|
1192
|
+
* Get scale type.
|
|
1193
|
+
* @returns - SCale type.
|
|
1194
|
+
*/
|
|
929
1195
|
getType() {
|
|
930
1196
|
return this.type;
|
|
931
1197
|
}
|
|
1198
|
+
/**
|
|
1199
|
+
* Get scale by given tonic.
|
|
1200
|
+
* @param tonic - Tonic (e.g. "C").
|
|
1201
|
+
* @returns - Scale.
|
|
1202
|
+
*/
|
|
932
1203
|
getScale(tonic) {
|
|
933
1204
|
let scale = this.scaleMap.get(tonic);
|
|
934
1205
|
if (!scale) {
|
|
@@ -937,6 +1208,11 @@ var ScaleFactory = class {
|
|
|
937
1208
|
return scale;
|
|
938
1209
|
}
|
|
939
1210
|
}
|
|
1211
|
+
/**
|
|
1212
|
+
* Test if this scale factory has scale for given tonic value.
|
|
1213
|
+
* @param tonic - Tonic.
|
|
1214
|
+
* @returns - True/false.
|
|
1215
|
+
*/
|
|
940
1216
|
hasScale(tonic) {
|
|
941
1217
|
return this.scaleMap.get(tonic) !== void 0;
|
|
942
1218
|
}
|
|
@@ -1101,9 +1377,13 @@ var Chord = class _Chord {
|
|
|
1101
1377
|
constructor(chordInfo, chordNotes, rootNote, bassNote) {
|
|
1102
1378
|
this.chordInfo = chordInfo;
|
|
1103
1379
|
this.rootNote = rootNote;
|
|
1380
|
+
/** Chord name. */
|
|
1104
1381
|
__publicField(this, "name");
|
|
1382
|
+
/** Notes of this chord. */
|
|
1105
1383
|
__publicField(this, "notes");
|
|
1384
|
+
/** Notes that are omitted in this chord (partial chord). */
|
|
1106
1385
|
__publicField(this, "omitNotes");
|
|
1386
|
+
/** Bass note if not chord root note (e.g. "B" in "C/B"). */
|
|
1107
1387
|
__publicField(this, "slashBassNote");
|
|
1108
1388
|
this.name = chordInfo.name;
|
|
1109
1389
|
let notesLeft = chordNotes.slice();
|
|
@@ -1142,6 +1422,11 @@ var Chord = class _Chord {
|
|
|
1142
1422
|
throw new InvalidChordException("Power chord no bass note allowed!");
|
|
1143
1423
|
}
|
|
1144
1424
|
}
|
|
1425
|
+
/**
|
|
1426
|
+
* Get all chords that can be made up with given notes.
|
|
1427
|
+
* @param notes - Array of notes.
|
|
1428
|
+
* @returns - Array of chords.
|
|
1429
|
+
*/
|
|
1145
1430
|
static getChords(notes) {
|
|
1146
1431
|
let chords = [];
|
|
1147
1432
|
let chordNotes = Note.sort(notes);
|
|
@@ -1181,7 +1466,8 @@ var Chord = class _Chord {
|
|
|
1181
1466
|
return true;
|
|
1182
1467
|
}
|
|
1183
1468
|
/**
|
|
1184
|
-
*
|
|
1469
|
+
* Get chord string presentation.
|
|
1470
|
+
* @returns Chord string presentation (e.g. "C/B").
|
|
1185
1471
|
*/
|
|
1186
1472
|
toString() {
|
|
1187
1473
|
let symbolSet = 1 /* Unicode */;
|
|
@@ -1190,7 +1476,8 @@ var Chord = class _Chord {
|
|
|
1190
1476
|
return rootNoteStr + this.name + slashBassStr;
|
|
1191
1477
|
}
|
|
1192
1478
|
/**
|
|
1193
|
-
*
|
|
1479
|
+
* Get degree notation string (e.g. "E - 1(C) - 3(E) - 5(G)").
|
|
1480
|
+
* @returns Degree notation string.
|
|
1194
1481
|
*/
|
|
1195
1482
|
getDegreeNotationString() {
|
|
1196
1483
|
let symbolSet = 1 /* Unicode */;
|
|
@@ -1201,7 +1488,8 @@ var Chord = class _Chord {
|
|
|
1201
1488
|
return bassNoteStr + degreeNoteStr;
|
|
1202
1489
|
}
|
|
1203
1490
|
/**
|
|
1204
|
-
*
|
|
1491
|
+
* Get string presentation of omitted degrees (e.g. "Omits 5(G), 9(D)").
|
|
1492
|
+
* @returns - String presentation of omitted degrees.
|
|
1205
1493
|
*/
|
|
1206
1494
|
getOmittedDegreesString() {
|
|
1207
1495
|
let omittedStrList = this.omitNotes.map((omit, i) => {
|
|
@@ -1210,15 +1498,17 @@ var Chord = class _Chord {
|
|
|
1210
1498
|
return omittedStrList.length > 0 ? "Omits " + omittedStrList.join(", ") : "";
|
|
1211
1499
|
}
|
|
1212
1500
|
/**
|
|
1213
|
-
*
|
|
1214
|
-
* @
|
|
1501
|
+
* Degree index for given degree index (e.g. "3").
|
|
1502
|
+
* @param i - Chord degree index (e.g. 0 is first note degree of chord).
|
|
1503
|
+
* @returns Degree string.
|
|
1215
1504
|
*/
|
|
1216
1505
|
getDegreeStr(i) {
|
|
1217
1506
|
return Note.replaceAccidentalSymbols("" + this.chordInfo.degrees[i], 1 /* Unicode */);
|
|
1218
1507
|
}
|
|
1219
1508
|
/**
|
|
1220
|
-
*
|
|
1221
|
-
* @
|
|
1509
|
+
* Get note name for given degree index (e.g. "E").
|
|
1510
|
+
* @param i - Chord degree index (e.g. 0 is first note degree of chord).
|
|
1511
|
+
* @returns - Note name string.
|
|
1222
1512
|
*/
|
|
1223
1513
|
getNoteStr(i) {
|
|
1224
1514
|
return this.notes[i].formatOmitOctave(1 /* Unicode */);
|
|
@@ -1530,6 +1820,7 @@ var NoteLength = /* @__PURE__ */ ((NoteLength3) => {
|
|
|
1530
1820
|
NoteLength3["Whole"] = "1n";
|
|
1531
1821
|
NoteLength3["WholeTriplet"] = "1t";
|
|
1532
1822
|
NoteLength3["WholeDot"] = "1.";
|
|
1823
|
+
NoteLength3["Whole2Dots"] = "1..";
|
|
1533
1824
|
NoteLength3["Whole12Dots"] = "1..";
|
|
1534
1825
|
NoteLength3["Whole3Dots"] = "1...";
|
|
1535
1826
|
NoteLength3["Whole4Dots"] = "1....";
|
|
@@ -1572,17 +1863,24 @@ function validateNoteLength(noteLength) {
|
|
|
1572
1863
|
}
|
|
1573
1864
|
}
|
|
1574
1865
|
var _NoteLengthProps = class _NoteLengthProps {
|
|
1575
|
-
// Is solid (black) note head?
|
|
1576
1866
|
constructor(noteLength) {
|
|
1867
|
+
/** Note length. */
|
|
1577
1868
|
__publicField(this, "noteLength");
|
|
1869
|
+
/** Note size (whole=1, half=2, quarter=4, ...). */
|
|
1578
1870
|
__publicField(this, "noteSize");
|
|
1871
|
+
/** Number of ticks (not altered by isTriplet). */
|
|
1579
1872
|
__publicField(this, "ticks");
|
|
1580
|
-
|
|
1873
|
+
/** Flag count. */
|
|
1581
1874
|
__publicField(this, "flagCount");
|
|
1875
|
+
/** Dot count. */
|
|
1582
1876
|
__publicField(this, "dotCount");
|
|
1877
|
+
/** Max dot count. */
|
|
1583
1878
|
__publicField(this, "maxDotCount");
|
|
1879
|
+
/** Is triplet? */
|
|
1584
1880
|
__publicField(this, "isTriplet");
|
|
1881
|
+
/** Has note stem. */
|
|
1585
1882
|
__publicField(this, "hasStem");
|
|
1883
|
+
/** Is note head solid (black)? */
|
|
1586
1884
|
__publicField(this, "isSolid");
|
|
1587
1885
|
this.noteLength = validateNoteLength(noteLength);
|
|
1588
1886
|
this.noteSize = parseInt(noteLength);
|
|
@@ -1599,6 +1897,11 @@ var _NoteLengthProps = class _NoteLengthProps {
|
|
|
1599
1897
|
throw new MusicError8(MusicErrorType8.Note, `noteLength "${this.noteLength}" is both triplet and dotted!`);
|
|
1600
1898
|
}
|
|
1601
1899
|
}
|
|
1900
|
+
/**
|
|
1901
|
+
* Get note length props.
|
|
1902
|
+
* @param noteLength - Note length.
|
|
1903
|
+
* @returns - Note length props.
|
|
1904
|
+
*/
|
|
1602
1905
|
static get(noteLength) {
|
|
1603
1906
|
let p = this.cache.get(noteLength);
|
|
1604
1907
|
if (!p) {
|
|
@@ -1606,6 +1909,12 @@ var _NoteLengthProps = class _NoteLengthProps {
|
|
|
1606
1909
|
}
|
|
1607
1910
|
return p;
|
|
1608
1911
|
}
|
|
1912
|
+
/**
|
|
1913
|
+
* Create note length props.
|
|
1914
|
+
* @param noteLength - Note length or note size.
|
|
1915
|
+
* @param dotCount - Dot count.
|
|
1916
|
+
* @returns - Note length props.
|
|
1917
|
+
*/
|
|
1609
1918
|
static create(noteLength, dotCount = 0) {
|
|
1610
1919
|
let noteSize = typeof noteLength === "number" ? noteLength : this.get(noteLength).noteSize;
|
|
1611
1920
|
return this.get(noteSize + (Utils8.Is.isIntegerGte(dotCount, 1) ? ".".repeat(dotCount) : "n"));
|
|
@@ -1635,7 +1944,9 @@ var _NoteLengthProps = class _NoteLengthProps {
|
|
|
1635
1944
|
return aNoteSize === bNoteSize;
|
|
1636
1945
|
}
|
|
1637
1946
|
};
|
|
1947
|
+
/** Longest note size (e.g. 1 = whole note). */
|
|
1638
1948
|
__publicField(_NoteLengthProps, "LongestNoteSize", Math.min(...Utils8.Enum.getEnumValues(NoteLength).map((noteLength) => parseInt(noteLength))));
|
|
1949
|
+
/** Shortest note size (e.g. 64 = sixtyfourth note). */
|
|
1639
1950
|
__publicField(_NoteLengthProps, "ShortestNoteSize", Math.max(...Utils8.Enum.getEnumValues(NoteLength).map((noteLength) => parseInt(noteLength))));
|
|
1640
1951
|
__publicField(_NoteLengthProps, "cache", /* @__PURE__ */ new Map());
|
|
1641
1952
|
var NoteLengthProps = _NoteLengthProps;
|
|
@@ -1647,23 +1958,30 @@ function validateTupletRatio(tupletRatio) {
|
|
|
1647
1958
|
}
|
|
1648
1959
|
}
|
|
1649
1960
|
var Tuplet = {
|
|
1650
|
-
/** 2 in the time of 3 */
|
|
1961
|
+
/** Duplet: 2 in the time of 3 */
|
|
1651
1962
|
Duplet: { parts: 2, inTimeOf: 3 },
|
|
1652
|
-
/** 3 in the time of 2 */
|
|
1963
|
+
/** Triplet: 3 in the time of 2 */
|
|
1653
1964
|
Triplet: { parts: 3, inTimeOf: 2 },
|
|
1654
|
-
/** 4 in the time of 3 */
|
|
1965
|
+
/** Quadruplet: 4 in the time of 3 */
|
|
1655
1966
|
Quadruplet: { parts: 4, inTimeOf: 3 }
|
|
1656
1967
|
};
|
|
1657
1968
|
var _RhythmProps = class _RhythmProps {
|
|
1658
1969
|
constructor(noteLength, dotCount, tupletRatio) {
|
|
1970
|
+
/** Note length. */
|
|
1659
1971
|
__publicField(this, "noteLength");
|
|
1972
|
+
/** Note size (whole=1, half=2, quarter=4, ...). */
|
|
1660
1973
|
__publicField(this, "noteSize");
|
|
1661
|
-
|
|
1974
|
+
/** Dot count. */
|
|
1662
1975
|
__publicField(this, "dotCount");
|
|
1976
|
+
/** Tuplet ratio. */
|
|
1663
1977
|
__publicField(this, "tupletRatio");
|
|
1978
|
+
/** Number of ticks. */
|
|
1664
1979
|
__publicField(this, "ticks");
|
|
1980
|
+
/** Flag count. */
|
|
1665
1981
|
__publicField(this, "flagCount");
|
|
1982
|
+
/** Has note stem. */
|
|
1666
1983
|
__publicField(this, "hasStem");
|
|
1984
|
+
/** Is note head solid (black)? */
|
|
1667
1985
|
__publicField(this, "isSolidNoteHead");
|
|
1668
1986
|
this.noteLength = validateNoteLength(noteLength);
|
|
1669
1987
|
let p = NoteLengthProps.get(noteLength);
|
|
@@ -1692,11 +2010,22 @@ var _RhythmProps = class _RhythmProps {
|
|
|
1692
2010
|
this.ticks *= this.tupletRatio.inTimeOf / this.tupletRatio.parts;
|
|
1693
2011
|
}
|
|
1694
2012
|
}
|
|
2013
|
+
/**
|
|
2014
|
+
* Get string presentation of rhythm props.
|
|
2015
|
+
* @returns - String presentation.
|
|
2016
|
+
*/
|
|
1695
2017
|
toString() {
|
|
1696
2018
|
let sym = _RhythmProps.NoteSymbolMap.get(this.noteSize);
|
|
1697
2019
|
let dots = ".".repeat(this.dotCount);
|
|
1698
2020
|
return sym ? sym + dots : "" + this.noteSize + (dots.length > 0 ? dots : "n");
|
|
1699
2021
|
}
|
|
2022
|
+
/**
|
|
2023
|
+
* Get rhythm props with given arguments.
|
|
2024
|
+
* @param noteLength - Note length.
|
|
2025
|
+
* @param dotCount - Dot count.
|
|
2026
|
+
* @param tupletRatio - Tuplet ratio.
|
|
2027
|
+
* @returns - Rhythm props.
|
|
2028
|
+
*/
|
|
1700
2029
|
static get(noteLength, dotCount, tupletRatio) {
|
|
1701
2030
|
if (dotCount !== void 0 || tupletRatio !== void 0) {
|
|
1702
2031
|
return new _RhythmProps(noteLength, dotCount, tupletRatio);
|
|
@@ -1733,22 +2062,50 @@ var RhythmProps = _RhythmProps;
|
|
|
1733
2062
|
|
|
1734
2063
|
// src/theory/time-signature.ts
|
|
1735
2064
|
import { MusicError as MusicError9, MusicErrorType as MusicErrorType9 } from "@tspro/web-music-score/core";
|
|
2065
|
+
var TimeSignatures = /* @__PURE__ */ ((TimeSignatures2) => {
|
|
2066
|
+
TimeSignatures2["_2_4"] = "2/4";
|
|
2067
|
+
TimeSignatures2["_3_4"] = "3/4";
|
|
2068
|
+
TimeSignatures2["_4_4"] = "4/4";
|
|
2069
|
+
TimeSignatures2["_5_8"] = "5/8";
|
|
2070
|
+
TimeSignatures2["_6_8"] = "6/8";
|
|
2071
|
+
TimeSignatures2["_7_8"] = "7/8";
|
|
2072
|
+
TimeSignatures2["_9_8"] = "9/8";
|
|
2073
|
+
TimeSignatures2["_12_8"] = "12/8";
|
|
2074
|
+
return TimeSignatures2;
|
|
2075
|
+
})(TimeSignatures || {});
|
|
2076
|
+
var BeamGrouping = /* @__PURE__ */ ((BeamGrouping2) => {
|
|
2077
|
+
BeamGrouping2["_2_3"] = "2-3";
|
|
2078
|
+
BeamGrouping2["_3_2"] = "3-2";
|
|
2079
|
+
BeamGrouping2["_2_2_3"] = "2-2-3";
|
|
2080
|
+
BeamGrouping2["_3_2_2"] = "3-2-2";
|
|
2081
|
+
return BeamGrouping2;
|
|
2082
|
+
})(BeamGrouping || {});
|
|
1736
2083
|
var TimeSignature = class {
|
|
1737
2084
|
constructor(...args) {
|
|
2085
|
+
/** Number of beats in measure, upper value (e.g. "3" in "3/4"). */
|
|
1738
2086
|
__publicField(this, "beatCount");
|
|
2087
|
+
/** Beat size of time signature, lower value (e.g. "4" in "3/4"). */
|
|
1739
2088
|
__publicField(this, "beatSize");
|
|
1740
|
-
/**
|
|
2089
|
+
/** Beat length. */
|
|
1741
2090
|
__publicField(this, "beatLength");
|
|
2091
|
+
/** Number of ticks in measure. */
|
|
1742
2092
|
__publicField(this, "measureTicks");
|
|
1743
|
-
|
|
1744
|
-
__publicField(this, "
|
|
1745
|
-
|
|
2093
|
+
/** Beam groups (e.g. [[2], [2]] or [[2, 2], [2, 2]] (first try as [[4], [4]])). */
|
|
2094
|
+
__publicField(this, "beamGroupSizes", []);
|
|
2095
|
+
let beamGrouping;
|
|
2096
|
+
if (Utils9.Is.isEnumValue(args[0], TimeSignatures)) {
|
|
1746
2097
|
let parts = args[0].split("/");
|
|
1747
2098
|
this.beatCount = +parts[0];
|
|
1748
2099
|
this.beatSize = +parts[1];
|
|
1749
|
-
|
|
2100
|
+
if (Utils9.Is.isEnumValue(args[1], BeamGrouping)) {
|
|
2101
|
+
beamGrouping = args[1];
|
|
2102
|
+
}
|
|
2103
|
+
} else if (Utils9.Is.isIntegerGte(args[0], 2) && Utils9.Is.isIntegerGte(args[1], 2)) {
|
|
1750
2104
|
this.beatCount = args[0];
|
|
1751
2105
|
this.beatSize = args[1];
|
|
2106
|
+
if (Utils9.Is.isEnumValue(args[2], BeamGrouping)) {
|
|
2107
|
+
beamGrouping = args[2];
|
|
2108
|
+
}
|
|
1752
2109
|
} else {
|
|
1753
2110
|
throw new MusicError9(MusicErrorType9.Timesignature, `Invalid args: ${args}`);
|
|
1754
2111
|
}
|
|
@@ -1757,25 +2114,55 @@ var TimeSignature = class {
|
|
|
1757
2114
|
} else if (!Utils9.Is.isIntegerGte(this.beatSize, 1)) {
|
|
1758
2115
|
throw new MusicError9(MusicErrorType9.Timesignature, `Invalid beatSize: ${this.beatSize}`);
|
|
1759
2116
|
}
|
|
1760
|
-
let
|
|
1761
|
-
this.beatLength =
|
|
1762
|
-
this.measureTicks = this.beatCount *
|
|
1763
|
-
if (this.is(2, 4)
|
|
1764
|
-
this.
|
|
1765
|
-
} else if (this.is(
|
|
1766
|
-
this.
|
|
1767
|
-
} else {
|
|
1768
|
-
|
|
1769
|
-
|
|
2117
|
+
let { noteLength, ticks } = NoteLengthProps.create(this.beatSize);
|
|
2118
|
+
this.beatLength = noteLength;
|
|
2119
|
+
this.measureTicks = this.beatCount * ticks;
|
|
2120
|
+
if (this.is(2, 4)) {
|
|
2121
|
+
this.beamGroupSizes = [[2], [2]];
|
|
2122
|
+
} else if (this.is(3, 4)) {
|
|
2123
|
+
this.beamGroupSizes = [[2], [2], [2]];
|
|
2124
|
+
} else if (this.is(4, 4)) {
|
|
2125
|
+
this.beamGroupSizes = [[2, 2], [2, 2]];
|
|
2126
|
+
} else if (this.is(5, 8)) {
|
|
2127
|
+
if (!Utils9.Is.isUndefined(beamGrouping) && beamGrouping !== "2-3" /* _2_3 */ && beamGrouping !== "3-2" /* _3_2 */) {
|
|
2128
|
+
throw new MusicError9(MusicErrorType9.Timesignature, `Invalid beam grouping "${beamGrouping}" for time signature "${this.toString()}".`);
|
|
2129
|
+
} else {
|
|
2130
|
+
this.beamGroupSizes = beamGrouping === "3-2" /* _3_2 */ ? [[3], [2]] : [[2], [3]];
|
|
2131
|
+
beamGrouping = void 0;
|
|
2132
|
+
}
|
|
2133
|
+
} else if (this.is(6, 8)) {
|
|
2134
|
+
this.beamGroupSizes = [[3], [3]];
|
|
2135
|
+
} else if (this.is(7, 8)) {
|
|
2136
|
+
if (!Utils9.Is.isUndefined(beamGrouping) && beamGrouping !== "2-2-3" /* _2_2_3 */ && beamGrouping !== "3-2-2" /* _3_2_2 */) {
|
|
2137
|
+
throw new MusicError9(MusicErrorType9.Timesignature, `Invalid beam grouping "${beamGrouping}" for time signature "${this.toString()}".`);
|
|
2138
|
+
} else {
|
|
2139
|
+
this.beamGroupSizes = beamGrouping === "3-2-2" /* _3_2_2 */ ? [[3], [2], [2]] : [[2], [2], [3]];
|
|
2140
|
+
beamGrouping = void 0;
|
|
2141
|
+
}
|
|
2142
|
+
} else if (this.is(9, 8)) {
|
|
2143
|
+
this.beamGroupSizes = [[3], [3], [3]];
|
|
2144
|
+
} else if (this.is(12, 8)) {
|
|
2145
|
+
this.beamGroupSizes = [[3], [3], [3], [3]];
|
|
1770
2146
|
}
|
|
1771
|
-
this.
|
|
1772
|
-
|
|
1773
|
-
|
|
2147
|
+
if (this.beamGroupSizes.length === 0) {
|
|
2148
|
+
throw new MusicError9(MusicErrorType9.Timesignature, `Unimplemented time signature "${this.toString()}".`);
|
|
2149
|
+
} else if (beamGrouping !== void 0) {
|
|
2150
|
+
throw new MusicError9(MusicErrorType9.Timesignature, `Invalid beam grouping "${beamGrouping}" for time signature "${this.toString()}".`);
|
|
1774
2151
|
}
|
|
1775
2152
|
}
|
|
2153
|
+
/**
|
|
2154
|
+
* Test whether this time signature has given beat count and size.
|
|
2155
|
+
* @param beatCount - Beat count.
|
|
2156
|
+
* @param beatSize - Beat size.
|
|
2157
|
+
* @returns - Boolean whether this time signature match given beat count and size.
|
|
2158
|
+
*/
|
|
1776
2159
|
is(beatCount, beatSize) {
|
|
1777
2160
|
return this.beatCount === beatCount && this.beatSize === beatSize;
|
|
1778
2161
|
}
|
|
2162
|
+
/**
|
|
2163
|
+
* Get string representation of this time signature (e.g. "3/4").
|
|
2164
|
+
* @returns - String representation.
|
|
2165
|
+
*/
|
|
1779
2166
|
toString() {
|
|
1780
2167
|
return this.beatCount + "/" + this.beatSize;
|
|
1781
2168
|
}
|
|
@@ -1811,6 +2198,7 @@ import { init as initCore } from "@tspro/web-music-score/core";
|
|
|
1811
2198
|
initCore();
|
|
1812
2199
|
export {
|
|
1813
2200
|
AccidentalType,
|
|
2201
|
+
BeamGrouping,
|
|
1814
2202
|
Chord,
|
|
1815
2203
|
DefaultGuitarNoteLabel,
|
|
1816
2204
|
DefaultHandedness,
|
|
@@ -1833,6 +2221,7 @@ export {
|
|
|
1833
2221
|
ScaleType,
|
|
1834
2222
|
SymbolSet,
|
|
1835
2223
|
TimeSignature,
|
|
2224
|
+
TimeSignatures,
|
|
1836
2225
|
TuningNameList,
|
|
1837
2226
|
Tuplet,
|
|
1838
2227
|
alterTempoSpeed,
|