mirror of
https://codeberg.org/uzu/strudel
synced 2026-07-25 23:10:34 -04:00
add events to audio slide
This commit is contained in:
@@ -0,0 +1,46 @@
|
||||
import { useState, useCallback } from 'react';
|
||||
import { atomone } from '@uiw/codemirror-themes-all';
|
||||
import { CodeMirror, flash, useKeydown } from '@strudel.cycles/react';
|
||||
import { initAudioOnFirstClick, webaudioOutput } from '@strudel.cycles/webaudio';
|
||||
import { TimeSpan } from '@strudel.cycles/core';
|
||||
|
||||
const initAudio = initAudioOnFirstClick();
|
||||
|
||||
function EventEditor({ code: initialCode }) {
|
||||
const [code, setCode] = useState(initialCode);
|
||||
const [view, setView] = useState();
|
||||
useKeydown(
|
||||
useCallback(
|
||||
async (e) => {
|
||||
if (view?.hasFocus) {
|
||||
if (e.ctrlKey || e.altKey) {
|
||||
if (e.code === 'Enter') {
|
||||
/* if (getAudioContext().state !== 'running') {
|
||||
alert('please click play to initialize the audio. you can use shortcuts after that!');
|
||||
return;
|
||||
} */
|
||||
e.preventDefault();
|
||||
flash(view);
|
||||
let json = JSON.parse(code);
|
||||
if (!Array.isArray(json)) {
|
||||
json = [json];
|
||||
}
|
||||
await initAudio;
|
||||
json.forEach((value) => {
|
||||
const hap = new Hap(new TimeSpan(0, 1), new TimeSpan(0, 1), value);
|
||||
webaudioOutput(hap, 0.1, 1, 1);
|
||||
});
|
||||
} else if (e.key === '.') {
|
||||
stop();
|
||||
e.preventDefault();
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
[code, view],
|
||||
),
|
||||
);
|
||||
return <CodeMirror value={code} onChange={setCode} theme={atomone} onViewChanged={(v) => setView(v)} fontSize={32} />;
|
||||
}
|
||||
|
||||
export default EventEditor;
|
||||
@@ -0,0 +1,45 @@
|
||||
import EventEditor from './EventEditor.jsx';
|
||||
import { useState } from 'react';
|
||||
|
||||
const snippets = [
|
||||
[`{ "s": "cp" }`, 'Samples'],
|
||||
[`{ "s": "sawtooth", "note": "e3" }`, 'Oscillators'],
|
||||
[
|
||||
`[
|
||||
{ "s": "gm_epiano2", "note": "c4" },
|
||||
{ "s": "gm_epiano2", "note": "eb4" },
|
||||
{ "s": "gm_epiano2", "note": "g4" }
|
||||
]`,
|
||||
'Soundfonts',
|
||||
],
|
||||
[
|
||||
`{
|
||||
"s": "toys",
|
||||
"cutoff": 2000,
|
||||
"delay": 0.5,
|
||||
"crush": 4
|
||||
}`,
|
||||
'Effects',
|
||||
],
|
||||
];
|
||||
|
||||
function EventsDemo() {
|
||||
const [step, setStep] = useState(1);
|
||||
|
||||
return (
|
||||
<div className="not-prose">
|
||||
{snippets.slice(0, step).map(([code, label], i) => {
|
||||
const isActive = i === step - 1;
|
||||
return (
|
||||
<div key={i} className={`border-l-4 pl-8 border-gray-500 py-4 ${isActive ? 'p-4 border-yellow-500' : ''}`}>
|
||||
<h3 className="pb-4">{label}</h3>
|
||||
<EventEditor code={code} />
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
{step < snippets.length && <button onClick={() => setStep((r) => r + 1)}>next</button>}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default EventsDemo;
|
||||
@@ -14,7 +14,7 @@ function MiniComparison() {
|
||||
const [step, setStep] = useState(1);
|
||||
return (
|
||||
<>
|
||||
<h1>Mini Notation vs Regular JS</h1>
|
||||
<h1>From Mini Notation to JavaScript</h1>
|
||||
<div className="not-prose">
|
||||
{snippets.slice(0, step).map(([a, b, label], i) => {
|
||||
const isActive = i === step - 1;
|
||||
|
||||
@@ -16,7 +16,7 @@ const loadedMDXFiles = await Promise.all(
|
||||
}),
|
||||
);
|
||||
|
||||
const order = ['01', '02-0', '02-1', '02-2', 'mini-comparison', 'patterns-events', '04'];
|
||||
const order = ['01', '02-0', '02-1', '02-2', 'mini-comparison', 'patterns-events', 'events-audio', '04'];
|
||||
|
||||
const slideEntries = order.map((name) => loadedMDXFiles.find(([file]) => file === name));
|
||||
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
import { SlideRepl } from '../SlideRepl.jsx';
|
||||
import Highlight from '../Highlight.jsx';
|
||||
import EventsDemo from '../EventsDemo.jsx';
|
||||
|
||||
# From Values to Sound
|
||||
|
||||
<EventsDemo />
|
||||
@@ -5,7 +5,7 @@ import Highlight from '../Highlight.jsx';
|
||||
|
||||
<SlideRepl tune={`sound("bd [hh sd]").log()`} hideHeader punchcard />
|
||||
|
||||
query = get events within time arc:
|
||||
query = get events within time arc. event = time + value
|
||||
|
||||
<Highlight code={`sound("bd [hh sd]").queryArc(0, 1)`} language="javascript" />
|
||||
|
||||
|
||||
Reference in New Issue
Block a user