sounds list can now filter out defaults

This commit is contained in:
Felix Roos 2023-03-08 00:33:21 +01:00
parent 35ef26c013
commit cee08ea67d
7 changed files with 76 additions and 22 deletions

View File

@ -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,
});
});
};

View File

@ -32,7 +32,7 @@ export function registerSynthSounds() {
//chain.push(adsr);
return o.connect(g).connect(adsr);
},
{ type: 'synth' },
{ type: 'synth', prebake: true },
);
});
}

View File

@ -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",

View File

@ -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]) => (
<Fragment key={category}>
<h3 className="pb-2 pt-4 text-lg">{category}:</h3>
</Fragment>
))}
*/
const getSamples = (samples) =>
Array.isArray(samples) ? samples.length : typeof samples === 'object' ? Object.values(samples).length : 1;
function SoundsTab() {
const sounds = useStore(soundMap);
const getSamples = (samples) =>
Array.isArray(samples) ? samples.length : typeof samples === 'object' ? Object.values(samples).length : 1;
const { soundsFilter } = useSettings();
const soundEntries = useMemo(() => {
if (!sounds) {
return [];
}
if (soundsFilter === 'hideDefaults') {
return Object.entries(sounds).filter(([_, { data }]) => !data.prebake);
}
return Object.entries(sounds);
}, [sounds, soundsFilter]);
return (
<div id="sounds-tab" className="break-normal w-full px-4 dark:text-white text-stone-900">
{/* <span>{loadedSamples.length} banks loaded:</span> */}
{Object.entries(sounds).map(([name, { data }]) => (
<span key={name} className="cursor-pointer hover:opacity-50" onClick={() => {}}>
{' '}
{name} {data?.type === 'sample' ? `(${getSamples(data.samples)})` : ''}
</span>
))}
<ButtonGroup
value={soundsFilter}
onChange={(value) => settingsMap.setKey('soundsFilter', value)}
items={{ all: 'All', hideDefaults: 'Hide Defaults' }}
></ButtonGroup>
<div className="pt-4">
{soundEntries.map(([name, { data }]) => (
<span key={name} className="cursor-pointer hover:opacity-50" onClick={() => {}}>
{' '}
{name}
{data?.type === 'sample' ? `(${getSamples(data.samples)})` : ''}
</span>
))}
{!soundEntries.length ? 'No Sounds' : ''}
</div>
</div>
);
}

View File

@ -4,17 +4,17 @@ import { registerSynthSounds, samples } from '@strudel.cycles/webaudio';
export async function prebake() {
// https://archive.org/details/SalamanderGrandPianoV3
// License: CC-by http://creativecommons.org/licenses/by/3.0/ Author: Alexander Holm
registerSynthSounds();
await Promise.all([
samples(`./piano.json`, `./piano/`),
samples(`./piano.json`, `./piano/`, { prebake: true }),
// https://github.com/sgossner/VCSL/
// https://api.github.com/repositories/126427031/contents/
// LICENSE: CC0 general-purpose
samples(`./vcsl.json`, 'github:sgossner/VCSL/master/'),
samples(`./tidal-drum-machines.json`, 'github:ritchse/tidal-drum-machines/main/machines/'),
samples(`./EmuSP12.json`, `./EmuSP12/`),
samples(`./vcsl.json`, 'github:sgossner/VCSL/master/', { prebake: true }),
samples(`./tidal-drum-machines.json`, 'github:ritchse/tidal-drum-machines/main/machines/', { prebake: true }),
samples(`./EmuSP12.json`, `./EmuSP12/`, { prebake: true }),
// samples('github:tidalcycles/Dirt-Samples/master'),
]);
registerSynthSounds();
}
const maxPan = toMidi('C8');

View File

@ -9,6 +9,7 @@ export const defaultSettings = {
fontSize: 18,
latestCode: '',
isZen: false,
soundsFilter: 'all',
};
export const settingsMap = persistentMap('strudel-settings', defaultSettings);

View File

@ -22,7 +22,6 @@
--app-height: 100vh;
}
#console-tab,
#sounds-tab {
#console-tab {
font-family: BigBlueTerminal, monospace;
}