@banou/ripple 0.0.33 → 0.0.34
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/fkn.json +1 -1
- package/index.js +4 -4
- package/package.json +1 -1
- package/sw.js +1 -1
- package/volume-normalizer-worklet.js +15 -7
package/fkn.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"v":0,"app":"fkn:app:1c7clnsv53zt7dr7q7rcbt455hxauykaxl4gibkuoao24dfmk2eqq","name":"Ripple","version":"0.0.
|
|
1
|
+
{"v":0,"app":"fkn:app:1c7clnsv53zt7dr7q7rcbt455hxauykaxl4gibkuoao24dfmk2eqq","name":"Ripple","version":"0.0.34","key":"vB+5jsZMRya/m8nc1Ba6qNELaua1jUjbGj90dEzuaF0=","issuedAt":1792954107,"perSource":["npm:@banou/ripple"],"url":"https://torrent.fkn.app/","contentsDigest":"SruQF1yJslply6yXv49Z3HbPhbO7Yj4F7cZFy4jTcTA=","sig":"oP2pmlsZrejcK4bWJniLGlNLbBWXv8URKXyC8Pi11hcB3F/JxsJbvizC7VlIvGJ6kbPlqXBmHB2PsVgQxkehAA==","contents":{"name":"@banou/ripple","version":"0.0.34","alg":"sha256","files":{"LICENSE":"ltuFZrZFyUvlPEfixC2u36goYudRNNWKEccYye+T9yY=","README.md":"MOc2IUIf9X9xFe9zaEyEFefq7rv3aCCZdazOrG2oAN0=","_headers":"/3GnajpvIIUp907PK8pIPx9H2wEmJgfEbrC3BKNLlgo=","app.webmanifest":"gIWmbT8RLQZNhLkGKZKO8zLWTEX3F1Dj7RAjIr1zEcQ=","assets/empty-BvRk9kiK.js":"47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=","assets/libtorrent-DleyqKUt.js":"J1FiefhYMfHuzA43oWjvGP2vkTy/Q4d6kMgd91903ZE=","assets/logo.png":"/u2ZiOWTOJxhO6AxbamaptNtn+kUxlrAiPncAEyqwIM=","assets/logo.svg":"3Ciuaqc0v2MjXzWy8x8yLaYwZsDdM0m1H42lzdQPKTg=","assets/sintel.torrent":"TI/a0EFLR2dUag+S/j1mCmbtwyRxh056HPqXEgMXuEo=","assets/worker-kaROsro7.js":"PymzapvqNsx3NdL0caH/r2DAheLG5tF4iiA83cJRZIw=","build-B7te3F-u.js":"R7BWxWTweMWYj6fVhUIDPAcGhMkmlWoq2zyRTe9wFN4=","index.html":"NzDOFOXPmq6jpxfz7igvOO2ti9cLkmZSJm1K3NhBxNE=","index.js":"JnkmbCVCJ1EQNs9ehk9QSUxrs958oZIdsRz741gHvRs=","jassub/default.woff2":"iGkpkDcHxbsosHzS7taZIbPV71xJxzoN0eGH6/ZUakw=","jassub/fonts.js":"JFrcfQn7ONAEVBPA8HdbKDW9YM3BYoIKvVpwHPdwMhw=","jassub/jassub-assets.js":"LkOyTls8XUtOqkH3PzaW5tDCgxL/e+3exAOIUP0F53Q=","jassub/jassub-worker-modern.wasm":"5rQ276ceAydM25k9OFU/eHDzfnmNfIO6eFZlHGa7CH0=","jassub/jassub-worker.js":"OWrfrgp0XQnWqO9puDygfyR+fy0iOz1vJGwO+zzB6MI=","jassub/jassub-worker.wasm":"K35l9lq3yEc228xfK746+VNtsUL2XKhnO1S8oh84+/g=","jassub/noto-sans-jp.otf":"XMmYe4YzRqCA7Qlyqe5Nd8QR04J+KI4HjZjfGZvzdLU=","jassub/worker.js":"MSN6aI3M0DU1AInpnJR1EEH9Kgl6UnewyLveVwYG+H8=","libav-jspi.wasm":"RX1E+c+tnf0//Ymngs1qT7PdAfi+0dNX2rmR6H/qQZs=","libav-worker.js":"wkge2gVzqqyfcgsV7VWjl+AgWPDKbO5hWJUEvg9Dd7o=","libav.wasm":"HjanO8rvPNX9DR3OEOkCiwmnO+hfVaS7KAaU7l2rV70=","package.json":"hvVm3ofTKDwMZOJILFr+ikdiE07/QnIPD+QwAGezwjg=","remote-DvdN47iT.js":"sGSSUKnjoHkfVqnVZ5r1E1NPaQgilhGahOZLnnhXesw=","sw.js":"+M2BPkt9xvnU6xRyLcfX+x7oc0inMzWVXih3NCBTttA=","volume-normalizer-worklet.js":"k5reZ67ViSqNiuk1IuRKIuhGsKtOdD34vTkAPMiwpE4="},"types":{"LICENSE":"application/octet-stream","README.md":"text/markdown","_headers":"application/octet-stream","app.webmanifest":"application/manifest+json","assets/empty-BvRk9kiK.js":"text/javascript","assets/libtorrent-DleyqKUt.js":"text/javascript","assets/logo.png":"image/png","assets/logo.svg":"image/svg+xml","assets/sintel.torrent":"application/octet-stream","assets/worker-kaROsro7.js":"text/javascript","build-B7te3F-u.js":"text/javascript","index.html":"text/html","index.js":"text/javascript","jassub/default.woff2":"font/woff2","jassub/fonts.js":"text/javascript","jassub/jassub-assets.js":"text/javascript","jassub/jassub-worker-modern.wasm":"application/wasm","jassub/jassub-worker.js":"text/javascript","jassub/jassub-worker.wasm":"application/wasm","jassub/noto-sans-jp.otf":"application/octet-stream","jassub/worker.js":"text/javascript","libav-jspi.wasm":"application/wasm","libav-worker.js":"text/javascript","libav.wasm":"application/wasm","package.json":"application/json","remote-DvdN47iT.js":"text/javascript","sw.js":"text/javascript","volume-normalizer-worklet.js":"text/javascript"}},"keys":{"app":"fkn:app:1c7clnsv53zt7dr7q7rcbt455hxauykaxl4gibkuoao24dfmk2eqq","serial":1790278249316,"issuedAt":1790278249,"founder":{"kind":"fkn","seed":"fsqkqngttg4s2gpm23qiz5nonk"},"signer":"fkn-1","name":"Ripple","members":[{"key":"vB+5jsZMRya/m8nc1Ba6qNELaua1jUjbGj90dEzuaF0=","since":1790278249}],"sig":"1ulbdoxt48ngFVZw6Oufds/QhcKE2+KRG7ZQqShFVPeiPyoLGH2IR3m8CmeSOxe3tA7oTmAGKSc4vWZ6pAuFDQ=="}}
|
package/index.js
CHANGED
|
@@ -45597,15 +45597,15 @@ var wq = () => window.location.origin + "/?magnet=%s", Tq = () => typeof window
|
|
|
45597
45597
|
}),
|
|
45598
45598
|
/* @__PURE__ */ K("a", {
|
|
45599
45599
|
className: "build",
|
|
45600
|
-
href: "https://github.com/banou26/ripple/commit/
|
|
45600
|
+
href: "https://github.com/banou26/ripple/commit/b6f3d3f3228aee48da755df4ec296724edf73635",
|
|
45601
45601
|
target: "_blank",
|
|
45602
45602
|
rel: "noreferrer",
|
|
45603
|
-
...hG("commit
|
|
45603
|
+
...hG("commit b6f3d3f3228aee48da755df4ec296724edf73635"),
|
|
45604
45604
|
children: [
|
|
45605
45605
|
"v",
|
|
45606
|
-
"0.0.
|
|
45606
|
+
"0.0.34",
|
|
45607
45607
|
" · ",
|
|
45608
|
-
"
|
|
45608
|
+
"b6f3d3f"
|
|
45609
45609
|
]
|
|
45610
45610
|
}),
|
|
45611
45611
|
/* @__PURE__ */ K("div", {
|
package/package.json
CHANGED
package/sw.js
CHANGED
|
@@ -8,7 +8,7 @@ const live = new Map()
|
|
|
8
8
|
/* Stamped at build time. These are the dev defaults and must never reach production: a worker whose
|
|
9
9
|
BUILD never changes is never reinstalled, so the update this feature announces would never fire. */
|
|
10
10
|
const MODE = "cache" // @stamp:mode
|
|
11
|
-
const BUILD = "
|
|
11
|
+
const BUILD = "7abdce2fbfa281a1" // @stamp:build
|
|
12
12
|
const MANIFEST = [["/assets/empty-BvRk9kiK.js","e3b0c44298fc1c14"],["/assets/libtorrent-DleyqKUt.js","27516279f85831f1"],["/assets/worker-kaROsro7.js","3f29b36a9bea36cc"],["/build-B7te3F-u.js","47b056c564f078c5"],["/remote-DvdN47iT.js","b0649250a9e3a079"]] // @stamp:manifest
|
|
13
13
|
|
|
14
14
|
const CACHE = 'ripple-assets-' + BUILD
|
|
@@ -20,6 +20,13 @@
|
|
|
20
20
|
const BINS_PER_SECOND = 1000
|
|
21
21
|
// the analysis's unit of work and of what the worklet holds: 10 s of 1 ms bins
|
|
22
22
|
const BLOCK_BINS = 10_000
|
|
23
|
+
/*
|
|
24
|
+
* The blocks the worklet keeps, those it was sent nearest the playhead, 4.8 MB of cut and fingerprint: as it plays,
|
|
25
|
+
* the 30 to 40 s sent ahead of it and 560 to 570 s behind. Under load Chrome plays a seek into audio it still has
|
|
26
|
+
* buffered before a block let go of is computed again: kept only 20 to 30 s behind and 30 to 40 s ahead, 3 to 32 ms of
|
|
27
|
+
* such a seek played on the live stage alone, in 51 of 75 seeks 24 to 44 s away on 4 loaded CPUs (HOR-681, 2026-10-25).
|
|
28
|
+
*/
|
|
29
|
+
const KEPT_BLOCKS = 60
|
|
23
30
|
/*
|
|
24
31
|
* How far a cut reaches from the audio that asks for it, in bins. The slow stage reads 1.85 s ahead and 1.65 s
|
|
25
32
|
* behind, and its exponential attack (0.3 s, backward) and release (0.5 s, forward) fall under 0.01 dB of a 20 dB cut
|
|
@@ -433,7 +440,8 @@ export const audioSamplesOf = (fragment, track) => {
|
|
|
433
440
|
/**
|
|
434
441
|
* The analysis: 1 ms bins of whatever audio it is given, the normal level learned from them, and the cut for the
|
|
435
442
|
* blocks around the playhead. `toWorklet` takes `{ block, gain, finger }` (10 s of bins from `block * 10` s, NaN where
|
|
436
|
-
* the cut or the audio is not known) and `{ drop }
|
|
443
|
+
* the cut or the audio is not known) and `{ drop }` for each block past the 60 sent nearest the playhead, which is all
|
|
444
|
+
* the worklet keeps; `toPage` takes the coverage reports the page schedules reads on.
|
|
437
445
|
* Separate from the worker's messages so a test can drive it with decoded audio.
|
|
438
446
|
*/
|
|
439
447
|
export const createAnalysis = ({ toWorklet, toPage = () => {} }) => {
|
|
@@ -557,13 +565,8 @@ export const createAnalysis = ({ toWorklet, toPage = () => {} }) => {
|
|
|
557
565
|
const update = () => {
|
|
558
566
|
timer = undefined
|
|
559
567
|
const level = normal()
|
|
560
|
-
const here = Math.floor(playhead * BINS_PER_SECOND / BLOCK_BINS)
|
|
561
|
-
for (const block of [...sent.keys()]) {
|
|
562
|
-
if (block >= here - 2 && block <= here + 4) continue
|
|
563
|
-
sent.delete(block)
|
|
564
|
-
toWorklet({ drop: block })
|
|
565
|
-
}
|
|
566
568
|
if (!Number.isFinite(level)) return
|
|
569
|
+
const here = Math.floor(playhead * BINS_PER_SECOND / BLOCK_BINS)
|
|
567
570
|
// the playhead's own block first: under load each took 21 to 43 ms, and sent after the one before it, a seek's
|
|
568
571
|
// cut over HTTP reached the worklet 64 to 75 ms after the seek, its audio 72 to 83 ms (HOR-888, 2026-10-23)
|
|
569
572
|
for (const block of [here, here - 1, here + 1, here + 2, here + 3]) {
|
|
@@ -577,6 +580,11 @@ export const createAnalysis = ({ toWorklet, toPage = () => {} }) => {
|
|
|
577
580
|
sent.set(block, { known, level })
|
|
578
581
|
toWorklet({ block, gain, finger }, [gain.buffer, finger.buffer])
|
|
579
582
|
}
|
|
583
|
+
const nearest = [...sent.keys()].sort((a, b) => Math.abs(a - here) - Math.abs(b - here))
|
|
584
|
+
for (const block of nearest.slice(KEPT_BLOCKS)) {
|
|
585
|
+
sent.delete(block)
|
|
586
|
+
toWorklet({ drop: block })
|
|
587
|
+
}
|
|
580
588
|
}
|
|
581
589
|
const schedule = () => { timer ??= setTimeout(update, 250) }
|
|
582
590
|
|