@tspro/web-music-score 4.1.0 → 4.2.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.
Files changed (34) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/README.md +64 -31
  3. package/dist/audio/index.js +1 -1
  4. package/dist/audio/index.mjs +2 -2
  5. package/dist/audio-cg/index.js +1 -1
  6. package/dist/audio-cg/index.mjs +2 -2
  7. package/dist/{chunk-MHNTJ6FU.mjs → chunk-5NWLGWHS.mjs} +2 -2
  8. package/dist/chunk-7MNV5JN6.mjs +264 -0
  9. package/dist/core/index.js +2 -2
  10. package/dist/core/index.mjs +3 -3
  11. package/dist/iife/index.global.js +11 -11
  12. package/dist/{music-objects-DIaqNPjs.d.mts → music-objects-3Hxlkxy6.d.mts} +105 -19
  13. package/dist/{music-objects-xJJNlFwK.d.ts → music-objects-CI7IjsjE.d.ts} +105 -19
  14. package/dist/pieces/index.d.mts +2 -2
  15. package/dist/pieces/index.d.ts +2 -2
  16. package/dist/pieces/index.js +2 -2
  17. package/dist/pieces/index.mjs +3 -3
  18. package/dist/react-ui/index.d.mts +3 -3
  19. package/dist/react-ui/index.d.ts +3 -3
  20. package/dist/react-ui/index.js +1 -1
  21. package/dist/react-ui/index.mjs +2 -2
  22. package/dist/{scale-DQNA-YLD.d.ts → scale-DGx3tJH4.d.ts} +1 -1
  23. package/dist/{scale-bnD0WnMV.d.mts → scale-DQP3b9Zx.d.mts} +1 -1
  24. package/dist/score/index.d.mts +43 -21
  25. package/dist/score/index.d.ts +43 -21
  26. package/dist/score/index.js +776 -249
  27. package/dist/score/index.mjs +495 -219
  28. package/dist/{tempo-Bp1UzsrZ.d.ts → tempo-GrstpD9G.d.ts} +2 -0
  29. package/dist/{tempo-S85Q7uJA.d.mts → tempo-dkctPkCS.d.mts} +2 -0
  30. package/dist/theory/index.d.mts +3 -3
  31. package/dist/theory/index.d.ts +3 -3
  32. package/dist/theory/index.js +4 -1
  33. package/dist/theory/index.mjs +28 -269
  34. package/package.json +6 -2
package/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # Changelog
2
2
 
3
+ ## [4.2.0] - 2025-10-03
4
+ ## Added
5
+ - Add support for lyrics/syllables with alignment and hyphen/extender.
6
+ - addNote accepts array of notes to add multiple notes at once.
7
+ - 3/8 time signature.
8
+
3
9
  ## [4.1.0] - 2025-10-01
4
10
  ## Added
5
11
  - 4-4 (in adition to 2-2-2-2) beam grouping for 4/4 time signature.
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
- # WebMusicScore
1
+ # Web Music Score
2
2
 
3
- The API Reference, Examples and Demos can be found [here](https://pahkasoft.github.io). The API Reference is very little commented but gives idea of the full API.
3
+ Homepage (docs, examples and demos): [Web Music Score](https://pahkasoft.github.io/web-music-score)
4
4
 
5
5
  ## About
6
6
 
@@ -13,8 +13,6 @@ This is a work in progress project. Lately there has been improvements that requ
13
13
  version update. As the project matures there might be less major updates, and more minor
14
14
  updates and patches.
15
15
 
16
- Version 4.0.0 added support for string arguments in addition to typescript enums (e.g. NoteLength.Quarter => "4n", just to name one).
17
-
18
16
  ## Installation
19
17
 
20
18
  ```sh
@@ -55,14 +53,17 @@ corresponding subpath modules (`react-ui` and `audio-cg` are not included in thi
55
53
  browser module).
56
54
 
57
55
  ```html
58
- <script src="https://unpkg.com/@tspro/web-music-score@4"></script>
59
- <script src="https://unpkg.com/@tspro/web-music-score@4.1.0"></script>
60
- <script src="https://unpkg.com/@tspro/web-music-score@4.1.0/dist/iife/index.global.js"></script>
56
+ <!--
57
+ It is recommended to use exact version number so that if something
58
+ breaks between versions then your web site does not stop working.
59
+ -->
60
+ <script src="https://unpkg.com/@tspro/web-music-score@4.2.0"></script>
61
61
 
62
62
  <!--
63
- Use one of above. It is recommended to use version number (e.g. @4.1.0 or at least @4).
64
- This way if something breaks between versions then your web site does not stop working.
63
+ Or you can use direct link to the js bundle.
65
64
  -->
65
+ <script src="https://unpkg.com/@tspro/web-music-score@4.2.0/dist/iife/index.global.js"></script>
66
+
66
67
 
67
68
  <script>
68
69
  const { Core, Audio, Theory, Score, Pieces } = window.WebMusicScore;
@@ -186,14 +187,15 @@ For optional beam grouping argument for 5/8 and 7/8 time signatures you can use
186
187
  enum values (e.g. `Theory.BeamGrouping._2_2_3`) or corresponding string values (e.g. `"2-2-3"`).
187
188
 
188
189
  ```js
189
- .setTimeSignature("2/4") // Set time signature of 2/4.
190
- .setTimeSignature("3/4") // Set time signature of 3/4.
191
- .setTimeSignature("4/4") // Set time signature of 4/4.
192
- .setTimeSignature("5/8", "2-3") // Set time signature of 5/8. Available beam groupings are "2-3" (default) and "3-2".
193
- .setTimeSignature("6/8") // Set time signature of 6/8.
194
- .setTimeSignature("7/8", "2-2-3") // Set time signature of 7/8. Available beam groupings are "2-2-3" (default) and "3-2-2".
195
- .setTimeSignature("9/8") // Set time signature of 9/8.
196
- .setTimeSignature(12, 8) // Set time signature of 12/8 using number arguments.
190
+ .setTimeSignature("2/4") // Set 2/4 time signature.
191
+ .setTimeSignature("3/4") // Set 3/4 time signature.
192
+ .setTimeSignature("4/4") // Set 4/4 time signature.
193
+ .setTimeSignature("3/8") // Set 3/8 time signature.
194
+ .setTimeSignature("5/8", "2-3") // Set 5/8 time signature. Available beam groupings are "2-3" (default) and "3-2".
195
+ .setTimeSignature("6/8") // Set 6/8 time signature.
196
+ .setTimeSignature("7/8", "2-2-3") // Set 7/8 time signature. Available beam groupings are "2-2-3" (default) and "3-2-2".
197
+ .setTimeSignature("9/8") // Set 9/8 time signature.
198
+ .setTimeSignature(12, 8) // Set 12/8 time signature using number arguments.
197
199
  ```
198
200
 
199
201
  ### Set Tempo
@@ -204,8 +206,9 @@ enum values (e.g. `Theory.BeamGrouping._2_2_3`) or corresponding string values (
204
206
 
205
207
  ### Add Note
206
208
  ```js
207
- .addNote(0, "C4", "1n") // Create whole note "C4"
208
- .addNote(0, "Bb4", "2..") // Create double dotted half note "Bb4"
209
+ .addNote(0, "C4", "1n") // Add whole note "C4"
210
+ .addNote(0, ["C4", "D4", "G4"], "1n") // Add three notes "C4", "D4", "G4" seuqentially (no chord).
211
+ .addNote(0, "Bb4", "2..") // Add double dotted half note "Bb4"
209
212
  .addNote(0, "C4", "4n", { stem: "up" }) // Stem direction Up (could be also Down)
210
213
  .addNote(0, "C4", "4n", { staccate: true }) // Show staccato dot and play in short
211
214
  .addNote(0, "C4", "4n", { diamond: true }) // Show diamond shaped note head
@@ -226,7 +229,7 @@ enum values (e.g. `Theory.BeamGrouping._2_2_3`) or corresponding string values (
226
229
  ```
227
230
 
228
231
  ### Add Tuplet
229
- This works for any tuplet:
232
+ This generic function works for any tuplet:
230
233
  ```js
231
234
  // Example: add triplet
232
235
  .addTuplet(0, { parts: 3, inTimeOf: 2 }, notes => {
@@ -239,14 +242,30 @@ This works for any tuplet:
239
242
  Triplets can also be created using note length (e.g. NoteLength.EighthTriplet or "8t").
240
243
  ```js
241
244
  // Example: add triplet using triplet note length.
242
- .addNote(0, "G3", "8t")
243
- .addNote(0, "B3", "8t")
244
- .addNote(0, "D4", "8t")
245
+ .addNote(0, ["G3", "B3", "D4"], "8t")
246
+ ```
247
+
248
+ ### Add Lyrics
249
+
250
+ For lyrics align you can use `Score.LyricsAlign` enum values (e.g. `Score.LyricsAlign.Left`)
251
+ or corresponding string values (e.g. `"left"`).
252
+
253
+ For lyrics hyphen you can use `Score.LyricsHyphen` enum values (e.g. `Score.LyricsHyphen.Hyphen`)
254
+ or corresponding string values (e.g. `"-"`).
255
+
256
+ ```js
257
+ .addLyrics(1, "4n", "La") // Add lyrics text/syllable "La", quarter note length, verse 1.
258
+ .addLyrics(1, "4n", ["La", "la", "la", "la"]) // Add multiple lysics texts/syllables, each quarter note length, verse 1.
259
+ .addLyrics(2, "4n", "La", { align: "left" }) // Left align lyrics text/syllable.
260
+ .addLyrics(2, "4n", "La", { align: "center" }) // Center align lyrics text/syllable.
261
+ .addLyrics(2, "4n", "La", { align: "right" }) // Right align lyrics text/syllable.
262
+ .addLyrics(3, "4n", "La", { hyphen: "-" }) // Add hyphen (short line '-') centered between this and next syllable.
263
+ .addLyrics(3, "4n", "La", { hyphen: "---" }) // Add extender (long line) between this and next syllable.
245
264
  ```
246
265
 
247
266
  ### Add Fermata
248
267
 
249
- For fermata you can use `Score.Fermata` enum values (e.g. `Scoore.Fermata.AtNote`)
268
+ For fermata you can use `Score.Fermata` enum values (e.g. `Score.Fermata.AtNote`)
250
269
  or corresponding string values (e.g. `"atNote"`).
251
270
 
252
271
  ```js
@@ -302,8 +321,8 @@ or corresponding string values (e.g. `"chord"`).
302
321
 
303
322
  ### Positioning Elements
304
323
 
305
- `addFermata`, `addNavigation`, `addAnnotation` and `addLabel` functions have alternate versions
306
- `addFermataTo`, `addNavigationTo`, `addAnnotationTo` and `addLabelTo` that contain extra first argument.
324
+ `addLyrics`, `addFermata`, `addNavigation`, `addAnnotation` and `addLabel` functions have alternate versions
325
+ `addLyricsTo`, `addFermataTo`, `addNavigationTo`, `addAnnotationTo` and `addLabelTo` that contain extra first argument.
307
326
 
308
327
  ```js
309
328
  .addLabelTo(0, "chord", "Am") // Add label to top (id 0) staff/tab.
@@ -363,7 +382,23 @@ Add notes with `string` property to specify at what string the fret number is re
363
382
 
364
383
  ### Beams
365
384
 
366
- Beams are detected and added automatically.
385
+ Beams are detected using beam grouping logic that is defined for each time signature.
386
+ These are the beam groupings for each time signature.
387
+
388
+ | Time signature | Beam grouping |
389
+ |----------------|---------------|
390
+ | `2/4` | `2-2` |
391
+ | `3/4` | `2-2-2` |
392
+ | `4/4` | `4-4` and `2-2-2-2` together |
393
+ | `3/8` | `3` |
394
+ | `5/8` | `2-3` or `3-2`, user selectable |
395
+ | `6/8` | `3-3` |
396
+ | `7/8` | `2-2-3` or `3-2-2`, user selectable |
397
+ | `9/8` | `3-3-3` |
398
+ | `12/8` | `3-3-3-3` |
399
+
400
+ How to set beam grouping for `5/8` and `7/8` time signatures,
401
+ see [Set Time Signature](#set-time-signature) section above.
367
402
 
368
403
  ### Classical Guitar Audio Module
369
404
 
@@ -466,11 +501,9 @@ While designed for compatibility in mind, the library has not been explicitly te
466
501
 
467
502
  ## Report a Bug
468
503
 
469
- Found a bug or unexpected behavior?
470
-
471
- [Please open a new issue.](https://github.com/pahkasoft/issues/issues/new)
504
+ Found a bug or unexpected behavior? Suggest a feature or impovement?
472
505
 
473
- You can also suggest a feature or impovement.
506
+ [Please open a new issue.](https://github.com/pahkasoft/web-music-score/issues/new/choose)
474
507
 
475
508
  Thanks for helping improve the project!
476
509
 
@@ -1,4 +1,4 @@
1
- /* WebMusicScore v4.1.0 | (c) 2023 PahkaSoft | MIT License | Includes: Tone.js (MIT License) */
1
+ /* WebMusicScore v4.2.0 | (c) 2023 PahkaSoft | MIT License | Includes: Tone.js (MIT License) */
2
2
  "use strict";
3
3
  var __create = Object.create;
4
4
  var __defProp = Object.defineProperty;
@@ -1,7 +1,7 @@
1
- /* WebMusicScore v4.1.0 | (c) 2023 PahkaSoft | MIT License | Includes: Tone.js (MIT License) */
1
+ /* WebMusicScore v4.2.0 | (c) 2023 PahkaSoft | MIT License | Includes: Tone.js (MIT License) */
2
2
  import {
3
3
  __publicField
4
- } from "../chunk-MHNTJ6FU.mjs";
4
+ } from "../chunk-5NWLGWHS.mjs";
5
5
 
6
6
  // src/audio/index.ts
7
7
  import { Note, PitchNotation, SymbolSet } from "@tspro/web-music-score/theory";
@@ -1,4 +1,4 @@
1
- /* WebMusicScore v4.1.0 | (c) 2023 PahkaSoft | MIT License | Includes: Tone.js (MIT License) */
1
+ /* WebMusicScore v4.2.0 | (c) 2023 PahkaSoft | MIT License | Includes: Tone.js (MIT License) */
2
2
  "use strict";
3
3
  var __create = Object.create;
4
4
  var __defProp = Object.defineProperty;
@@ -1,7 +1,7 @@
1
- /* WebMusicScore v4.1.0 | (c) 2023 PahkaSoft | MIT License | Includes: Tone.js (MIT License) */
1
+ /* WebMusicScore v4.2.0 | (c) 2023 PahkaSoft | MIT License | Includes: Tone.js (MIT License) */
2
2
  import {
3
3
  __publicField
4
- } from "../chunk-MHNTJ6FU.mjs";
4
+ } from "../chunk-5NWLGWHS.mjs";
5
5
 
6
6
  // src/audio-cg/index.ts
7
7
  import * as Tone from "tone";
@@ -1,4 +1,4 @@
1
- /* WebMusicScore v4.1.0 | (c) 2023 PahkaSoft | MIT License | Includes: Tone.js (MIT License) */
1
+ /* WebMusicScore v4.2.0 | (c) 2023 PahkaSoft | MIT License | Includes: Tone.js (MIT License) */
2
2
  var __defProp = Object.defineProperty;
3
3
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
4
4
  var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
@@ -6,4 +6,4 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
6
6
  export {
7
7
  __publicField
8
8
  };
9
- //# sourceMappingURL=chunk-MHNTJ6FU.mjs.map
9
+ //# sourceMappingURL=chunk-5NWLGWHS.mjs.map
@@ -0,0 +1,264 @@
1
+ /* WebMusicScore v4.2.0 | (c) 2023 PahkaSoft | MIT License | Includes: Tone.js (MIT License) */
2
+ import {
3
+ __publicField
4
+ } from "./chunk-5NWLGWHS.mjs";
5
+
6
+ // src/theory/rhythm.ts
7
+ import { Utils } from "@tspro/ts-utils-lib";
8
+ import { MusicError, MusicErrorType } from "@tspro/web-music-score/core";
9
+ var cmp = (a, b) => a === b ? 0 : a < b ? -1 : 1;
10
+ var MaxTupletRatioValue = 12;
11
+ var TicksMultiplier = 12 * 11 * 9 * 7 * 5;
12
+ var NoteLength = /* @__PURE__ */ ((NoteLength2) => {
13
+ NoteLength2["Whole"] = "1n";
14
+ NoteLength2["WholeTriplet"] = "1t";
15
+ NoteLength2["WholeDot"] = "1.";
16
+ NoteLength2["Whole2Dots"] = "1..";
17
+ NoteLength2["Whole12Dots"] = "1..";
18
+ NoteLength2["Whole3Dots"] = "1...";
19
+ NoteLength2["Whole4Dots"] = "1....";
20
+ NoteLength2["Whole5Dots"] = "1.....";
21
+ NoteLength2["Whole6Dots"] = "1......";
22
+ NoteLength2["Half"] = "2n";
23
+ NoteLength2["HalfTriplet"] = "2t";
24
+ NoteLength2["HalfDot"] = "2.";
25
+ NoteLength2["Half2Dots"] = "2..";
26
+ NoteLength2["Half3Dots"] = "2...";
27
+ NoteLength2["Half4Dots"] = "2....";
28
+ NoteLength2["Half5Dots"] = "2.....";
29
+ NoteLength2["Quarter"] = "4n";
30
+ NoteLength2["QuarterTriplet"] = "4t";
31
+ NoteLength2["QuarterDot"] = "4.";
32
+ NoteLength2["Quarter2Dots"] = "4..";
33
+ NoteLength2["Quarter3Dots"] = "4...";
34
+ NoteLength2["Quarter4Dots"] = "4....";
35
+ NoteLength2["Eighth"] = "8n";
36
+ NoteLength2["EighthTriplet"] = "8t";
37
+ NoteLength2["EighthDot"] = "8.";
38
+ NoteLength2["Eighth2Dots"] = "8..";
39
+ NoteLength2["Eighth3Dots"] = "8...";
40
+ NoteLength2["Sixteenth"] = "16n";
41
+ NoteLength2["SixteenthTriplet"] = "16t";
42
+ NoteLength2["SixteenthDot"] = "16.";
43
+ NoteLength2["Sixteenth2Dots"] = "16..";
44
+ NoteLength2["ThirtySecond"] = "32n";
45
+ NoteLength2["ThirtySecondTriplet"] = "32t";
46
+ NoteLength2["ThirtySecondDot"] = "32.";
47
+ NoteLength2["SixtyFourth"] = "64n";
48
+ NoteLength2["SixtyFourthTriplet"] = "64t";
49
+ return NoteLength2;
50
+ })(NoteLength || {});
51
+ function validateNoteLength(noteLength) {
52
+ if (Utils.Is.isEnumValue(noteLength, NoteLength)) {
53
+ return noteLength;
54
+ } else {
55
+ throw new MusicError(MusicErrorType.InvalidArg, `Invalid noteLength: ${noteLength}`);
56
+ }
57
+ }
58
+ var _NoteLengthProps = class _NoteLengthProps {
59
+ constructor(noteLength) {
60
+ /** Note length. */
61
+ __publicField(this, "noteLength");
62
+ /** Note size (whole=1, half=2, quarter=4, ...). */
63
+ __publicField(this, "noteSize");
64
+ /** Number of ticks (not altered by isTriplet). */
65
+ __publicField(this, "ticks");
66
+ /** Flag count. */
67
+ __publicField(this, "flagCount");
68
+ /** Dot count. */
69
+ __publicField(this, "dotCount");
70
+ /** Max dot count. */
71
+ __publicField(this, "maxDotCount");
72
+ /** Is triplet? */
73
+ __publicField(this, "isTriplet");
74
+ /** Has note stem. */
75
+ __publicField(this, "hasStem");
76
+ /** Is note head solid (black)? */
77
+ __publicField(this, "isSolid");
78
+ this.noteLength = validateNoteLength(noteLength);
79
+ this.noteSize = parseInt(noteLength);
80
+ this.isTriplet = noteLength.endsWith("t");
81
+ this.maxDotCount = this.isTriplet ? 0 : Math.floor(Math.log2(_NoteLengthProps.ShortestNoteSize / this.noteSize));
82
+ this.dotCount = Utils.Str.charCount(noteLength, ".");
83
+ this.flagCount = this.noteSize > 4 ? Math.floor(Math.log2(this.noteSize / 4)) : 0;
84
+ this.ticks = TicksMultiplier * _NoteLengthProps.ShortestNoteSize / this.noteSize;
85
+ this.hasStem = this.noteSize > 1;
86
+ this.isSolid = this.noteSize > 2;
87
+ if (this.dotCount > this.maxDotCount) {
88
+ throw new MusicError(MusicErrorType.Note, `dotCount ${this.dotCount} > maxDotCount ${this.maxDotCount}, for noteLength "${this.noteLength}".`);
89
+ } else if (this.isTriplet && this.dotCount > 0) {
90
+ throw new MusicError(MusicErrorType.Note, `noteLength "${this.noteLength}" is both triplet and dotted!`);
91
+ }
92
+ }
93
+ /**
94
+ * Get note length props.
95
+ * @param noteLength - Note length.
96
+ * @returns - Note length props.
97
+ */
98
+ static get(noteLength) {
99
+ let p = this.cache.get(noteLength);
100
+ if (!p) {
101
+ this.cache.set(noteLength, p = new _NoteLengthProps(noteLength));
102
+ }
103
+ return p;
104
+ }
105
+ /**
106
+ * Create note length props.
107
+ * @param noteLength - Note length or note size.
108
+ * @param dotCount - Dot count.
109
+ * @returns - Note length props.
110
+ */
111
+ static create(noteLength, dotCount = 0) {
112
+ let noteSize = typeof noteLength === "number" ? noteLength : this.get(noteLength).noteSize;
113
+ return this.get(noteSize + (Utils.Is.isIntegerGte(dotCount, 1) ? ".".repeat(dotCount) : "n"));
114
+ }
115
+ /**
116
+ * Compare note lengths/sizes. Whole (1) > half (2) > quarter (4), etc.
117
+ * Ignores possible triplet property of note length.
118
+ * @param a - NoteLengthProps, NoteLength/Str or noteSize
119
+ * @param b - NoteLengthProps, NoteLength/Str or noteSize
120
+ * @returns - -1: a < b, 0: a === b, +1: a > b (note length/size comparisons)
121
+ */
122
+ static cmp(a, b) {
123
+ let aNoteSize = a instanceof _NoteLengthProps ? a.noteSize : typeof a === "number" ? a : _NoteLengthProps.get(a).noteSize;
124
+ let bNoteSize = b instanceof _NoteLengthProps ? b.noteSize : typeof b === "number" ? b : _NoteLengthProps.get(b).noteSize;
125
+ return cmp(bNoteSize, aNoteSize);
126
+ }
127
+ /**
128
+ * Compare note lengths/sizes for equality.
129
+ * Ignores possible triplet property of note length.
130
+ * @param a - NoteLengthProps, NoteLength/Str or noteSize
131
+ * @param b - NoteLengthProps, NoteLength/Str or noteSize
132
+ * @returns - true: a === b, false: a !== b (note length/size comparisons)
133
+ */
134
+ static equals(a, b) {
135
+ let aNoteSize = a instanceof _NoteLengthProps ? a.noteSize : typeof a === "number" ? a : _NoteLengthProps.get(a).noteSize;
136
+ let bNoteSize = b instanceof _NoteLengthProps ? b.noteSize : typeof b === "number" ? b : _NoteLengthProps.get(b).noteSize;
137
+ return aNoteSize === bNoteSize;
138
+ }
139
+ };
140
+ /** Longest note size (e.g. 1 = whole note). */
141
+ __publicField(_NoteLengthProps, "LongestNoteSize", Math.min(...Utils.Enum.getEnumValues(NoteLength).map((noteLength) => parseInt(noteLength))));
142
+ /** Shortest note size (e.g. 64 = sixtyfourth note). */
143
+ __publicField(_NoteLengthProps, "ShortestNoteSize", Math.max(...Utils.Enum.getEnumValues(NoteLength).map((noteLength) => parseInt(noteLength))));
144
+ __publicField(_NoteLengthProps, "cache", /* @__PURE__ */ new Map());
145
+ var NoteLengthProps = _NoteLengthProps;
146
+ function validateTupletRatio(tupletRatio) {
147
+ if (Utils.Is.isObject(tupletRatio) && Utils.Is.isIntegerBetween(tupletRatio.parts, 2, MaxTupletRatioValue) && Utils.Is.isIntegerBetween(tupletRatio.inTimeOf, 2, MaxTupletRatioValue)) {
148
+ return tupletRatio;
149
+ } else {
150
+ throw new MusicError(MusicErrorType.Note, `Invalid tupletRatio ${JSON.stringify(tupletRatio)}`);
151
+ }
152
+ }
153
+ var Tuplet = {
154
+ /** Duplet: 2 in the time of 3 */
155
+ Duplet: { parts: 2, inTimeOf: 3 },
156
+ /** Triplet: 3 in the time of 2 */
157
+ Triplet: { parts: 3, inTimeOf: 2 },
158
+ /** Quadruplet: 4 in the time of 3 */
159
+ Quadruplet: { parts: 4, inTimeOf: 3 }
160
+ };
161
+ var _RhythmProps = class _RhythmProps {
162
+ constructor(noteLength, dotCount, tupletRatio) {
163
+ /** Note length. */
164
+ __publicField(this, "noteLength");
165
+ /** Note size (whole=1, half=2, quarter=4, ...). */
166
+ __publicField(this, "noteSize");
167
+ /** Dot count. */
168
+ __publicField(this, "dotCount");
169
+ /** Tuplet ratio. */
170
+ __publicField(this, "tupletRatio");
171
+ /** Number of ticks. */
172
+ __publicField(this, "ticks");
173
+ /** Flag count. */
174
+ __publicField(this, "flagCount");
175
+ /** Has note stem. */
176
+ __publicField(this, "hasStem");
177
+ /** Is note head solid (black)? */
178
+ __publicField(this, "isSolidNoteHead");
179
+ this.noteLength = validateNoteLength(noteLength);
180
+ let p = NoteLengthProps.get(noteLength);
181
+ this.noteSize = p.noteSize;
182
+ this.ticks = p.ticks;
183
+ this.flagCount = p.flagCount;
184
+ this.dotCount = dotCount != null ? dotCount : p.dotCount;
185
+ this.hasStem = p.hasStem;
186
+ this.isSolidNoteHead = p.isSolid;
187
+ if (Utils.Is.isObject(tupletRatio)) {
188
+ this.tupletRatio = validateTupletRatio(tupletRatio);
189
+ } else if (p.isTriplet) {
190
+ this.tupletRatio = Tuplet.Triplet;
191
+ } else {
192
+ this.tupletRatio = void 0;
193
+ }
194
+ if (this.dotCount > 0 && this.tupletRatio !== void 0) {
195
+ throw new MusicError(MusicErrorType.Note, `Note cannot be both dotted and tuplet!`);
196
+ } else if (this.dotCount > p.maxDotCount) {
197
+ throw new MusicError(MusicErrorType.Note, `Too big dot count ${this.dotCount} for note length ${this.noteLength}.`);
198
+ }
199
+ for (let add = this.ticks / 2, i = 1; i <= this.dotCount; i++, add /= 2) {
200
+ this.ticks += add;
201
+ }
202
+ if (this.tupletRatio) {
203
+ this.ticks *= this.tupletRatio.inTimeOf / this.tupletRatio.parts;
204
+ }
205
+ }
206
+ /**
207
+ * Get string presentation of rhythm props.
208
+ * @returns - String presentation.
209
+ */
210
+ toString() {
211
+ let sym = _RhythmProps.NoteSymbolMap.get(this.noteSize);
212
+ let dots = ".".repeat(this.dotCount);
213
+ return sym ? sym + dots : "" + this.noteSize + (dots.length > 0 ? dots : "n");
214
+ }
215
+ /**
216
+ * Get rhythm props with given arguments.
217
+ * @param noteLength - Note length.
218
+ * @param dotCount - Dot count.
219
+ * @param tupletRatio - Tuplet ratio.
220
+ * @returns - Rhythm props.
221
+ */
222
+ static get(noteLength, dotCount, tupletRatio) {
223
+ if (dotCount !== void 0 || tupletRatio !== void 0) {
224
+ return new _RhythmProps(noteLength, dotCount, tupletRatio);
225
+ } else {
226
+ let rhythmProps = this.cache.get(noteLength);
227
+ if (!rhythmProps) {
228
+ this.cache.set(noteLength, rhythmProps = new _RhythmProps(noteLength));
229
+ }
230
+ return rhythmProps;
231
+ }
232
+ }
233
+ /**
234
+ * Compare duration of rhythm props.
235
+ * @param a - RhythmProps
236
+ * @param b - RhythmProps
237
+ * @returns - -1: a < b, 0: a === b, +1: a > b (duration comparisons)
238
+ */
239
+ static cmp(a, b) {
240
+ return cmp(a.ticks, b.ticks);
241
+ }
242
+ /**
243
+ * Compare duration equality of rhythm props.
244
+ * @param a - RhythmProps
245
+ * @param b - RhythmProps
246
+ * @returns - true: a === b, false: a !== b (duration comparisons)
247
+ */
248
+ static equals(a, b) {
249
+ return a.ticks === b.ticks;
250
+ }
251
+ };
252
+ __publicField(_RhythmProps, "NoteSymbolMap", /* @__PURE__ */ new Map([[1, "\u{1D15D}"], [2, "\u{1D15E}"], [4, "\u{1D15F}"], [8, "\u{1D160}"], [16, "\u{1D161}"], [32, "\u{1D162}"], [64, "\u{1D163}"], [128, "\u{1D164}"]]));
253
+ __publicField(_RhythmProps, "cache", /* @__PURE__ */ new Map());
254
+ var RhythmProps = _RhythmProps;
255
+
256
+ export {
257
+ NoteLength,
258
+ validateNoteLength,
259
+ NoteLengthProps,
260
+ validateTupletRatio,
261
+ Tuplet,
262
+ RhythmProps
263
+ };
264
+ //# sourceMappingURL=chunk-7MNV5JN6.mjs.map
@@ -1,4 +1,4 @@
1
- /* WebMusicScore v4.1.0 | (c) 2023 PahkaSoft | MIT License | Includes: Tone.js (MIT License) */
1
+ /* WebMusicScore v4.2.0 | (c) 2023 PahkaSoft | MIT License | Includes: Tone.js (MIT License) */
2
2
  "use strict";
3
3
  var __defProp = Object.defineProperty;
4
4
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
@@ -62,7 +62,7 @@ function init() {
62
62
  return;
63
63
  }
64
64
  initialized = true;
65
- console.log("%cWebMusicScore v4.1.0 (cjs) initialized.", "background: black; color: white; padding: 2px;");
65
+ console.log("%cWebMusicScore v4.2.0 (cjs) initialized.", "background: black; color: white; padding: 2px;");
66
66
  }
67
67
  // Annotate the CommonJS export names for ESM import in node:
68
68
  0 && (module.exports = {
@@ -1,7 +1,7 @@
1
- /* WebMusicScore v4.1.0 | (c) 2023 PahkaSoft | MIT License | Includes: Tone.js (MIT License) */
1
+ /* WebMusicScore v4.2.0 | (c) 2023 PahkaSoft | MIT License | Includes: Tone.js (MIT License) */
2
2
  import {
3
3
  __publicField
4
- } from "../chunk-MHNTJ6FU.mjs";
4
+ } from "../chunk-5NWLGWHS.mjs";
5
5
 
6
6
  // src/core/error.ts
7
7
  var MusicErrorType = /* @__PURE__ */ ((MusicErrorType2) => {
@@ -36,7 +36,7 @@ function init() {
36
36
  return;
37
37
  }
38
38
  initialized = true;
39
- console.log("%cWebMusicScore v4.1.0 (esm) initialized.", "background: black; color: white; padding: 2px;");
39
+ console.log("%cWebMusicScore v4.2.0 (esm) initialized.", "background: black; color: white; padding: 2px;");
40
40
  }
41
41
  export {
42
42
  MusicError,