mirror of
https://github.com/eliasstepanik/strudel-docker.git
synced 2026-01-25 20:48:27 +00:00
fix could not play after pressing pause
+ some notes
This commit is contained in:
parent
f97837d15a
commit
f95f181301
@ -11,8 +11,15 @@ import hot from '../public/hot';
|
|||||||
import { isNote } from 'tone';
|
import { isNote } from 'tone';
|
||||||
import { useWebMidi } from './midi';
|
import { useWebMidi } from './midi';
|
||||||
|
|
||||||
|
// TODO: use https://www.npmjs.com/package/@monaco-editor/react
|
||||||
|
|
||||||
const [_, codeParam] = window.location.href.split('#');
|
const [_, codeParam] = window.location.href.split('#');
|
||||||
const decoded = atob(decodeURIComponent(codeParam || ''));
|
let decoded;
|
||||||
|
try {
|
||||||
|
decoded = atob(decodeURIComponent(codeParam || ''));
|
||||||
|
} catch (err) {
|
||||||
|
console.warn('failed to decode', err);
|
||||||
|
}
|
||||||
|
|
||||||
const getHotCode = async () => {
|
const getHotCode = async () => {
|
||||||
return fetch('/hot.js')
|
return fetch('/hot.js')
|
||||||
@ -48,6 +55,7 @@ function App() {
|
|||||||
const [activePattern, setActivePattern] = useState<Pattern>();
|
const [activePattern, setActivePattern] = useState<Pattern>();
|
||||||
const dirty = code !== activeCode;
|
const dirty = code !== activeCode;
|
||||||
const activateCode = (_code = code) => {
|
const activateCode = (_code = code) => {
|
||||||
|
!cycle.started && cycle.start();
|
||||||
if (activeCode && !dirty) {
|
if (activeCode && !dirty) {
|
||||||
setError(undefined);
|
setError(undefined);
|
||||||
return;
|
return;
|
||||||
@ -62,11 +70,11 @@ function App() {
|
|||||||
setError(err);
|
setError(err);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
// TODO: move to activateCode + remove hot mode..
|
||||||
const activatePattern = (_pattern) => {
|
const activatePattern = (_pattern) => {
|
||||||
try {
|
try {
|
||||||
setActivePattern(() => _pattern);
|
setActivePattern(() => _pattern);
|
||||||
window.location.hash = '#' + encodeURIComponent(btoa(code));
|
window.location.hash = '#' + encodeURIComponent(btoa(code));
|
||||||
!cycle.started && cycle.start();
|
|
||||||
} catch (err: any) {
|
} catch (err: any) {
|
||||||
setError(err);
|
setError(err);
|
||||||
}
|
}
|
||||||
@ -123,6 +131,7 @@ function App() {
|
|||||||
switch (e.code) {
|
switch (e.code) {
|
||||||
case 'Enter':
|
case 'Enter':
|
||||||
activateCode();
|
activateCode();
|
||||||
|
!cycle.started && cycle.start();
|
||||||
break;
|
break;
|
||||||
case 'Period':
|
case 'Period':
|
||||||
cycle.stop();
|
cycle.stop();
|
||||||
@ -233,10 +242,13 @@ function App() {
|
|||||||
<button
|
<button
|
||||||
className="flex-none w-full border border-gray-700 p-2 bg-slate-700 hover:bg-slate-500"
|
className="flex-none w-full border border-gray-700 p-2 bg-slate-700 hover:bg-slate-500"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
|
// TODO: find out why sometimes, after a longer time coming back to the strudel repl, the button wont do anything
|
||||||
if (!cycle.started) {
|
if (!cycle.started) {
|
||||||
|
// console.log('start');
|
||||||
// activatePattern();
|
// activatePattern();
|
||||||
activateCode();
|
activateCode();
|
||||||
} else {
|
} else {
|
||||||
|
// console.log('stop');
|
||||||
cycle.stop();
|
cycle.stop();
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
|
|||||||
@ -24,3 +24,7 @@ export default (code) => {
|
|||||||
});
|
});
|
||||||
return codegen(shifted);
|
return codegen(shifted);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// TODO: turn x.groove['[~ x]*2'] into x.groove('[~ x]*2'.m)
|
||||||
|
// and ['c1*2'].xx into 'c1*2'.m.xx ??
|
||||||
|
// or just all templated strings?? x.groove(`[~ x]*2`)
|
||||||
@ -1,6 +1,9 @@
|
|||||||
import { Pattern as _Pattern } from '../../strudel.mjs';
|
import { Pattern as _Pattern } from '../../strudel.mjs';
|
||||||
import { AutoFilter, Destination, Filter, Gain, isNote, Synth, PolySynth } from 'tone';
|
import { AutoFilter, Destination, Filter, Gain, isNote, Synth, PolySynth } from 'tone';
|
||||||
|
|
||||||
|
// what about
|
||||||
|
// https://www.charlie-roberts.com/gibberish/playground/
|
||||||
|
|
||||||
const Pattern = _Pattern as any;
|
const Pattern = _Pattern as any;
|
||||||
|
|
||||||
// with this function, you can play the pattern with any tone synth
|
// with this function, you can play the pattern with any tone synth
|
||||||
|
|||||||
@ -462,3 +462,66 @@ export const caverave = `() => {
|
|||||||
synths
|
synths
|
||||||
).slow(2);
|
).slow(2);
|
||||||
}`;
|
}`;
|
||||||
|
|
||||||
|
export const caveravefuture = `() => {
|
||||||
|
const delay = new FeedbackDelay(1/8, .4).chain(vol(0.5), out);
|
||||||
|
const kick = new MembraneSynth().chain(vol(.8), out);
|
||||||
|
const snare = new NoiseSynth().chain(vol(.8), out);
|
||||||
|
const hihat = new MetalSynth().set(adsr(0, .08, 0, .1)).chain(vol(.3).connect(delay),out);
|
||||||
|
const bass = new Synth().set({ ...osc('sawtooth'), ...adsr(0, .1, .4) }).chain(lowpass(900), vol(.5), out);
|
||||||
|
const keys = new PolySynth().set({ ...osc('sawtooth'), ...adsr(0, .5, .2, .7) }).chain(lowpass(1200), vol(.5), out);
|
||||||
|
|
||||||
|
const drums = stack(
|
||||||
|
\`c1*2\`.tone(kick).bypass(\`<0@7 1>/8\`),
|
||||||
|
\`~ <x!7 [x@3 x]>\`.tone(snare).bypass(\`<0@7 1>/4\`),
|
||||||
|
\`[~ c4]*2\`.tone(hihat)
|
||||||
|
);
|
||||||
|
|
||||||
|
const thru = (x) => x.transpose(\`<0 1>/8\`).transpose(-1);
|
||||||
|
const synths = stack(
|
||||||
|
\`<eb4 d4 c4 b3>/2\`.scale(timeCat([3,'C minor'],[1,'C melodic minor']).slow(8)).groove(\`[~ x]*2\`)
|
||||||
|
.edit(
|
||||||
|
scaleTranspose(0).early(0),
|
||||||
|
scaleTranspose(2).early(1/8),
|
||||||
|
scaleTranspose(7).early(1/4),
|
||||||
|
scaleTranspose(8).early(3/8)
|
||||||
|
).edit(thru).tone(keys).bypass(\`<1 0>/16\`),
|
||||||
|
\`<C2 Bb1 Ab1 [G1 [G2 G1]]>/2\`.groove(\`x [~ x] <[~ [~ x]]!3 [x x]>@2\`).edit(thru).tone(bass),
|
||||||
|
\`<Cm7 Bb7 Fm7 G7b13>/2\`.groove(\`~ [x@0.5 ~]\`.fast(2)).voicings().edit(thru).every(2, early(1/8)).tone(keys).bypass(\`<0@7 1>/8\`.early(1/4)),
|
||||||
|
)
|
||||||
|
return stack(
|
||||||
|
drums.fast(2),
|
||||||
|
synths
|
||||||
|
).slow(2);
|
||||||
|
}`;
|
||||||
|
|
||||||
|
export const caveravefuture2 = `const delay = new FeedbackDelay(1/8, .4).chain(vol(0.5), out);
|
||||||
|
const kick = new MembraneSynth().chain(vol(.8), out);
|
||||||
|
const snare = new NoiseSynth().chain(vol(.8), out);
|
||||||
|
const hihat = new MetalSynth().set(adsr(0, .08, 0, .1)).chain(vol(.3).connect(delay),out);
|
||||||
|
const bass = new Synth().set({ ...osc('sawtooth'), ...adsr(0, .1, .4) }).chain(lowpass(900), vol(.5), out);
|
||||||
|
const keys = new PolySynth().set({ ...osc('sawtooth'), ...adsr(0, .5, .2, .7) }).chain(lowpass(1200), vol(.5), out);
|
||||||
|
|
||||||
|
const drums = stack(
|
||||||
|
"c1*2".tone(kick).bypass("<0@7 1>/8"),
|
||||||
|
"~ <x!7 [x@3 x]>".tone(snare).bypass("<0@7 1>/4"),
|
||||||
|
"[~ c4]*2".tone(hihat)
|
||||||
|
);
|
||||||
|
|
||||||
|
const thru = (x) => x.transpose("<0 1>/8").transpose(-1);
|
||||||
|
const synths = stack(
|
||||||
|
"<eb4 d4 c4 b3>/2".scale(timeCat([3, 'C minor'], [1, 'C melodic minor']).slow(8)).groove("[~ x]*2")
|
||||||
|
.edit(
|
||||||
|
scaleTranspose(0).early(0),
|
||||||
|
scaleTranspose(2).early(1/8),
|
||||||
|
scaleTranspose(7).early(1/4),
|
||||||
|
scaleTranspose(8).early(3/8)
|
||||||
|
).edit(thru).tone(keys).bypass("<1 0>/16"),
|
||||||
|
"<C2 Bb1 Ab1 [G1 [G2 G1]]>/2".groove("x [~ x] <[~ [~ x]]!3 [x x]>@2").edit(thru).tone(bass),
|
||||||
|
"<Cm7 Bb7 Fm7 G7b13>/2".groove("~ [x@0.5 ~]".fast(2)).voicings().edit(thru).every(2, early(1/8)).tone(keys).bypass("<0@7 1>/8".early(1/4)),
|
||||||
|
)
|
||||||
|
$: stack(
|
||||||
|
drums.fast(2),
|
||||||
|
synths
|
||||||
|
).slow(2);
|
||||||
|
`;
|
||||||
|
|||||||
16
strudel.mjs
16
strudel.mjs
@ -588,6 +588,22 @@ class Pattern {
|
|||||||
hush() {
|
hush() {
|
||||||
return silence;
|
return silence;
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
_resolveTies() {
|
||||||
|
return this._withEvents((events)=>{
|
||||||
|
return events.reduce((tied, event, i) => {
|
||||||
|
const value = event.value?.value || event.value;
|
||||||
|
if (value !== '_') {
|
||||||
|
return tied.concat([event]);
|
||||||
|
}
|
||||||
|
console.log('tie!', lastEvent);
|
||||||
|
tied[i - 1] = tied[i - 1].withSpan((span) => span.withEnd((_) => event.part.end));
|
||||||
|
// above only works if the tie is not across a cycle boundary... how to do that???
|
||||||
|
// TODO: handle case that there is a gap between tied[i-1].part.end and event.part.begin => tie would make no sense
|
||||||
|
return tied;
|
||||||
|
}, []);
|
||||||
|
})
|
||||||
|
} */
|
||||||
}
|
}
|
||||||
|
|
||||||
// methods of Pattern that get callable factories
|
// methods of Pattern that get callable factories
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user