mirror of
https://codeberg.org/uzu/strudel
synced 2026-07-23 13:42:56 -04:00
Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 29d9100e44 | |||
| ef585cc779 |
@@ -34,7 +34,8 @@
|
|||||||
},
|
},
|
||||||
"homepage": "https://github.com/tidalcycles/strudel#readme",
|
"homepage": "https://github.com/tidalcycles/strudel#readme",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@strudel.cycles/core": "workspace:*"
|
"@strudel.cycles/core": "workspace:*",
|
||||||
|
"idb-keyval": "^6.2.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"vite": "^3.2.2"
|
"vite": "^3.2.2"
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { logger, toMidi, valueToMidi } from '@strudel.cycles/core';
|
import { logger, toMidi, valueToMidi } from '@strudel.cycles/core';
|
||||||
import { getAudioContext } from './index.mjs';
|
import { getAudioContext } from './index.mjs';
|
||||||
|
import { get, set } from 'idb-keyval';
|
||||||
|
|
||||||
const bufferCache = {}; // string: Promise<ArrayBuffer>
|
const bufferCache = {}; // string: Promise<ArrayBuffer>
|
||||||
const loadCache = {}; // string: Promise<ArrayBuffer>
|
const loadCache = {}; // string: Promise<ArrayBuffer>
|
||||||
@@ -74,22 +75,37 @@ export const getSampleBufferSource = async (s, n, note, speed, freq) => {
|
|||||||
return bufferSource;
|
return bufferSource;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const loadBuffer = (url, ac, s, n = 0) => {
|
const useOfflineCache = true;
|
||||||
|
|
||||||
|
export const loadBuffer = async (url, ac, s, n = 0) => {
|
||||||
const label = s ? `sound "${s}:${n}"` : 'sample';
|
const label = s ? `sound "${s}:${n}"` : 'sample';
|
||||||
|
// only load if not already requested (loadCache = cache promises loading buffers by url)
|
||||||
if (!loadCache[url]) {
|
if (!loadCache[url]) {
|
||||||
logger(`[sampler] load ${label}..`, 'load-sample', { url });
|
loadCache[url] = (async () => {
|
||||||
const timestamp = Date.now();
|
logger(`[sampler] load ${label}..`, 'load-sample', { url });
|
||||||
loadCache[url] = fetch(url)
|
const timestamp = Date.now();
|
||||||
.then((res) => res.arrayBuffer())
|
if (useOfflineCache) {
|
||||||
.then(async (res) => {
|
const cachedDataUrl = await get(url);
|
||||||
const took = Date.now() - timestamp;
|
if (cachedDataUrl) {
|
||||||
const size = humanFileSize(res.byteLength);
|
// buffer has been loaded into offline cache in a previous session
|
||||||
// const downSpeed = humanFileSize(res.byteLength / took);
|
logger(`[sampler] load ${label}... done! found in offline cache!`, 'loaded-sample', { url });
|
||||||
logger(`[sampler] load ${label}... done! loaded ${size} in ${took}ms`, 'loaded-sample', { url });
|
return dataUrlToAudioBuffer(ac, cachedDataUrl);
|
||||||
const decoded = await ac.decodeAudioData(res);
|
}
|
||||||
bufferCache[url] = decoded;
|
}
|
||||||
return decoded;
|
// buffer not cached offline => fetch from url =>
|
||||||
});
|
const res = await fetch(url);
|
||||||
|
const buf = await res.arrayBuffer();
|
||||||
|
if (useOfflineCache) {
|
||||||
|
// we don't need to wait for the offline cache to finish here
|
||||||
|
bufferToDataUrl(buf).then((dataUrl) => set(url, dataUrl));
|
||||||
|
}
|
||||||
|
const audioBuffer = await ac.decodeAudioData(buf);
|
||||||
|
const took = Date.now() - timestamp;
|
||||||
|
const size = humanFileSize(buf.byteLength);
|
||||||
|
logger(`[sampler] load ${label}... done! loaded ${size} in ${took}ms`, 'loaded-sample', { url });
|
||||||
|
bufferCache[url] = audioBuffer;
|
||||||
|
return audioBuffer;
|
||||||
|
})();
|
||||||
}
|
}
|
||||||
return loadCache[url];
|
return loadCache[url];
|
||||||
};
|
};
|
||||||
@@ -179,3 +195,20 @@ export const resetLoadedSamples = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const getLoadedSamples = () => sampleCache.current;
|
export const getLoadedSamples = () => sampleCache.current;
|
||||||
|
|
||||||
|
async function bufferToDataUrl(buf) {
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
var blob = new Blob([buf], { type: 'application/octet-binary' });
|
||||||
|
var reader = new FileReader();
|
||||||
|
reader.onload = function (event) {
|
||||||
|
resolve(event.target.result);
|
||||||
|
};
|
||||||
|
reader.readAsDataURL(blob);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function dataUrlToAudioBuffer(ctx, dataUrl) {
|
||||||
|
return fetch(dataUrl)
|
||||||
|
.then((res) => res.arrayBuffer())
|
||||||
|
.then((res) => ctx.decodeAudioData(res));
|
||||||
|
}
|
||||||
|
|||||||
Generated
+66
-4
@@ -313,9 +313,11 @@ importers:
|
|||||||
packages/webaudio:
|
packages/webaudio:
|
||||||
specifiers:
|
specifiers:
|
||||||
'@strudel.cycles/core': workspace:*
|
'@strudel.cycles/core': workspace:*
|
||||||
|
idb-keyval: ^6.2.0
|
||||||
vite: ^3.2.2
|
vite: ^3.2.2
|
||||||
dependencies:
|
dependencies:
|
||||||
'@strudel.cycles/core': link:../core
|
'@strudel.cycles/core': link:../core
|
||||||
|
idb-keyval: 6.2.0
|
||||||
devDependencies:
|
devDependencies:
|
||||||
vite: 3.2.5
|
vite: 3.2.5
|
||||||
|
|
||||||
@@ -7448,6 +7450,12 @@ packages:
|
|||||||
dev: true
|
dev: true
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
|
/idb-keyval/6.2.0:
|
||||||
|
resolution: {integrity: sha512-uw+MIyQn2jl3+hroD7hF8J7PUviBU7BPKWw4f/ISf32D4LoGu98yHjrzWWJDASu9QNrX10tCJqk9YY0ClWm8Ng==}
|
||||||
|
dependencies:
|
||||||
|
safari-14-idb-fix: 3.0.0
|
||||||
|
dev: false
|
||||||
|
|
||||||
/idb/7.1.1:
|
/idb/7.1.1:
|
||||||
resolution: {integrity: sha512-gchesWBzyvGHRO9W8tzUWFDycow5gwjvFKfyV9FF32Y7F50yZMp7mP+T2mJIWFx49zicqyC4uefHM17o6xKIVQ==}
|
resolution: {integrity: sha512-gchesWBzyvGHRO9W8tzUWFDycow5gwjvFKfyV9FF32Y7F50yZMp7mP+T2mJIWFx49zicqyC4uefHM17o6xKIVQ==}
|
||||||
dev: true
|
dev: true
|
||||||
@@ -10221,6 +10229,17 @@ packages:
|
|||||||
- supports-color
|
- supports-color
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/postcss-import/14.1.0:
|
||||||
|
resolution: {integrity: sha512-flwI+Vgm4SElObFVPpTIT7SU7R3qk2L7PyduMcokiaVKuWv9d/U+Gm/QAd8NDLuykTWTkcrjOeD2Pp1rMeBTGw==}
|
||||||
|
engines: {node: '>=10.0.0'}
|
||||||
|
peerDependencies:
|
||||||
|
postcss: ^8.0.0
|
||||||
|
dependencies:
|
||||||
|
postcss-value-parser: 4.2.0
|
||||||
|
read-cache: 1.0.0
|
||||||
|
resolve: 1.22.1
|
||||||
|
dev: false
|
||||||
|
|
||||||
/postcss-import/14.1.0_postcss@8.4.21:
|
/postcss-import/14.1.0_postcss@8.4.21:
|
||||||
resolution: {integrity: sha512-flwI+Vgm4SElObFVPpTIT7SU7R3qk2L7PyduMcokiaVKuWv9d/U+Gm/QAd8NDLuykTWTkcrjOeD2Pp1rMeBTGw==}
|
resolution: {integrity: sha512-flwI+Vgm4SElObFVPpTIT7SU7R3qk2L7PyduMcokiaVKuWv9d/U+Gm/QAd8NDLuykTWTkcrjOeD2Pp1rMeBTGw==}
|
||||||
engines: {node: '>=10.0.0'}
|
engines: {node: '>=10.0.0'}
|
||||||
@@ -10231,6 +10250,16 @@ packages:
|
|||||||
postcss-value-parser: 4.2.0
|
postcss-value-parser: 4.2.0
|
||||||
read-cache: 1.0.0
|
read-cache: 1.0.0
|
||||||
resolve: 1.22.1
|
resolve: 1.22.1
|
||||||
|
dev: true
|
||||||
|
|
||||||
|
/postcss-js/4.0.0:
|
||||||
|
resolution: {integrity: sha512-77QESFBwgX4irogGVPgQ5s07vLvFqWr228qZY+w6lW599cRlK/HmnlivnnVUxkjHnCu4J16PDMHcH+e+2HbvTQ==}
|
||||||
|
engines: {node: ^12 || ^14 || >= 16}
|
||||||
|
peerDependencies:
|
||||||
|
postcss: ^8.3.3
|
||||||
|
dependencies:
|
||||||
|
camelcase-css: 2.0.1
|
||||||
|
dev: false
|
||||||
|
|
||||||
/postcss-js/4.0.0_postcss@8.4.21:
|
/postcss-js/4.0.0_postcss@8.4.21:
|
||||||
resolution: {integrity: sha512-77QESFBwgX4irogGVPgQ5s07vLvFqWr228qZY+w6lW599cRlK/HmnlivnnVUxkjHnCu4J16PDMHcH+e+2HbvTQ==}
|
resolution: {integrity: sha512-77QESFBwgX4irogGVPgQ5s07vLvFqWr228qZY+w6lW599cRlK/HmnlivnnVUxkjHnCu4J16PDMHcH+e+2HbvTQ==}
|
||||||
@@ -10240,6 +10269,23 @@ packages:
|
|||||||
dependencies:
|
dependencies:
|
||||||
camelcase-css: 2.0.1
|
camelcase-css: 2.0.1
|
||||||
postcss: 8.4.21
|
postcss: 8.4.21
|
||||||
|
dev: true
|
||||||
|
|
||||||
|
/postcss-load-config/3.1.4:
|
||||||
|
resolution: {integrity: sha512-6DiM4E7v4coTE4uzA8U//WhtPwyhiim3eyjEMFCnUpzbrkK9wJHgKDT2mR+HbtSrd/NubVaYTOpSpjUl8NQeRg==}
|
||||||
|
engines: {node: '>= 10'}
|
||||||
|
peerDependencies:
|
||||||
|
postcss: '>=8.0.9'
|
||||||
|
ts-node: '>=9.0.0'
|
||||||
|
peerDependenciesMeta:
|
||||||
|
postcss:
|
||||||
|
optional: true
|
||||||
|
ts-node:
|
||||||
|
optional: true
|
||||||
|
dependencies:
|
||||||
|
lilconfig: 2.0.6
|
||||||
|
yaml: 1.10.2
|
||||||
|
dev: false
|
||||||
|
|
||||||
/postcss-load-config/3.1.4_postcss@8.4.21:
|
/postcss-load-config/3.1.4_postcss@8.4.21:
|
||||||
resolution: {integrity: sha512-6DiM4E7v4coTE4uzA8U//WhtPwyhiim3eyjEMFCnUpzbrkK9wJHgKDT2mR+HbtSrd/NubVaYTOpSpjUl8NQeRg==}
|
resolution: {integrity: sha512-6DiM4E7v4coTE4uzA8U//WhtPwyhiim3eyjEMFCnUpzbrkK9wJHgKDT2mR+HbtSrd/NubVaYTOpSpjUl8NQeRg==}
|
||||||
@@ -10257,6 +10303,15 @@ packages:
|
|||||||
postcss: 8.4.21
|
postcss: 8.4.21
|
||||||
yaml: 1.10.2
|
yaml: 1.10.2
|
||||||
|
|
||||||
|
/postcss-nested/6.0.0:
|
||||||
|
resolution: {integrity: sha512-0DkamqrPcmkBDsLn+vQDIrtkSbNkv5AD/M322ySo9kqFkCIYklym2xEmWkwo+Y3/qZo34tzEPNUw4y7yMCdv5w==}
|
||||||
|
engines: {node: '>=12.0'}
|
||||||
|
peerDependencies:
|
||||||
|
postcss: ^8.2.14
|
||||||
|
dependencies:
|
||||||
|
postcss-selector-parser: 6.0.11
|
||||||
|
dev: false
|
||||||
|
|
||||||
/postcss-nested/6.0.0_postcss@8.4.21:
|
/postcss-nested/6.0.0_postcss@8.4.21:
|
||||||
resolution: {integrity: sha512-0DkamqrPcmkBDsLn+vQDIrtkSbNkv5AD/M322ySo9kqFkCIYklym2xEmWkwo+Y3/qZo34tzEPNUw4y7yMCdv5w==}
|
resolution: {integrity: sha512-0DkamqrPcmkBDsLn+vQDIrtkSbNkv5AD/M322ySo9kqFkCIYklym2xEmWkwo+Y3/qZo34tzEPNUw4y7yMCdv5w==}
|
||||||
engines: {node: '>=12.0'}
|
engines: {node: '>=12.0'}
|
||||||
@@ -10265,6 +10320,7 @@ packages:
|
|||||||
dependencies:
|
dependencies:
|
||||||
postcss: 8.4.21
|
postcss: 8.4.21
|
||||||
postcss-selector-parser: 6.0.11
|
postcss-selector-parser: 6.0.11
|
||||||
|
dev: true
|
||||||
|
|
||||||
/postcss-selector-parser/6.0.10:
|
/postcss-selector-parser/6.0.10:
|
||||||
resolution: {integrity: sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==}
|
resolution: {integrity: sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==}
|
||||||
@@ -11210,6 +11266,10 @@ packages:
|
|||||||
mri: 1.2.0
|
mri: 1.2.0
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/safari-14-idb-fix/3.0.0:
|
||||||
|
resolution: {integrity: sha512-eBNFLob4PMq8JA1dGyFn6G97q3/WzNtFK4RnzT1fnLq+9RyrGknzYiM/9B12MnKAxuj1IXr7UKYtTNtjyKMBog==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/safe-buffer/5.1.2:
|
/safe-buffer/5.1.2:
|
||||||
resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==}
|
resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==}
|
||||||
|
|
||||||
@@ -11873,6 +11933,8 @@ packages:
|
|||||||
resolution: {integrity: sha512-AhwtHCKMtR71JgeYDaswmZXhPcW9iuI9Sp2LvZPo9upDZ7231ZJ7eA9RaURbhpXGVlrjX4cFNlB4ieTetEb7hQ==}
|
resolution: {integrity: sha512-AhwtHCKMtR71JgeYDaswmZXhPcW9iuI9Sp2LvZPo9upDZ7231ZJ7eA9RaURbhpXGVlrjX4cFNlB4ieTetEb7hQ==}
|
||||||
engines: {node: '>=12.13.0'}
|
engines: {node: '>=12.13.0'}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
|
peerDependencies:
|
||||||
|
postcss: ^8.0.9
|
||||||
dependencies:
|
dependencies:
|
||||||
arg: 5.0.2
|
arg: 5.0.2
|
||||||
chokidar: 3.5.3
|
chokidar: 3.5.3
|
||||||
@@ -11889,10 +11951,10 @@ packages:
|
|||||||
object-hash: 3.0.0
|
object-hash: 3.0.0
|
||||||
picocolors: 1.0.0
|
picocolors: 1.0.0
|
||||||
postcss: 8.4.21
|
postcss: 8.4.21
|
||||||
postcss-import: 14.1.0_postcss@8.4.21
|
postcss-import: 14.1.0
|
||||||
postcss-js: 4.0.0_postcss@8.4.21
|
postcss-js: 4.0.0
|
||||||
postcss-load-config: 3.1.4_postcss@8.4.21
|
postcss-load-config: 3.1.4
|
||||||
postcss-nested: 6.0.0_postcss@8.4.21
|
postcss-nested: 6.0.0
|
||||||
postcss-selector-parser: 6.0.11
|
postcss-selector-parser: 6.0.11
|
||||||
postcss-value-parser: 4.2.0
|
postcss-value-parser: 4.2.0
|
||||||
quick-lru: 5.1.1
|
quick-lru: 5.1.1
|
||||||
|
|||||||
Reference in New Issue
Block a user