mirror of
https://github.com/eliasstepanik/strudel-docker.git
synced 2026-01-25 04:28:30 +00:00
example code logic
This commit is contained in:
parent
3604d3940c
commit
4e0a60db00
@ -20,12 +20,14 @@ import {
|
|||||||
useSettings,
|
useSettings,
|
||||||
getViewingPattern,
|
getViewingPattern,
|
||||||
setViewingPattern,
|
setViewingPattern,
|
||||||
|
getNextCloneName,
|
||||||
} from '../settings.mjs';
|
} from '../settings.mjs';
|
||||||
import { Header } from './Header';
|
import { Header } from './Header';
|
||||||
import Loader from './Loader';
|
import Loader from './Loader';
|
||||||
import { Panel } from './panel/Panel';
|
import { Panel } from './panel/Panel';
|
||||||
import { useStore } from '@nanostores/react';
|
import { useStore } from '@nanostores/react';
|
||||||
import { prebake } from './prebake.mjs';
|
import { prebake } from './prebake.mjs';
|
||||||
|
import * as tunes from './tunes.mjs';
|
||||||
import { getRandomTune, initCode, loadModules, shareCode } from './util.mjs';
|
import { getRandomTune, initCode, loadModules, shareCode } from './util.mjs';
|
||||||
import PlayCircleIcon from '@heroicons/react/20/solid/PlayCircleIcon';
|
import PlayCircleIcon from '@heroicons/react/20/solid/PlayCircleIcon';
|
||||||
import './Repl.css';
|
import './Repl.css';
|
||||||
@ -44,7 +46,6 @@ if (typeof window !== 'undefined') {
|
|||||||
clearCanvas = () => drawContext.clearRect(0, 0, drawContext.canvas.height, drawContext.canvas.width);
|
clearCanvas = () => drawContext.clearRect(0, 0, drawContext.canvas.height, drawContext.canvas.width);
|
||||||
isIframe = window.location !== window.parent.location;
|
isIframe = window.location !== window.parent.location;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function Repl({ embedded = false }) {
|
export function Repl({ embedded = false }) {
|
||||||
const isEmbedded = embedded || isIframe;
|
const isEmbedded = embedded || isIframe;
|
||||||
const { panelPosition, isZen } = useSettings();
|
const { panelPosition, isZen } = useSettings();
|
||||||
@ -74,13 +75,23 @@ export function Repl({ embedded = false }) {
|
|||||||
setReplState({ ...state });
|
setReplState({ ...state });
|
||||||
},
|
},
|
||||||
afterEval: ({ code }) => {
|
afterEval: ({ code }) => {
|
||||||
updateUserCode(code);
|
|
||||||
// setPending(false);
|
|
||||||
setLatestCode(code);
|
setLatestCode(code);
|
||||||
const viewingPatternID = getViewingPattern();
|
let pattern = getViewingPattern();
|
||||||
window.location.hash = '#' + code2hash(code);
|
window.location.hash = '#' + code2hash(code);
|
||||||
if (viewingPatternID != null) {
|
const isExamplePattern = !!tunes[pattern];
|
||||||
setActivePattern(viewingPatternID);
|
|
||||||
|
if (isExamplePattern) {
|
||||||
|
const codeHasChanged = code !== tunes[pattern];
|
||||||
|
if (codeHasChanged) {
|
||||||
|
// fork example
|
||||||
|
pattern = getNextCloneName(pattern);
|
||||||
|
setViewingPattern(pattern);
|
||||||
|
updateUserCode(pattern, code);
|
||||||
|
}
|
||||||
|
setActivePattern(pattern);
|
||||||
|
} else {
|
||||||
|
setActivePattern(pattern);
|
||||||
|
updateUserCode(pattern, code);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
bgFill: false,
|
bgFill: false,
|
||||||
@ -149,6 +160,7 @@ export function Repl({ embedded = false }) {
|
|||||||
// payload = {reset?: boolean, code?: string, evaluate?: boolean, patternID?: string }
|
// payload = {reset?: boolean, code?: string, evaluate?: boolean, patternID?: string }
|
||||||
const handleUpdate = async (payload) => {
|
const handleUpdate = async (payload) => {
|
||||||
const { reset = false, code = null, evaluate = true, patternID = null } = payload;
|
const { reset = false, code = null, evaluate = true, patternID = null } = payload;
|
||||||
|
|
||||||
if (reset) {
|
if (reset) {
|
||||||
clearCanvas();
|
clearCanvas();
|
||||||
resetLoadedSounds();
|
resetLoadedSounds();
|
||||||
|
|||||||
@ -24,8 +24,8 @@ function PatternButton({ showOutline, onClick, label, showHiglight }) {
|
|||||||
<a
|
<a
|
||||||
className={classNames(
|
className={classNames(
|
||||||
'mr-4 hover:opacity-50 cursor-pointer inline-block',
|
'mr-4 hover:opacity-50 cursor-pointer inline-block',
|
||||||
showOutline ? 'outline outline-1' : '',
|
showOutline && 'outline outline-1',
|
||||||
showHiglight ? 'bg-red-500' : '',
|
showHiglight && 'bg-selection',
|
||||||
)}
|
)}
|
||||||
onClick={onClick}
|
onClick={onClick}
|
||||||
>
|
>
|
||||||
@ -54,15 +54,15 @@ export function PatternsTab({ context }) {
|
|||||||
const { userPatterns } = useSettings();
|
const { userPatterns } = useSettings();
|
||||||
const activePattern = useActivePattern();
|
const activePattern = useActivePattern();
|
||||||
const viewingPattern = useViewingPattern();
|
const viewingPattern = useViewingPattern();
|
||||||
const isExample = useMemo(() => activePattern && !!tunes[activePattern], [activePattern]);
|
// const isExample = useMemo(() => activePattern && !!tunes[activePattern], [activePattern]);
|
||||||
const onPatternClick = (key, data) => {
|
const onPatternClick = (key, data) => {
|
||||||
const { code } = data;
|
// display selected pattern code in the window
|
||||||
context.handleUpdate({ patternID: key, code, evaluate: false });
|
context.handleUpdate({ patternID: key, code: data.code, evaluate: false });
|
||||||
};
|
};
|
||||||
|
|
||||||
const examplePatterns = {};
|
const examplePatterns = {};
|
||||||
Object.entries(tunes).forEach(([key, code]) => (examplePatterns[key] = { code }));
|
Object.entries(tunes).forEach(([key, code]) => (examplePatterns[key] = { code }));
|
||||||
|
const isExample = examplePatterns[viewingPattern] != null;
|
||||||
return (
|
return (
|
||||||
<div className="px-4 w-full dark:text-white text-stone-900 space-y-4 pb-4">
|
<div className="px-4 w-full dark:text-white text-stone-900 space-y-4 pb-4">
|
||||||
<section>
|
<section>
|
||||||
@ -124,7 +124,12 @@ export function PatternsTab({ context }) {
|
|||||||
</section>
|
</section>
|
||||||
<section>
|
<section>
|
||||||
<h2 className="text-xl mb-2">Examples</h2>
|
<h2 className="text-xl mb-2">Examples</h2>
|
||||||
<PatternButtons onClick={onPatternClick} patterns={examplePatterns} activePattern={activePattern} />
|
<PatternButtons
|
||||||
|
onClick={onPatternClick}
|
||||||
|
patterns={examplePatterns}
|
||||||
|
activePattern={activePattern}
|
||||||
|
viewingPattern={viewingPattern}
|
||||||
|
/>
|
||||||
</section>
|
</section>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -5,6 +5,9 @@ This program is free software: you can redistribute it and/or modify it under th
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
export const swimming = `// Koji Kondo - Swimming (Super Mario World)
|
export const swimming = `// Koji Kondo - Swimming (Super Mario World)
|
||||||
|
|
||||||
|
setCps(1)
|
||||||
|
|
||||||
stack(
|
stack(
|
||||||
seq(
|
seq(
|
||||||
"~",
|
"~",
|
||||||
@ -69,6 +72,8 @@ stack(
|
|||||||
|
|
||||||
export const giantSteps = `// John Coltrane - Giant Steps
|
export const giantSteps = `// John Coltrane - Giant Steps
|
||||||
|
|
||||||
|
setCps(1)
|
||||||
|
|
||||||
let melody = note(
|
let melody = note(
|
||||||
"[F#5 D5] [B4 G4] Bb4 [B4 A4]",
|
"[F#5 D5] [B4 G4] Bb4 [B4 A4]",
|
||||||
"[D5 Bb4] [G4 Eb4] F#4 [G4 F4]",
|
"[D5 Bb4] [G4 Eb4] F#4 [G4 F4]",
|
||||||
@ -99,6 +104,9 @@ stack(
|
|||||||
.pianoroll({fold:1})`;
|
.pianoroll({fold:1})`;
|
||||||
|
|
||||||
export const zeldasRescue = `// Koji Kondo - Princess Zelda's Rescue
|
export const zeldasRescue = `// Koji Kondo - Princess Zelda's Rescue
|
||||||
|
|
||||||
|
setCps(1)
|
||||||
|
|
||||||
stack(
|
stack(
|
||||||
// melody
|
// melody
|
||||||
\`[B3@2 D4] [A3@2 [G3 A3]] [B3@2 D4] [A3]
|
\`[B3@2 D4] [A3@2 [G3 A3]] [B3@2 D4] [A3]
|
||||||
@ -128,6 +136,9 @@ export const caverave = `// "Caverave"
|
|||||||
// @license CC BY-NC-SA 4.0 https://creativecommons.org/licenses/by-nc-sa/4.0/
|
// @license CC BY-NC-SA 4.0 https://creativecommons.org/licenses/by-nc-sa/4.0/
|
||||||
// @by Felix Roos
|
// @by Felix Roos
|
||||||
|
|
||||||
|
|
||||||
|
setCps(1)
|
||||||
|
|
||||||
const keys = x => x.s('sawtooth').cutoff(1200).gain(.5)
|
const keys = x => x.s('sawtooth').cutoff(1200).gain(.5)
|
||||||
.attack(0).decay(.16).sustain(.3).release(.1);
|
.attack(0).decay(.16).sustain(.3).release(.1);
|
||||||
|
|
||||||
@ -174,6 +185,8 @@ export const sampleDrums = `samples({
|
|||||||
hh: 'hh/000_hh3closedhh.wav'
|
hh: 'hh/000_hh3closedhh.wav'
|
||||||
}, 'https://loophole-letters.vercel.app/samples/tidal/')
|
}, 'https://loophole-letters.vercel.app/samples/tidal/')
|
||||||
|
|
||||||
|
setCps(1)
|
||||||
|
|
||||||
stack(
|
stack(
|
||||||
"<bd!3 bd(3,4,3)>".color('#F5A623'),
|
"<bd!3 bd(3,4,3)>".color('#F5A623'),
|
||||||
"hh*4".color('#673AB7'),
|
"hh*4".color('#673AB7'),
|
||||||
@ -183,6 +196,9 @@ stack(
|
|||||||
`;
|
`;
|
||||||
|
|
||||||
export const barryHarris = `// adapted from a Barry Harris excercise
|
export const barryHarris = `// adapted from a Barry Harris excercise
|
||||||
|
|
||||||
|
setCps(1)
|
||||||
|
|
||||||
"0,2,[7 6]"
|
"0,2,[7 6]"
|
||||||
.add("<0 1 2 3 4 5 7 8>")
|
.add("<0 1 2 3 4 5 7 8>")
|
||||||
.scale('C bebop major')
|
.scale('C bebop major')
|
||||||
@ -196,6 +212,8 @@ export const blippyRhodes = `// "Blippy Rhodes"
|
|||||||
// @license CC BY-NC-SA 4.0 https://creativecommons.org/licenses/by-nc-sa/4.0/
|
// @license CC BY-NC-SA 4.0 https://creativecommons.org/licenses/by-nc-sa/4.0/
|
||||||
// @by Felix Roos
|
// @by Felix Roos
|
||||||
|
|
||||||
|
setCps(1)
|
||||||
|
|
||||||
samples({
|
samples({
|
||||||
bd: 'samples/tidal/bd/BT0A0D0.wav',
|
bd: 'samples/tidal/bd/BT0A0D0.wav',
|
||||||
sn: 'samples/tidal/sn/ST0T0S3.wav',
|
sn: 'samples/tidal/sn/ST0T0S3.wav',
|
||||||
@ -239,6 +257,8 @@ export const wavyKalimba = `// "Wavy kalimba"
|
|||||||
// @license CC BY-NC-SA 4.0 https://creativecommons.org/licenses/by-nc-sa/4.0/
|
// @license CC BY-NC-SA 4.0 https://creativecommons.org/licenses/by-nc-sa/4.0/
|
||||||
// @by Felix Roos
|
// @by Felix Roos
|
||||||
|
|
||||||
|
setCps(1)
|
||||||
|
|
||||||
samples({
|
samples({
|
||||||
'kalimba': { c5:'https://freesound.org/data/previews/536/536549_11935698-lq.mp3' }
|
'kalimba': { c5:'https://freesound.org/data/previews/536/536549_11935698-lq.mp3' }
|
||||||
})
|
})
|
||||||
@ -269,6 +289,8 @@ export const festivalOfFingers = `// "Festival of fingers"
|
|||||||
// @license CC BY-NC-SA 4.0 https://creativecommons.org/licenses/by-nc-sa/4.0/
|
// @license CC BY-NC-SA 4.0 https://creativecommons.org/licenses/by-nc-sa/4.0/
|
||||||
// @by Felix Roos
|
// @by Felix Roos
|
||||||
|
|
||||||
|
setCps(1)
|
||||||
|
|
||||||
const chords = "<Cm7 Fm7 G7 F#7>";
|
const chords = "<Cm7 Fm7 G7 F#7>";
|
||||||
stack(
|
stack(
|
||||||
chord(chords).dict('lefthand').voicing().struct("x(3,8,-1)")
|
chord(chords).dict('lefthand').voicing().struct("x(3,8,-1)")
|
||||||
@ -292,6 +314,8 @@ export const undergroundPlumber = `// "Underground plumber"
|
|||||||
// @by Felix Roos
|
// @by Felix Roos
|
||||||
// @details inspired by Friendship - Let's not talk about it (1979) :)
|
// @details inspired by Friendship - Let's not talk about it (1979) :)
|
||||||
|
|
||||||
|
setCps(1)
|
||||||
|
|
||||||
samples({ bd: 'bd/BT0A0D0.wav', sn: 'sn/ST0T0S3.wav', hh: 'hh/000_hh3closedhh.wav', cp: 'cp/HANDCLP0.wav',
|
samples({ bd: 'bd/BT0A0D0.wav', sn: 'sn/ST0T0S3.wav', hh: 'hh/000_hh3closedhh.wav', cp: 'cp/HANDCLP0.wav',
|
||||||
}, 'https://loophole-letters.vercel.app/samples/tidal/')
|
}, 'https://loophole-letters.vercel.app/samples/tidal/')
|
||||||
|
|
||||||
@ -319,6 +343,8 @@ export const bridgeIsOver = `// "Bridge is over"
|
|||||||
// @license CC BY-NC-SA 4.0 https://creativecommons.org/licenses/by-nc-sa/4.0/
|
// @license CC BY-NC-SA 4.0 https://creativecommons.org/licenses/by-nc-sa/4.0/
|
||||||
// @by Felix Roos, bassline by BDP - The Bridge Is Over
|
// @by Felix Roos, bassline by BDP - The Bridge Is Over
|
||||||
|
|
||||||
|
setCps(1)
|
||||||
|
|
||||||
samples({mad:'https://freesound.org/data/previews/22/22274_109943-lq.mp3'})
|
samples({mad:'https://freesound.org/data/previews/22/22274_109943-lq.mp3'})
|
||||||
stack(
|
stack(
|
||||||
stack(
|
stack(
|
||||||
@ -339,6 +365,8 @@ export const goodTimes = `// "Good times"
|
|||||||
// @license CC BY-NC-SA 4.0 https://creativecommons.org/licenses/by-nc-sa/4.0/
|
// @license CC BY-NC-SA 4.0 https://creativecommons.org/licenses/by-nc-sa/4.0/
|
||||||
// @by Felix Roos
|
// @by Felix Roos
|
||||||
|
|
||||||
|
setCps(1)
|
||||||
|
|
||||||
const scale = cat('C3 dorian','Bb2 major').slow(4);
|
const scale = cat('C3 dorian','Bb2 major').slow(4);
|
||||||
stack(
|
stack(
|
||||||
n("2*4".add(12)).off(1/8, add(2))
|
n("2*4".add(12)).off(1/8, add(2))
|
||||||
@ -361,6 +389,8 @@ export const echoPiano = `// "Echo piano"
|
|||||||
// @license CC BY-NC-SA 4.0 https://creativecommons.org/licenses/by-nc-sa/4.0/
|
// @license CC BY-NC-SA 4.0 https://creativecommons.org/licenses/by-nc-sa/4.0/
|
||||||
// @by Felix Roos
|
// @by Felix Roos
|
||||||
|
|
||||||
|
setCps(1)
|
||||||
|
|
||||||
n("<0 2 [4 6](3,4,2) 3*2>").color('salmon')
|
n("<0 2 [4 6](3,4,2) 3*2>").color('salmon')
|
||||||
.off(1/4, x=>x.add(2).color('green'))
|
.off(1/4, x=>x.add(2).color('green'))
|
||||||
.off(1/2, x=>x.add(6).color('steelblue'))
|
.off(1/2, x=>x.add(6).color('steelblue'))
|
||||||
@ -371,6 +401,9 @@ n("<0 2 [4 6](3,4,2) 3*2>").color('salmon')
|
|||||||
.pianoroll()`;
|
.pianoroll()`;
|
||||||
|
|
||||||
export const sml1 = `// Hirokazu Tanaka - World 1-1
|
export const sml1 = `// Hirokazu Tanaka - World 1-1
|
||||||
|
|
||||||
|
setCps(1)
|
||||||
|
|
||||||
stack(
|
stack(
|
||||||
// melody
|
// melody
|
||||||
note(\`<
|
note(\`<
|
||||||
@ -409,6 +442,8 @@ export const randomBells = `// "Random bells"
|
|||||||
// @license CC BY-NC-SA 4.0 https://creativecommons.org/licenses/by-nc-sa/4.0/
|
// @license CC BY-NC-SA 4.0 https://creativecommons.org/licenses/by-nc-sa/4.0/
|
||||||
// @by Felix Roos
|
// @by Felix Roos
|
||||||
|
|
||||||
|
setCps(1)
|
||||||
|
|
||||||
samples({
|
samples({
|
||||||
bell: { c6: 'https://freesound.org/data/previews/411/411089_5121236-lq.mp3' },
|
bell: { c6: 'https://freesound.org/data/previews/411/411089_5121236-lq.mp3' },
|
||||||
bass: { d2: 'https://freesound.org/data/previews/608/608286_13074022-lq.mp3' }
|
bass: { d2: 'https://freesound.org/data/previews/608/608286_13074022-lq.mp3' }
|
||||||
@ -432,6 +467,8 @@ export const waa2 = `// "Waa2"
|
|||||||
// @license CC BY-NC-SA 4.0 https://creativecommons.org/licenses/by-nc-sa/4.0/
|
// @license CC BY-NC-SA 4.0 https://creativecommons.org/licenses/by-nc-sa/4.0/
|
||||||
// @by Felix Roos
|
// @by Felix Roos
|
||||||
|
|
||||||
|
setCps(1)
|
||||||
|
|
||||||
note(
|
note(
|
||||||
"a4 [a3 c3] a3 c3"
|
"a4 [a3 c3] a3 c3"
|
||||||
.sub("<7 12 5 12>".slow(2))
|
.sub("<7 12 5 12>".slow(2))
|
||||||
@ -450,6 +487,8 @@ export const hyperpop = `// "Hyperpop"
|
|||||||
// @license CC BY-NC-SA 4.0 https://creativecommons.org/licenses/by-nc-sa/4.0/
|
// @license CC BY-NC-SA 4.0 https://creativecommons.org/licenses/by-nc-sa/4.0/
|
||||||
// @by Felix Roos
|
// @by Felix Roos
|
||||||
|
|
||||||
|
setCps(1)
|
||||||
|
|
||||||
const lfo = cosine.slow(15);
|
const lfo = cosine.slow(15);
|
||||||
const lfo2 = sine.slow(16);
|
const lfo2 = sine.slow(16);
|
||||||
const filter1 = x=>x.cutoff(lfo2.range(300,3000));
|
const filter1 = x=>x.cutoff(lfo2.range(300,3000));
|
||||||
@ -505,6 +544,8 @@ export const festivalOfFingers3 = `// "Festival of fingers 3"
|
|||||||
// @license CC BY-NC-SA 4.0 https://creativecommons.org/licenses/by-nc-sa/4.0/
|
// @license CC BY-NC-SA 4.0 https://creativecommons.org/licenses/by-nc-sa/4.0/
|
||||||
// @by Felix Roos
|
// @by Felix Roos
|
||||||
|
|
||||||
|
setCps(1)
|
||||||
|
|
||||||
n("[-7*3],0,2,6,[8 7]")
|
n("[-7*3],0,2,6,[8 7]")
|
||||||
.echoWith(
|
.echoWith(
|
||||||
4, // echo 4 times
|
4, // echo 4 times
|
||||||
@ -528,6 +569,8 @@ export const meltingsubmarine = `// "Melting submarine"
|
|||||||
// @by Felix Roos
|
// @by Felix Roos
|
||||||
|
|
||||||
await samples('github:tidalcycles/Dirt-Samples/master/')
|
await samples('github:tidalcycles/Dirt-Samples/master/')
|
||||||
|
setCps(1)
|
||||||
|
|
||||||
stack(
|
stack(
|
||||||
s("bd:5,[~ <sd:1!3 sd:1(3,4,3)>],hh27(3,4,1)") // drums
|
s("bd:5,[~ <sd:1!3 sd:1(3,4,3)>],hh27(3,4,1)") // drums
|
||||||
.speed(perlin.range(.7,.9)) // random sample speed variation
|
.speed(perlin.range(.7,.9)) // random sample speed variation
|
||||||
@ -609,6 +652,7 @@ bd: ['bd/BT0AADA.wav','bd/BT0AAD0.wav','bd/BT0A0DA.wav','bd/BT0A0D3.wav','bd/BT0
|
|||||||
sd: ['sd/rytm-01-classic.wav','sd/rytm-00-hard.wav'],
|
sd: ['sd/rytm-01-classic.wav','sd/rytm-00-hard.wav'],
|
||||||
hh: ['hh27/000_hh27closedhh.wav','hh/000_hh3closedhh.wav'],
|
hh: ['hh27/000_hh27closedhh.wav','hh/000_hh3closedhh.wav'],
|
||||||
}, 'github:tidalcycles/Dirt-Samples/master/');
|
}, 'github:tidalcycles/Dirt-Samples/master/');
|
||||||
|
setCps(1)
|
||||||
|
|
||||||
note("<8(3,8) <7 7*2> [4 5@3] 8>".sub(1) // sub 1 -> 1-indexed
|
note("<8(3,8) <7 7*2> [4 5@3] 8>".sub(1) // sub 1 -> 1-indexed
|
||||||
.layer(
|
.layer(
|
||||||
@ -631,6 +675,7 @@ export const chop = `// "Chop"
|
|||||||
// @by Felix Roos
|
// @by Felix Roos
|
||||||
|
|
||||||
samples({ p: 'https://cdn.freesound.org/previews/648/648433_11943129-lq.mp3' })
|
samples({ p: 'https://cdn.freesound.org/previews/648/648433_11943129-lq.mp3' })
|
||||||
|
setCps(1)
|
||||||
|
|
||||||
s("p")
|
s("p")
|
||||||
.loopAt(32)
|
.loopAt(32)
|
||||||
@ -656,6 +701,8 @@ export const orbit = `// "Orbit"
|
|||||||
// @license CC BY-NC-SA 4.0 https://creativecommons.org/licenses/by-nc-sa/4.0/
|
// @license CC BY-NC-SA 4.0 https://creativecommons.org/licenses/by-nc-sa/4.0/
|
||||||
// @by Felix Roos
|
// @by Felix Roos
|
||||||
|
|
||||||
|
setCps(1)
|
||||||
|
|
||||||
stack(
|
stack(
|
||||||
s("bd <sd cp>")
|
s("bd <sd cp>")
|
||||||
.delay(.5)
|
.delay(.5)
|
||||||
@ -673,6 +720,8 @@ export const belldub = `// "Belldub"
|
|||||||
// @by Felix Roos
|
// @by Felix Roos
|
||||||
|
|
||||||
samples({ bell: {b4:'https://cdn.freesound.org/previews/339/339809_5121236-lq.mp3'}})
|
samples({ bell: {b4:'https://cdn.freesound.org/previews/339/339809_5121236-lq.mp3'}})
|
||||||
|
setCps(1)
|
||||||
|
|
||||||
// "Hand Bells, B, Single.wav" by InspectorJ (www.jshaw.co.uk) of Freesound.org
|
// "Hand Bells, B, Single.wav" by InspectorJ (www.jshaw.co.uk) of Freesound.org
|
||||||
stack(
|
stack(
|
||||||
// bass
|
// bass
|
||||||
@ -712,6 +761,7 @@ export const dinofunk = `// "Dinofunk"
|
|||||||
samples({bass:'https://cdn.freesound.org/previews/614/614637_2434927-hq.mp3',
|
samples({bass:'https://cdn.freesound.org/previews/614/614637_2434927-hq.mp3',
|
||||||
dino:{b4:'https://cdn.freesound.org/previews/316/316403_5123851-hq.mp3'}})
|
dino:{b4:'https://cdn.freesound.org/previews/316/316403_5123851-hq.mp3'}})
|
||||||
setVoicingRange('lefthand', ['c3','a4'])
|
setVoicingRange('lefthand', ['c3','a4'])
|
||||||
|
setCps(1)
|
||||||
|
|
||||||
stack(
|
stack(
|
||||||
s('bass').loopAt(8).clip(1),
|
s('bass').loopAt(8).clip(1),
|
||||||
@ -736,6 +786,8 @@ export const sampleDemo = `// "Sample demo"
|
|||||||
// @license CC BY-NC-SA 4.0 https://creativecommons.org/licenses/by-nc-sa/4.0/
|
// @license CC BY-NC-SA 4.0 https://creativecommons.org/licenses/by-nc-sa/4.0/
|
||||||
// @by Felix Roos
|
// @by Felix Roos
|
||||||
|
|
||||||
|
setCps(1)
|
||||||
|
|
||||||
stack(
|
stack(
|
||||||
// percussion
|
// percussion
|
||||||
s("[woodblock:1 woodblock:2*2] snare_rim:0,gong/8,brakedrum:1(3,8),~@3 cowbell:3")
|
s("[woodblock:1 woodblock:2*2] snare_rim:0,gong/8,brakedrum:1(3,8),~@3 cowbell:3")
|
||||||
@ -754,6 +806,8 @@ export const holyflute = `// "Holy flute"
|
|||||||
// @license CC BY-NC-SA 4.0 https://creativecommons.org/licenses/by-nc-sa/4.0/
|
// @license CC BY-NC-SA 4.0 https://creativecommons.org/licenses/by-nc-sa/4.0/
|
||||||
// @by Felix Roos
|
// @by Felix Roos
|
||||||
|
|
||||||
|
setCps(1)
|
||||||
|
|
||||||
"c3 eb3(3,8) c4/2 g3*2"
|
"c3 eb3(3,8) c4/2 g3*2"
|
||||||
.superimpose(
|
.superimpose(
|
||||||
x=>x.slow(2).add(12),
|
x=>x.slow(2).add(12),
|
||||||
@ -795,6 +849,8 @@ export const amensister = `// "Amensister"
|
|||||||
// @license CC BY-NC-SA 4.0 https://creativecommons.org/licenses/by-nc-sa/4.0/
|
// @license CC BY-NC-SA 4.0 https://creativecommons.org/licenses/by-nc-sa/4.0/
|
||||||
// @by Felix Roos
|
// @by Felix Roos
|
||||||
|
|
||||||
|
setCps(1)
|
||||||
|
|
||||||
await samples('github:tidalcycles/Dirt-Samples/master')
|
await samples('github:tidalcycles/Dirt-Samples/master')
|
||||||
|
|
||||||
stack(
|
stack(
|
||||||
@ -833,6 +889,8 @@ export const juxUndTollerei = `// "Jux und tollerei"
|
|||||||
// @license CC BY-NC-SA 4.0 https://creativecommons.org/licenses/by-nc-sa/4.0/
|
// @license CC BY-NC-SA 4.0 https://creativecommons.org/licenses/by-nc-sa/4.0/
|
||||||
// @by Felix Roos
|
// @by Felix Roos
|
||||||
|
|
||||||
|
setCps(1)
|
||||||
|
|
||||||
note("c3 eb3 g3 bb3").palindrome()
|
note("c3 eb3 g3 bb3").palindrome()
|
||||||
.s('sawtooth')
|
.s('sawtooth')
|
||||||
.jux(x=>x.rev().color('green').s('sawtooth'))
|
.jux(x=>x.rev().color('green').s('sawtooth'))
|
||||||
@ -848,6 +906,8 @@ export const csoundDemo = `// "CSound demo"
|
|||||||
// @license with CC BY-NC-SA 4.0 https://creativecommons.org/licenses/by-nc-sa/4.0/
|
// @license with CC BY-NC-SA 4.0 https://creativecommons.org/licenses/by-nc-sa/4.0/
|
||||||
// @by Felix Roos
|
// @by Felix Roos
|
||||||
|
|
||||||
|
setCps(1)
|
||||||
|
|
||||||
await loadCsound\`
|
await loadCsound\`
|
||||||
instr CoolSynth
|
instr CoolSynth
|
||||||
iduration = p3
|
iduration = p3
|
||||||
@ -885,6 +945,7 @@ export const loungeSponge = `// "Lounge sponge"
|
|||||||
// @by Felix Roos, livecode.orc by Steven Yi
|
// @by Felix Roos, livecode.orc by Steven Yi
|
||||||
|
|
||||||
await loadOrc('github:kunstmusik/csound-live-code/master/livecode.orc')
|
await loadOrc('github:kunstmusik/csound-live-code/master/livecode.orc')
|
||||||
|
setCps(1)
|
||||||
|
|
||||||
stack(
|
stack(
|
||||||
chord("<C^7 A7 Dm7 Fm7>/2").dict('lefthand').voicing()
|
chord("<C^7 A7 Dm7 Fm7>/2").dict('lefthand').voicing()
|
||||||
@ -905,6 +966,7 @@ export const arpoon = `// "Arpoon"
|
|||||||
// @by Felix Roos
|
// @by Felix Roos
|
||||||
|
|
||||||
await samples('github:tidalcycles/Dirt-Samples/master')
|
await samples('github:tidalcycles/Dirt-Samples/master')
|
||||||
|
setCps(1)
|
||||||
|
|
||||||
n("[0,3] 2 [1,3] 2".fast(3).lastOf(4, fast(2))).clip(2)
|
n("[0,3] 2 [1,3] 2".fast(3).lastOf(4, fast(2))).clip(2)
|
||||||
.offset("<<1 2> 2 1 1>")
|
.offset("<<1 2> 2 1 1>")
|
||||||
|
|||||||
@ -110,3 +110,4 @@ export async function shareCode(codeToShare) {
|
|||||||
logger(message);
|
logger(message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,7 +1,6 @@
|
|||||||
import { persistentMap, persistentAtom } from '@nanostores/persistent';
|
import { persistentMap, persistentAtom } from '@nanostores/persistent';
|
||||||
import { useStore } from '@nanostores/react';
|
import { useStore } from '@nanostores/react';
|
||||||
import { register } from '@strudel.cycles/core';
|
import { register } from '@strudel.cycles/core';
|
||||||
import * as tunes from './repl/tunes.mjs';
|
|
||||||
import { defaultAudioDeviceName } from './repl/panel/AudioDeviceSelector';
|
import { defaultAudioDeviceName } from './repl/panel/AudioDeviceSelector';
|
||||||
import { logger } from '@strudel.cycles/core';
|
import { logger } from '@strudel.cycles/core';
|
||||||
|
|
||||||
@ -126,11 +125,10 @@ export function newUserPattern() {
|
|||||||
const date = new Date().toISOString().split('T')[0];
|
const date = new Date().toISOString().split('T')[0];
|
||||||
const todays = Object.entries(userPatterns).filter(([name]) => name.startsWith(date));
|
const todays = Object.entries(userPatterns).filter(([name]) => name.startsWith(date));
|
||||||
const num = String(todays.length + 1).padStart(3, '0');
|
const num = String(todays.length + 1).padStart(3, '0');
|
||||||
const defaultNewPattern = 's("hh")';
|
|
||||||
const name = date + '_' + num;
|
const name = date + '_' + num;
|
||||||
addUserPattern(name, { code: defaultNewPattern });
|
const code = 's("hh")';
|
||||||
setActivePattern(name);
|
setUserPatterns({ ...userPatterns, [name]: { code } });
|
||||||
return name;
|
setViewingPattern(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function clearUserPatterns() {
|
export function clearUserPatterns() {
|
||||||
@ -173,26 +171,9 @@ export function renamePattern(pattern) {
|
|||||||
setViewingPattern(newName);
|
setViewingPattern(newName);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function updateUserCode(code) {
|
export function updateUserCode(pattern, code ) {
|
||||||
const userPatterns = getUserPatterns();
|
const userPatterns = getUserPatterns();
|
||||||
let activePattern = getActivePattern();
|
setUserPatterns({ ...userPatterns, [pattern]: { code } });
|
||||||
// check if code is that of an example tune
|
|
||||||
const [example] = Object.entries(tunes).find(([_, tune]) => tune === code) || [];
|
|
||||||
if (example && (!activePattern || activePattern === example)) {
|
|
||||||
// select example
|
|
||||||
setActivePattern(example);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!activePattern) {
|
|
||||||
// create new user pattern
|
|
||||||
activePattern = newUserPattern();
|
|
||||||
setActivePattern(activePattern);
|
|
||||||
} else if (!!tunes[activePattern] && code !== tunes[activePattern]) {
|
|
||||||
// fork example
|
|
||||||
activePattern = getNextCloneName(activePattern);
|
|
||||||
setActivePattern(activePattern);
|
|
||||||
}
|
|
||||||
setUserPatterns({ ...userPatterns, [activePattern]: { code } });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function deletePattern(pattern) {
|
export function deletePattern(pattern) {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user