diff --git a/packages/webaudio/sampler.mjs b/packages/webaudio/sampler.mjs
index eaaaf8dd..cff090d7 100644
--- a/packages/webaudio/sampler.mjs
+++ b/packages/webaudio/sampler.mjs
@@ -105,7 +105,7 @@ export const getLoadedBuffer = (url) => {
*
*/
-export const samples = async (sampleMap, baseUrl = sampleMap._base || '') => {
+export const samples = async (sampleMap, baseUrl = sampleMap._base || '', options = {}) => {
if (typeof sampleMap === 'string') {
if (sampleMap.startsWith('github:')) {
let [_, path] = sampleMap.split('github:');
@@ -123,12 +123,13 @@ export const samples = async (sampleMap, baseUrl = sampleMap._base || '') => {
}
return fetch(sampleMap)
.then((res) => res.json())
- .then((json) => samples(json, baseUrl || json._base || base))
+ .then((json) => samples(json, baseUrl || json._base || base, options))
.catch((error) => {
console.error(error);
throw new Error(`error loading "${sampleMap}"`);
});
}
+ const { prebake } = options;
Object.entries(sampleMap).forEach(([key, value]) => {
if (typeof value === 'string') {
value = [value];
@@ -149,7 +150,12 @@ export const samples = async (sampleMap, baseUrl = sampleMap._base || '') => {
}),
);
}
- setSound(key, (options) => onTriggerSample(options, value), { type: 'sample', samples: value });
+ setSound(key, (options) => onTriggerSample(options, value), {
+ type: 'sample',
+ samples: value,
+ baseUrl,
+ prebake,
+ });
});
};
diff --git a/packages/webaudio/synth.mjs b/packages/webaudio/synth.mjs
index b840a6aa..d615661a 100644
--- a/packages/webaudio/synth.mjs
+++ b/packages/webaudio/synth.mjs
@@ -32,7 +32,7 @@ export function registerSynthSounds() {
//chain.push(adsr);
return o.connect(g).connect(adsr);
},
- { type: 'synth' },
+ { type: 'synth', prebake: true },
);
});
}
diff --git a/website/public/vcsl.json b/website/public/vcsl.json
index 9ab06549..983cde89 100644
--- a/website/public/vcsl.json
+++ b/website/public/vcsl.json
@@ -1986,7 +1986,7 @@
"Idiophones/Struck%20Idiophones/Tambourine%202/Tamb2_Shake_rr3_Mid.wav",
"Idiophones/Struck%20Idiophones/Tambourine%202/Tamb2_Shake_rr4_Mid.wav"
],
- "triangle": [
+ "triangles": [
"Idiophones/Struck%20Idiophones/Triangles/Triangle1_HitFM_v1_rr1_Mid.wav",
"Idiophones/Struck%20Idiophones/Triangles/Triangle1_HitFM_v1_rr2_Mid.wav",
"Idiophones/Struck%20Idiophones/Triangles/Triangle1_HitM_v1_rr2_Mid.wav",
diff --git a/website/src/repl/Footer.jsx b/website/src/repl/Footer.jsx
index 947b6b87..f5454541 100644
--- a/website/src/repl/Footer.jsx
+++ b/website/src/repl/Footer.jsx
@@ -3,7 +3,7 @@ import { logger } from '@strudel.cycles/core';
import { useEvent, cx } from '@strudel.cycles/react';
// import { cx } from '@strudel.cycles/react';
import { nanoid } from 'nanoid';
-import React, { useCallback, useLayoutEffect, useRef, useState } from 'react';
+import React, { useMemo, useCallback, useLayoutEffect, useRef, useState } from 'react';
import { Reference } from './Reference';
import { themes } from './themes.mjs';
import { useSettings, settingsMap, setActiveFooter, defaultSettings } from '../settings.mjs';
@@ -194,19 +194,67 @@ function ConsoleTab({ log }) {
);
}
+/*
+function groupBy(obj = {}, getter) {
+ const grouped = Object.entries(obj).reduce((acc, [key, value]) => {
+ const propValue = getter(value, key);
+ if (!acc.has(propValue)) {
+ acc.set(propValue, new Map());
+ }
+ acc.get(propValue).set(key, value);
+ return acc;
+ }, new Map());
+ return grouped;
+}
+ const grouped = useMemo(() => {
+ if (!sounds) {
+ return {};
+ }
+ return groupBy(sounds, (s) =>
+ s.data.type === 'sample' ? 'Samples from ' + s.data?.baseUrl : 'Type ' + s.data.type,
+ );
+}, [sounds]);
+
+ {Array.from(grouped).map(([category, sounds]) => (
+ {category}:
+