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.mjs
CHANGED
|
@@ -318,7 +318,7 @@ function pickPlaybackParams(obj) {
|
|
|
318
318
|
return result;
|
|
319
319
|
}
|
|
320
320
|
function resolveParams(defaults, group, region, midi, velocity, overrides) {
|
|
321
|
-
var _a, _b, _c, _d, _e;
|
|
321
|
+
var _a, _b, _c, _d, _e, _f;
|
|
322
322
|
const merged = __spreadValues(__spreadValues(__spreadValues(__spreadValues({}, PARAM_DEFAULTS), defaults), pickPlaybackParams(group)), pickPlaybackParams(region));
|
|
323
323
|
const pitch = (_b = (_a = region.pitch) != null ? _a : region.key) != null ? _b : midi;
|
|
324
324
|
const semitones = midi - pitch;
|
|
@@ -337,7 +337,7 @@ function resolveParams(defaults, group, region, midi, velocity, overrides) {
|
|
|
337
337
|
loopEnd: merged.loopEnd,
|
|
338
338
|
ampVelCurve: region.ampVelCurve,
|
|
339
339
|
loopAuto: region.loopAuto,
|
|
340
|
-
reverse: overrides == null ? void 0 : overrides.reverse
|
|
340
|
+
reverse: (_f = overrides == null ? void 0 : overrides.reverse) != null ? _f : merged.reverse
|
|
341
341
|
};
|
|
342
342
|
}
|
|
343
343
|
|
|
@@ -515,14 +515,6 @@ var SampleLoaderImpl = class {
|
|
|
515
515
|
__privateSet(this, _context, context);
|
|
516
516
|
__privateSet(this, _storage, (_a = options == null ? void 0 : options.storage) != null ? _a : HttpStorage);
|
|
517
517
|
}
|
|
518
|
-
/**
|
|
519
|
-
* Load all samples referenced in `json`. Returns a Map of sample name →
|
|
520
|
-
* AudioBuffer. Progress is reported via `onProgress` callback or via
|
|
521
|
-
* options object.
|
|
522
|
-
*
|
|
523
|
-
* - `buffers` in options: pre-loaded buffers — skips fetch for these names.
|
|
524
|
-
* - All samples load in parallel. Failed samples are silently omitted.
|
|
525
|
-
*/
|
|
526
518
|
load(json, onProgressOrOptions) {
|
|
527
519
|
return __async(this, null, function* () {
|
|
528
520
|
var _a, _b;
|
|
@@ -642,14 +634,6 @@ var SchedulerImpl = class {
|
|
|
642
634
|
__privateSet(this, _intervalMs, (_b = options == null ? void 0 : options.intervalMs) != null ? _b : INTERVAL_MS_DEFAULT);
|
|
643
635
|
__privateSet(this, _queue, new SortedQueue((a, b) => a.time - b.time));
|
|
644
636
|
}
|
|
645
|
-
/**
|
|
646
|
-
* Schedule a callback for a NoteEvent.
|
|
647
|
-
*
|
|
648
|
-
* - If the event's time falls within the lookahead window (or has no time), the
|
|
649
|
-
* callback is called synchronously and a no-op StopFn is returned.
|
|
650
|
-
* - Otherwise the event is queued, the interval is started if needed, and a StopFn
|
|
651
|
-
* is returned that removes the event from the queue before it is dispatched.
|
|
652
|
-
*/
|
|
653
637
|
schedule(event, callback) {
|
|
654
638
|
var _a;
|
|
655
639
|
const now = __privateGet(this, _context2).currentTime;
|
|
@@ -665,10 +649,6 @@ var SchedulerImpl = class {
|
|
|
665
649
|
__privateGet(this, _queue).removeAll((q) => q === item);
|
|
666
650
|
};
|
|
667
651
|
}
|
|
668
|
-
/**
|
|
669
|
-
* Clear all queued (not-yet-dispatched) events and stop the interval.
|
|
670
|
-
* Does not affect voices that are already playing.
|
|
671
|
-
*/
|
|
672
652
|
stop() {
|
|
673
653
|
__privateGet(this, _queue).clear();
|
|
674
654
|
if (__privateGet(this, _intervalId) !== void 0) {
|
|
@@ -941,10 +921,12 @@ var SmplrImpl = class {
|
|
|
941
921
|
__privateSet(this, _voices2, new VoiceManager());
|
|
942
922
|
this.loader = (_c = options == null ? void 0 : options.loader) != null ? _c : SampleLoader(context, { storage: options == null ? void 0 : options.storage });
|
|
943
923
|
if (json) {
|
|
944
|
-
this.ready = this.loader.load(json,
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
924
|
+
this.ready = this.loader.load(json, {
|
|
925
|
+
onProgress: (loaded, total) => {
|
|
926
|
+
var _a2;
|
|
927
|
+
__privateSet(this, _loadProgress, { loaded, total });
|
|
928
|
+
(_a2 = __privateGet(this, _onLoadProgress)) == null ? void 0 : _a2.call(this, { loaded, total });
|
|
929
|
+
}
|
|
948
930
|
}).then((buffers) => {
|
|
949
931
|
__privateSet(this, _buffers, buffers);
|
|
950
932
|
});
|
|
@@ -1400,6 +1382,465 @@ function drumMachineToPreset(instrument) {
|
|
|
1400
1382
|
};
|
|
1401
1383
|
}
|
|
1402
1384
|
|
|
1385
|
+
// src/drum-abuse/index.ts
|
|
1386
|
+
var DEFAULT_BASE_URL = "https://smpldsnds.github.io";
|
|
1387
|
+
var MIDI_BASE = 36;
|
|
1388
|
+
var DRUM_ABUSE_PACKS = [
|
|
1389
|
+
"vol1",
|
|
1390
|
+
"vol2",
|
|
1391
|
+
"vol3",
|
|
1392
|
+
"vol4",
|
|
1393
|
+
"vol5"
|
|
1394
|
+
];
|
|
1395
|
+
var MACHINES_BY_PACK = {
|
|
1396
|
+
vol1: [
|
|
1397
|
+
"4-inthefloor-percussioncombo",
|
|
1398
|
+
"ace-tone-rhythm-ace-fr-1",
|
|
1399
|
+
"ace-tone-rhythm-ace-fr-7l",
|
|
1400
|
+
"ace-tone-rhythm-ace-fr6",
|
|
1401
|
+
"ace-tone-rhythm-king",
|
|
1402
|
+
"ace-tone-rhythm-master",
|
|
1403
|
+
"antonelli-2377",
|
|
1404
|
+
"arp-axxe",
|
|
1405
|
+
"conn-min-o-matic",
|
|
1406
|
+
"eko-compu-rhythm",
|
|
1407
|
+
"eko-ritmo-12",
|
|
1408
|
+
"eko-ritmo-20",
|
|
1409
|
+
"elgam-carousel",
|
|
1410
|
+
"emu-modular",
|
|
1411
|
+
"farfisa-pro",
|
|
1412
|
+
"farfisa-rhythm-10",
|
|
1413
|
+
"farfisa-rhythm-maker-16",
|
|
1414
|
+
"gibson-maestro-g-2",
|
|
1415
|
+
"gibson-maestro-rhythm-jester",
|
|
1416
|
+
"gibson-maestro-rhythm-king-mrk-1",
|
|
1417
|
+
"gulbransen-organ",
|
|
1418
|
+
"hammond-rhythm",
|
|
1419
|
+
"hammond-rhythm-ii",
|
|
1420
|
+
"hohner-automatic-rhythm-player",
|
|
1421
|
+
"jen-sx-1000",
|
|
1422
|
+
"kay-r-8",
|
|
1423
|
+
"keio-checkmate",
|
|
1424
|
+
"kent-k-200",
|
|
1425
|
+
"kent-rhythm-master",
|
|
1426
|
+
"korg-kr-33",
|
|
1427
|
+
"korg-krz",
|
|
1428
|
+
"korg-minipops-series",
|
|
1429
|
+
"korg-s-3",
|
|
1430
|
+
"korg-univox-micro-rhythmer-12",
|
|
1431
|
+
"korg-univox-sr-120",
|
|
1432
|
+
"korg-univox-sr-95",
|
|
1433
|
+
"luxor-passat",
|
|
1434
|
+
"moog-modular-55",
|
|
1435
|
+
"roland-arr",
|
|
1436
|
+
"roland-edp-1",
|
|
1437
|
+
"roland-sh-3a",
|
|
1438
|
+
"roland-system-100",
|
|
1439
|
+
"roland-tr-1-prototype",
|
|
1440
|
+
"roland-tr-33",
|
|
1441
|
+
"roland-tr-41-prototype",
|
|
1442
|
+
"roland-tr-66",
|
|
1443
|
+
"roland-tr-77",
|
|
1444
|
+
"seeburg-rhythm-prince",
|
|
1445
|
+
"seeburg-select-a-rhythm",
|
|
1446
|
+
"solton-disco-64",
|
|
1447
|
+
"sonor-mini-mammut-module",
|
|
1448
|
+
"video-tech-rythmic-10",
|
|
1449
|
+
"vox-percussion-king",
|
|
1450
|
+
"whippany-melo-sonic-350",
|
|
1451
|
+
"wurlitzer-swinging-rhythm",
|
|
1452
|
+
"yamaha-cs-15d",
|
|
1453
|
+
"yamaha-cs-5",
|
|
1454
|
+
"yamaha-cs-6",
|
|
1455
|
+
"yamaha-ps-1",
|
|
1456
|
+
"yamaha-ps-2",
|
|
1457
|
+
"yamaha-ps-3"
|
|
1458
|
+
],
|
|
1459
|
+
vol2: [
|
|
1460
|
+
"bontempi-hf222",
|
|
1461
|
+
"boss-dr-55",
|
|
1462
|
+
"casio-mt-18",
|
|
1463
|
+
"casio-pt-30",
|
|
1464
|
+
"casio-vl-1",
|
|
1465
|
+
"chaser-computer-drum-pr-80",
|
|
1466
|
+
"crb-rhythmboy-480",
|
|
1467
|
+
"eko-musicbox-12",
|
|
1468
|
+
"electro-harmonix-drm-15",
|
|
1469
|
+
"electro-harmonix-drm-16",
|
|
1470
|
+
"electro-harmonix-spacedrum",
|
|
1471
|
+
"elka-drumstar-80",
|
|
1472
|
+
"elka-x-1000",
|
|
1473
|
+
"emu-e-drum",
|
|
1474
|
+
"gem-drum-15",
|
|
1475
|
+
"hammond-autovari-64",
|
|
1476
|
+
"hohner-rhythm-80k",
|
|
1477
|
+
"korg-kpr-77",
|
|
1478
|
+
"korg-kr-55",
|
|
1479
|
+
"korg-kr-mini",
|
|
1480
|
+
"korg-monopoly",
|
|
1481
|
+
"korg-ms-10",
|
|
1482
|
+
"korg-trident",
|
|
1483
|
+
"linn-lm-1",
|
|
1484
|
+
"monacor-rhythmical-choice",
|
|
1485
|
+
"mti-auto-orchestra-ao-1",
|
|
1486
|
+
"multi-moog",
|
|
1487
|
+
"mxr-185",
|
|
1488
|
+
"new-england-digital-synclavier",
|
|
1489
|
+
"oberheim-dmx",
|
|
1490
|
+
"pearl-drum-x",
|
|
1491
|
+
"pollard-syndrum-178",
|
|
1492
|
+
"roland-cr-1000",
|
|
1493
|
+
"roland-cr-68",
|
|
1494
|
+
"roland-cr-78",
|
|
1495
|
+
"roland-cr-80",
|
|
1496
|
+
"roland-cr-8000",
|
|
1497
|
+
"roland-dr-55",
|
|
1498
|
+
"roland-jupiter-8",
|
|
1499
|
+
"roland-pb-300-rhythm-plus",
|
|
1500
|
+
"roland-rhy-33",
|
|
1501
|
+
"roland-rhy-55",
|
|
1502
|
+
"roland-sh-09",
|
|
1503
|
+
"roland-tr-55",
|
|
1504
|
+
"roland-tr-606",
|
|
1505
|
+
"roland-tr-808",
|
|
1506
|
+
"simmons-drum",
|
|
1507
|
+
"simmons-sds-1",
|
|
1508
|
+
"simmons-sds-5",
|
|
1509
|
+
"solton-programmer-24",
|
|
1510
|
+
"star-instruments-synare-3",
|
|
1511
|
+
"star-instruments-synare-ps-1",
|
|
1512
|
+
"visco-space-drum",
|
|
1513
|
+
"watford-electronics-rhythm-generator",
|
|
1514
|
+
"yamaha-cs-40m",
|
|
1515
|
+
"yamaha-mr-10",
|
|
1516
|
+
"yamaha-ps-55"
|
|
1517
|
+
],
|
|
1518
|
+
vol3: [
|
|
1519
|
+
"amdek-pck-100",
|
|
1520
|
+
"austin-arb-6",
|
|
1521
|
+
"bme-rattlesnake-parametric-percussion-system",
|
|
1522
|
+
"boss-dr-110",
|
|
1523
|
+
"casio-mt-100",
|
|
1524
|
+
"coron-drumsynce-ds-7",
|
|
1525
|
+
"coron-rds",
|
|
1526
|
+
"denon-crb-90",
|
|
1527
|
+
"drumfire-df-2000",
|
|
1528
|
+
"drumfire-df-500",
|
|
1529
|
+
"electro-harmonix-drm-32",
|
|
1530
|
+
"emu-drumulator",
|
|
1531
|
+
"kay-drm-1",
|
|
1532
|
+
"korg-ddm-110",
|
|
1533
|
+
"korg-ddm-220",
|
|
1534
|
+
"korg-poly-800",
|
|
1535
|
+
"linn-linndrum-lm-1-vinyl",
|
|
1536
|
+
"linn-lm-2",
|
|
1537
|
+
"mattel-electronics-synsonics-drm",
|
|
1538
|
+
"mattel-electronics-synsonics-pro",
|
|
1539
|
+
"panasonic-rd-9844",
|
|
1540
|
+
"pearl-drx-1",
|
|
1541
|
+
"roland-ddr-30",
|
|
1542
|
+
"roland-mc-202",
|
|
1543
|
+
"roland-rhy-77",
|
|
1544
|
+
"roland-tr-909",
|
|
1545
|
+
"rsf-dd-30",
|
|
1546
|
+
"sakata-dpm-48",
|
|
1547
|
+
"sequential-circuits-drumtraks",
|
|
1548
|
+
"simmons-clap-trap",
|
|
1549
|
+
"simmons-sds-200",
|
|
1550
|
+
"simmons-sds-400",
|
|
1551
|
+
"soundmaster-sm-8",
|
|
1552
|
+
"soundmaster-sr-88",
|
|
1553
|
+
"tama-ts-206",
|
|
1554
|
+
"tama-ts-305",
|
|
1555
|
+
"wersi-wm-24",
|
|
1556
|
+
"yamaha-dx7"
|
|
1557
|
+
],
|
|
1558
|
+
vol4: [
|
|
1559
|
+
"atlantex-mpc-1",
|
|
1560
|
+
"boss-hc-2",
|
|
1561
|
+
"boss-pc-2",
|
|
1562
|
+
"casio-ct-310",
|
|
1563
|
+
"casio-mt-500",
|
|
1564
|
+
"casio-mt-800",
|
|
1565
|
+
"casio-pt-68",
|
|
1566
|
+
"casio-pt-82",
|
|
1567
|
+
"casio-sk-1",
|
|
1568
|
+
"dr-b-hm-digital-drums",
|
|
1569
|
+
"emu-sp-12",
|
|
1570
|
+
"ensoniq-mirage",
|
|
1571
|
+
"hing-hon-ek-001",
|
|
1572
|
+
"kawai-acr-20",
|
|
1573
|
+
"kawai-sx-240",
|
|
1574
|
+
"klone-dual-percussion-synthesiser",
|
|
1575
|
+
"korg-ddd-1",
|
|
1576
|
+
"korg-pss-50",
|
|
1577
|
+
"kurzweil-electrodrum-prototype",
|
|
1578
|
+
"linn-9000",
|
|
1579
|
+
"linn-linndrum-lm-2-vinyl",
|
|
1580
|
+
"nasta-hitstix-2",
|
|
1581
|
+
"oberheim-dx",
|
|
1582
|
+
"pearl-sc-40",
|
|
1583
|
+
"rhodes-polaris",
|
|
1584
|
+
"roland-juno-106",
|
|
1585
|
+
"roland-super-quartet-mks-7",
|
|
1586
|
+
"roland-tr-707",
|
|
1587
|
+
"roland-tr-727",
|
|
1588
|
+
"siel-mdp-40",
|
|
1589
|
+
"simmons-sds-1000",
|
|
1590
|
+
"simmons-sds-7",
|
|
1591
|
+
"simmons-sds-8",
|
|
1592
|
+
"simmons-sds-9",
|
|
1593
|
+
"sony-drp-1",
|
|
1594
|
+
"soundmaster-stix-st-305",
|
|
1595
|
+
"suzuki-rpm-40",
|
|
1596
|
+
"tama-ts-500",
|
|
1597
|
+
"technics-ax-5",
|
|
1598
|
+
"technics-pcm-dp-50",
|
|
1599
|
+
"wersi-prisma-dx-5",
|
|
1600
|
+
"yamaha-dd-5",
|
|
1601
|
+
"yamaha-rx-11",
|
|
1602
|
+
"yamaha-rx-15",
|
|
1603
|
+
"yamaha-rx-21",
|
|
1604
|
+
"yamaha-rx-5"
|
|
1605
|
+
],
|
|
1606
|
+
vol5: [
|
|
1607
|
+
"boss-dr-pad-drp-i",
|
|
1608
|
+
"casio-ct-403",
|
|
1609
|
+
"casio-cz-230s",
|
|
1610
|
+
"casio-ht-700",
|
|
1611
|
+
"casio-rz-1",
|
|
1612
|
+
"cheetah-spec-drum",
|
|
1613
|
+
"forat-f-9000",
|
|
1614
|
+
"korg-ddd-5",
|
|
1615
|
+
"korg-dss-1",
|
|
1616
|
+
"m-p-c-electronics-dsm-1",
|
|
1617
|
+
"pearl-sy-1",
|
|
1618
|
+
"roland-tr-505",
|
|
1619
|
+
"sequential-circuits-studio-440",
|
|
1620
|
+
"simmons-sds-2000",
|
|
1621
|
+
"simmons-sdx",
|
|
1622
|
+
"yamaha-pss-130",
|
|
1623
|
+
"yamaha-ptx8",
|
|
1624
|
+
"yamaha-rx-21l"
|
|
1625
|
+
]
|
|
1626
|
+
};
|
|
1627
|
+
var machineToPack = (() => {
|
|
1628
|
+
const m = /* @__PURE__ */ new Map();
|
|
1629
|
+
for (const pack of DRUM_ABUSE_PACKS) {
|
|
1630
|
+
for (const id of MACHINES_BY_PACK[pack]) m.set(id, pack);
|
|
1631
|
+
}
|
|
1632
|
+
return m;
|
|
1633
|
+
})();
|
|
1634
|
+
function getDrumAbuseMachineNames() {
|
|
1635
|
+
return [...machineToPack.keys()];
|
|
1636
|
+
}
|
|
1637
|
+
function getDrumAbuseMachinesForPack(pack) {
|
|
1638
|
+
return MACHINES_BY_PACK[pack];
|
|
1639
|
+
}
|
|
1640
|
+
function getDrumAbusePackNames() {
|
|
1641
|
+
return DRUM_ABUSE_PACKS;
|
|
1642
|
+
}
|
|
1643
|
+
function getDrumAbuseMachinePack(id) {
|
|
1644
|
+
return machineToPack.get(id);
|
|
1645
|
+
}
|
|
1646
|
+
var encSeg = (s) => s.split("/").map(encodeURIComponent).join("/");
|
|
1647
|
+
function packBase(baseUrl, pack) {
|
|
1648
|
+
return `${baseUrl}/drum-abuse-${pack}`;
|
|
1649
|
+
}
|
|
1650
|
+
function sampleBaseUrl(baseUrl, pack, urlPath) {
|
|
1651
|
+
return `${packBase(baseUrl, pack)}/samples/${encSeg(urlPath)}/`;
|
|
1652
|
+
}
|
|
1653
|
+
function drumAbuseSampleUrl(pack, urlPath, fileNoExt, format = "wav", baseUrl = DEFAULT_BASE_URL) {
|
|
1654
|
+
return `${sampleBaseUrl(baseUrl, pack, urlPath)}${encodeURIComponent(fileNoExt)}.${format}`;
|
|
1655
|
+
}
|
|
1656
|
+
function stripExt(filename) {
|
|
1657
|
+
return filename.replace(/\.[^.]+$/, "");
|
|
1658
|
+
}
|
|
1659
|
+
var jsonCache = /* @__PURE__ */ new Map();
|
|
1660
|
+
function fetchJSON(url, storage) {
|
|
1661
|
+
let p = jsonCache.get(url);
|
|
1662
|
+
if (!p) {
|
|
1663
|
+
p = storage.fetch(url).then((r) => {
|
|
1664
|
+
if (r.status >= 400) throw new Error(`DrumAbuse: ${r.status} ${url}`);
|
|
1665
|
+
return r.json();
|
|
1666
|
+
});
|
|
1667
|
+
jsonCache.set(url, p);
|
|
1668
|
+
}
|
|
1669
|
+
return p;
|
|
1670
|
+
}
|
|
1671
|
+
function buildMachinePreset(machine, setPath, baseUrl, pack) {
|
|
1672
|
+
if (machine.sample_sets.length === 0) {
|
|
1673
|
+
throw new Error(`DrumAbuse: machine "${machine.id}" has no sample sets`);
|
|
1674
|
+
}
|
|
1675
|
+
const set = setPath ? machine.sample_sets.find((s) => s.path === setPath) : machine.sample_sets[0];
|
|
1676
|
+
if (!set) {
|
|
1677
|
+
throw new Error(`DrumAbuse: set "${setPath}" not found on "${machine.id}"`);
|
|
1678
|
+
}
|
|
1679
|
+
if (set.samples.length === 0) {
|
|
1680
|
+
throw new Error(
|
|
1681
|
+
`DrumAbuse: set "${set.path}" of "${machine.id}" has no samples`
|
|
1682
|
+
);
|
|
1683
|
+
}
|
|
1684
|
+
const sampleNames = [];
|
|
1685
|
+
const groupNames = [];
|
|
1686
|
+
const sampleNamesForGroup = {};
|
|
1687
|
+
const aliases = {};
|
|
1688
|
+
const regions = set.samples.map((file, i) => {
|
|
1689
|
+
const key = stripExt(file);
|
|
1690
|
+
const midi = MIDI_BASE + i;
|
|
1691
|
+
sampleNames.push(key);
|
|
1692
|
+
aliases[key] = midi;
|
|
1693
|
+
const group = set.sample_instruments[i] || "";
|
|
1694
|
+
if (group) {
|
|
1695
|
+
if (!sampleNamesForGroup[group]) {
|
|
1696
|
+
sampleNamesForGroup[group] = [];
|
|
1697
|
+
groupNames.push(group);
|
|
1698
|
+
aliases[group] = midi;
|
|
1699
|
+
}
|
|
1700
|
+
sampleNamesForGroup[group].push(key);
|
|
1701
|
+
}
|
|
1702
|
+
return {
|
|
1703
|
+
sample: key,
|
|
1704
|
+
keyRange: [midi, midi],
|
|
1705
|
+
pitch: midi
|
|
1706
|
+
};
|
|
1707
|
+
});
|
|
1708
|
+
return {
|
|
1709
|
+
preset: {
|
|
1710
|
+
samples: {
|
|
1711
|
+
baseUrl: sampleBaseUrl(baseUrl, pack, set.url_path),
|
|
1712
|
+
formats: ["wav"]
|
|
1713
|
+
},
|
|
1714
|
+
groups: [{ regions }],
|
|
1715
|
+
aliases
|
|
1716
|
+
},
|
|
1717
|
+
sampleNames,
|
|
1718
|
+
groupNames,
|
|
1719
|
+
sampleNamesForGroup,
|
|
1720
|
+
setPath: set.path
|
|
1721
|
+
};
|
|
1722
|
+
}
|
|
1723
|
+
function buildPackPreset(list, baseUrl, pack) {
|
|
1724
|
+
var _a;
|
|
1725
|
+
if (list.length === 0) {
|
|
1726
|
+
throw new Error(`DrumAbuse: empty pack-instrument list for pack "${pack}"`);
|
|
1727
|
+
}
|
|
1728
|
+
const fileCount = {};
|
|
1729
|
+
for (const s of list) {
|
|
1730
|
+
const f = stripExt(s.file);
|
|
1731
|
+
fileCount[f] = ((_a = fileCount[f]) != null ? _a : 0) + 1;
|
|
1732
|
+
}
|
|
1733
|
+
const sampleNames = [];
|
|
1734
|
+
const groupNames = [];
|
|
1735
|
+
const sampleNamesForGroup = {};
|
|
1736
|
+
const map = {};
|
|
1737
|
+
const aliases = {};
|
|
1738
|
+
const regions = list.map((s, i) => {
|
|
1739
|
+
const fileKey = stripExt(s.file);
|
|
1740
|
+
const uniqueKey = `${s.machine_id}/${fileKey}`;
|
|
1741
|
+
const midi = MIDI_BASE + i;
|
|
1742
|
+
sampleNames.push(uniqueKey);
|
|
1743
|
+
aliases[uniqueKey] = midi;
|
|
1744
|
+
if (fileCount[fileKey] === 1) aliases[fileKey] = midi;
|
|
1745
|
+
map[uniqueKey] = `${packBase(baseUrl, pack)}/samples/${encSeg(s.url_path)}/${encodeURIComponent(s.file)}`;
|
|
1746
|
+
if (!sampleNamesForGroup[s.machine_id]) {
|
|
1747
|
+
sampleNamesForGroup[s.machine_id] = [];
|
|
1748
|
+
groupNames.push(s.machine_id);
|
|
1749
|
+
aliases[s.machine_id] = midi;
|
|
1750
|
+
}
|
|
1751
|
+
sampleNamesForGroup[s.machine_id].push(uniqueKey);
|
|
1752
|
+
return {
|
|
1753
|
+
sample: uniqueKey,
|
|
1754
|
+
keyRange: [midi, midi],
|
|
1755
|
+
pitch: midi
|
|
1756
|
+
};
|
|
1757
|
+
});
|
|
1758
|
+
return {
|
|
1759
|
+
preset: {
|
|
1760
|
+
samples: { baseUrl: "", formats: ["wav"], map },
|
|
1761
|
+
groups: [{ regions }],
|
|
1762
|
+
aliases
|
|
1763
|
+
},
|
|
1764
|
+
sampleNames,
|
|
1765
|
+
groupNames,
|
|
1766
|
+
sampleNamesForGroup,
|
|
1767
|
+
setPath: null
|
|
1768
|
+
};
|
|
1769
|
+
}
|
|
1770
|
+
var DrumAbuse = Instrument(
|
|
1771
|
+
(_ctx, options = {}, smplr) => {
|
|
1772
|
+
var _a, _b;
|
|
1773
|
+
const source = options.source;
|
|
1774
|
+
if (!source) {
|
|
1775
|
+
throw new Error("DrumAbuse: options.source is required");
|
|
1776
|
+
}
|
|
1777
|
+
const baseUrl = (_a = options.baseUrl) != null ? _a : DEFAULT_BASE_URL;
|
|
1778
|
+
const storage = (_b = options.storage) != null ? _b : HttpStorage;
|
|
1779
|
+
let sampleNames = [];
|
|
1780
|
+
let groupNames = [];
|
|
1781
|
+
let sampleNamesForGroup = {};
|
|
1782
|
+
let machineId = null;
|
|
1783
|
+
let setPath = null;
|
|
1784
|
+
let packId;
|
|
1785
|
+
let mode;
|
|
1786
|
+
let presetPromise;
|
|
1787
|
+
if (source.kind === "machine") {
|
|
1788
|
+
mode = "machine";
|
|
1789
|
+
const pack = getDrumAbuseMachinePack(source.machine);
|
|
1790
|
+
if (!pack) {
|
|
1791
|
+
throw new Error(`DrumAbuse: unknown machine "${source.machine}"`);
|
|
1792
|
+
}
|
|
1793
|
+
packId = pack;
|
|
1794
|
+
machineId = source.machine;
|
|
1795
|
+
const url = `${packBase(baseUrl, pack)}/machines/${encodeURIComponent(source.machine)}.json`;
|
|
1796
|
+
presetPromise = fetchJSON(url, storage).then((machine) => {
|
|
1797
|
+
const built = buildMachinePreset(machine, source.set, baseUrl, pack);
|
|
1798
|
+
sampleNames = built.sampleNames;
|
|
1799
|
+
groupNames = built.groupNames;
|
|
1800
|
+
sampleNamesForGroup = built.sampleNamesForGroup;
|
|
1801
|
+
setPath = built.setPath;
|
|
1802
|
+
return built.preset;
|
|
1803
|
+
});
|
|
1804
|
+
} else {
|
|
1805
|
+
mode = "pack";
|
|
1806
|
+
if (!DRUM_ABUSE_PACKS.includes(source.pack)) {
|
|
1807
|
+
throw new Error(`DrumAbuse: unknown pack "${source.pack}"`);
|
|
1808
|
+
}
|
|
1809
|
+
packId = source.pack;
|
|
1810
|
+
const url = `${packBase(baseUrl, source.pack)}/instruments/${encodeURIComponent(source.instrument)}.json`;
|
|
1811
|
+
presetPromise = fetchJSON(url, storage).then((list) => {
|
|
1812
|
+
const built = buildPackPreset(list, baseUrl, source.pack);
|
|
1813
|
+
sampleNames = built.sampleNames;
|
|
1814
|
+
groupNames = built.groupNames;
|
|
1815
|
+
sampleNamesForGroup = built.sampleNamesForGroup;
|
|
1816
|
+
return built.preset;
|
|
1817
|
+
});
|
|
1818
|
+
}
|
|
1819
|
+
const baseStart = smplr.start.bind(smplr);
|
|
1820
|
+
const extras = {
|
|
1821
|
+
get mode() {
|
|
1822
|
+
return mode;
|
|
1823
|
+
},
|
|
1824
|
+
getSampleNames: () => sampleNames.slice(),
|
|
1825
|
+
getGroupNames: () => groupNames.slice(),
|
|
1826
|
+
getSampleNamesForGroup: (g) => {
|
|
1827
|
+
var _a2;
|
|
1828
|
+
return ((_a2 = sampleNamesForGroup[g]) != null ? _a2 : []).slice();
|
|
1829
|
+
},
|
|
1830
|
+
getMachineId: () => machineId,
|
|
1831
|
+
getSetPath: () => setPath,
|
|
1832
|
+
getPackId: () => packId,
|
|
1833
|
+
start: (event) => {
|
|
1834
|
+
var _a2;
|
|
1835
|
+
const ev = typeof event === "object" ? event : { note: event };
|
|
1836
|
+
return baseStart(__spreadProps(__spreadValues({}, ev), { stopId: (_a2 = ev.stopId) != null ? _a2 : ev.note }));
|
|
1837
|
+
}
|
|
1838
|
+
};
|
|
1839
|
+
const ready = presetPromise.then((preset) => smplr.loadInstrument(preset));
|
|
1840
|
+
return { extras, ready };
|
|
1841
|
+
}
|
|
1842
|
+
);
|
|
1843
|
+
|
|
1403
1844
|
// src/offline/wav-encoder.ts
|
|
1404
1845
|
function audioBufferToWav(buffer) {
|
|
1405
1846
|
return encodeWav(buffer, 32);
|
|
@@ -1693,6 +2134,11 @@ var TransportClock = class {
|
|
|
1693
2134
|
*
|
|
1694
2135
|
* Any checkpoints at or after `audioTime` are removed and replaced with this
|
|
1695
2136
|
* new anchor, preserving the BPM that was in effect at that time.
|
|
2137
|
+
*
|
|
2138
|
+
* @internal Leaks checkpoint-list semantics; only called by `Sequencer._flush`
|
|
2139
|
+
* for loop-boundary re-anchoring. Not safe to share between Sequencers — see
|
|
2140
|
+
* thoughts/research/2026-05-17_20-18-43_shared-transport.md §3. Must not be
|
|
2141
|
+
* exported from any barrel.
|
|
1696
2142
|
*/
|
|
1697
2143
|
seekAt(tick, audioTime) {
|
|
1698
2144
|
let bpm = this._bpm;
|
|
@@ -1746,9 +2192,13 @@ var TransportClock = class {
|
|
|
1746
2192
|
return cp.tick + (audioTime - cp.audioTime) / this._secondsPerTick(cp.bpm);
|
|
1747
2193
|
}
|
|
1748
2194
|
/**
|
|
1749
|
-
*
|
|
2195
|
+
* Convert a tick count to seconds at the current (snapshot) BPM.
|
|
2196
|
+
*
|
|
2197
|
+
* Uses `this._bpm` directly, not the checkpoint history — so after a
|
|
2198
|
+
* mid-play BPM change this returns a value based on the *latest* BPM only.
|
|
2199
|
+
* For checkpoint-aware durations, use `tickToAudioTime(end) - tickToAudioTime(start)`.
|
|
1750
2200
|
*/
|
|
1751
|
-
|
|
2201
|
+
ticksToSeconds(ticks) {
|
|
1752
2202
|
return ticks * this._secondsPerTick(this._bpm);
|
|
1753
2203
|
}
|
|
1754
2204
|
// ---------------------------------------------------------------------------
|
|
@@ -2035,6 +2485,7 @@ var SequencerImpl = class {
|
|
|
2035
2485
|
this._clock.stop();
|
|
2036
2486
|
this._stopLoop();
|
|
2037
2487
|
this._endScheduled = false;
|
|
2488
|
+
for (const stopFn of this._activeVoices.values()) stopFn();
|
|
2038
2489
|
this._activeVoices.clear();
|
|
2039
2490
|
this._emitStateChange("stopped");
|
|
2040
2491
|
return this;
|
|
@@ -2301,7 +2752,7 @@ var SequencerImpl = class {
|
|
|
2301
2752
|
if (Math.random() * 100 >= note.chance) continue;
|
|
2302
2753
|
}
|
|
2303
2754
|
const audioTime = this._clock.tickToAudioTime(noteTick);
|
|
2304
|
-
const durationSec = note.duration !== void 0 ? this._clock.
|
|
2755
|
+
const durationSec = note.duration !== void 0 ? this._clock.ticksToSeconds(
|
|
2305
2756
|
parseTicks(note.duration, this._ppq, this._timeSignature)
|
|
2306
2757
|
) : void 0;
|
|
2307
2758
|
const timingOffset = trackHumanize.timing ? (Math.random() * 2 - 1) * trackHumanize.timing / 1e3 : 0;
|
|
@@ -2672,8 +3123,10 @@ function createTremolo(context, depth) {
|
|
|
2672
3123
|
splitter.disconnect(ampR, 1);
|
|
2673
3124
|
ampL.disconnect(merger, 0, 0);
|
|
2674
3125
|
ampR.disconnect(merger, 0, 1);
|
|
2675
|
-
lfoL.disconnect(
|
|
2676
|
-
|
|
3126
|
+
lfoL.disconnect(lfoLAmp);
|
|
3127
|
+
lfoLAmp.disconnect(ampL.gain);
|
|
3128
|
+
lfoR.disconnect(lfoRAmp);
|
|
3129
|
+
lfoRAmp.disconnect(ampR.gain);
|
|
2677
3130
|
merger.disconnect(output);
|
|
2678
3131
|
};
|
|
2679
3132
|
return { input, output };
|
|
@@ -2744,15 +3197,11 @@ var ElectricPiano = Instrument(
|
|
|
2744
3197
|
|
|
2745
3198
|
// src/versilian.ts
|
|
2746
3199
|
var VCSL_BASE_URL = "https://smpldsnds.github.io/sgossner-vcsl";
|
|
2747
|
-
var
|
|
3200
|
+
var instrumentsPromise;
|
|
2748
3201
|
function getVersilianInstruments() {
|
|
2749
|
-
return
|
|
2750
|
-
|
|
2751
|
-
|
|
2752
|
-
(res) => res.json()
|
|
2753
|
-
);
|
|
2754
|
-
return instruments;
|
|
2755
|
-
});
|
|
3202
|
+
return instrumentsPromise != null ? instrumentsPromise : instrumentsPromise = fetch(
|
|
3203
|
+
VCSL_BASE_URL + "/sfz_files.json"
|
|
3204
|
+
).then((res) => res.json());
|
|
2756
3205
|
}
|
|
2757
3206
|
var Versilian = Instrument(
|
|
2758
3207
|
(ctx, options = {}, smplr) => loadVersilianInstrument(smplr, options)
|
|
@@ -2762,11 +3211,11 @@ function loadVersilianInstrument(smplr, options) {
|
|
|
2762
3211
|
const instrument = (_a = options.instrument) != null ? _a : "Strings/Violin/Violin - Arco";
|
|
2763
3212
|
const sfzUrl = `${VCSL_BASE_URL}/${instrument}.sfz`;
|
|
2764
3213
|
const base = instrument.slice(0, instrument.lastIndexOf("/") + 1);
|
|
2765
|
-
const
|
|
3214
|
+
const sampleBaseUrl2 = `${VCSL_BASE_URL}/${base}`;
|
|
2766
3215
|
return fetch(sfzUrl).then((r) => r.text()).then(
|
|
2767
3216
|
(sfzText) => smplr.loadInstrument(
|
|
2768
3217
|
sfzToPreset(sfzText, {
|
|
2769
|
-
baseUrl:
|
|
3218
|
+
baseUrl: sampleBaseUrl2,
|
|
2770
3219
|
pathFromSampleName: (name) => name.replace(/\.wav$/i, ""),
|
|
2771
3220
|
formats: ["ogg", "m4a"]
|
|
2772
3221
|
})
|
|
@@ -2884,7 +3333,7 @@ function mellotronToPreset(sampleNames, config) {
|
|
|
2884
3333
|
for (const sampleName of sampleNames) {
|
|
2885
3334
|
if (config.variation && !sampleName.includes(config.variation)) continue;
|
|
2886
3335
|
const midi = toMidi((_a = sampleName.split(" ")[0]) != null ? _a : "");
|
|
2887
|
-
if (
|
|
3336
|
+
if (midi === void 0) continue;
|
|
2888
3337
|
entries.push([midi, sampleName]);
|
|
2889
3338
|
}
|
|
2890
3339
|
const spread = spreadKeyRanges(entries);
|
|
@@ -2969,7 +3418,7 @@ var ReverbImpl = class {
|
|
|
2969
3418
|
}
|
|
2970
3419
|
getParam(name) {
|
|
2971
3420
|
var _a;
|
|
2972
|
-
return (_a = __privateGet(this, _effect)) == null ? void 0 : _a.parameters.get(
|
|
3421
|
+
return (_a = __privateGet(this, _effect)) == null ? void 0 : _a.parameters.get(name);
|
|
2973
3422
|
}
|
|
2974
3423
|
get isReady() {
|
|
2975
3424
|
return __privateGet(this, _effect) !== void 0;
|
|
@@ -3296,10 +3745,9 @@ function fetchSoundfontLoopData(url, sampleRate = 44100) {
|
|
|
3296
3745
|
const loopData = {};
|
|
3297
3746
|
Object.keys(raw).forEach((key) => {
|
|
3298
3747
|
const midi = toMidi(key);
|
|
3299
|
-
if (midi)
|
|
3300
|
-
|
|
3301
|
-
|
|
3302
|
-
}
|
|
3748
|
+
if (midi === void 0) return;
|
|
3749
|
+
const offsets = raw[key];
|
|
3750
|
+
loopData[midi] = [offsets[0] / sampleRate, offsets[1] / sampleRate];
|
|
3303
3751
|
});
|
|
3304
3752
|
return loopData;
|
|
3305
3753
|
} catch (err) {
|
|
@@ -3344,7 +3792,7 @@ function decodeSoundfontFile(context, config) {
|
|
|
3344
3792
|
yield Promise.all(
|
|
3345
3793
|
noteNames.map((noteName) => __async(null, null, function* () {
|
|
3346
3794
|
const midi = toMidi(noteName);
|
|
3347
|
-
if (
|
|
3795
|
+
if (midi === void 0) return;
|
|
3348
3796
|
try {
|
|
3349
3797
|
const audioData = base64ToArrayBuffer(
|
|
3350
3798
|
removeBase64Prefix(json[noteName])
|
|
@@ -3914,6 +4362,8 @@ var LAYERS = [
|
|
|
3914
4362
|
];
|
|
3915
4363
|
export {
|
|
3916
4364
|
CacheStorage,
|
|
4365
|
+
DRUM_ABUSE_PACKS,
|
|
4366
|
+
DrumAbuse,
|
|
3917
4367
|
DrumMachine,
|
|
3918
4368
|
ElectricPiano,
|
|
3919
4369
|
HttpStorage,
|
|
@@ -3935,7 +4385,12 @@ export {
|
|
|
3935
4385
|
Versilian,
|
|
3936
4386
|
audioBufferToWav,
|
|
3937
4387
|
audioBufferToWav16,
|
|
4388
|
+
drumAbuseSampleUrl,
|
|
3938
4389
|
drumMachineToPreset,
|
|
4390
|
+
getDrumAbuseMachineNames,
|
|
4391
|
+
getDrumAbuseMachinePack,
|
|
4392
|
+
getDrumAbuseMachinesForPack,
|
|
4393
|
+
getDrumAbusePackNames,
|
|
3939
4394
|
getDrumMachineNames,
|
|
3940
4395
|
getElectricPianoNames,
|
|
3941
4396
|
getMalletNames,
|