Skip to content

Commit

Permalink
feat: soundfont2 example allow custom urls
Browse files Browse the repository at this point in the history
  • Loading branch information
danigb committed Oct 6, 2024
1 parent c1108a8 commit 121da6b
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 7 deletions.
1 change: 1 addition & 0 deletions site/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
},
"dependencies": {
"smplr": "link:..",
"soundfont2": "^0.4.0",
"tonal": "^6.2.0",
"webmidi": "^3.1.11"
},
Expand Down
8 changes: 8 additions & 0 deletions site/pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

43 changes: 36 additions & 7 deletions site/src/Soundfont2Example.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,16 +35,22 @@ export function Soundfont2Example({ className }: { className?: string }) {
const [status, setStatus] = useStatus();
const [reverbMix, setReverbMix] = useState(0);
const [volume, setVolume] = useState(100);
const [isCustomEnabled, setCustomEnabled] = useState(false);
const [customUrl, setCustomUrl] = useState(
"https://smpldsnds.github.io/soundfonts/soundfonts/yamaha-grand-lite.sf2"
);

function loadSampler(sf2Name: string) {
function loadSampler(nameOrUrl: string) {
if (sampler) sampler.disconnect();
setStatus("loading");
const context = getAudioContext();
setSamplerName(sf2Name);
const isUrl = nameOrUrl.startsWith("http");
setSamplerName(isUrl ? "_custom" : nameOrUrl);

reverb ??= new Reverb(context);
const url = isUrl ? nameOrUrl : SF2_INSTRUMENTS[nameOrUrl];
const newSampler = new Soundfont2Sampler(context, {
url: SF2_INSTRUMENTS[sf2Name],
url,
createSoundfont: (data) => new SoundFont2(data),
});
newSampler.output.addEffect("reverb", reverb, reverbMix);
Expand All @@ -70,25 +76,48 @@ export function Soundfont2Example({ className }: { className?: string }) {

<LoadWithStatus
status={status}
onClick={() => loadSampler("Supersaw")}
onClick={() => {
if (isCustomEnabled) {
loadSampler(customUrl);
} else {
loadSampler("Supersaw");
}
}}
/>
<ConnectMidi instrument={sampler} />
</div>
<div className="my-2">
<div className="my-2 flex gap-4">
<select
className="appearance-none bg-zinc-700 text-zinc-200 rounded border border-gray-400 py-2 px-3 leading-tight focus:outline-none focus:border-blue-500"
value={samplerName}
onChange={(e) => {
const sf2name = e.target.value;
loadSampler(sf2name);
const value = e.target.value;
if (value === "_custom") {
setCustomEnabled(true);
setSamplerName("_custom");
} else {
loadSampler(value);
}
}}
>
{samplerNames.map((name) => (
<option key={name} value={name}>
{name}
</option>
))}
<option key="custom" value="_custom">
Custom URL
</option>
</select>
<input
className="w-80 border p-1 bg-zinc-700 text-zinc-200 disabled:opacity-25"
disabled={!isCustomEnabled}
placeholder="https://example.com/soundfont.sf2"
value={customUrl}
onChange={(e) => {
setCustomUrl(e.target.value);
}}
/>
</div>
<div className={status !== "ready" ? "opacity-30" : ""}>
<div className="flex gap-4 mb-2 no-select">
Expand Down

0 comments on commit 121da6b

Please # to comment.