@tspro/web-music-score 3.2.0 → 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. package/CHANGELOG.md +26 -10
  2. package/README.md +189 -331
  3. package/dist/audio/index.d.ts +1 -1
  4. package/dist/audio/index.js +1 -1
  5. package/dist/audio/index.mjs +2 -2
  6. package/dist/audio-cg/index.js +1 -1
  7. package/dist/audio-cg/index.mjs +2 -2
  8. package/dist/{chunk-LCTM7BID.mjs → chunk-D643HZHM.mjs} +2 -2
  9. package/dist/core/index.js +2 -2
  10. package/dist/core/index.mjs +3 -3
  11. package/dist/{guitar-C2Cp71NZ.d.ts → guitar-cNmE-EvH.d.ts} +1 -1
  12. package/dist/iife/index.global.js +11 -11
  13. package/dist/{interface-BlNl69uT.d.ts → interface-7k8qGG44.d.ts} +89 -81
  14. package/dist/{interface-Bn5HFt_U.d.mts → interface-XoKiryoV.d.mts} +88 -80
  15. package/dist/{note-BFa43I86.d.ts → note-CcVdUFqS.d.ts} +1 -1
  16. package/dist/pieces/index.d.mts +2 -2
  17. package/dist/pieces/index.d.ts +3 -3
  18. package/dist/pieces/index.js +4 -7
  19. package/dist/pieces/index.mjs +8 -11
  20. package/dist/react-ui/index.d.mts +3 -3
  21. package/dist/react-ui/index.d.ts +5 -5
  22. package/dist/react-ui/index.js +1 -1
  23. package/dist/react-ui/index.mjs +2 -2
  24. package/dist/{scale-DRR-t4Kr.d.mts → scale-C2pCNxdE.d.mts} +4 -3
  25. package/dist/{scale-ebJm37q1.d.ts → scale-CvPbJvfN.d.ts} +5 -4
  26. package/dist/score/index.d.mts +98 -31
  27. package/dist/score/index.d.ts +99 -32
  28. package/dist/score/index.js +748 -567
  29. package/dist/score/index.mjs +755 -574
  30. package/dist/tempo-BAYoZ_Li.d.mts +187 -0
  31. package/dist/tempo-r2sb6Ku2.d.ts +187 -0
  32. package/dist/theory/index.d.mts +3 -3
  33. package/dist/theory/index.d.ts +6 -6
  34. package/dist/theory/index.js +221 -78
  35. package/dist/theory/index.mjs +218 -76
  36. package/package.json +2 -2
  37. package/dist/tempo-B4h5Ktob.d.mts +0 -104
  38. package/dist/tempo-DgqDEsn0.d.ts +0 -104
@@ -1,7 +1,7 @@
1
- /* WebMusicScore v3.2.0 | (c) 2023 PahkaSoft | MIT License | Includes: Tone.js (MIT License) */
1
+ /* WebMusicScore v4.0.0 | (c) 2023 PahkaSoft | MIT License | Includes: Tone.js (MIT License) */
2
2
  import {
3
3
  __publicField
4
- } from "../chunk-LCTM7BID.mjs";
4
+ } from "../chunk-D643HZHM.mjs";
5
5
 
6
6
  // src/theory/chord.ts
7
7
  import { Utils as Utils6 } from "@tspro/ts-utils-lib";
@@ -25,10 +25,10 @@ var PitchNotation = /* @__PURE__ */ ((PitchNotation2) => {
25
25
  var PitchNotationList = Utils.Enum.getEnumValues(PitchNotation);
26
26
  var DefaultPitchNotation = 0 /* Scientific */;
27
27
  function validatePitchNotation(pn) {
28
- if (!Utils.Is.isEnumValue(pn, PitchNotation)) {
29
- throw new MusicError(MusicErrorType.InvalidArg, `Invalid pitchNotation: ${pn}`);
30
- } else {
28
+ if (Utils.Is.isEnumValue(pn, PitchNotation)) {
31
29
  return pn;
30
+ } else {
31
+ throw new MusicError(MusicErrorType.InvalidArg, `Invalid pitchNotation: ${pn}`);
32
32
  }
33
33
  }
34
34
  function getPitchNotationName(pn) {
@@ -43,10 +43,10 @@ var GuitarNoteLabel = /* @__PURE__ */ ((GuitarNoteLabel2) => {
43
43
  var DefaultGuitarNoteLabel = "Default" /* Default */;
44
44
  var GuitarNoteLabelList = Utils.Enum.getEnumValues(GuitarNoteLabel);
45
45
  function validateGuitarNoteLabel(label) {
46
- if (!Utils.Is.isEnumValue(label, GuitarNoteLabel)) {
47
- throw new MusicError(MusicErrorType.Timesignature, `Invalid guitarNoteLabel: ${label}`);
48
- } else {
46
+ if (Utils.Is.isEnumValue(label, GuitarNoteLabel)) {
49
47
  return label;
48
+ } else {
49
+ throw new MusicError(MusicErrorType.Timesignature, `Invalid guitarNoteLabel: ${label}`);
50
50
  }
51
51
  }
52
52
 
@@ -982,10 +982,19 @@ function validateScaleType(scaleType) {
982
982
  if (Utils5.Is.isEnumValue(scaleType, ScaleType)) {
983
983
  return scaleType;
984
984
  } else {
985
- throw new MusicError5(MusicErrorType5.Scale, `Invalid scaleType: ${scaleType}`);
985
+ throw new MusicError5(MusicErrorType5.Scale, `Invalid scaleType: "${scaleType}"`);
986
986
  }
987
987
  }
988
- function getScale(tonic, scaleType) {
988
+ function getScale(arg0, arg1) {
989
+ let tonic;
990
+ let scaleType;
991
+ if (arg1 !== void 0) {
992
+ tonic = arg0;
993
+ scaleType = validateScaleType(arg1);
994
+ } else {
995
+ tonic = arg0.split(" ")[0];
996
+ scaleType = validateScaleType(arg0.substring(tonic.length + 1));
997
+ }
989
998
  return getScaleFactory(scaleType).getScale(tonic);
990
999
  }
991
1000
  var DefaultScale = getScale("C", "Major" /* Major */);
@@ -1476,10 +1485,10 @@ var Handedness = /* @__PURE__ */ ((Handedness2) => {
1476
1485
  })(Handedness || {});
1477
1486
  var DefaultHandedness = 0 /* RightHanded */;
1478
1487
  function validateHandedness(h) {
1479
- if (!Utils7.Is.isEnumValue(h, Handedness)) {
1480
- throw new MusicError7(MusicErrorType7.InvalidArg, `Invalid handedness: ${h}`);
1481
- } else {
1488
+ if (Utils7.Is.isEnumValue(h, Handedness)) {
1482
1489
  return h;
1490
+ } else {
1491
+ throw new MusicError7(MusicErrorType7.InvalidArg, `Invalid handedness: ${h}`);
1483
1492
  }
1484
1493
  }
1485
1494
  var TuningNameList = tunings_default.list.map((data) => data.name);
@@ -1514,81 +1523,213 @@ import { Utils as Utils9 } from "@tspro/ts-utils-lib";
1514
1523
  // src/theory/rhythm.ts
1515
1524
  import { Utils as Utils8 } from "@tspro/ts-utils-lib";
1516
1525
  import { MusicError as MusicError8, MusicErrorType as MusicErrorType8 } from "@tspro/web-music-score/core";
1526
+ var cmp = (a, b) => a === b ? 0 : a < b ? -1 : 1;
1527
+ var MaxTupletRatioValue = 12;
1528
+ var TicksMultiplier = 12 * 11 * 9 * 7 * 5;
1517
1529
  var NoteLength = /* @__PURE__ */ ((NoteLength3) => {
1518
- NoteLength3[NoteLength3["Whole"] = 192] = "Whole";
1519
- NoteLength3[NoteLength3["Half"] = 96] = "Half";
1520
- NoteLength3[NoteLength3["Quarter"] = 48] = "Quarter";
1521
- NoteLength3[NoteLength3["Eighth"] = 24] = "Eighth";
1522
- NoteLength3[NoteLength3["Sixteenth"] = 12] = "Sixteenth";
1523
- NoteLength3[NoteLength3["ThirtySecond"] = 6] = "ThirtySecond";
1524
- NoteLength3[NoteLength3["SixtyFourth"] = 3] = "SixtyFourth";
1530
+ NoteLength3["Whole"] = "1n";
1531
+ NoteLength3["WholeTriplet"] = "1t";
1532
+ NoteLength3["WholeDot"] = "1.";
1533
+ NoteLength3["Whole12Dots"] = "1..";
1534
+ NoteLength3["Whole3Dots"] = "1...";
1535
+ NoteLength3["Whole4Dots"] = "1....";
1536
+ NoteLength3["Whole5Dots"] = "1.....";
1537
+ NoteLength3["Whole6Dots"] = "1......";
1538
+ NoteLength3["Half"] = "2n";
1539
+ NoteLength3["HalfTriplet"] = "2t";
1540
+ NoteLength3["HalfDot"] = "2.";
1541
+ NoteLength3["Half2Dots"] = "2..";
1542
+ NoteLength3["Half3Dots"] = "2...";
1543
+ NoteLength3["Half4Dots"] = "2....";
1544
+ NoteLength3["Half5Dots"] = "2.....";
1545
+ NoteLength3["Quarter"] = "4n";
1546
+ NoteLength3["QuarterTriplet"] = "4t";
1547
+ NoteLength3["QuarterDot"] = "4.";
1548
+ NoteLength3["Quarter2Dots"] = "4..";
1549
+ NoteLength3["Quarter3Dots"] = "4...";
1550
+ NoteLength3["Quarter4Dots"] = "4....";
1551
+ NoteLength3["Eighth"] = "8n";
1552
+ NoteLength3["EighthTriplet"] = "8t";
1553
+ NoteLength3["EighthDot"] = "8.";
1554
+ NoteLength3["Eighth2Dots"] = "8..";
1555
+ NoteLength3["Eighth3Dots"] = "8...";
1556
+ NoteLength3["Sixteenth"] = "16n";
1557
+ NoteLength3["SixteenthTriplet"] = "16t";
1558
+ NoteLength3["SixteenthDot"] = "16.";
1559
+ NoteLength3["Sixteenth2Dots"] = "16..";
1560
+ NoteLength3["ThirtySecond"] = "32n";
1561
+ NoteLength3["ThirtySecondTriplet"] = "32t";
1562
+ NoteLength3["ThirtySecondDot"] = "32.";
1563
+ NoteLength3["SixtyFourth"] = "64n";
1564
+ NoteLength3["SixtyFourthTriplet"] = "64t";
1525
1565
  return NoteLength3;
1526
1566
  })(NoteLength || {});
1527
- var MaxNoteLength = 192 /* Whole */;
1528
- var MinNoteLength = 3 /* SixtyFourth */;
1529
- var FlagCountMap = /* @__PURE__ */ new Map([
1530
- [192 /* Whole */, 0],
1531
- [96 /* Half */, 0],
1532
- [48 /* Quarter */, 0],
1533
- [24 /* Eighth */, 1],
1534
- [12 /* Sixteenth */, 2],
1535
- [6 /* ThirtySecond */, 3],
1536
- [3 /* SixtyFourth */, 4]
1537
- ]);
1538
- var NoteSymbolMap = /* @__PURE__ */ new Map([
1539
- [192 /* Whole */, "\u{1D15D}"],
1540
- [96 /* Half */, "\u{1D15E}"],
1541
- [48 /* Quarter */, "\u{1D15F}"],
1542
- [24 /* Eighth */, "\u{1D160}"],
1543
- [12 /* Sixteenth */, "\u{1D161}"],
1544
- [6 /* ThirtySecond */, "\u{1D162}"],
1545
- [3 /* SixtyFourth */, "\u{1D163}"]
1546
- ]);
1547
1567
  function validateNoteLength(noteLength) {
1548
- if (!Utils8.Is.isEnumValue(noteLength, NoteLength)) {
1568
+ if (Utils8.Is.isEnumValue(noteLength, NoteLength)) {
1569
+ return noteLength;
1570
+ } else {
1549
1571
  throw new MusicError8(MusicErrorType8.InvalidArg, `Invalid noteLength: ${noteLength}`);
1572
+ }
1573
+ }
1574
+ var _NoteLengthProps = class _NoteLengthProps {
1575
+ // Is solid (black) note head?
1576
+ constructor(noteLength) {
1577
+ __publicField(this, "noteLength");
1578
+ __publicField(this, "noteSize");
1579
+ __publicField(this, "ticks");
1580
+ // Not altered by isTriplet!
1581
+ __publicField(this, "flagCount");
1582
+ __publicField(this, "dotCount");
1583
+ __publicField(this, "maxDotCount");
1584
+ __publicField(this, "isTriplet");
1585
+ __publicField(this, "hasStem");
1586
+ __publicField(this, "isSolid");
1587
+ this.noteLength = validateNoteLength(noteLength);
1588
+ this.noteSize = parseInt(noteLength);
1589
+ this.isTriplet = noteLength.endsWith("t");
1590
+ this.maxDotCount = this.isTriplet ? 0 : Math.floor(Math.log2(_NoteLengthProps.ShortestNoteSize / this.noteSize));
1591
+ this.dotCount = Utils8.Str.charCount(noteLength, ".");
1592
+ this.flagCount = this.noteSize > 4 ? Math.floor(Math.log2(this.noteSize / 4)) : 0;
1593
+ this.ticks = TicksMultiplier * _NoteLengthProps.ShortestNoteSize / this.noteSize;
1594
+ this.hasStem = this.noteSize > 1;
1595
+ this.isSolid = this.noteSize > 2;
1596
+ if (this.dotCount > this.maxDotCount) {
1597
+ throw new MusicError8(MusicErrorType8.Note, `dotCount ${this.dotCount} > maxDotCount ${this.maxDotCount}, for noteLength "${this.noteLength}".`);
1598
+ } else if (this.isTriplet && this.dotCount > 0) {
1599
+ throw new MusicError8(MusicErrorType8.Note, `noteLength "${this.noteLength}" is both triplet and dotted!`);
1600
+ }
1601
+ }
1602
+ static get(noteLength) {
1603
+ let p = this.cache.get(noteLength);
1604
+ if (!p) {
1605
+ this.cache.set(noteLength, p = new _NoteLengthProps(noteLength));
1606
+ }
1607
+ return p;
1608
+ }
1609
+ static create(noteLength, dotCount = 0) {
1610
+ let noteSize = typeof noteLength === "number" ? noteLength : this.get(noteLength).noteSize;
1611
+ return this.get(noteSize + (Utils8.Is.isIntegerGte(dotCount, 1) ? ".".repeat(dotCount) : "n"));
1612
+ }
1613
+ /**
1614
+ * Compare note lengths/sizes. Whole (1) > half (2) > quarter (4), etc.
1615
+ * Ignores possible triplet property of note length.
1616
+ * @param a - NoteLengthProps, NoteLength/Str or noteSize
1617
+ * @param b - NoteLengthProps, NoteLength/Str or noteSize
1618
+ * @returns - -1: a < b, 0: a === b, +1: a > b (note length/size comparisons)
1619
+ */
1620
+ static cmp(a, b) {
1621
+ let aNoteSize = a instanceof _NoteLengthProps ? a.noteSize : typeof a === "number" ? a : _NoteLengthProps.get(a).noteSize;
1622
+ let bNoteSize = b instanceof _NoteLengthProps ? b.noteSize : typeof b === "number" ? b : _NoteLengthProps.get(b).noteSize;
1623
+ return cmp(bNoteSize, aNoteSize);
1624
+ }
1625
+ /**
1626
+ * Compare note lengths/sizes for equality.
1627
+ * Ignores possible triplet property of note length.
1628
+ * @param a - NoteLengthProps, NoteLength/Str or noteSize
1629
+ * @param b - NoteLengthProps, NoteLength/Str or noteSize
1630
+ * @returns - true: a === b, false: a !== b (note length/size comparisons)
1631
+ */
1632
+ static equals(a, b) {
1633
+ let aNoteSize = a instanceof _NoteLengthProps ? a.noteSize : typeof a === "number" ? a : _NoteLengthProps.get(a).noteSize;
1634
+ let bNoteSize = b instanceof _NoteLengthProps ? b.noteSize : typeof b === "number" ? b : _NoteLengthProps.get(b).noteSize;
1635
+ return aNoteSize === bNoteSize;
1636
+ }
1637
+ };
1638
+ __publicField(_NoteLengthProps, "LongestNoteSize", Math.min(...Utils8.Enum.getEnumValues(NoteLength).map((noteLength) => parseInt(noteLength))));
1639
+ __publicField(_NoteLengthProps, "ShortestNoteSize", Math.max(...Utils8.Enum.getEnumValues(NoteLength).map((noteLength) => parseInt(noteLength))));
1640
+ __publicField(_NoteLengthProps, "cache", /* @__PURE__ */ new Map());
1641
+ var NoteLengthProps = _NoteLengthProps;
1642
+ function validateTupletRatio(tupletRatio) {
1643
+ if (Utils8.Is.isObject(tupletRatio) && Utils8.Is.isIntegerBetween(tupletRatio.parts, 2, MaxTupletRatioValue) && Utils8.Is.isIntegerBetween(tupletRatio.inTimeOf, 2, MaxTupletRatioValue)) {
1644
+ return tupletRatio;
1550
1645
  } else {
1551
- return noteLength;
1646
+ throw new MusicError8(MusicErrorType8.Note, `Invalid tupletRatio ${JSON.stringify(tupletRatio)}`);
1552
1647
  }
1553
1648
  }
1554
- var RhythmProps = class _RhythmProps {
1555
- constructor(noteLength, dotted, triplet) {
1649
+ var Tuplet = {
1650
+ /** 2 in the time of 3 */
1651
+ Duplet: { parts: 2, inTimeOf: 3 },
1652
+ /** 3 in the time of 2 */
1653
+ Triplet: { parts: 3, inTimeOf: 2 },
1654
+ /** 4 in the time of 3 */
1655
+ Quadruplet: { parts: 4, inTimeOf: 3 }
1656
+ };
1657
+ var _RhythmProps = class _RhythmProps {
1658
+ constructor(noteLength, dotCount, tupletRatio) {
1556
1659
  __publicField(this, "noteLength");
1557
- __publicField(this, "dotted");
1558
- __publicField(this, "triplet");
1660
+ __publicField(this, "noteSize");
1661
+ // whole=1, half=2, quarter=4, etc.
1662
+ __publicField(this, "dotCount");
1663
+ __publicField(this, "tupletRatio");
1559
1664
  __publicField(this, "ticks");
1560
1665
  __publicField(this, "flagCount");
1561
- var _a;
1666
+ __publicField(this, "hasStem");
1667
+ __publicField(this, "isSolidNoteHead");
1562
1668
  this.noteLength = validateNoteLength(noteLength);
1563
- this.dotted = dotted === true;
1564
- this.triplet = triplet === true;
1565
- this.ticks = this.noteLength;
1566
- this.flagCount = (_a = FlagCountMap.get(this.noteLength)) != null ? _a : 0;
1567
- if (this.dotted && this.triplet) {
1568
- throw new MusicError8(MusicErrorType8.Note, "Note cannot be both dotted and triplet!");
1569
- } else if (this.dotted && this.noteLength === MinNoteLength) {
1570
- throw new MusicError8(MusicErrorType8.Note, "Shortest note cannot be dotted!");
1669
+ let p = NoteLengthProps.get(noteLength);
1670
+ this.noteSize = p.noteSize;
1671
+ this.ticks = p.ticks;
1672
+ this.flagCount = p.flagCount;
1673
+ this.dotCount = dotCount != null ? dotCount : p.dotCount;
1674
+ this.hasStem = p.hasStem;
1675
+ this.isSolidNoteHead = p.isSolid;
1676
+ if (Utils8.Is.isObject(tupletRatio)) {
1677
+ this.tupletRatio = validateTupletRatio(tupletRatio);
1678
+ } else if (p.isTriplet) {
1679
+ this.tupletRatio = Tuplet.Triplet;
1680
+ } else {
1681
+ this.tupletRatio = void 0;
1571
1682
  }
1572
- if (this.dotted) {
1573
- this.ticks += this.noteLength / 2;
1683
+ if (this.dotCount > 0 && this.tupletRatio !== void 0) {
1684
+ throw new MusicError8(MusicErrorType8.Note, `Note cannot be both dotted and tuplet!`);
1685
+ } else if (this.dotCount > p.maxDotCount) {
1686
+ throw new MusicError8(MusicErrorType8.Note, `Too big dot count ${this.dotCount} for note length ${this.noteLength}.`);
1574
1687
  }
1575
- if (this.triplet) {
1576
- this.ticks = this.ticks * 2 / 3;
1688
+ for (let add = this.ticks / 2, i = 1; i <= this.dotCount; i++, add /= 2) {
1689
+ this.ticks += add;
1690
+ }
1691
+ if (this.tupletRatio) {
1692
+ this.ticks *= this.tupletRatio.inTimeOf / this.tupletRatio.parts;
1577
1693
  }
1578
1694
  }
1579
- static createFromNoteSize(noteSize) {
1580
- return new _RhythmProps(MaxNoteLength / noteSize);
1695
+ toString() {
1696
+ let sym = _RhythmProps.NoteSymbolMap.get(this.noteSize);
1697
+ let dots = ".".repeat(this.dotCount);
1698
+ return sym ? sym + dots : "" + this.noteSize + (dots.length > 0 ? dots : "n");
1581
1699
  }
1582
- canDot() {
1583
- return !this.dotted && this.noteLength !== MinNoteLength;
1700
+ static get(noteLength, dotCount, tupletRatio) {
1701
+ if (dotCount !== void 0 || tupletRatio !== void 0) {
1702
+ return new _RhythmProps(noteLength, dotCount, tupletRatio);
1703
+ } else {
1704
+ let rhythmProps = this.cache.get(noteLength);
1705
+ if (!rhythmProps) {
1706
+ this.cache.set(noteLength, rhythmProps = new _RhythmProps(noteLength));
1707
+ }
1708
+ return rhythmProps;
1709
+ }
1584
1710
  }
1585
- hasStem() {
1586
- return this.noteLength < 192 /* Whole */;
1711
+ /**
1712
+ * Compare duration of rhythm props.
1713
+ * @param a - RhythmProps
1714
+ * @param b - RhythmProps
1715
+ * @returns - -1: a < b, 0: a === b, +1: a > b (duration comparisons)
1716
+ */
1717
+ static cmp(a, b) {
1718
+ return cmp(a.ticks, b.ticks);
1587
1719
  }
1588
- toString() {
1589
- return NoteSymbolMap.get(this.noteLength) + (this.dotted ? "." : "");
1720
+ /**
1721
+ * Compare duration equality of rhythm props.
1722
+ * @param a - RhythmProps
1723
+ * @param b - RhythmProps
1724
+ * @returns - true: a === b, false: a !== b (duration comparisons)
1725
+ */
1726
+ static equals(a, b) {
1727
+ return a.ticks === b.ticks;
1590
1728
  }
1591
1729
  };
1730
+ __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}"]]));
1731
+ __publicField(_RhythmProps, "cache", /* @__PURE__ */ new Map());
1732
+ var RhythmProps = _RhythmProps;
1592
1733
 
1593
1734
  // src/theory/time-signature.ts
1594
1735
  import { MusicError as MusicError9, MusicErrorType as MusicErrorType9 } from "@tspro/web-music-score/core";
@@ -1616,9 +1757,9 @@ var TimeSignature = class {
1616
1757
  } else if (!Utils9.Is.isIntegerGte(this.beatSize, 1)) {
1617
1758
  throw new MusicError9(MusicErrorType9.Timesignature, `Invalid beatSize: ${this.beatSize}`);
1618
1759
  }
1619
- let beatLengthValue = RhythmProps.createFromNoteSize(this.beatSize);
1620
- this.beatLength = beatLengthValue.noteLength;
1621
- this.measureTicks = this.beatCount * beatLengthValue.ticks;
1760
+ let props = NoteLengthProps.create(this.beatSize);
1761
+ this.beatLength = props.noteLength;
1762
+ this.measureTicks = this.beatCount * props.ticks;
1622
1763
  if (this.is(2, 4) || this.is(3, 4) || this.is(4, 4)) {
1623
1764
  this.beamGroupCount = this.beatCount;
1624
1765
  } else if (this.is(6, 8) || this.is(9, 8)) {
@@ -1651,17 +1792,17 @@ function getDefaultTimeSignature() {
1651
1792
  var defaultTempo;
1652
1793
  function getDefaultTempo() {
1653
1794
  if (!defaultTempo) {
1654
- defaultTempo = { beatsPerMinute: 120, options: { beatLength: 48 /* Quarter */, dotted: false } };
1795
+ defaultTempo = { beatsPerMinute: 120, options: { beatLength: "4n" /* Quarter */, dotCount: 0 } };
1655
1796
  }
1656
1797
  return defaultTempo;
1657
1798
  }
1658
1799
  function getTempoString(tempo) {
1659
- return new RhythmProps(tempo.options.beatLength, tempo.options.dotted).toString() + "=" + tempo.beatsPerMinute;
1800
+ return RhythmProps.get(tempo.options.beatLength, tempo.options.dotCount).toString() + "=" + tempo.beatsPerMinute;
1660
1801
  }
1661
1802
  function alterTempoSpeed(tempo, speed) {
1662
1803
  return {
1663
1804
  beatsPerMinute: tempo.beatsPerMinute * speed,
1664
- options: { beatLength: tempo.options.beatLength, dotted: tempo.options.dotted }
1805
+ options: { beatLength: tempo.options.beatLength, dotCount: tempo.options.dotCount }
1665
1806
  };
1666
1807
  }
1667
1808
 
@@ -1680,11 +1821,10 @@ export {
1680
1821
  Handedness,
1681
1822
  Interval,
1682
1823
  KeySignature,
1683
- MaxNoteLength,
1684
- MinNoteLength,
1685
1824
  Mode,
1686
1825
  Note,
1687
1826
  NoteLength,
1827
+ NoteLengthProps,
1688
1828
  PitchNotation,
1689
1829
  PitchNotationList,
1690
1830
  RhythmProps,
@@ -1694,6 +1834,7 @@ export {
1694
1834
  SymbolSet,
1695
1835
  TimeSignature,
1696
1836
  TuningNameList,
1837
+ Tuplet,
1697
1838
  alterTempoSpeed,
1698
1839
  getDefaultKeySignature,
1699
1840
  getDefaultScale,
@@ -1711,6 +1852,7 @@ export {
1711
1852
  validateNoteLength,
1712
1853
  validatePitchNotation,
1713
1854
  validateScaleType,
1714
- validateTuningName
1855
+ validateTuningName,
1856
+ validateTupletRatio
1715
1857
  };
1716
1858
  //# sourceMappingURL=index.mjs.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tspro/web-music-score",
3
- "version": "3.2.0",
3
+ "version": "4.0.0",
4
4
  "author": "PahkaSoft",
5
5
  "license": "MIT",
6
6
  "private": false,
@@ -92,7 +92,7 @@
92
92
  "package.json"
93
93
  ],
94
94
  "dependencies": {
95
- "@tspro/ts-utils-lib": "^1.3.0",
95
+ "@tspro/ts-utils-lib": "^1.6.0",
96
96
  "tone": "^15.1.22"
97
97
  },
98
98
  "peerDependencies": {
@@ -1,104 +0,0 @@
1
- import { N as Note, A as Accidental } from './note-BFa43I86.mjs';
2
-
3
- declare enum Mode {
4
- Ionian = 1,
5
- Dorian = 2,
6
- Phrygian = 3,
7
- Lydian = 4,
8
- Mixolydian = 5,
9
- Aeolian = 6,
10
- Locrian = 7
11
- }
12
- declare enum AccidentalType {
13
- Natural = 0,
14
- Flats = 1,
15
- Sharps = 2
16
- }
17
- declare function getDefaultKeySignature(): KeySignature;
18
- declare class KeySignature {
19
- readonly tonic: string;
20
- readonly mode: Mode;
21
- private static readonly OrderOfSharps;
22
- private static readonly OrderOfFlats;
23
- private readonly naturalScaleNotes;
24
- private readonly accidentalByDiatonicClass;
25
- private readonly orderedAccidentedNotes;
26
- /**
27
- * @param tonic - Tonic/root note.
28
- * @param mode - Mode: Ionian/Major = 1, Dorian = 2, ..., Locrian = 7
29
- */
30
- protected constructor(tonic: string, mode: Mode);
31
- getAccidentalType(): AccidentalType;
32
- getNaturalScaleNotes(): ReadonlyArray<Note>;
33
- getAccidental(diatonicId: number): Accidental;
34
- getNumAccidentals(): number;
35
- getOrderedAccidentalNotes(): ReadonlyArray<Note>;
36
- /**
37
- *
38
- * @param degree - number 1..7 or string e.g "b5" or "#4"
39
- * @returns
40
- */
41
- getNoteByDegree(degree: number | string): Note;
42
- static equals(a: KeySignature | null | undefined, b: KeySignature | null | undefined): boolean;
43
- }
44
-
45
- declare enum NoteLength {
46
- Whole = 192,// * 3 because triplets are multiplied by 2 / 3, integer result
47
- Half = 96,
48
- Quarter = 48,
49
- Eighth = 24,
50
- Sixteenth = 12,
51
- ThirtySecond = 6,
52
- SixtyFourth = 3
53
- }
54
- declare const MaxNoteLength = NoteLength.Whole;
55
- declare const MinNoteLength = NoteLength.SixtyFourth;
56
- declare function validateNoteLength(noteLength: unknown): NoteLength;
57
- declare class RhythmProps {
58
- readonly noteLength: NoteLength;
59
- readonly dotted: boolean;
60
- readonly triplet: boolean;
61
- readonly ticks: number;
62
- readonly flagCount: number;
63
- constructor(noteLength: NoteLength, dotted?: boolean, triplet?: boolean);
64
- static createFromNoteSize(noteSize: number): RhythmProps;
65
- canDot(): boolean;
66
- hasStem(): boolean;
67
- toString(): string;
68
- }
69
-
70
- type TimeSignatureString = "2/4" | "3/4" | "4/4" | "6/8" | "9/8";
71
- declare class TimeSignature {
72
- readonly beatCount: number;
73
- readonly beatSize: number;
74
- /** Lengths in ticks */
75
- readonly beatLength: NoteLength;
76
- readonly measureTicks: number;
77
- readonly beamGroupCount: number;
78
- readonly beamGroupLength: number;
79
- /**
80
- * @param str - For example "4/4".
81
- */
82
- constructor(str: TimeSignatureString);
83
- /**
84
- * @param beatCount - Measure beat count.
85
- * @param beatSize - Size value: whole-note=1, half-note=2, quarter-note=4, etc.
86
- */
87
- constructor(beatCount: number, beatSize: number);
88
- is(beatCount: number, beatSize: number): boolean;
89
- toString(): string;
90
- }
91
- declare function getDefaultTimeSignature(): TimeSignature;
92
-
93
- type Tempo = {
94
- beatsPerMinute: number;
95
- options: {
96
- beatLength: NoteLength;
97
- dotted: boolean;
98
- };
99
- };
100
- declare function getDefaultTempo(): Readonly<Tempo>;
101
- declare function getTempoString(tempo: Tempo): string;
102
- declare function alterTempoSpeed(tempo: Tempo, speed: number): Tempo;
103
-
104
- export { AccidentalType as A, KeySignature as K, Mode as M, NoteLength as N, RhythmProps as R, type TimeSignatureString as T, TimeSignature as a, getDefaultTimeSignature as b, type Tempo as c, getDefaultTempo as d, getTempoString as e, alterTempoSpeed as f, getDefaultKeySignature as g, MaxNoteLength as h, MinNoteLength as i, validateNoteLength as v };
@@ -1,104 +0,0 @@
1
- import { N as Note, A as Accidental } from './note-BFa43I86.js';
2
-
3
- declare enum Mode {
4
- Ionian = 1,
5
- Dorian = 2,
6
- Phrygian = 3,
7
- Lydian = 4,
8
- Mixolydian = 5,
9
- Aeolian = 6,
10
- Locrian = 7
11
- }
12
- declare enum AccidentalType {
13
- Natural = 0,
14
- Flats = 1,
15
- Sharps = 2
16
- }
17
- declare function getDefaultKeySignature(): KeySignature;
18
- declare class KeySignature {
19
- readonly tonic: string;
20
- readonly mode: Mode;
21
- private static readonly OrderOfSharps;
22
- private static readonly OrderOfFlats;
23
- private readonly naturalScaleNotes;
24
- private readonly accidentalByDiatonicClass;
25
- private readonly orderedAccidentedNotes;
26
- /**
27
- * @param tonic - Tonic/root note.
28
- * @param mode - Mode: Ionian/Major = 1, Dorian = 2, ..., Locrian = 7
29
- */
30
- protected constructor(tonic: string, mode: Mode);
31
- getAccidentalType(): AccidentalType;
32
- getNaturalScaleNotes(): ReadonlyArray<Note>;
33
- getAccidental(diatonicId: number): Accidental;
34
- getNumAccidentals(): number;
35
- getOrderedAccidentalNotes(): ReadonlyArray<Note>;
36
- /**
37
- *
38
- * @param degree - number 1..7 or string e.g "b5" or "#4"
39
- * @returns
40
- */
41
- getNoteByDegree(degree: number | string): Note;
42
- static equals(a: KeySignature | null | undefined, b: KeySignature | null | undefined): boolean;
43
- }
44
-
45
- declare enum NoteLength {
46
- Whole = 192,// * 3 because triplets are multiplied by 2 / 3, integer result
47
- Half = 96,
48
- Quarter = 48,
49
- Eighth = 24,
50
- Sixteenth = 12,
51
- ThirtySecond = 6,
52
- SixtyFourth = 3
53
- }
54
- declare const MaxNoteLength = NoteLength.Whole;
55
- declare const MinNoteLength = NoteLength.SixtyFourth;
56
- declare function validateNoteLength(noteLength: unknown): NoteLength;
57
- declare class RhythmProps {
58
- readonly noteLength: NoteLength;
59
- readonly dotted: boolean;
60
- readonly triplet: boolean;
61
- readonly ticks: number;
62
- readonly flagCount: number;
63
- constructor(noteLength: NoteLength, dotted?: boolean, triplet?: boolean);
64
- static createFromNoteSize(noteSize: number): RhythmProps;
65
- canDot(): boolean;
66
- hasStem(): boolean;
67
- toString(): string;
68
- }
69
-
70
- type TimeSignatureString = "2/4" | "3/4" | "4/4" | "6/8" | "9/8";
71
- declare class TimeSignature {
72
- readonly beatCount: number;
73
- readonly beatSize: number;
74
- /** Lengths in ticks */
75
- readonly beatLength: NoteLength;
76
- readonly measureTicks: number;
77
- readonly beamGroupCount: number;
78
- readonly beamGroupLength: number;
79
- /**
80
- * @param str - For example "4/4".
81
- */
82
- constructor(str: TimeSignatureString);
83
- /**
84
- * @param beatCount - Measure beat count.
85
- * @param beatSize - Size value: whole-note=1, half-note=2, quarter-note=4, etc.
86
- */
87
- constructor(beatCount: number, beatSize: number);
88
- is(beatCount: number, beatSize: number): boolean;
89
- toString(): string;
90
- }
91
- declare function getDefaultTimeSignature(): TimeSignature;
92
-
93
- type Tempo = {
94
- beatsPerMinute: number;
95
- options: {
96
- beatLength: NoteLength;
97
- dotted: boolean;
98
- };
99
- };
100
- declare function getDefaultTempo(): Readonly<Tempo>;
101
- declare function getTempoString(tempo: Tempo): string;
102
- declare function alterTempoSpeed(tempo: Tempo, speed: number): Tempo;
103
-
104
- export { AccidentalType as A, KeySignature as K, Mode as M, NoteLength as N, RhythmProps as R, type TimeSignatureString as T, TimeSignature as a, getDefaultTimeSignature as b, type Tempo as c, getDefaultTempo as d, getTempoString as e, alterTempoSpeed as f, getDefaultKeySignature as g, MaxNoteLength as h, MinNoteLength as i, validateNoteLength as v };