smplr 0.24.0 → 0.26.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/README.md +197 -147
- package/dist/index.d.mts +117 -46
- package/dist/index.d.ts +117 -46
- package/dist/index.js +510 -48
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +503 -48
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -74,6 +74,8 @@ var __async = (__this, __arguments, generator) => {
|
|
|
74
74
|
var index_exports = {};
|
|
75
75
|
__export(index_exports, {
|
|
76
76
|
CacheStorage: () => CacheStorage,
|
|
77
|
+
DRUM_ABUSE_PACKS: () => DRUM_ABUSE_PACKS,
|
|
78
|
+
DrumAbuse: () => DrumAbuse,
|
|
77
79
|
DrumMachine: () => DrumMachine,
|
|
78
80
|
ElectricPiano: () => ElectricPiano,
|
|
79
81
|
HttpStorage: () => HttpStorage,
|
|
@@ -95,7 +97,12 @@ __export(index_exports, {
|
|
|
95
97
|
Versilian: () => Versilian,
|
|
96
98
|
audioBufferToWav: () => audioBufferToWav,
|
|
97
99
|
audioBufferToWav16: () => audioBufferToWav16,
|
|
100
|
+
drumAbuseSampleUrl: () => drumAbuseSampleUrl,
|
|
98
101
|
drumMachineToPreset: () => drumMachineToPreset,
|
|
102
|
+
getDrumAbuseMachineNames: () => getDrumAbuseMachineNames,
|
|
103
|
+
getDrumAbuseMachinePack: () => getDrumAbuseMachinePack,
|
|
104
|
+
getDrumAbuseMachinesForPack: () => getDrumAbuseMachinesForPack,
|
|
105
|
+
getDrumAbusePackNames: () => getDrumAbusePackNames,
|
|
99
106
|
getDrumMachineNames: () => getDrumMachineNames,
|
|
100
107
|
getElectricPianoNames: () => getElectricPianoNames,
|
|
101
108
|
getMalletNames: () => getMalletNames,
|
|
@@ -379,7 +386,7 @@ function pickPlaybackParams(obj) {
|
|
|
379
386
|
return result;
|
|
380
387
|
}
|
|
381
388
|
function resolveParams(defaults, group, region, midi, velocity, overrides) {
|
|
382
|
-
var _a, _b, _c, _d, _e;
|
|
389
|
+
var _a, _b, _c, _d, _e, _f;
|
|
383
390
|
const merged = __spreadValues(__spreadValues(__spreadValues(__spreadValues({}, PARAM_DEFAULTS), defaults), pickPlaybackParams(group)), pickPlaybackParams(region));
|
|
384
391
|
const pitch = (_b = (_a = region.pitch) != null ? _a : region.key) != null ? _b : midi;
|
|
385
392
|
const semitones = midi - pitch;
|
|
@@ -398,7 +405,7 @@ function resolveParams(defaults, group, region, midi, velocity, overrides) {
|
|
|
398
405
|
loopEnd: merged.loopEnd,
|
|
399
406
|
ampVelCurve: region.ampVelCurve,
|
|
400
407
|
loopAuto: region.loopAuto,
|
|
401
|
-
reverse: overrides == null ? void 0 : overrides.reverse
|
|
408
|
+
reverse: (_f = overrides == null ? void 0 : overrides.reverse) != null ? _f : merged.reverse
|
|
402
409
|
};
|
|
403
410
|
}
|
|
404
411
|
|
|
@@ -576,14 +583,6 @@ var SampleLoaderImpl = class {
|
|
|
576
583
|
__privateSet(this, _context, context);
|
|
577
584
|
__privateSet(this, _storage, (_a = options == null ? void 0 : options.storage) != null ? _a : HttpStorage);
|
|
578
585
|
}
|
|
579
|
-
/**
|
|
580
|
-
* Load all samples referenced in `json`. Returns a Map of sample name →
|
|
581
|
-
* AudioBuffer. Progress is reported via `onProgress` callback or via
|
|
582
|
-
* options object.
|
|
583
|
-
*
|
|
584
|
-
* - `buffers` in options: pre-loaded buffers — skips fetch for these names.
|
|
585
|
-
* - All samples load in parallel. Failed samples are silently omitted.
|
|
586
|
-
*/
|
|
587
586
|
load(json, onProgressOrOptions) {
|
|
588
587
|
return __async(this, null, function* () {
|
|
589
588
|
var _a, _b;
|
|
@@ -703,14 +702,6 @@ var SchedulerImpl = class {
|
|
|
703
702
|
__privateSet(this, _intervalMs, (_b = options == null ? void 0 : options.intervalMs) != null ? _b : INTERVAL_MS_DEFAULT);
|
|
704
703
|
__privateSet(this, _queue, new SortedQueue((a, b) => a.time - b.time));
|
|
705
704
|
}
|
|
706
|
-
/**
|
|
707
|
-
* Schedule a callback for a NoteEvent.
|
|
708
|
-
*
|
|
709
|
-
* - If the event's time falls within the lookahead window (or has no time), the
|
|
710
|
-
* callback is called synchronously and a no-op StopFn is returned.
|
|
711
|
-
* - Otherwise the event is queued, the interval is started if needed, and a StopFn
|
|
712
|
-
* is returned that removes the event from the queue before it is dispatched.
|
|
713
|
-
*/
|
|
714
705
|
schedule(event, callback) {
|
|
715
706
|
var _a;
|
|
716
707
|
const now = __privateGet(this, _context2).currentTime;
|
|
@@ -726,10 +717,6 @@ var SchedulerImpl = class {
|
|
|
726
717
|
__privateGet(this, _queue).removeAll((q) => q === item);
|
|
727
718
|
};
|
|
728
719
|
}
|
|
729
|
-
/**
|
|
730
|
-
* Clear all queued (not-yet-dispatched) events and stop the interval.
|
|
731
|
-
* Does not affect voices that are already playing.
|
|
732
|
-
*/
|
|
733
720
|
stop() {
|
|
734
721
|
__privateGet(this, _queue).clear();
|
|
735
722
|
if (__privateGet(this, _intervalId) !== void 0) {
|
|
@@ -1002,10 +989,12 @@ var SmplrImpl = class {
|
|
|
1002
989
|
__privateSet(this, _voices2, new VoiceManager());
|
|
1003
990
|
this.loader = (_c = options == null ? void 0 : options.loader) != null ? _c : SampleLoader(context, { storage: options == null ? void 0 : options.storage });
|
|
1004
991
|
if (json) {
|
|
1005
|
-
this.ready = this.loader.load(json,
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
992
|
+
this.ready = this.loader.load(json, {
|
|
993
|
+
onProgress: (loaded, total) => {
|
|
994
|
+
var _a2;
|
|
995
|
+
__privateSet(this, _loadProgress, { loaded, total });
|
|
996
|
+
(_a2 = __privateGet(this, _onLoadProgress)) == null ? void 0 : _a2.call(this, { loaded, total });
|
|
997
|
+
}
|
|
1009
998
|
}).then((buffers) => {
|
|
1010
999
|
__privateSet(this, _buffers, buffers);
|
|
1011
1000
|
});
|
|
@@ -1461,6 +1450,465 @@ function drumMachineToPreset(instrument) {
|
|
|
1461
1450
|
};
|
|
1462
1451
|
}
|
|
1463
1452
|
|
|
1453
|
+
// src/drum-abuse/index.ts
|
|
1454
|
+
var DEFAULT_BASE_URL = "https://smpldsnds.github.io";
|
|
1455
|
+
var MIDI_BASE = 36;
|
|
1456
|
+
var DRUM_ABUSE_PACKS = [
|
|
1457
|
+
"vol1",
|
|
1458
|
+
"vol2",
|
|
1459
|
+
"vol3",
|
|
1460
|
+
"vol4",
|
|
1461
|
+
"vol5"
|
|
1462
|
+
];
|
|
1463
|
+
var MACHINES_BY_PACK = {
|
|
1464
|
+
vol1: [
|
|
1465
|
+
"4-inthefloor-percussioncombo",
|
|
1466
|
+
"ace-tone-rhythm-ace-fr-1",
|
|
1467
|
+
"ace-tone-rhythm-ace-fr-7l",
|
|
1468
|
+
"ace-tone-rhythm-ace-fr6",
|
|
1469
|
+
"ace-tone-rhythm-king",
|
|
1470
|
+
"ace-tone-rhythm-master",
|
|
1471
|
+
"antonelli-2377",
|
|
1472
|
+
"arp-axxe",
|
|
1473
|
+
"conn-min-o-matic",
|
|
1474
|
+
"eko-compu-rhythm",
|
|
1475
|
+
"eko-ritmo-12",
|
|
1476
|
+
"eko-ritmo-20",
|
|
1477
|
+
"elgam-carousel",
|
|
1478
|
+
"emu-modular",
|
|
1479
|
+
"farfisa-pro",
|
|
1480
|
+
"farfisa-rhythm-10",
|
|
1481
|
+
"farfisa-rhythm-maker-16",
|
|
1482
|
+
"gibson-maestro-g-2",
|
|
1483
|
+
"gibson-maestro-rhythm-jester",
|
|
1484
|
+
"gibson-maestro-rhythm-king-mrk-1",
|
|
1485
|
+
"gulbransen-organ",
|
|
1486
|
+
"hammond-rhythm",
|
|
1487
|
+
"hammond-rhythm-ii",
|
|
1488
|
+
"hohner-automatic-rhythm-player",
|
|
1489
|
+
"jen-sx-1000",
|
|
1490
|
+
"kay-r-8",
|
|
1491
|
+
"keio-checkmate",
|
|
1492
|
+
"kent-k-200",
|
|
1493
|
+
"kent-rhythm-master",
|
|
1494
|
+
"korg-kr-33",
|
|
1495
|
+
"korg-krz",
|
|
1496
|
+
"korg-minipops-series",
|
|
1497
|
+
"korg-s-3",
|
|
1498
|
+
"korg-univox-micro-rhythmer-12",
|
|
1499
|
+
"korg-univox-sr-120",
|
|
1500
|
+
"korg-univox-sr-95",
|
|
1501
|
+
"luxor-passat",
|
|
1502
|
+
"moog-modular-55",
|
|
1503
|
+
"roland-arr",
|
|
1504
|
+
"roland-edp-1",
|
|
1505
|
+
"roland-sh-3a",
|
|
1506
|
+
"roland-system-100",
|
|
1507
|
+
"roland-tr-1-prototype",
|
|
1508
|
+
"roland-tr-33",
|
|
1509
|
+
"roland-tr-41-prototype",
|
|
1510
|
+
"roland-tr-66",
|
|
1511
|
+
"roland-tr-77",
|
|
1512
|
+
"seeburg-rhythm-prince",
|
|
1513
|
+
"seeburg-select-a-rhythm",
|
|
1514
|
+
"solton-disco-64",
|
|
1515
|
+
"sonor-mini-mammut-module",
|
|
1516
|
+
"video-tech-rythmic-10",
|
|
1517
|
+
"vox-percussion-king",
|
|
1518
|
+
"whippany-melo-sonic-350",
|
|
1519
|
+
"wurlitzer-swinging-rhythm",
|
|
1520
|
+
"yamaha-cs-15d",
|
|
1521
|
+
"yamaha-cs-5",
|
|
1522
|
+
"yamaha-cs-6",
|
|
1523
|
+
"yamaha-ps-1",
|
|
1524
|
+
"yamaha-ps-2",
|
|
1525
|
+
"yamaha-ps-3"
|
|
1526
|
+
],
|
|
1527
|
+
vol2: [
|
|
1528
|
+
"bontempi-hf222",
|
|
1529
|
+
"boss-dr-55",
|
|
1530
|
+
"casio-mt-18",
|
|
1531
|
+
"casio-pt-30",
|
|
1532
|
+
"casio-vl-1",
|
|
1533
|
+
"chaser-computer-drum-pr-80",
|
|
1534
|
+
"crb-rhythmboy-480",
|
|
1535
|
+
"eko-musicbox-12",
|
|
1536
|
+
"electro-harmonix-drm-15",
|
|
1537
|
+
"electro-harmonix-drm-16",
|
|
1538
|
+
"electro-harmonix-spacedrum",
|
|
1539
|
+
"elka-drumstar-80",
|
|
1540
|
+
"elka-x-1000",
|
|
1541
|
+
"emu-e-drum",
|
|
1542
|
+
"gem-drum-15",
|
|
1543
|
+
"hammond-autovari-64",
|
|
1544
|
+
"hohner-rhythm-80k",
|
|
1545
|
+
"korg-kpr-77",
|
|
1546
|
+
"korg-kr-55",
|
|
1547
|
+
"korg-kr-mini",
|
|
1548
|
+
"korg-monopoly",
|
|
1549
|
+
"korg-ms-10",
|
|
1550
|
+
"korg-trident",
|
|
1551
|
+
"linn-lm-1",
|
|
1552
|
+
"monacor-rhythmical-choice",
|
|
1553
|
+
"mti-auto-orchestra-ao-1",
|
|
1554
|
+
"multi-moog",
|
|
1555
|
+
"mxr-185",
|
|
1556
|
+
"new-england-digital-synclavier",
|
|
1557
|
+
"oberheim-dmx",
|
|
1558
|
+
"pearl-drum-x",
|
|
1559
|
+
"pollard-syndrum-178",
|
|
1560
|
+
"roland-cr-1000",
|
|
1561
|
+
"roland-cr-68",
|
|
1562
|
+
"roland-cr-78",
|
|
1563
|
+
"roland-cr-80",
|
|
1564
|
+
"roland-cr-8000",
|
|
1565
|
+
"roland-dr-55",
|
|
1566
|
+
"roland-jupiter-8",
|
|
1567
|
+
"roland-pb-300-rhythm-plus",
|
|
1568
|
+
"roland-rhy-33",
|
|
1569
|
+
"roland-rhy-55",
|
|
1570
|
+
"roland-sh-09",
|
|
1571
|
+
"roland-tr-55",
|
|
1572
|
+
"roland-tr-606",
|
|
1573
|
+
"roland-tr-808",
|
|
1574
|
+
"simmons-drum",
|
|
1575
|
+
"simmons-sds-1",
|
|
1576
|
+
"simmons-sds-5",
|
|
1577
|
+
"solton-programmer-24",
|
|
1578
|
+
"star-instruments-synare-3",
|
|
1579
|
+
"star-instruments-synare-ps-1",
|
|
1580
|
+
"visco-space-drum",
|
|
1581
|
+
"watford-electronics-rhythm-generator",
|
|
1582
|
+
"yamaha-cs-40m",
|
|
1583
|
+
"yamaha-mr-10",
|
|
1584
|
+
"yamaha-ps-55"
|
|
1585
|
+
],
|
|
1586
|
+
vol3: [
|
|
1587
|
+
"amdek-pck-100",
|
|
1588
|
+
"austin-arb-6",
|
|
1589
|
+
"bme-rattlesnake-parametric-percussion-system",
|
|
1590
|
+
"boss-dr-110",
|
|
1591
|
+
"casio-mt-100",
|
|
1592
|
+
"coron-drumsynce-ds-7",
|
|
1593
|
+
"coron-rds",
|
|
1594
|
+
"denon-crb-90",
|
|
1595
|
+
"drumfire-df-2000",
|
|
1596
|
+
"drumfire-df-500",
|
|
1597
|
+
"electro-harmonix-drm-32",
|
|
1598
|
+
"emu-drumulator",
|
|
1599
|
+
"kay-drm-1",
|
|
1600
|
+
"korg-ddm-110",
|
|
1601
|
+
"korg-ddm-220",
|
|
1602
|
+
"korg-poly-800",
|
|
1603
|
+
"linn-linndrum-lm-1-vinyl",
|
|
1604
|
+
"linn-lm-2",
|
|
1605
|
+
"mattel-electronics-synsonics-drm",
|
|
1606
|
+
"mattel-electronics-synsonics-pro",
|
|
1607
|
+
"panasonic-rd-9844",
|
|
1608
|
+
"pearl-drx-1",
|
|
1609
|
+
"roland-ddr-30",
|
|
1610
|
+
"roland-mc-202",
|
|
1611
|
+
"roland-rhy-77",
|
|
1612
|
+
"roland-tr-909",
|
|
1613
|
+
"rsf-dd-30",
|
|
1614
|
+
"sakata-dpm-48",
|
|
1615
|
+
"sequential-circuits-drumtraks",
|
|
1616
|
+
"simmons-clap-trap",
|
|
1617
|
+
"simmons-sds-200",
|
|
1618
|
+
"simmons-sds-400",
|
|
1619
|
+
"soundmaster-sm-8",
|
|
1620
|
+
"soundmaster-sr-88",
|
|
1621
|
+
"tama-ts-206",
|
|
1622
|
+
"tama-ts-305",
|
|
1623
|
+
"wersi-wm-24",
|
|
1624
|
+
"yamaha-dx7"
|
|
1625
|
+
],
|
|
1626
|
+
vol4: [
|
|
1627
|
+
"atlantex-mpc-1",
|
|
1628
|
+
"boss-hc-2",
|
|
1629
|
+
"boss-pc-2",
|
|
1630
|
+
"casio-ct-310",
|
|
1631
|
+
"casio-mt-500",
|
|
1632
|
+
"casio-mt-800",
|
|
1633
|
+
"casio-pt-68",
|
|
1634
|
+
"casio-pt-82",
|
|
1635
|
+
"casio-sk-1",
|
|
1636
|
+
"dr-b-hm-digital-drums",
|
|
1637
|
+
"emu-sp-12",
|
|
1638
|
+
"ensoniq-mirage",
|
|
1639
|
+
"hing-hon-ek-001",
|
|
1640
|
+
"kawai-acr-20",
|
|
1641
|
+
"kawai-sx-240",
|
|
1642
|
+
"klone-dual-percussion-synthesiser",
|
|
1643
|
+
"korg-ddd-1",
|
|
1644
|
+
"korg-pss-50",
|
|
1645
|
+
"kurzweil-electrodrum-prototype",
|
|
1646
|
+
"linn-9000",
|
|
1647
|
+
"linn-linndrum-lm-2-vinyl",
|
|
1648
|
+
"nasta-hitstix-2",
|
|
1649
|
+
"oberheim-dx",
|
|
1650
|
+
"pearl-sc-40",
|
|
1651
|
+
"rhodes-polaris",
|
|
1652
|
+
"roland-juno-106",
|
|
1653
|
+
"roland-super-quartet-mks-7",
|
|
1654
|
+
"roland-tr-707",
|
|
1655
|
+
"roland-tr-727",
|
|
1656
|
+
"siel-mdp-40",
|
|
1657
|
+
"simmons-sds-1000",
|
|
1658
|
+
"simmons-sds-7",
|
|
1659
|
+
"simmons-sds-8",
|
|
1660
|
+
"simmons-sds-9",
|
|
1661
|
+
"sony-drp-1",
|
|
1662
|
+
"soundmaster-stix-st-305",
|
|
1663
|
+
"suzuki-rpm-40",
|
|
1664
|
+
"tama-ts-500",
|
|
1665
|
+
"technics-ax-5",
|
|
1666
|
+
"technics-pcm-dp-50",
|
|
1667
|
+
"wersi-prisma-dx-5",
|
|
1668
|
+
"yamaha-dd-5",
|
|
1669
|
+
"yamaha-rx-11",
|
|
1670
|
+
"yamaha-rx-15",
|
|
1671
|
+
"yamaha-rx-21",
|
|
1672
|
+
"yamaha-rx-5"
|
|
1673
|
+
],
|
|
1674
|
+
vol5: [
|
|
1675
|
+
"boss-dr-pad-drp-i",
|
|
1676
|
+
"casio-ct-403",
|
|
1677
|
+
"casio-cz-230s",
|
|
1678
|
+
"casio-ht-700",
|
|
1679
|
+
"casio-rz-1",
|
|
1680
|
+
"cheetah-spec-drum",
|
|
1681
|
+
"forat-f-9000",
|
|
1682
|
+
"korg-ddd-5",
|
|
1683
|
+
"korg-dss-1",
|
|
1684
|
+
"m-p-c-electronics-dsm-1",
|
|
1685
|
+
"pearl-sy-1",
|
|
1686
|
+
"roland-tr-505",
|
|
1687
|
+
"sequential-circuits-studio-440",
|
|
1688
|
+
"simmons-sds-2000",
|
|
1689
|
+
"simmons-sdx",
|
|
1690
|
+
"yamaha-pss-130",
|
|
1691
|
+
"yamaha-ptx8",
|
|
1692
|
+
"yamaha-rx-21l"
|
|
1693
|
+
]
|
|
1694
|
+
};
|
|
1695
|
+
var machineToPack = (() => {
|
|
1696
|
+
const m = /* @__PURE__ */ new Map();
|
|
1697
|
+
for (const pack of DRUM_ABUSE_PACKS) {
|
|
1698
|
+
for (const id of MACHINES_BY_PACK[pack]) m.set(id, pack);
|
|
1699
|
+
}
|
|
1700
|
+
return m;
|
|
1701
|
+
})();
|
|
1702
|
+
function getDrumAbuseMachineNames() {
|
|
1703
|
+
return [...machineToPack.keys()];
|
|
1704
|
+
}
|
|
1705
|
+
function getDrumAbuseMachinesForPack(pack) {
|
|
1706
|
+
return MACHINES_BY_PACK[pack];
|
|
1707
|
+
}
|
|
1708
|
+
function getDrumAbusePackNames() {
|
|
1709
|
+
return DRUM_ABUSE_PACKS;
|
|
1710
|
+
}
|
|
1711
|
+
function getDrumAbuseMachinePack(id) {
|
|
1712
|
+
return machineToPack.get(id);
|
|
1713
|
+
}
|
|
1714
|
+
var encSeg = (s) => s.split("/").map(encodeURIComponent).join("/");
|
|
1715
|
+
function packBase(baseUrl, pack) {
|
|
1716
|
+
return `${baseUrl}/drum-abuse-${pack}`;
|
|
1717
|
+
}
|
|
1718
|
+
function sampleBaseUrl(baseUrl, pack, urlPath) {
|
|
1719
|
+
return `${packBase(baseUrl, pack)}/samples/${encSeg(urlPath)}/`;
|
|
1720
|
+
}
|
|
1721
|
+
function drumAbuseSampleUrl(pack, urlPath, fileNoExt, format = "wav", baseUrl = DEFAULT_BASE_URL) {
|
|
1722
|
+
return `${sampleBaseUrl(baseUrl, pack, urlPath)}${encodeURIComponent(fileNoExt)}.${format}`;
|
|
1723
|
+
}
|
|
1724
|
+
function stripExt(filename) {
|
|
1725
|
+
return filename.replace(/\.[^.]+$/, "");
|
|
1726
|
+
}
|
|
1727
|
+
var jsonCache = /* @__PURE__ */ new Map();
|
|
1728
|
+
function fetchJSON(url, storage) {
|
|
1729
|
+
let p = jsonCache.get(url);
|
|
1730
|
+
if (!p) {
|
|
1731
|
+
p = storage.fetch(url).then((r) => {
|
|
1732
|
+
if (r.status >= 400) throw new Error(`DrumAbuse: ${r.status} ${url}`);
|
|
1733
|
+
return r.json();
|
|
1734
|
+
});
|
|
1735
|
+
jsonCache.set(url, p);
|
|
1736
|
+
}
|
|
1737
|
+
return p;
|
|
1738
|
+
}
|
|
1739
|
+
function buildMachinePreset(machine, setPath, baseUrl, pack) {
|
|
1740
|
+
if (machine.sample_sets.length === 0) {
|
|
1741
|
+
throw new Error(`DrumAbuse: machine "${machine.id}" has no sample sets`);
|
|
1742
|
+
}
|
|
1743
|
+
const set = setPath ? machine.sample_sets.find((s) => s.path === setPath) : machine.sample_sets[0];
|
|
1744
|
+
if (!set) {
|
|
1745
|
+
throw new Error(`DrumAbuse: set "${setPath}" not found on "${machine.id}"`);
|
|
1746
|
+
}
|
|
1747
|
+
if (set.samples.length === 0) {
|
|
1748
|
+
throw new Error(
|
|
1749
|
+
`DrumAbuse: set "${set.path}" of "${machine.id}" has no samples`
|
|
1750
|
+
);
|
|
1751
|
+
}
|
|
1752
|
+
const sampleNames = [];
|
|
1753
|
+
const groupNames = [];
|
|
1754
|
+
const sampleNamesForGroup = {};
|
|
1755
|
+
const aliases = {};
|
|
1756
|
+
const regions = set.samples.map((file, i) => {
|
|
1757
|
+
const key = stripExt(file);
|
|
1758
|
+
const midi = MIDI_BASE + i;
|
|
1759
|
+
sampleNames.push(key);
|
|
1760
|
+
aliases[key] = midi;
|
|
1761
|
+
const group = set.sample_instruments[i] || "";
|
|
1762
|
+
if (group) {
|
|
1763
|
+
if (!sampleNamesForGroup[group]) {
|
|
1764
|
+
sampleNamesForGroup[group] = [];
|
|
1765
|
+
groupNames.push(group);
|
|
1766
|
+
aliases[group] = midi;
|
|
1767
|
+
}
|
|
1768
|
+
sampleNamesForGroup[group].push(key);
|
|
1769
|
+
}
|
|
1770
|
+
return {
|
|
1771
|
+
sample: key,
|
|
1772
|
+
keyRange: [midi, midi],
|
|
1773
|
+
pitch: midi
|
|
1774
|
+
};
|
|
1775
|
+
});
|
|
1776
|
+
return {
|
|
1777
|
+
preset: {
|
|
1778
|
+
samples: {
|
|
1779
|
+
baseUrl: sampleBaseUrl(baseUrl, pack, set.url_path),
|
|
1780
|
+
formats: ["wav"]
|
|
1781
|
+
},
|
|
1782
|
+
groups: [{ regions }],
|
|
1783
|
+
aliases
|
|
1784
|
+
},
|
|
1785
|
+
sampleNames,
|
|
1786
|
+
groupNames,
|
|
1787
|
+
sampleNamesForGroup,
|
|
1788
|
+
setPath: set.path
|
|
1789
|
+
};
|
|
1790
|
+
}
|
|
1791
|
+
function buildPackPreset(list, baseUrl, pack) {
|
|
1792
|
+
var _a;
|
|
1793
|
+
if (list.length === 0) {
|
|
1794
|
+
throw new Error(`DrumAbuse: empty pack-instrument list for pack "${pack}"`);
|
|
1795
|
+
}
|
|
1796
|
+
const fileCount = {};
|
|
1797
|
+
for (const s of list) {
|
|
1798
|
+
const f = stripExt(s.file);
|
|
1799
|
+
fileCount[f] = ((_a = fileCount[f]) != null ? _a : 0) + 1;
|
|
1800
|
+
}
|
|
1801
|
+
const sampleNames = [];
|
|
1802
|
+
const groupNames = [];
|
|
1803
|
+
const sampleNamesForGroup = {};
|
|
1804
|
+
const map = {};
|
|
1805
|
+
const aliases = {};
|
|
1806
|
+
const regions = list.map((s, i) => {
|
|
1807
|
+
const fileKey = stripExt(s.file);
|
|
1808
|
+
const uniqueKey = `${s.machine_id}/${fileKey}`;
|
|
1809
|
+
const midi = MIDI_BASE + i;
|
|
1810
|
+
sampleNames.push(uniqueKey);
|
|
1811
|
+
aliases[uniqueKey] = midi;
|
|
1812
|
+
if (fileCount[fileKey] === 1) aliases[fileKey] = midi;
|
|
1813
|
+
map[uniqueKey] = `${packBase(baseUrl, pack)}/samples/${encSeg(s.url_path)}/${encodeURIComponent(s.file)}`;
|
|
1814
|
+
if (!sampleNamesForGroup[s.machine_id]) {
|
|
1815
|
+
sampleNamesForGroup[s.machine_id] = [];
|
|
1816
|
+
groupNames.push(s.machine_id);
|
|
1817
|
+
aliases[s.machine_id] = midi;
|
|
1818
|
+
}
|
|
1819
|
+
sampleNamesForGroup[s.machine_id].push(uniqueKey);
|
|
1820
|
+
return {
|
|
1821
|
+
sample: uniqueKey,
|
|
1822
|
+
keyRange: [midi, midi],
|
|
1823
|
+
pitch: midi
|
|
1824
|
+
};
|
|
1825
|
+
});
|
|
1826
|
+
return {
|
|
1827
|
+
preset: {
|
|
1828
|
+
samples: { baseUrl: "", formats: ["wav"], map },
|
|
1829
|
+
groups: [{ regions }],
|
|
1830
|
+
aliases
|
|
1831
|
+
},
|
|
1832
|
+
sampleNames,
|
|
1833
|
+
groupNames,
|
|
1834
|
+
sampleNamesForGroup,
|
|
1835
|
+
setPath: null
|
|
1836
|
+
};
|
|
1837
|
+
}
|
|
1838
|
+
var DrumAbuse = Instrument(
|
|
1839
|
+
(_ctx, options = {}, smplr) => {
|
|
1840
|
+
var _a, _b;
|
|
1841
|
+
const source = options.source;
|
|
1842
|
+
if (!source) {
|
|
1843
|
+
throw new Error("DrumAbuse: options.source is required");
|
|
1844
|
+
}
|
|
1845
|
+
const baseUrl = (_a = options.baseUrl) != null ? _a : DEFAULT_BASE_URL;
|
|
1846
|
+
const storage = (_b = options.storage) != null ? _b : HttpStorage;
|
|
1847
|
+
let sampleNames = [];
|
|
1848
|
+
let groupNames = [];
|
|
1849
|
+
let sampleNamesForGroup = {};
|
|
1850
|
+
let machineId = null;
|
|
1851
|
+
let setPath = null;
|
|
1852
|
+
let packId;
|
|
1853
|
+
let mode;
|
|
1854
|
+
let presetPromise;
|
|
1855
|
+
if (source.kind === "machine") {
|
|
1856
|
+
mode = "machine";
|
|
1857
|
+
const pack = getDrumAbuseMachinePack(source.machine);
|
|
1858
|
+
if (!pack) {
|
|
1859
|
+
throw new Error(`DrumAbuse: unknown machine "${source.machine}"`);
|
|
1860
|
+
}
|
|
1861
|
+
packId = pack;
|
|
1862
|
+
machineId = source.machine;
|
|
1863
|
+
const url = `${packBase(baseUrl, pack)}/machines/${encodeURIComponent(source.machine)}.json`;
|
|
1864
|
+
presetPromise = fetchJSON(url, storage).then((machine) => {
|
|
1865
|
+
const built = buildMachinePreset(machine, source.set, baseUrl, pack);
|
|
1866
|
+
sampleNames = built.sampleNames;
|
|
1867
|
+
groupNames = built.groupNames;
|
|
1868
|
+
sampleNamesForGroup = built.sampleNamesForGroup;
|
|
1869
|
+
setPath = built.setPath;
|
|
1870
|
+
return built.preset;
|
|
1871
|
+
});
|
|
1872
|
+
} else {
|
|
1873
|
+
mode = "pack";
|
|
1874
|
+
if (!DRUM_ABUSE_PACKS.includes(source.pack)) {
|
|
1875
|
+
throw new Error(`DrumAbuse: unknown pack "${source.pack}"`);
|
|
1876
|
+
}
|
|
1877
|
+
packId = source.pack;
|
|
1878
|
+
const url = `${packBase(baseUrl, source.pack)}/instruments/${encodeURIComponent(source.instrument)}.json`;
|
|
1879
|
+
presetPromise = fetchJSON(url, storage).then((list) => {
|
|
1880
|
+
const built = buildPackPreset(list, baseUrl, source.pack);
|
|
1881
|
+
sampleNames = built.sampleNames;
|
|
1882
|
+
groupNames = built.groupNames;
|
|
1883
|
+
sampleNamesForGroup = built.sampleNamesForGroup;
|
|
1884
|
+
return built.preset;
|
|
1885
|
+
});
|
|
1886
|
+
}
|
|
1887
|
+
const baseStart = smplr.start.bind(smplr);
|
|
1888
|
+
const extras = {
|
|
1889
|
+
get mode() {
|
|
1890
|
+
return mode;
|
|
1891
|
+
},
|
|
1892
|
+
getSampleNames: () => sampleNames.slice(),
|
|
1893
|
+
getGroupNames: () => groupNames.slice(),
|
|
1894
|
+
getSampleNamesForGroup: (g) => {
|
|
1895
|
+
var _a2;
|
|
1896
|
+
return ((_a2 = sampleNamesForGroup[g]) != null ? _a2 : []).slice();
|
|
1897
|
+
},
|
|
1898
|
+
getMachineId: () => machineId,
|
|
1899
|
+
getSetPath: () => setPath,
|
|
1900
|
+
getPackId: () => packId,
|
|
1901
|
+
start: (event) => {
|
|
1902
|
+
var _a2;
|
|
1903
|
+
const ev = typeof event === "object" ? event : { note: event };
|
|
1904
|
+
return baseStart(__spreadProps(__spreadValues({}, ev), { stopId: (_a2 = ev.stopId) != null ? _a2 : ev.note }));
|
|
1905
|
+
}
|
|
1906
|
+
};
|
|
1907
|
+
const ready = presetPromise.then((preset) => smplr.loadInstrument(preset));
|
|
1908
|
+
return { extras, ready };
|
|
1909
|
+
}
|
|
1910
|
+
);
|
|
1911
|
+
|
|
1464
1912
|
// src/offline/wav-encoder.ts
|
|
1465
1913
|
function audioBufferToWav(buffer) {
|
|
1466
1914
|
return encodeWav(buffer, 32);
|
|
@@ -1754,6 +2202,11 @@ var TransportClock = class {
|
|
|
1754
2202
|
*
|
|
1755
2203
|
* Any checkpoints at or after `audioTime` are removed and replaced with this
|
|
1756
2204
|
* new anchor, preserving the BPM that was in effect at that time.
|
|
2205
|
+
*
|
|
2206
|
+
* @internal Leaks checkpoint-list semantics; only called by `Sequencer._flush`
|
|
2207
|
+
* for loop-boundary re-anchoring. Not safe to share between Sequencers — see
|
|
2208
|
+
* thoughts/research/2026-05-17_20-18-43_shared-transport.md §3. Must not be
|
|
2209
|
+
* exported from any barrel.
|
|
1757
2210
|
*/
|
|
1758
2211
|
seekAt(tick, audioTime) {
|
|
1759
2212
|
let bpm = this._bpm;
|
|
@@ -1807,9 +2260,13 @@ var TransportClock = class {
|
|
|
1807
2260
|
return cp.tick + (audioTime - cp.audioTime) / this._secondsPerTick(cp.bpm);
|
|
1808
2261
|
}
|
|
1809
2262
|
/**
|
|
1810
|
-
*
|
|
2263
|
+
* Convert a tick count to seconds at the current (snapshot) BPM.
|
|
2264
|
+
*
|
|
2265
|
+
* Uses `this._bpm` directly, not the checkpoint history — so after a
|
|
2266
|
+
* mid-play BPM change this returns a value based on the *latest* BPM only.
|
|
2267
|
+
* For checkpoint-aware durations, use `tickToAudioTime(end) - tickToAudioTime(start)`.
|
|
1811
2268
|
*/
|
|
1812
|
-
|
|
2269
|
+
ticksToSeconds(ticks) {
|
|
1813
2270
|
return ticks * this._secondsPerTick(this._bpm);
|
|
1814
2271
|
}
|
|
1815
2272
|
// ---------------------------------------------------------------------------
|
|
@@ -2096,6 +2553,7 @@ var SequencerImpl = class {
|
|
|
2096
2553
|
this._clock.stop();
|
|
2097
2554
|
this._stopLoop();
|
|
2098
2555
|
this._endScheduled = false;
|
|
2556
|
+
for (const stopFn of this._activeVoices.values()) stopFn();
|
|
2099
2557
|
this._activeVoices.clear();
|
|
2100
2558
|
this._emitStateChange("stopped");
|
|
2101
2559
|
return this;
|
|
@@ -2362,7 +2820,7 @@ var SequencerImpl = class {
|
|
|
2362
2820
|
if (Math.random() * 100 >= note.chance) continue;
|
|
2363
2821
|
}
|
|
2364
2822
|
const audioTime = this._clock.tickToAudioTime(noteTick);
|
|
2365
|
-
const durationSec = note.duration !== void 0 ? this._clock.
|
|
2823
|
+
const durationSec = note.duration !== void 0 ? this._clock.ticksToSeconds(
|
|
2366
2824
|
parseTicks(note.duration, this._ppq, this._timeSignature)
|
|
2367
2825
|
) : void 0;
|
|
2368
2826
|
const timingOffset = trackHumanize.timing ? (Math.random() * 2 - 1) * trackHumanize.timing / 1e3 : 0;
|
|
@@ -2733,8 +3191,10 @@ function createTremolo(context, depth) {
|
|
|
2733
3191
|
splitter.disconnect(ampR, 1);
|
|
2734
3192
|
ampL.disconnect(merger, 0, 0);
|
|
2735
3193
|
ampR.disconnect(merger, 0, 1);
|
|
2736
|
-
lfoL.disconnect(
|
|
2737
|
-
|
|
3194
|
+
lfoL.disconnect(lfoLAmp);
|
|
3195
|
+
lfoLAmp.disconnect(ampL.gain);
|
|
3196
|
+
lfoR.disconnect(lfoRAmp);
|
|
3197
|
+
lfoRAmp.disconnect(ampR.gain);
|
|
2738
3198
|
merger.disconnect(output);
|
|
2739
3199
|
};
|
|
2740
3200
|
return { input, output };
|
|
@@ -2805,15 +3265,11 @@ var ElectricPiano = Instrument(
|
|
|
2805
3265
|
|
|
2806
3266
|
// src/versilian.ts
|
|
2807
3267
|
var VCSL_BASE_URL = "https://smpldsnds.github.io/sgossner-vcsl";
|
|
2808
|
-
var
|
|
3268
|
+
var instrumentsPromise;
|
|
2809
3269
|
function getVersilianInstruments() {
|
|
2810
|
-
return
|
|
2811
|
-
|
|
2812
|
-
|
|
2813
|
-
(res) => res.json()
|
|
2814
|
-
);
|
|
2815
|
-
return instruments;
|
|
2816
|
-
});
|
|
3270
|
+
return instrumentsPromise != null ? instrumentsPromise : instrumentsPromise = fetch(
|
|
3271
|
+
VCSL_BASE_URL + "/sfz_files.json"
|
|
3272
|
+
).then((res) => res.json());
|
|
2817
3273
|
}
|
|
2818
3274
|
var Versilian = Instrument(
|
|
2819
3275
|
(ctx, options = {}, smplr) => loadVersilianInstrument(smplr, options)
|
|
@@ -2823,11 +3279,11 @@ function loadVersilianInstrument(smplr, options) {
|
|
|
2823
3279
|
const instrument = (_a = options.instrument) != null ? _a : "Strings/Violin/Violin - Arco";
|
|
2824
3280
|
const sfzUrl = `${VCSL_BASE_URL}/${instrument}.sfz`;
|
|
2825
3281
|
const base = instrument.slice(0, instrument.lastIndexOf("/") + 1);
|
|
2826
|
-
const
|
|
3282
|
+
const sampleBaseUrl2 = `${VCSL_BASE_URL}/${base}`;
|
|
2827
3283
|
return fetch(sfzUrl).then((r) => r.text()).then(
|
|
2828
3284
|
(sfzText) => smplr.loadInstrument(
|
|
2829
3285
|
sfzToPreset(sfzText, {
|
|
2830
|
-
baseUrl:
|
|
3286
|
+
baseUrl: sampleBaseUrl2,
|
|
2831
3287
|
pathFromSampleName: (name) => name.replace(/\.wav$/i, ""),
|
|
2832
3288
|
formats: ["ogg", "m4a"]
|
|
2833
3289
|
})
|
|
@@ -2945,7 +3401,7 @@ function mellotronToPreset(sampleNames, config) {
|
|
|
2945
3401
|
for (const sampleName of sampleNames) {
|
|
2946
3402
|
if (config.variation && !sampleName.includes(config.variation)) continue;
|
|
2947
3403
|
const midi = toMidi((_a = sampleName.split(" ")[0]) != null ? _a : "");
|
|
2948
|
-
if (
|
|
3404
|
+
if (midi === void 0) continue;
|
|
2949
3405
|
entries.push([midi, sampleName]);
|
|
2950
3406
|
}
|
|
2951
3407
|
const spread = spreadKeyRanges(entries);
|
|
@@ -3030,7 +3486,7 @@ var ReverbImpl = class {
|
|
|
3030
3486
|
}
|
|
3031
3487
|
getParam(name) {
|
|
3032
3488
|
var _a;
|
|
3033
|
-
return (_a = __privateGet(this, _effect)) == null ? void 0 : _a.parameters.get(
|
|
3489
|
+
return (_a = __privateGet(this, _effect)) == null ? void 0 : _a.parameters.get(name);
|
|
3034
3490
|
}
|
|
3035
3491
|
get isReady() {
|
|
3036
3492
|
return __privateGet(this, _effect) !== void 0;
|
|
@@ -3357,10 +3813,9 @@ function fetchSoundfontLoopData(url, sampleRate = 44100) {
|
|
|
3357
3813
|
const loopData = {};
|
|
3358
3814
|
Object.keys(raw).forEach((key) => {
|
|
3359
3815
|
const midi = toMidi(key);
|
|
3360
|
-
if (midi)
|
|
3361
|
-
|
|
3362
|
-
|
|
3363
|
-
}
|
|
3816
|
+
if (midi === void 0) return;
|
|
3817
|
+
const offsets = raw[key];
|
|
3818
|
+
loopData[midi] = [offsets[0] / sampleRate, offsets[1] / sampleRate];
|
|
3364
3819
|
});
|
|
3365
3820
|
return loopData;
|
|
3366
3821
|
} catch (err) {
|
|
@@ -3405,7 +3860,7 @@ function decodeSoundfontFile(context, config) {
|
|
|
3405
3860
|
yield Promise.all(
|
|
3406
3861
|
noteNames.map((noteName) => __async(null, null, function* () {
|
|
3407
3862
|
const midi = toMidi(noteName);
|
|
3408
|
-
if (
|
|
3863
|
+
if (midi === void 0) return;
|
|
3409
3864
|
try {
|
|
3410
3865
|
const audioData = base64ToArrayBuffer(
|
|
3411
3866
|
removeBase64Prefix(json[noteName])
|
|
@@ -3976,6 +4431,8 @@ var LAYERS = [
|
|
|
3976
4431
|
// Annotate the CommonJS export names for ESM import in node:
|
|
3977
4432
|
0 && (module.exports = {
|
|
3978
4433
|
CacheStorage,
|
|
4434
|
+
DRUM_ABUSE_PACKS,
|
|
4435
|
+
DrumAbuse,
|
|
3979
4436
|
DrumMachine,
|
|
3980
4437
|
ElectricPiano,
|
|
3981
4438
|
HttpStorage,
|
|
@@ -3997,7 +4454,12 @@ var LAYERS = [
|
|
|
3997
4454
|
Versilian,
|
|
3998
4455
|
audioBufferToWav,
|
|
3999
4456
|
audioBufferToWav16,
|
|
4457
|
+
drumAbuseSampleUrl,
|
|
4000
4458
|
drumMachineToPreset,
|
|
4459
|
+
getDrumAbuseMachineNames,
|
|
4460
|
+
getDrumAbuseMachinePack,
|
|
4461
|
+
getDrumAbuseMachinesForPack,
|
|
4462
|
+
getDrumAbusePackNames,
|
|
4001
4463
|
getDrumMachineNames,
|
|
4002
4464
|
getElectricPianoNames,
|
|
4003
4465
|
getMalletNames,
|