From 82225f0b81a9d1f55310908923007e8fb4c43b18 Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Fri, 26 May 2023 14:12:53 +0200 Subject: [PATCH 01/33] started workshop pages --- packages/react/src/components/MiniRepl.jsx | 3 +- website/src/components/Box.astro | 10 + website/src/components/QA.tsx | 18 ++ website/src/config.ts | 9 +- website/src/docs/MiniRepl.jsx | 3 +- website/src/pages/workshop/first-effects.mdx | 62 ++++++ website/src/pages/workshop/first-sounds.mdx | 207 +++++++++++++++++++ website/src/pages/workshop/index.astro | 3 + website/src/pages/workshop/intro.mdx | 6 + website/src/pages/workshop/langebank.mdx | 37 ++++ website/src/pages/workshop/mini-notation.mdx | 69 +++++++ website/src/repl/prebake.mjs | 2 +- website/tsconfig.json | 7 +- 13 files changed, 431 insertions(+), 5 deletions(-) create mode 100644 website/src/components/Box.astro create mode 100644 website/src/components/QA.tsx create mode 100644 website/src/pages/workshop/first-effects.mdx create mode 100644 website/src/pages/workshop/first-sounds.mdx create mode 100644 website/src/pages/workshop/index.astro create mode 100644 website/src/pages/workshop/intro.mdx create mode 100644 website/src/pages/workshop/langebank.mdx create mode 100644 website/src/pages/workshop/mini-notation.mdx diff --git a/packages/react/src/components/MiniRepl.jsx b/packages/react/src/components/MiniRepl.jsx index a8de79788..8c45f1ed9 100644 --- a/packages/react/src/components/MiniRepl.jsx +++ b/packages/react/src/components/MiniRepl.jsx @@ -20,10 +20,11 @@ export function MiniRepl({ enableKeyboard, drawTime, punchcard, + span, canvasHeight = 200, theme, }) { - drawTime = drawTime || (punchcard ? [0, 4] : undefined); + drawTime = drawTime || (punchcard ? span || [0, 4] : undefined); const evalOnMount = !!drawTime; const drawContext = useCallback( !!drawTime ? (canvasId) => document.querySelector('#' + canvasId)?.getContext('2d') : null, diff --git a/website/src/components/Box.astro b/website/src/components/Box.astro new file mode 100644 index 000000000..d27671eaf --- /dev/null +++ b/website/src/components/Box.astro @@ -0,0 +1,10 @@ +--- +import LightBulbIcon from '@heroicons/react/20/solid/LightBulbIcon'; +//import MusicalNoteIcon from '@heroicons/react/20/solid/MusicalNoteIcon'; +--- + +
+
+ + +
diff --git a/website/src/components/QA.tsx b/website/src/components/QA.tsx new file mode 100644 index 000000000..ef743bede --- /dev/null +++ b/website/src/components/QA.tsx @@ -0,0 +1,18 @@ +import ChevronDownIcon from '@heroicons/react/20/solid/ChevronDownIcon'; +import ChevronUpIcon from '@heroicons/react/20/solid/ChevronUpIcon'; +import { useState } from 'react'; + +export default function QA({ children, q }) { + const [visible, setVisible] = useState(false); + return ( +
+
setVisible((v) => !v)}> +
{q}
+ + {visible ? : } + +
+ {visible &&
{children}
} +
+ ); +} diff --git a/website/src/config.ts b/website/src/config.ts index bf26fff15..541703786 100644 --- a/website/src/config.ts +++ b/website/src/config.ts @@ -38,9 +38,16 @@ export const ALGOLIA = { apiKey: 'd5044f9d21b80e7721e5b0067a8730b1', }; -export type Sidebar = Record<(typeof KNOWN_LANGUAGE_CODES)[number], Record>; +export type SidebarLang = Record; +export type Sidebar = Record<(typeof KNOWN_LANGUAGE_CODES)[number], SidebarLang>; export const SIDEBAR: Sidebar = { en: { + Workshop: [ + { text: 'Intro', link: 'workshop/intro' }, + { text: 'First Sounds', link: 'workshop/first-sounds' }, + { text: 'First Effects', link: 'workshop/first-effects' }, + { text: 'Mini Notation', link: 'workshop/mini-notation' }, + ], Tutorial: [ { text: 'Getting Started', link: 'learn/getting-started' }, { text: 'Notes', link: 'learn/notes' }, diff --git a/website/src/docs/MiniRepl.jsx b/website/src/docs/MiniRepl.jsx index cce24623f..8b93a4461 100644 --- a/website/src/docs/MiniRepl.jsx +++ b/website/src/docs/MiniRepl.jsx @@ -27,7 +27,7 @@ if (typeof window !== 'undefined') { prebake(); } -export function MiniRepl({ tune, drawTime, punchcard, canvasHeight = 100 }) { +export function MiniRepl({ tune, drawTime, punchcard, span = [0, 4], canvasHeight = 100 }) { const [Repl, setRepl] = useState(); const { theme } = useSettings(); useEffect(() => { @@ -44,6 +44,7 @@ export function MiniRepl({ tune, drawTime, punchcard, canvasHeight = 100 }) { hideOutsideView={true} drawTime={drawTime} punchcard={punchcard} + span={span} canvasHeight={canvasHeight} theme={themes[theme]} /> diff --git a/website/src/pages/workshop/first-effects.mdx b/website/src/pages/workshop/first-effects.mdx new file mode 100644 index 000000000..56914dbc5 --- /dev/null +++ b/website/src/pages/workshop/first-effects.mdx @@ -0,0 +1,62 @@ +--- +title: First Effects +layout: ../../layouts/MainLayout.astro +--- + +import { MiniRepl } from '../../docs/MiniRepl'; + +# First Effects + +**vowel** + + + +You can probably think of more vowels :) + +**gain** + + + +**control the gain with a sine wave** + + + +Try also `saw`, `square`, `tri` + +**The 'structure' comes from the left - try swapping:** + + + +**speed of playback, e.g. 2 = double speed (up 1 octave)** + + + + + +**set note** + + + +**pan** + + + + + +**delay** + + + +**room** + + diff --git a/website/src/pages/workshop/first-sounds.mdx b/website/src/pages/workshop/first-sounds.mdx new file mode 100644 index 000000000..1a9df5f63 --- /dev/null +++ b/website/src/pages/workshop/first-sounds.mdx @@ -0,0 +1,207 @@ +--- +title: First Sounds +layout: ../../layouts/MainLayout.astro +--- + +import { MiniRepl } from '@src/docs/MiniRepl'; +import Box from '@components/Box.astro'; +import QA from '@components/QA'; + +# First Sounds + +## Make a Sound + +Let's start by making some noise: + + + + + +1. press play button to start +2. change `house` to `casio` +3. press refresh button to update +4. press stop button to stop + + + +Congratulations, you've played your first pattern! + +Instead of clicking update all the time, you can use keyboard shortcuts: + + + +1. click into the text field +2. press `ctrl`+`enter` to play +3. change `casio` to `crow` +4. press `ctrl`+`enter` to update +5. press `ctrl`+`.` to stop + + + +To play code like an instrument, these shortcuts should become second nature to you. + +**Try more Sounds** + +You can pick a different sample from the same set, with ':' + + + +Try changing `east:1` to `east:2` + +Here are some more sound sets to try + +``` +casio control crow techno house jazz +metal east jvbass juno insect space wind +bd sd rim hh oh +``` + + + +- `bd` = **b**ass **d**rum +- `sd` = **s**nare **d**rum +- `sn` = **sn**are +- `rim` = **rim**shot +- `hh` = **h**i**h**at +- `oh` = **o**pen **h**ihat + + + +## Sequences + +**Make a Sequence** + + + +Notice how the currently playing sound is highlighted in the code and also visualized below. + + + +Try adding more sounds to the sequence! + + + +**The longer the sequence, the faster it runs** + + + +The content of the sequence will be squished into one second, called a cycle. + +**One way to change the tempo is using `cpm`** + + + + + +cpm = cycles per minute + +By default, the tempo is 60 cycles per minute = 1 cycle per second. + + + +We will look at other ways to change the tempo later! + +**Add a rests in a sequence with '~'** + + + +**Sub-Sequences with [brackets]** + + + + + +Try adding more sounds inside a bracket! + + + +Similar to the whole sequence, the content of a sub-sequence will be squished to the its own length. + +**Multiplication: Speed things up** + + + +**Multiplication: Speeeeeeeeed things up** + + + + + +Pitch = Really fast Rhythm + + + +**Sub-Sub-Sequences with [[brackets]]** + + + +**Play Sounds in parallel with comma** + + + + + +**Multiple Lines with backticks** + + + +## Recap + +Now we've learned the basics of the so called Mini-Notation, the rhythm language of Tidal. +This is what we've leared so far: + +| Concept | Syntax | Example | +| ----------------- | ---------- | --------------------------------------------------------------------- | +| Sequence | space | | +| Sample Number | :x | | +| Rests | ~ | | +| Sub-Sequences | \[ \] | | +| Sub-Sub-Sequences | \[ \[ \]\] | | +| Speed up | \* | | +| Parallel | , | | + +## Examples + +Imitation of a step sequencer: + + + +Shorter variant: + + + +Another beat: + + diff --git a/website/src/pages/workshop/index.astro b/website/src/pages/workshop/index.astro new file mode 100644 index 000000000..9f79e4c22 --- /dev/null +++ b/website/src/pages/workshop/index.astro @@ -0,0 +1,3 @@ + diff --git a/website/src/pages/workshop/intro.mdx b/website/src/pages/workshop/intro.mdx new file mode 100644 index 000000000..e7b075b4c --- /dev/null +++ b/website/src/pages/workshop/intro.mdx @@ -0,0 +1,6 @@ +--- +title: Introduction +layout: ../../layouts/MainLayout.astro +--- + +# Introduction diff --git a/website/src/pages/workshop/langebank.mdx b/website/src/pages/workshop/langebank.mdx new file mode 100644 index 000000000..55fbdf4b7 --- /dev/null +++ b/website/src/pages/workshop/langebank.mdx @@ -0,0 +1,37 @@ +Everythings repeats once per second => 1 **c**ycle **p**er **s**econd (cps) + +**Change tempo** + + + +adding your own samples + + + +").slow(3)`} + punchcard +/> + + +n(run(8)).sound("east") \ No newline at end of file diff --git a/website/src/pages/workshop/mini-notation.mdx b/website/src/pages/workshop/mini-notation.mdx new file mode 100644 index 000000000..df1c8cbee --- /dev/null +++ b/website/src/pages/workshop/mini-notation.mdx @@ -0,0 +1,69 @@ +--- +title: First Sounds +layout: ../../layouts/MainLayout.astro +--- + +import { MiniRepl } from '../../docs/MiniRepl'; + +# Mini Notation + +Mini Notation is everything between the quotes. It the short rhythm language of Tidal. + +## Cycles + +**The longer the sequence, the faster it runs** + + + +**Play less sounds per cycle with \{curly braces\}** + + + +**Use \`backticks\` for multiple lines** + + + +**Play one sounds per cycle with \** + +")`} punchcard /> + +This is the same as `{...}%1` + +## Operators + +**Multiplication: Speed things up** + + + +**Division: Slow things down** + + + +`bd` will play only every second time + +## Combining it all + +**Speed up Sub-Sequences** + + + +**Slow down Sequences** + + + +**Parallel Sub-Sequences** + + + +**Sample Numbers on groups** + + diff --git a/website/src/repl/prebake.mjs b/website/src/repl/prebake.mjs index edf63f546..f8a4e4770 100644 --- a/website/src/repl/prebake.mjs +++ b/website/src/repl/prebake.mjs @@ -22,8 +22,8 @@ export async function prebake() { tag: 'drum-machines', }), samples(`./EmuSP12.json`, `./EmuSP12/`, { prebake: true, tag: 'drum-machines' }), - // samples('github:tidalcycles/Dirt-Samples/master'), ]); + await samples('github:tidalcycles/Dirt-Samples/master'); } const maxPan = noteToMidi('C8'); diff --git a/website/tsconfig.json b/website/tsconfig.json index 78017eafe..90aa524fd 100644 --- a/website/tsconfig.json +++ b/website/tsconfig.json @@ -7,6 +7,11 @@ "noImplicitAny": false, "types": [ "vite-plugin-pwa/client" - ] + ], + "baseUrl": ".", + "paths": { + "@components/*": ["src/components/*"], + "@src/*": ["src/*"], + } } } \ No newline at end of file From 0d6fcf78d83691ca324fb69acd63e14322924688 Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Fri, 26 May 2023 16:05:53 +0200 Subject: [PATCH 02/33] hide mini repl headers + improve workshop --- packages/react/src/components/MiniRepl.jsx | 62 ++++--- website/src/docs/MiniRepl.jsx | 3 +- website/src/pages/workshop/first-sounds.mdx | 180 +++++++++++++------- website/src/pages/workshop/langebank.mdx | 23 ++- 4 files changed, 178 insertions(+), 90 deletions(-) diff --git a/packages/react/src/components/MiniRepl.jsx b/packages/react/src/components/MiniRepl.jsx index 8c45f1ed9..9c30dc29d 100644 --- a/packages/react/src/components/MiniRepl.jsx +++ b/packages/react/src/components/MiniRepl.jsx @@ -20,11 +20,12 @@ export function MiniRepl({ enableKeyboard, drawTime, punchcard, - span, canvasHeight = 200, + fontSize = 18, + hideHeader = false, theme, }) { - drawTime = drawTime || (punchcard ? span || [0, 4] : undefined); + drawTime = drawTime || (punchcard ? [0, 4] : undefined); const evalOnMount = !!drawTime; const drawContext = useCallback( !!drawTime ? (canvasId) => document.querySelector('#' + canvasId)?.getContext('2d') : null, @@ -48,7 +49,10 @@ export function MiniRepl({ } = useStrudel({ initialCode: tune, defaultOutput: webaudioOutput, - editPattern: (pat) => (punchcard ? pat.punchcard() : pat), + editPattern: (pat, id) => { + //pat = pat.withContext((ctx) => ({ ...ctx, id })); + return punchcard ? pat.punchcard() : pat; + }, getTime, evalOnMount, drawContext, @@ -102,7 +106,7 @@ export function MiniRepl({ // const logId = data?.pattern?.meta?.id; if (logId === replId) { setLog((l) => { - return l.concat([e.detail]).slice(-10); + return l.concat([e.detail]).slice(-8); }); } }, []), @@ -110,31 +114,35 @@ export function MiniRepl({ return (
-
-
- - + {!hideHeader && ( +
+
+ + +
- {error &&
{error.message}
} -
+ )}
- {show && } + {show && ( + + )} + {error &&
{error.message}
}
{drawTime && ( { @@ -47,6 +47,7 @@ export function MiniRepl({ tune, drawTime, punchcard, span = [0, 4], canvasHeigh span={span} canvasHeight={canvasHeight} theme={themes[theme]} + hideHeader={hideHeader} />
) : ( diff --git a/website/src/pages/workshop/first-sounds.mdx b/website/src/pages/workshop/first-sounds.mdx index 1a9df5f63..65a79093b 100644 --- a/website/src/pages/workshop/first-sounds.mdx +++ b/website/src/pages/workshop/first-sounds.mdx @@ -13,50 +13,51 @@ import QA from '@components/QA'; Let's start by making some noise: - + -1. press play button to start -2. change `house` to `casio` -3. press refresh button to update -4. press stop button to stop - - - -Congratulations, you've played your first pattern! - -Instead of clicking update all the time, you can use keyboard shortcuts: - - - -1. click into the text field +1. ⬆️ click into the text field above ⬆️ 2. press `ctrl`+`enter` to play -3. change `casio` to `crow` +3. change `house` to `casio` 4. press `ctrl`+`enter` to update 5. press `ctrl`+`.` to stop -To play code like an instrument, these shortcuts should become second nature to you. +Congratulations, you are now live coding! **Try more Sounds** You can pick a different sample from the same set, with ':' - + -Try changing `east:1` to `east:2` + -Here are some more sound sets to try +Try changing `east:1` to `east:2` to hear a different sound in the `east` set. + +You can try other numbers too! You might hear a little pause while the sound is loading + + + +Here are some more sound sets to try: ``` casio control crow techno house jazz metal east jvbass juno insect space wind -bd sd rim hh oh ``` - +Now you know how to use different sounds. +For now we'll stick to this little selection of sounds, but we'll find out how to load your own sounds later. + +## Drum Sounds + +By default, Strudel comes with a wide selection of drum sounds: + + + +These letter combinations stand for different parts of a drum set: - `bd` = **b**ass **d**rum - `sd` = **s**nare **d**rum @@ -65,13 +66,30 @@ bd sd rim hh oh - `hh` = **h**i**h**at - `oh` = **o**pen **h**ihat - +To change the sound character of our drums, we can use `bank` to change the drum machine: + + + +In this example `RolandTR909` is the name of the drum machine that we're using. +It is a famous drum machine for house and techno beats. + + + +Try changing `RolandTR909` to one of + +- `AkaiLinn` +- `RhythmAce` +- `RolandTR808` +- `RolandTR707` +- `ViscoSpaceDrum` + + ## Sequences -**Make a Sequence** +In the last example, we already saw that you can play multiple sounds in a sequence by separating them with a space: - + Notice how the currently playing sound is highlighted in the code and also visualized below. @@ -83,13 +101,13 @@ Try adding more sounds to the sequence! **The longer the sequence, the faster it runs** - + -The content of the sequence will be squished into one second, called a cycle. +The content of a sequence will be squished into what's called a cycle. **One way to change the tempo is using `cpm`** - + @@ -103,11 +121,11 @@ We will look at other ways to change the tempo later! **Add a rests in a sequence with '~'** - + **Sub-Sequences with [brackets]** - + @@ -119,31 +137,44 @@ Similar to the whole sequence, the content of a sub-sequence will be squished to **Multiplication: Speed things up** - + + +**Multiplication: Speed up sequences** + + **Multiplication: Speeeeeeeeed things up** - + -Pitch = Really fast Rhythm +Pitch = really fast rhythm **Sub-Sub-Sequences with [[brackets]]** - + -**Play Sounds in parallel with comma** + + +You can go as deep as you want! - + - +**Play sequences in parallel with comma** + + + +You can use as many commas as you want: + + **Multiple Lines with backticks** | -| Sample Number | :x | | -| Rests | ~ | | -| Sub-Sequences | \[ \] | | -| Sub-Sub-Sequences | \[ \[ \]\] | | -| Speed up | \* | | -| Parallel | , | | +| Concept | Syntax | Example | +| ----------------- | ---------- | -------------------------------------------------------------------------------- | +| Sequence | space | | +| Sample Number | :x | | +| Rests | ~ | | +| Sub-Sequences | \[ \] | | +| Sub-Sub-Sequences | \[ \[ \]\] | | +| Speed up | \* | | +| Parallel | , | | ## Examples -Imitation of a step sequencer: +**Basic rock beat** + + + +**Classic house** + + + +Notice that the house and rock beats are extremely similar. Besides their different tempos and minor differences in the hihat and kick drum lines, these patterns are the same. You'll find certain drum patterns reused in many styles. + +We Will Rock you + + + +**Yellow Magic Orchestra - Firecracker** -Shorter variant: +**Imitation of a 16 step sequencer** -Another beat: +**Another one** + +**Not your average drums** + + + +This was just the tip of the iceberg! diff --git a/website/src/pages/workshop/langebank.mdx b/website/src/pages/workshop/langebank.mdx index 55fbdf4b7..b41d96580 100644 --- a/website/src/pages/workshop/langebank.mdx +++ b/website/src/pages/workshop/langebank.mdx @@ -1,4 +1,11 @@ -Everythings repeats once per second => 1 **c**ycle **p**er **s**econd (cps) + + +1. press play button to start +2. change `house` to `casio` +3. press refresh button to update +4. press stop button to stop + + **Change tempo** @@ -33,5 +40,17 @@ adding your own samples punchcard /> +n(run(8)).sound("east") -n(run(8)).sound("east") \ No newline at end of file +Shorter variant: + + From fc0618121701b39c46d6bd4e3ab0c8fbcaff837f Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Sat, 27 May 2023 13:30:57 +0200 Subject: [PATCH 03/33] - add claviature flag to minirepl - bring back option+dot on macos - consume more editor settings in minirepl --- packages/core/util.mjs | 3 +- packages/react/src/components/MiniRepl.jsx | 30 ++++++++++--- packages/react/src/hooks/useStrudel.mjs | 3 +- pnpm-lock.yaml | 51 ++++++++++++---------- website/package.json | 3 +- website/src/components/Claviature.jsx | 24 ++++++++++ website/src/docs/MiniRepl.jsx | 41 +++++++++++++++-- website/src/repl/Repl.jsx | 2 +- 8 files changed, 121 insertions(+), 36 deletions(-) create mode 100644 website/src/components/Claviature.jsx diff --git a/packages/core/util.mjs b/packages/core/util.mjs index 2b43cf0b6..37fe6b6c1 100644 --- a/packages/core/util.mjs +++ b/packages/core/util.mjs @@ -67,13 +67,14 @@ export const getFreq = (noteOrMidi) => { return midiToFreq(noteToMidi(noteOrMidi)); }; +const pcs = ['C', 'Db', 'D', 'Eb', 'E', 'F', 'Gb', 'G', 'Ab', 'A', 'Bb', 'B']; /** * @deprecated does not appear to be referenced or invoked anywhere in the codebase * @noAutocomplete */ export const midi2note = (n) => { const oct = Math.floor(n / 12) - 1; - const pc = ['C', 'Db', 'D', 'Eb', 'E', 'F', 'Gb', 'G', 'Ab', 'A', 'Bb', 'B'][n % 12]; + const pc = pcs[n % 12]; return pc + oct; }; diff --git a/packages/react/src/components/MiniRepl.jsx b/packages/react/src/components/MiniRepl.jsx index 9c30dc29d..8ff738e69 100644 --- a/packages/react/src/components/MiniRepl.jsx +++ b/packages/react/src/components/MiniRepl.jsx @@ -18,18 +18,21 @@ export function MiniRepl({ tune, hideOutsideView = false, enableKeyboard, + onTrigger, drawTime, punchcard, + onPaint, canvasHeight = 200, fontSize = 18, hideHeader = false, theme, + keybindings, }) { drawTime = drawTime || (punchcard ? [0, 4] : undefined); const evalOnMount = !!drawTime; const drawContext = useCallback( - !!drawTime ? (canvasId) => document.querySelector('#' + canvasId)?.getContext('2d') : null, - [drawTime], + punchcard ? (canvasId) => document.querySelector('#' + canvasId)?.getContext('2d') : null, + [punchcard], ); const { code, @@ -51,7 +54,15 @@ export function MiniRepl({ defaultOutput: webaudioOutput, editPattern: (pat, id) => { //pat = pat.withContext((ctx) => ({ ...ctx, id })); - return punchcard ? pat.punchcard() : pat; + if (onTrigger) { + pat = pat.onTrigger(onTrigger, false); + } + if (onPaint) { + pat = pat.onPaint(onPaint); + } else if (punchcard) { + pat = pat.punchcard(); + } + return pat; }, getTime, evalOnMount, @@ -87,7 +98,7 @@ export function MiniRepl({ e.preventDefault(); flash(view); await activateCode(); - } else if (e.key === '.') { + } else if (e.key === '.' || e.code === 'Period') { stop(); e.preventDefault(); } @@ -140,11 +151,18 @@ export function MiniRepl({ )}
{show && ( - + )} {error &&
{error.message}
}
- {drawTime && ( + {punchcard && ( !!(pat?.context?.onPaint && drawContext), [drawContext]); + //const shouldPaint = useCallback((pat) => !!(pat?.context?.onPaint && drawContext), [drawContext]); + const shouldPaint = useCallback((pat) => !!pat?.context?.onPaint, []); // TODO: make sure this hook reruns when scheduler.started changes const { scheduler, evaluate, start, stop, pause, setCps } = useMemo( diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 3a135d893..6542a7072 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -92,7 +92,7 @@ importers: devDependencies: vite: specifier: ^4.3.3 - version: 4.3.3(@types/node@18.16.3) + version: 4.3.3(@types/node@18.11.18) packages/core: dependencies: @@ -102,7 +102,7 @@ importers: devDependencies: vite: specifier: ^4.3.3 - version: 4.3.3(@types/node@18.16.3) + version: 4.3.3(@types/node@18.11.18) vitest: specifier: ^0.28.0 version: 0.28.0(@vitest/ui@0.28.0) @@ -127,7 +127,7 @@ importers: devDependencies: vite: specifier: ^4.3.3 - version: 4.3.3(@types/node@18.16.3) + version: 4.3.3(@types/node@18.11.18) packages/core/examples/vite-vanilla-repl-cm6: dependencies: @@ -155,7 +155,7 @@ importers: devDependencies: vite: specifier: ^4.3.2 - version: 4.3.3(@types/node@18.16.3) + version: 4.3.3(@types/node@18.11.18) packages/csound: dependencies: @@ -171,7 +171,7 @@ importers: devDependencies: vite: specifier: ^4.3.3 - version: 4.3.3(@types/node@18.16.3) + version: 4.3.3(@types/node@18.11.18) packages/embed: {} @@ -204,7 +204,7 @@ importers: version: link:../mini vite: specifier: ^4.3.3 - version: 4.3.3(@types/node@18.16.3) + version: 4.3.3(@types/node@18.11.18) vitest: specifier: ^0.28.0 version: 0.28.0(@vitest/ui@0.28.0) @@ -223,7 +223,7 @@ importers: devDependencies: vite: specifier: ^4.3.3 - version: 4.3.3(@types/node@18.16.3) + version: 4.3.3(@types/node@18.11.18) packages/mini: dependencies: @@ -236,7 +236,7 @@ importers: version: 3.0.2 vite: specifier: ^4.3.3 - version: 4.3.3(@types/node@18.16.3) + version: 4.3.3(@types/node@18.11.18) vitest: specifier: ^0.28.0 version: 0.28.0(@vitest/ui@0.28.0) @@ -255,7 +255,7 @@ importers: version: 5.8.1 vite: specifier: ^4.3.3 - version: 4.3.3(@types/node@18.16.3) + version: 4.3.3(@types/node@18.11.18) packages/react: dependencies: @@ -325,7 +325,7 @@ importers: version: 3.3.2 vite: specifier: ^4.3.3 - version: 4.3.3(@types/node@18.16.3) + version: 4.3.3(@types/node@18.11.18) packages/react/examples/nano-repl: dependencies: @@ -380,7 +380,7 @@ importers: version: 3.3.2 vite: specifier: ^4.3.3 - version: 4.3.3(@types/node@18.16.3) + version: 4.3.3(@types/node@18.11.18) packages/serial: dependencies: @@ -390,7 +390,7 @@ importers: devDependencies: vite: specifier: ^4.3.3 - version: 4.3.3(@types/node@18.16.3) + version: 4.3.3(@types/node@18.11.18) packages/soundfonts: dependencies: @@ -412,7 +412,7 @@ importers: version: 3.3.1 vite: specifier: ^4.3.3 - version: 4.3.3(@types/node@18.16.3) + version: 4.3.3(@types/node@18.11.18) packages/tonal: dependencies: @@ -431,7 +431,7 @@ importers: devDependencies: vite: specifier: ^4.3.3 - version: 4.3.3(@types/node@18.16.3) + version: 4.3.3(@types/node@18.11.18) vitest: specifier: ^0.28.0 version: 0.28.0(@vitest/ui@0.28.0) @@ -447,7 +447,7 @@ importers: devDependencies: vite: specifier: ^4.3.3 - version: 4.3.3(@types/node@18.16.3) + version: 4.3.3(@types/node@18.11.18) vitest: specifier: ^0.28.0 version: 0.28.0(@vitest/ui@0.28.0) @@ -469,7 +469,7 @@ importers: devDependencies: vite: specifier: ^4.3.3 - version: 4.3.3(@types/node@18.16.3) + version: 4.3.3(@types/node@18.11.18) vitest: specifier: ^0.28.0 version: 0.28.0(@vitest/ui@0.28.0) @@ -494,7 +494,7 @@ importers: devDependencies: vite: specifier: ^4.3.3 - version: 4.3.3(@types/node@18.16.3) + version: 4.3.3(@types/node@18.11.18) packages/web/examples/repl-example: dependencies: @@ -504,7 +504,7 @@ importers: devDependencies: vite: specifier: ^4.3.2 - version: 4.3.3(@types/node@18.16.3) + version: 4.3.3(@types/node@18.11.18) packages/webaudio: dependencies: @@ -517,7 +517,7 @@ importers: devDependencies: vite: specifier: ^4.3.3 - version: 4.3.3(@types/node@18.16.3) + version: 4.3.3(@types/node@18.11.18) packages/webdirt: dependencies: @@ -533,7 +533,7 @@ importers: devDependencies: vite: specifier: ^4.3.3 - version: 4.3.3(@types/node@18.16.3) + version: 4.3.3(@types/node@18.11.18) vitest: specifier: ^0.28.0 version: 0.28.0(@vitest/ui@0.28.0) @@ -546,7 +546,7 @@ importers: devDependencies: vite: specifier: ^4.3.3 - version: 4.3.3(@types/node@18.16.3) + version: 4.3.3(@types/node@18.11.18) vitest: specifier: ^0.28.0 version: 0.28.0(@vitest/ui@0.28.0) @@ -646,6 +646,9 @@ importers: canvas: specifier: ^2.11.2 version: 2.11.2 + claviature: + specifier: ^0.1.0 + version: 0.1.0 fraction.js: specifier: ^4.2.0 version: 4.2.0 @@ -4502,7 +4505,7 @@ packages: '@babel/plugin-transform-react-jsx-self': 7.21.0(@babel/core@7.21.5) '@babel/plugin-transform-react-jsx-source': 7.19.6(@babel/core@7.21.5) react-refresh: 0.14.0 - vite: 4.3.3(@types/node@18.16.3) + vite: 4.3.3(@types/node@18.11.18) transitivePeerDependencies: - supports-color dev: true @@ -5413,6 +5416,10 @@ packages: resolution: {integrity: sha512-4jYS4MOAaCIStSRwiuxc4B8MYhIe676yO1sYGzARnjXkWpmzZMMYxY6zu8WYWDhSuth5zhrQ1rhNSibyyvv4/w==} engines: {node: '>=8'} + /claviature@0.1.0: + resolution: {integrity: sha512-Ai12axNwQ7x/F9QAj64RYKsgvi5Y33+X3GUSKAC/9s/adEws8TSSc0efeiqhKNGKBo6rT/c+CSCwSXzXxwxZzQ==} + dev: false + /clean-stack@2.2.0: resolution: {integrity: sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==} engines: {node: '>=6'} diff --git a/website/package.json b/website/package.json index 6b8b7a6cf..d6100625d 100644 --- a/website/package.json +++ b/website/package.json @@ -13,7 +13,7 @@ }, "dependencies": { "@algolia/client-search": "^4.17.0", - "@astrojs/mdx": "^0.19.0", + "@astrojs/mdx": "^0.19.0", "@astrojs/react": "^2.1.1", "@astrojs/tailwind": "^3.1.1", "@docsearch/css": "^3.3.4", @@ -43,6 +43,7 @@ "@uiw/codemirror-themes-all": "^4.19.16", "astro": "^2.3.2", "canvas": "^2.11.2", + "claviature": "^0.1.0", "fraction.js": "^4.2.0", "nanoid": "^4.0.2", "nanostores": "^0.8.1", diff --git a/website/src/components/Claviature.jsx b/website/src/components/Claviature.jsx new file mode 100644 index 000000000..e97facbc4 --- /dev/null +++ b/website/src/components/Claviature.jsx @@ -0,0 +1,24 @@ +import { getClaviature } from 'claviature'; +import React from 'react'; + +export default function Claviature({ options, onClick, onMouseDown, onMouseUp, onMouseLeave }) { + const svg = getClaviature({ + options, + onClick, + onMouseDown, + onMouseUp, + onMouseLeave, + }); + return ( + + {svg.children.map((el, i) => { + const TagName = el.name; + return ( + + {el.value} + + ); + })} + + ); +} diff --git a/website/src/docs/MiniRepl.jsx b/website/src/docs/MiniRepl.jsx index 6b434353a..651241a95 100644 --- a/website/src/docs/MiniRepl.jsx +++ b/website/src/docs/MiniRepl.jsx @@ -1,10 +1,11 @@ -import { evalScope, controls } from '@strudel.cycles/core'; +import { evalScope, controls, noteToMidi } from '@strudel.cycles/core'; import { initAudioOnFirstClick } from '@strudel.cycles/webaudio'; import { useEffect, useState } from 'react'; import { prebake } from '../repl/prebake'; import { themes, settings } from '../repl/themes.mjs'; import './MiniRepl.css'; import { useSettings } from '../settings.mjs'; +import Claviature from '@components/Claviature'; let modules; if (typeof window !== 'undefined') { @@ -27,9 +28,19 @@ if (typeof window !== 'undefined') { prebake(); } -export function MiniRepl({ tune, drawTime, punchcard, span = [0, 4], canvasHeight = 100, hideHeader }) { +export function MiniRepl({ + tune, + drawTime, + punchcard, + span = [0, 4], + canvasHeight = 100, + hideHeader, + claviature, + claviatureLabels, +}) { const [Repl, setRepl] = useState(); - const { theme } = useSettings(); + const { theme, keybindings, fontSize, fontFamily } = useSettings(); + const [activeNotes, setActiveNotes] = useState([]); useEffect(() => { // we have to load this package on the client // because codemirror throws an error on the server @@ -42,13 +53,35 @@ export function MiniRepl({ tune, drawTime, punchcard, span = [0, 4], canvasHeigh { + const active = haps + .map((hap) => hap.value.note) + .filter(Boolean) + .map((n) => (typeof n === 'string' ? noteToMidi(n) : n)); + setActiveNotes(active); + } + : undefined + } /> + {claviature && ( + + )}
) : (
{tune}
diff --git a/website/src/repl/Repl.jsx b/website/src/repl/Repl.jsx index 4ad387fee..1db8f8dd1 100644 --- a/website/src/repl/Repl.jsx +++ b/website/src/repl/Repl.jsx @@ -157,7 +157,7 @@ export function Repl({ embedded = false }) { e.preventDefault(); flash(view); await activateCode(); - } else if (e.key === '.') { + } else if (e.key === '.' || e.keyCode === 'Period') { stop(); e.preventDefault(); } From 4e575c44b3f2821d745303f90034a99fec0299c8 Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Sat, 27 May 2023 13:31:18 +0200 Subject: [PATCH 04/33] begin first notes page --- website/src/components/QA.tsx | 1 + website/src/config.ts | 1 + website/src/pages/workshop/first-notes.mdx | 227 ++++++++++++++++++++ website/src/pages/workshop/first-sounds.mdx | 4 +- website/src/pages/workshop/langebank.mdx | 35 +++ 5 files changed, 267 insertions(+), 1 deletion(-) create mode 100644 website/src/pages/workshop/first-notes.mdx diff --git a/website/src/components/QA.tsx b/website/src/components/QA.tsx index ef743bede..7d2ac53d9 100644 --- a/website/src/components/QA.tsx +++ b/website/src/components/QA.tsx @@ -1,5 +1,6 @@ import ChevronDownIcon from '@heroicons/react/20/solid/ChevronDownIcon'; import ChevronUpIcon from '@heroicons/react/20/solid/ChevronUpIcon'; +import React from 'react'; import { useState } from 'react'; export default function QA({ children, q }) { diff --git a/website/src/config.ts b/website/src/config.ts index 541703786..6fc7bb771 100644 --- a/website/src/config.ts +++ b/website/src/config.ts @@ -45,6 +45,7 @@ export const SIDEBAR: Sidebar = { Workshop: [ { text: 'Intro', link: 'workshop/intro' }, { text: 'First Sounds', link: 'workshop/first-sounds' }, + { text: 'First Notes', link: 'workshop/first-notes' }, { text: 'First Effects', link: 'workshop/first-effects' }, { text: 'Mini Notation', link: 'workshop/mini-notation' }, ], diff --git a/website/src/pages/workshop/first-notes.mdx b/website/src/pages/workshop/first-notes.mdx new file mode 100644 index 000000000..6e4f91102 --- /dev/null +++ b/website/src/pages/workshop/first-notes.mdx @@ -0,0 +1,227 @@ +--- +title: First Notes +layout: ../../layouts/MainLayout.astro +--- + +import { MiniRepl } from '@src/docs/MiniRepl'; +import { midi2note } from '@strudel.cycles/core/'; +import Box from '@components/Box.astro'; +import QA from '@components/QA'; + +# First Notes + +Let's look at how we can play notes + +## numbers and notes + +**play notes with numbers** + + [midi2note(i + 36), i + 36]), + )} +/> + + + +Try out different numbers! + +Try decimal numbers, like 55.5 + + + +**play notes with letters** + + [n, n.split('')[0]]))} +/> + + + +Try out different letters (a - g). + +Can you find melodies that are actual words? Hint: ☕ 😉 ⚪ + + + +**add flats or sharps to play the black keys** + + [n, n.split('').slice(0, 2).join('')]), + )} +/> + + [n, n.split('').slice(0, 2).join('')]), + )} +/> + +**play notes with letters in different octaves** + + [n, n]))} + claviatureLabels={Object.fromEntries( + Array(49) + .fill() + .map((_, i) => [midi2note(i + 36), midi2note(i + 36)]), + )} +/> + + + +Try out different octaves (1-8) + + + +## changing the sound + +Just like with unpitched sounds, we can change the sound of our notes with `sound`: + + + + + +Try out different sounds: + +- gm_electric_guitar_muted +- gm_acoustic_bass +- gm_voice_oohs +- gm_blown_bottle +- sawtooth +- square +- triangle +- how about bd, sd or hh? +- remove `.sound('...')` completely + + + +**switch between sounds** + + + +**stack multiple sounds** + + + + + +The `note` and `sound` patterns are combined! + +We will see more ways to combine patterns later.. + + + +## Longer Sequences + +**Divide sequences with `/` to slow them down** + +{/* [c2 bb1 f2 eb2] */} + + + + + +The `/4` plays the sequence in brackets over 4 cycles (=4s). + +Try adding more notes inside the brackets and notice how it gets faster. + + + +Because it is so common to just play one thing per cycle, you can.. + +**Play one per cycle with \< \>** + +").sound("gm_acoustic_bass")`} punchcard /> + + + +Try adding more notes inside the brackets and notice how it does **not** get faster. + + + +**Play one sequence per cycle** + +{/* <[c2 c3]*4 [bb1 bb2]*4 [f2 f3]*4 [eb2 eb3]*4>/2 */} + +/2") + .sound("gm_acoustic_bass")`} +/> + +**Play X per cycle with \{ \}** + + + + + +Try different numbers after `%` + +`{ ... }%1` is the same as `< ... >` + + + +## Examples + +Small Town Boy + +/2") +.sound("gm_synth_bass_1").lpf(1000)`} +/> + +/2" +.add.squeeze("[0 12]\*4") +.note() +.sound("gm_synth_bass_1")`} +/> diff --git a/website/src/pages/workshop/first-sounds.mdx b/website/src/pages/workshop/first-sounds.mdx index 65a79093b..b0aeb1fbb 100644 --- a/website/src/pages/workshop/first-sounds.mdx +++ b/website/src/pages/workshop/first-sounds.mdx @@ -83,6 +83,8 @@ Try changing `RolandTR909` to one of - `RolandTR707` - `ViscoSpaceDrum` +There are a lot more, but let's keep it simple for now + ## Sequences @@ -264,4 +266,4 @@ insect [crow metal] ~ ~, punchcard /> -This was just the tip of the iceberg! +Now that we know the basics of how to make beats, let's look at how we can play [notes](/workshop/first-notes) diff --git a/website/src/pages/workshop/langebank.mdx b/website/src/pages/workshop/langebank.mdx index b41d96580..44e5d6009 100644 --- a/website/src/pages/workshop/langebank.mdx +++ b/website/src/pages/workshop/langebank.mdx @@ -54,3 +54,38 @@ Shorter variant: bd [~ ~ ~ bd] [~ bd] [~ ~ ~ bd] \`).cpm(90/4)`} /> + +polyrythms & polymeters + +-- This can make for flexible time signatures: + +d1 $ sound "[bd bd sn:5] [bd sn:3]" + +-- You can put subsequences inside subsequences: +d1 $ sound "[[bd bd] bd sn:5] [bd sn:3]" + +-- Keep going.. +d1 $ sound "[[bd [bd bd bd bd]] bd sn:5] [bd sn:3]" + +-- * Polymetric / polyrhythmic sequences + +-- Play two subsequences at once by separating with a comma: + +d1 $ sound "[voodoo voodoo:3, arpy arpy:4 arpy:2]" + +-- compare how [,] and {,} work: + +d1 $ sound "[voodoo voodoo:3, arpy arpy:4 arpy:2]" + +d1 $ sound "{voodoo voodoo:3, arpy arpy:4 arpy:2}" + +d1 $ sound "[drum bd hh bd, can can:2 can:3 can:4 can:2]" + +d1 $ sound "{drum bd hh bd, can can:2 can:3 can:4 can:2}" + +d1 $ sound "[bd sn, can:2 can:3 can:1, arpy arpy:1 arpy:2 arpy:3 arpy:5]" + +d1 $ sound "{bd sn, can:2 can:3 can:1, arpy arpy:1 arpy:2 arpy:3 arpy:5}" + + + From ed792fc0d46a75b6836a5d74ca79079f004b2111 Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Sat, 27 May 2023 16:29:05 +0200 Subject: [PATCH 05/33] continue notes chapter --- website/src/pages/workshop/first-notes.mdx | 74 ++++++++++++++++------ website/src/pages/workshop/langebank.mdx | 30 +++++++++ 2 files changed, 86 insertions(+), 18 deletions(-) diff --git a/website/src/pages/workshop/first-notes.mdx b/website/src/pages/workshop/first-notes.mdx index 6e4f91102..cb40713fa 100644 --- a/website/src/pages/workshop/first-notes.mdx +++ b/website/src/pages/workshop/first-notes.mdx @@ -97,11 +97,17 @@ Try out different octaves (1-8) +If you are not comfortable with the note letter system, it should be easier to use numbers instead. +Most of the examples below will use numbers for that reason. +We will also look at ways to make it easier to play the right notes later. + ## changing the sound Just like with unpitched sounds, we can change the sound of our notes with `sound`: - + + +{/* c2 g2, e3 b3 d4 e4 */} @@ -157,6 +163,8 @@ We will see more ways to combine patterns later.. The `/4` plays the sequence in brackets over 4 cycles (=4s). +So each of the 4 notes is 1s long. + Try adding more notes inside the brackets and notice how it gets faster. @@ -181,47 +189,77 @@ Try adding more notes inside the brackets and notice how it does **not** get fas hideHeader client:visible tune={`note("<[36 48]*4 [34 46]*4 [41 53]*4 [39 51]*4>/2") - .sound("gm_acoustic_bass")`} +.sound("gm_acoustic_bass")`} +/> + +**Alternate between multiple things** + +") +.sound("gm_xylophone")`} +/> + +This is also useful for unpitched sounds: + +, [~ hh]*2") +.bank("RolandTR909")`} /> -**Play X per cycle with \{ \}** +## Scales + +Finding the right notes can be difficult.. Scales are here to help: ") +.scale("C:minor").sound("piano")`} /> -Try different numbers after `%` +Try out different numbers. Any number should sound good! + +Try out different scales: -`{ ... }%1` is the same as `< ... >` +- C:major +- A2:minor +- D:dorian +- G:mixolydian +- A2:minor:pentatonic +- F:major:pentatonic -## Examples +**automate scales** -Small Town Boy +Just like anything, we can automate the scale with a pattern: + +") +.scale("/2") +.sound("piano")`} +/> + +## Examples /2") -.sound("gm_synth_bass_1").lpf(1000)`} +.sound("gm_synth_bass_1")`} /> /2" -.add.squeeze("[0 12]\*4") -.note() + tune={`note("[0 12]*2".add("<36 34 41 39>/2")) .sound("gm_synth_bass_1")`} /> diff --git a/website/src/pages/workshop/langebank.mdx b/website/src/pages/workshop/langebank.mdx index 44e5d6009..9190afa66 100644 --- a/website/src/pages/workshop/langebank.mdx +++ b/website/src/pages/workshop/langebank.mdx @@ -89,3 +89,33 @@ d1 $ sound "{bd sn, can:2 can:3 can:1, arpy arpy:1 arpy:2 arpy:3 arpy:5}" + + + +**Play X per cycle with \{ \}** + + + + + +Try different numbers after `%` + +`{ ... }%1` is the same as `< ... >` + + + +## Bracket Recap + +- `[]` squeezes contents to 1 cycle +- `<>` plays one item per cycle +- `{}%x` plays x items per cycle From 1ba5d2e1ca09c5aa086130c57c87746e021e3081 Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Sat, 27 May 2023 21:52:44 +0200 Subject: [PATCH 06/33] finish notes chapter --- website/src/pages/workshop/first-effects.mdx | 22 ++-- website/src/pages/workshop/first-notes.mdx | 127 ++++++++++++++++++- website/src/pages/workshop/first-sounds.mdx | 23 +++- website/src/pages/workshop/langebank.mdx | 45 ++++++- 4 files changed, 191 insertions(+), 26 deletions(-) diff --git a/website/src/pages/workshop/first-effects.mdx b/website/src/pages/workshop/first-effects.mdx index 56914dbc5..1b718b166 100644 --- a/website/src/pages/workshop/first-effects.mdx +++ b/website/src/pages/workshop/first-effects.mdx @@ -9,54 +9,52 @@ import { MiniRepl } from '../../docs/MiniRepl'; **vowel** - + You can probably think of more vowels :) **gain** - + **control the gain with a sine wave** - + Try also `saw`, `square`, `tri` **The 'structure' comes from the left - try swapping:** - + **speed of playback, e.g. 2 = double speed (up 1 octave)** - + -**set note** - - - **pan** - + **delay** - + **room** - + diff --git a/website/src/pages/workshop/first-notes.mdx b/website/src/pages/workshop/first-notes.mdx index cb40713fa..b986ba791 100644 --- a/website/src/pages/workshop/first-notes.mdx +++ b/website/src/pages/workshop/first-notes.mdx @@ -190,6 +190,7 @@ Try adding more notes inside the brackets and notice how it does **not** get fas client:visible tune={`note("<[36 48]*4 [34 46]*4 [41 53]*4 [39 51]*4>/2") .sound("gm_acoustic_bass")`} + punchcard /> **Alternate between multiple things** @@ -199,6 +200,7 @@ Try adding more notes inside the brackets and notice how it does **not** get fas client:visible tune={`note("60 <63 62 65 63>") .sound("gm_xylophone")`} + punchcard /> This is also useful for unpitched sounds: @@ -208,6 +210,7 @@ This is also useful for unpitched sounds: client:visible tune={`sound("bd*2, ~ , [~ hh]*2") .bank("RolandTR909")`} + punchcard /> ## Scales @@ -219,6 +222,7 @@ Finding the right notes can be difficult.. Scales are here to help: client:visible tune={`n("0 2 4 <[6,8] [7,9]>") .scale("C:minor").sound("piano")`} + punchcard /> @@ -243,23 +247,136 @@ Just like anything, we can automate the scale with a pattern: ") -.scale("/2") + tune={`n("<0 -3>, 2 4 <[6,8] [7,9]>") +.scale("/4") .sound("piano")`} + punchcard /> + + +If you have no idea what these scale mean, don't worry. +These are just labels for different sets of notes that go well together. + +Take your time and you'll find scales you like! + + + +## Repeat & Elongate + +**Elongate with @** + + + + + +Not using `@` is like using `@1`. In the above example, c is 3 units long and eb is 1 unit long. + +Try changing that number! + + + +**Elongate within sub-sequences** + +*2") +.scale("/4") +.sound("gm_acoustic_bass")`} + punchcard +/> + + + +This groove is called a `shuffle`. +Each beat has two notes, where the first is twice as long as the second. +This is also sometimes called triplet swing. You'll often find it in blues and jazz. + + + +**Replicate** + +]").sound("piano")`} punchcard /> + + + +Try switching between `!`, `*` and `@` + +What's the difference? + + + +## Recap + +Let's recap what we've learned in this chapter: + +| Concept | Syntax | Example | +| --------- | ------ | ------------------------------------------------------------------- | +| Slow down | \/ | | +| Alternate | \<\> | ")`} /> | +| Elongate | @ | | +| Replicate | ! | | + ## Examples +**Classy Bassline** + /2") -.sound("gm_synth_bass_1")`} +.sound("gm_synth_bass_1") +.lpf(800) // <-- we'll learn about this soon`} +/> + +**Classy Melody** + +*2\`).scale("C4:minor") +.sound("gm_synth_strings_1")`} /> +**Classy Drums** + /2")) -.sound("gm_synth_bass_1")`} + tune={`sound("bd*2, ~ , [~ hh]*2") +.bank("RolandTR909")`} /> + +**If there just was a way to play all the above at the same time.......** + + + +It's called `stack` 😙 + + + +/2") + .sound("gm_synth_bass_1").lpf(800), + n(\`< + [~ 0] 2 [0 2] [~ 2] + [~ 0] 1 [0 1] [~ 1] + [~ 0] 3 [0 3] [~ 3] + [~ 0] 2 [0 2] [~ 2] + >*2\`).scale("C4:minor") + .sound("gm_synth_strings_1"), + sound("bd*2, ~ , [~ hh]*2") + .bank("RolandTR909") +)`} +/> + +This is starting to sound like actual music! We have sounds, we have notes, now the last piece of the puzzle is missing: [effects](/workshop/first-effects) diff --git a/website/src/pages/workshop/first-sounds.mdx b/website/src/pages/workshop/first-sounds.mdx index b0aeb1fbb..852977a3c 100644 --- a/website/src/pages/workshop/first-sounds.mdx +++ b/website/src/pages/workshop/first-sounds.mdx @@ -91,7 +91,7 @@ There are a lot more, but let's keep it simple for now In the last example, we already saw that you can play multiple sounds in a sequence by separating them with a space: - + Notice how the currently playing sound is highlighted in the code and also visualized below. @@ -173,6 +173,18 @@ You can use as many commas as you want: +Commas can also be used inside sub-sequences: + + + + + +Notice how the 2 above are the same? + +It is quite common that there are many ways to express the same idea. + + + **Multiple Lines with backticks** + **Classic house** -Notice that the house and rock beats are extremely similar. Besides their different tempos and minor differences in the hihat and kick drum lines, these patterns are the same. You'll find certain drum patterns reused in many styles. + + +Notice that the two patterns are extremely similar. +Certain drum patterns are reused across genres. + + We Will Rock you diff --git a/website/src/pages/workshop/langebank.mdx b/website/src/pages/workshop/langebank.mdx index 9190afa66..7a1ca6977 100644 --- a/website/src/pages/workshop/langebank.mdx +++ b/website/src/pages/workshop/langebank.mdx @@ -67,7 +67,7 @@ d1 $ sound "[[bd bd] bd sn:5] [bd sn:3]" -- Keep going.. d1 $ sound "[[bd [bd bd bd bd]] bd sn:5] [bd sn:3]" --- * Polymetric / polyrhythmic sequences +-- \* Polymetric / polyrhythmic sequences -- Play two subsequences at once by separating with a comma: @@ -87,11 +87,6 @@ d1 $ sound "[bd sn, can:2 can:3 can:1, arpy arpy:1 arpy:2 arpy:3 arpy:5]" d1 $ sound "{bd sn, can:2 can:3 can:1, arpy arpy:1 arpy:2 arpy:3 arpy:5}" - - - - - **Play X per cycle with \{ \}** ` plays one item per cycle - `{}%x` plays x items per cycle + +/2")) +.sound("gm_synth_bass_1")`} +/> + +vertical + + +< 4 4 4 3> +<[2,7] [2,6] [1,6] [1,6]> +< 4 4 4 3> +>*2\`) +.scale("/4") +.sound("piano")`} +/> + +horizontal + +*2\`) +.scale("/4") +.sound("piano")`} +/> From 8c93e578a062ee24fdc0edc2c356caa118bf5964 Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Sun, 28 May 2023 12:41:46 +0200 Subject: [PATCH 07/33] clamp delayfeedback --- packages/webaudio/webaudio.mjs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/packages/webaudio/webaudio.mjs b/packages/webaudio/webaudio.mjs index 6b069a859..c59223031 100644 --- a/packages/webaudio/webaudio.mjs +++ b/packages/webaudio/webaudio.mjs @@ -85,7 +85,12 @@ export async function initAudioOnFirstClick() { } let delays = {}; +const maxfeedback = 0.98; function getDelay(orbit, delaytime, delayfeedback, t) { + if (delayfeedback > maxfeedback) { + logger(`delayfeedback was clamped to ${maxfeedback} to save your ears`); + } + delayfeedback = strudel.clamp(delayfeedback, 0, 0.98); if (!delays[orbit]) { const ac = getAudioContext(); const dly = ac.createFeedbackDelay(1, delaytime, delayfeedback); From 9971867e2f2adfa9b93f244bccdf71875ab65913 Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Sun, 28 May 2023 12:41:53 +0200 Subject: [PATCH 08/33] clamp function --- packages/core/util.mjs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/core/util.mjs b/packages/core/util.mjs index 37fe6b6c1..5dbf65fcb 100644 --- a/packages/core/util.mjs +++ b/packages/core/util.mjs @@ -213,3 +213,5 @@ export const splitAt = function (index, value) { }; export const zipWith = (f, xs, ys) => xs.map((n, i) => f(n, ys[i])); + +export const clamp = (num, min, max) => Math.min(Math.max(num, min), max); From d2dffe318685ec7d196d654ccb1a60b4cecc6acc Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Sun, 28 May 2023 12:42:15 +0200 Subject: [PATCH 09/33] MiniRepl: consume font settings --- packages/react/src/components/MiniRepl.jsx | 2 ++ website/src/docs/MiniRepl.css | 4 ++++ website/src/docs/MiniRepl.jsx | 2 ++ 3 files changed, 8 insertions(+) diff --git a/packages/react/src/components/MiniRepl.jsx b/packages/react/src/components/MiniRepl.jsx index 8ff738e69..c13ff28ed 100644 --- a/packages/react/src/components/MiniRepl.jsx +++ b/packages/react/src/components/MiniRepl.jsx @@ -24,6 +24,7 @@ export function MiniRepl({ onPaint, canvasHeight = 200, fontSize = 18, + fontFamily, hideHeader = false, theme, keybindings, @@ -156,6 +157,7 @@ export function MiniRepl({ onChange={setCode} onViewChanged={setView} theme={theme} + fontFamily={fontFamily} fontSize={fontSize} keybindings={keybindings} /> diff --git a/website/src/docs/MiniRepl.css b/website/src/docs/MiniRepl.css index e9b49af84..5e5206714 100644 --- a/website/src/docs/MiniRepl.css +++ b/website/src/docs/MiniRepl.css @@ -7,3 +7,7 @@ border: 1px solid var(--lineHighlight); padding: 2px; } + +.cm-scroller { + font-family: inherit !important; +} diff --git a/website/src/docs/MiniRepl.jsx b/website/src/docs/MiniRepl.jsx index 651241a95..6dfaf28e0 100644 --- a/website/src/docs/MiniRepl.jsx +++ b/website/src/docs/MiniRepl.jsx @@ -60,6 +60,8 @@ export function MiniRepl({ theme={themes[theme]} hideHeader={hideHeader} keybindings={keybindings} + fontFamily={fontFamily} + fontSize={fontSize} onPaint={ claviature ? (ctx, time, haps, drawTime) => { From 1e9979ae186b84d3c1f97f36b9167b7a7d5f5094 Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Sun, 28 May 2023 12:42:24 +0200 Subject: [PATCH 10/33] start fleshing out effects chapter --- website/src/pages/workshop/first-effects.mdx | 166 ++++++++++++++++++- website/src/pages/workshop/first-sounds.mdx | 35 ++-- 2 files changed, 181 insertions(+), 20 deletions(-) diff --git a/website/src/pages/workshop/first-effects.mdx b/website/src/pages/workshop/first-effects.mdx index 1b718b166..3c0fc0fda 100644 --- a/website/src/pages/workshop/first-effects.mdx +++ b/website/src/pages/workshop/first-effects.mdx @@ -7,15 +7,175 @@ import { MiniRepl } from '../../docs/MiniRepl'; # First Effects +import Box from '@components/Box.astro'; + +We have sounds, we have notes, now let's look at effects! + +**low-pass filter with lpf** + +/2") +.sound("sawtooth").lpf(800)`} +/> + + + +- Change lpf to 200. Notice how it gets muffled. Think of it as standing in front of the club with the door closed 🚪. +- Now let's open the door... change it to 8000. Notice how it gets sharper 🪩 + + + +**automate the filter** + +/2") +.sound("sawtooth").lpf("200 1000")`} +/> + + + +- Try adding more values +- Notice how the pattern in lpf does not change the overall rhythm + + + **vowel** - +/2") +.sound("sawtooth").vowel("/2")`} +/> + + + +- Try adding more values +- Notice how the pattern in lpf does not change the overall rhythm -You can probably think of more vowels :) + **gain** - + + + + +Rhythm is all about dynamics! + +Remove the gain and notice how flat it sounds. + + + +**stacks within stacks** + +Let's combine all of the above into a little tune: + +/2") + .sound("sawtooth").lpf("200 1000"), + note("<[c3,g3,e4] [bb2,f3,d4] [a2,f3,c4] [bb2,g3,eb4]>/2") + .sound("sawtooth").vowel("/2") +) `} +/> + + + +Pay attention to where the commas are and identify the individual parts of the stacks. +The 3 parts (drums, bassline, chords) are exactly as earlier, just stacked together. + + + +**fast and slow** + +We can use `fast` and `slow` to change the tempo of a pattern outside of Mini-Notation: + + + + + +Change the `slow` value. Try replacing it with `fast`. + +What happens if you use a pattern like `"<1 [2 4]>"`? + + + +By the way, inside Mini-Notation, `fast` is `*` and slow is `/`. + +")`} /> + +**delay** + + ~]") + .sound("gm_electric_guitar_muted"), + sound("").bank("RolandTR707") +).delay(".5")`} +/> + + + +Try some `delay` values between 0 and 1. Btw, `.5` is short for `0.5` + +What happens if you use `.delay(".8:.125")` ? Can you guess what the second number does? + +What happens if you use `.delay(".8:.06:.8")` ? Can you guess what the third number does? + + + +**room** + + ~@16] ~>/2") +.scale("D4:minor").sound("gm_accordion:2") +.room(2)`} +/> + + + +Try different values! + +Add a delay too! + + + +**little dub tune** + + ~]") + .sound("gm_electric_guitar_muted"), + sound("").bank("RolandTR707"), + n("<4 [3@3 4] [<2 0> ~@16] ~>/2") + .scale("D4:minor").sound("gm_accordion:2") + .room(2).gain(.5) +).delay(.5)`} +/> **control the gain with a sine wave** diff --git a/website/src/pages/workshop/first-sounds.mdx b/website/src/pages/workshop/first-sounds.mdx index 852977a3c..5b87d10f6 100644 --- a/website/src/pages/workshop/first-sounds.mdx +++ b/website/src/pages/workshop/first-sounds.mdx @@ -190,9 +190,10 @@ It is quite common that there are many ways to express the same idea. @@ -201,25 +202,25 @@ bd*2, [~ casio], Now we've learned the basics of the so called Mini-Notation, the rhythm language of Tidal. This is what we've leared so far: -| Concept | Syntax | Example | -| ----------------- | ---------- | -------------------------------------------------------------------------------- | -| Sequence | space | | -| Sample Number | :x | | -| Rests | ~ | | -| Sub-Sequences | \[ \] | | -| Sub-Sub-Sequences | \[ \[ \]\] | | -| Speed up | \* | | -| Parallel | , | | +| Concept | Syntax | Example | +| ----------------- | -------- | -------------------------------------------------------------------------------- | +| Sequence | space | | +| Sample Number | :x | | +| Rests | ~ | | +| Sub-Sequences | \[\] | | +| Sub-Sub-Sequences | \[\[\]\] | | +| Speed up | \* | | +| Parallel | , | | ## Examples **Basic rock beat** - + **Classic house** - + @@ -230,15 +231,15 @@ Certain drum patterns are reused across genres. We Will Rock you - + **Yellow Magic Orchestra - Firecracker** From 8679dc63beee41032e0e228994b2c5b3785eefb3 Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Mon, 29 May 2023 02:18:27 +0200 Subject: [PATCH 11/33] pianoroll: also reflect gain in transparency --- packages/core/pianoroll.mjs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/core/pianoroll.mjs b/packages/core/pianoroll.mjs index 594760155..2b5af1a79 100644 --- a/packages/core/pianoroll.mjs +++ b/packages/core/pianoroll.mjs @@ -87,7 +87,7 @@ Pattern.prototype.pianoroll = function ({ const isActive = event.whole.begin <= t && event.whole.end > t; ctx.fillStyle = event.context?.color || inactive; ctx.strokeStyle = event.context?.color || active; - ctx.globalAlpha = event.context.velocity ?? 1; + ctx.globalAlpha = event.context.velocity ?? event.value?.gain ?? 1; const timePx = scale((event.whole.begin - (flipTime ? to : from)) / timeExtent, ...timeRange); let durationPx = scale(event.duration / timeExtent, 0, timeAxis); const value = getValue(event); @@ -240,7 +240,7 @@ export function pianoroll({ const color = event.value?.color || event.context?.color; ctx.fillStyle = color || inactive; ctx.strokeStyle = color || active; - ctx.globalAlpha = event.context.velocity ?? 1; + ctx.globalAlpha = event.context.velocity ?? event.value?.gain ?? 1; const timePx = scale((event.whole.begin - (flipTime ? to : from)) / timeExtent, ...timeRange); let durationPx = scale(event.duration / timeExtent, 0, timeAxis); const value = getValue(event); From 536327f403dd3d79b3b0b00a088a4c8dcf9adf17 Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Mon, 29 May 2023 02:18:36 +0200 Subject: [PATCH 12/33] effects chapter mostly finished --- website/src/pages/workshop/first-effects.mdx | 166 ++++++++++++------- 1 file changed, 110 insertions(+), 56 deletions(-) diff --git a/website/src/pages/workshop/first-effects.mdx b/website/src/pages/workshop/first-effects.mdx index 3c0fc0fda..f1162ef09 100644 --- a/website/src/pages/workshop/first-effects.mdx +++ b/website/src/pages/workshop/first-effects.mdx @@ -11,7 +11,9 @@ import Box from '@components/Box.astro'; We have sounds, we have notes, now let's look at effects! -**low-pass filter with lpf** +## Some basic effects + +**low-pass filter** +lpf = **l**ow **p**ass **f**ilter + - Change lpf to 200. Notice how it gets muffled. Think of it as standing in front of the club with the door closed 🚪. -- Now let's open the door... change it to 8000. Notice how it gets sharper 🪩 +- Now let's open the door... change it to 5000. Notice how it gets brighter ✨🪩 -**automate the filter** +**pattern the filter** **vowel** @@ -52,13 +58,6 @@ We have sounds, we have notes, now let's look at effects! .sound("sawtooth").vowel("/2")`} /> - - -- Try adding more values -- Notice how the pattern in lpf does not change the overall rhythm - - - **gain** Rhythm is all about dynamics! -Remove the gain and notice how flat it sounds. +- Remove `.gain(...)` and notice how flat it sounds. +- Bring it back by undoing (ctrl+z) @@ -88,7 +89,7 @@ Let's combine all of the above into a little tune: tune={`stack( stack( sound("hh*8").gain("[.25 1]*2"), - sound("bd*2,~ rim") + sound("bd*2,~ sd:1") ), note("<[c2 c3]*4 [bb1 bb2]*4 [f2 f3]*4 [eb2 eb3]*4>/2") .sound("sawtooth").lpf("200 1000"), @@ -99,29 +100,11 @@ Let's combine all of the above into a little tune: -Pay attention to where the commas are and identify the individual parts of the stacks. -The 3 parts (drums, bassline, chords) are exactly as earlier, just stacked together. - - - -**fast and slow** - -We can use `fast` and `slow` to change the tempo of a pattern outside of Mini-Notation: - - - - - -Change the `slow` value. Try replacing it with `fast`. - -What happens if you use a pattern like `"<1 [2 4]>"`? +Try to identify the individual parts of the stacks, pay attention to where the commas are. +The 3 parts (drums, bassline, chords) are exactly as earlier, just stacked together, separated by comma. -By the way, inside Mini-Notation, `fast` is `*` and slow is `/`. - -")`} /> - **delay** -**room** +**room aka reverb** ~]") - .sound("gm_electric_guitar_muted"), - sound("").bank("RolandTR707"), + .sound("gm_electric_guitar_muted").delay(.5), + sound("").bank("RolandTR707").delay(.5), n("<4 [3@3 4] [<2 0> ~@16] ~>/2") .scale("D4:minor").sound("gm_accordion:2") .room(2).gain(.5) -).delay(.5)`} +)`} /> -**control the gain with a sine wave** +Let's add a bass to make this complete: - - -Try also `saw`, `square`, `tri` + ~]") + .sound("gm_electric_guitar_muted").delay(.5), + sound("").bank("RolandTR707").delay(.5), + n("<4 [3@3 4] [<2 0> ~@16] ~>/2") + .scale("D4:minor").sound("gm_accordion:2") + .room(2).gain(.4), + n("<0 [~ 0] 4 [3 2] [0 ~] [0 ~] <0 2> ~>*2") + .scale("D2:minor") + .sound("sawtooth,triangle").lpf(800) +)`} +/> -**The 'structure' comes from the left - try swapping:** + - +Try adding `.hush()` at the end of one of the patterns in the stack... -**speed of playback, e.g. 2 = double speed (up 1 octave)** + - +**pan** -**pan** +**speed** + +").room(.2)`} /> + +**fast and slow** + +We can use `fast` and `slow` to change the tempo of a pattern outside of Mini-Notation: + + + + + +Change the `slow` value. Try replacing it with `fast`. + +What happens if you use a pattern like `.fast("<1 [2 4]>")`? + + + +By the way, inside Mini-Notation, `fast` is `*` and slow is `/`. + +")`} /> + +## automation with signals + +Instead of changing values stepwise, we can also control them with signals: + + + + + +The basic waveforms for signals are `sine`, `saw`, `square`, `tri` 🌊 + +Try also random signals `rand` and `perlin`! + +The gain is visualized as transparency in the pianoroll. + + + +**setting a range** + + + + + +What happens if you flip the range values? + + + +**setting a range** + +By default, waves oscillate between 0 to 1. We can change that with `range`: /2") +.sound("sawtooth") +.lpf(sine.range(100, 2000).slow(8))`} /> - - -**delay** + - +Notice how the wave is slowed down. The whole automation will take 8 cycles to repeat. -**room** + - +## Recap + +| name | example | +| ----- | ----------------------------------------------------------------------------------------------- | +| lpf | ")`} /> | +| vowel | ")`} /> | +| gain | | +| delay | | +| room | | +| pan | | +| speed | ")`} /> | +| range | | From 39d5955e587f70e136a09267540755dfcef66aa6 Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Mon, 29 May 2023 12:39:05 +0200 Subject: [PATCH 13/33] add function recap to sounds chapter --- website/src/pages/workshop/first-sounds.mdx | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/website/src/pages/workshop/first-sounds.mdx b/website/src/pages/workshop/first-sounds.mdx index 5b87d10f6..b651c0ba4 100644 --- a/website/src/pages/workshop/first-sounds.mdx +++ b/website/src/pages/workshop/first-sounds.mdx @@ -212,6 +212,14 @@ This is what we've leared so far: | Speed up | \* | | | Parallel | , | | +The Mini-Notation is usually used inside some function. These are the functions we've seen so far: + +| Name | Description | Example | +| ----- | ----------------------------------- | ---------------------------------------------------------------------------------- | +| sound | plays the sound of the given name | | +| bank | selects the sound bank | | +| cpm | sets the tempo in cycles per minute | | + ## Examples **Basic rock beat** From 8b7bb7b6ae482458872971ac9d63d0d473b72d1b Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Mon, 29 May 2023 12:39:17 +0200 Subject: [PATCH 14/33] add adsr section to effects chapter --- website/src/pages/workshop/first-effects.mdx | 49 ++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/website/src/pages/workshop/first-effects.mdx b/website/src/pages/workshop/first-effects.mdx index f1162ef09..c9b6dc569 100644 --- a/website/src/pages/workshop/first-effects.mdx +++ b/website/src/pages/workshop/first-effects.mdx @@ -4,6 +4,7 @@ layout: ../../layouts/MainLayout.astro --- import { MiniRepl } from '../../docs/MiniRepl'; +import QA from '@components/QA'; # First Effects @@ -105,6 +106,54 @@ The 3 parts (drums, bassline, chords) are exactly as earlier, just stacked toget +**adsr envelope** + +") +.sound("sawtooth").lpf(600) +.attack(.1) +.decay(.1) +.sustain(.25) +.release(.2)`} +/> + + + +Try to find out what the numbers do.. Compare the following + +- attack: `.5` vs `0` +- decay: `.5` vs `0` +- sustain: `1` vs `.25` vs `0` +- release: `0` vs `.5` vs `1` + +Can you guess what they do? + + + + + +- attack: time it takes to fade in +- decay: time it takes to fade to sustain +- sustain: level after decay +- release: time it takes to fade out after note is finished + +![ADSR](https://upload.wikimedia.org/wikipedia/commons/thumb/e/ea/ADSR_parameter.svg/1920px-ADSR_parameter.svg.png) + + + +**adsr short notation** + +") +.sound("sawtooth").lpf(600) +.adsr(".1:.1:.5:.2") +`} +/> + **delay** Date: Mon, 29 May 2023 12:39:36 +0200 Subject: [PATCH 15/33] add compound adsr + ds controls --- packages/core/controls.mjs | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/packages/core/controls.mjs b/packages/core/controls.mjs index ef5bd33f9..c4044d4a4 100644 --- a/packages/core/controls.mjs +++ b/packages/core/controls.mjs @@ -4,7 +4,7 @@ Copyright (C) 2022 Strudel contributors - see . */ -import { Pattern, sequence } from './pattern.mjs'; +import { Pattern, register, sequence } from './pattern.mjs'; import { zipWith } from './util.mjs'; const controls = {}; @@ -810,4 +810,15 @@ generic_params.forEach(([names, ...aliases]) => { controls.createParams = (...names) => names.reduce((acc, name) => Object.assign(acc, { [name]: controls.createParam(name) }), {}); +controls.adsr = register('adsr', (adsr, pat) => { + adsr = !Array.isArray(adsr) ? [adsr] : adsr; + const [attack, decay, sustain, release] = adsr; + return pat.set({ attack, decay, sustain, release }); +}); +controls.ds = register('ds', (ds, pat) => { + ds = !Array.isArray(ds) ? [ds] : ds; + const [decay, sustain] = ds; + return pat.set({ decay, sustain }); +}); + export default controls; From c4a38d9008fd1cc81de288c171286aafa0716bcc Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Tue, 30 May 2023 06:16:02 +0200 Subject: [PATCH 16/33] + pattern effects chapter + recap page + only load mini repls when visible --- website/src/config.ts | 3 +- website/src/pages/workshop/first-effects.mdx | 66 +++--- website/src/pages/workshop/first-notes.mdx | 8 + website/src/pages/workshop/first-sounds.mdx | 11 + website/src/pages/workshop/intro.mdx | 16 ++ .../src/pages/workshop/pattern-effects.mdx | 194 ++++++++++++++++++ website/src/pages/workshop/recap.mdx | 98 +++++++++ 7 files changed, 362 insertions(+), 34 deletions(-) create mode 100644 website/src/pages/workshop/pattern-effects.mdx create mode 100644 website/src/pages/workshop/recap.mdx diff --git a/website/src/config.ts b/website/src/config.ts index 6fc7bb771..a3629fe34 100644 --- a/website/src/config.ts +++ b/website/src/config.ts @@ -47,7 +47,8 @@ export const SIDEBAR: Sidebar = { { text: 'First Sounds', link: 'workshop/first-sounds' }, { text: 'First Notes', link: 'workshop/first-notes' }, { text: 'First Effects', link: 'workshop/first-effects' }, - { text: 'Mini Notation', link: 'workshop/mini-notation' }, + { text: 'Pattern Effects', link: 'workshop/pattern-effects' }, + { text: 'Recap', link: 'workshop/recap' }, ], Tutorial: [ { text: 'Getting Started', link: 'learn/getting-started' }, diff --git a/website/src/pages/workshop/first-effects.mdx b/website/src/pages/workshop/first-effects.mdx index c9b6dc569..1428e2bdf 100644 --- a/website/src/pages/workshop/first-effects.mdx +++ b/website/src/pages/workshop/first-effects.mdx @@ -18,7 +18,7 @@ We have sounds, we have notes, now let's look at effects! /2") .sound("sawtooth").lpf(800)`} /> @@ -36,7 +36,7 @@ lpf = **l**ow **p**ass **f**ilter /2") .sound("sawtooth").lpf("200 1000")`} /> @@ -54,7 +54,7 @@ We will learn how to automate with waves later... /2") .sound("sawtooth").vowel("/2")`} /> @@ -63,7 +63,7 @@ We will learn how to automate with waves later... -**adsr envelope** +**shape the sound with an adsr envelope** ") .sound("sawtooth").lpf(600) .attack(.1) @@ -147,7 +147,7 @@ Can you guess what they do? ") .sound("sawtooth").lpf(600) .adsr(".1:.1:.5:.2") @@ -158,7 +158,7 @@ Can you guess what they do? ~]") .sound("gm_electric_guitar_muted"), @@ -180,7 +180,7 @@ What happens if you use `.delay(".8:.06:.8")` ? Can you guess what the third num ~@16] ~>/2") .scale("D4:minor").sound("gm_accordion:2") .room(2)`} @@ -198,7 +198,7 @@ Add a delay too! ~]") .sound("gm_electric_guitar_muted").delay(.5), @@ -213,7 +213,7 @@ Let's add a bass to make this complete: ~]") .sound("gm_electric_guitar_muted").delay(.5), @@ -237,7 +237,7 @@ Try adding `.hush()` at the end of one of the patterns in the stack... ").room(.2)`} /> +").room(.2)`} /> **fast and slow** We can use `fast` and `slow` to change the tempo of a pattern outside of Mini-Notation: - + @@ -263,13 +263,13 @@ What happens if you use a pattern like `.fast("<1 [2 4]>")`? By the way, inside Mini-Notation, `fast` is `*` and slow is `/`. -")`} /> +")`} /> ## automation with signals Instead of changing values stepwise, we can also control them with signals: - + @@ -283,7 +283,9 @@ The gain is visualized as transparency in the pianoroll. **setting a range** - +By default, waves oscillate between 0 to 1. We can change that with `range`: + + @@ -291,13 +293,11 @@ What happens if you flip the range values? -**setting a range** - -By default, waves oscillate between 0 to 1. We can change that with `range`: +We can change the automation speed with slow / fast: /2") .sound("sawtooth") .lpf(sine.range(100, 2000).slow(8))`} @@ -305,19 +305,19 @@ By default, waves oscillate between 0 to 1. We can change that with `range`: -Notice how the wave is slowed down. The whole automation will take 8 cycles to repeat. +The whole automation will now take 8 cycles to repeat. ## Recap -| name | example | -| ----- | ----------------------------------------------------------------------------------------------- | -| lpf | ")`} /> | -| vowel | ")`} /> | -| gain | | -| delay | | -| room | | -| pan | | -| speed | ")`} /> | -| range | | +| name | example | +| ----- | -------------------------------------------------------------------------------------------------- | +| lpf | ")`} /> | +| vowel | ")`} /> | +| gain | | +| delay | | +| room | | +| pan | | +| speed | ")`} /> | +| range | | diff --git a/website/src/pages/workshop/first-notes.mdx b/website/src/pages/workshop/first-notes.mdx index b986ba791..330dd0721 100644 --- a/website/src/pages/workshop/first-notes.mdx +++ b/website/src/pages/workshop/first-notes.mdx @@ -318,6 +318,14 @@ Let's recap what we've learned in this chapter: | Elongate | @ | | | Replicate | ! | | +New functions: + +| Name | Description | Example | +| ----- | ----------------------------------- | -------------------------------------------------------------------------------------------- | +| note | set pitch as number or letter | | +| scale | interpret `n` as scale degree | | +| stack | play patterns in parallel (read on) | | + ## Examples **Classy Bassline** diff --git a/website/src/pages/workshop/first-sounds.mdx b/website/src/pages/workshop/first-sounds.mdx index b651c0ba4..618943339 100644 --- a/website/src/pages/workshop/first-sounds.mdx +++ b/website/src/pages/workshop/first-sounds.mdx @@ -197,6 +197,16 @@ It is quite common that there are many ways to express the same idea. punchcard /> +**selecting sample numbers separately** + +Instead of using ":", we can also use the `n` function to select sample numbers: + + + +This is shorter and more readable than: + + + ## Recap Now we've learned the basics of the so called Mini-Notation, the rhythm language of Tidal. @@ -219,6 +229,7 @@ The Mini-Notation is usually used inside some function. These are the functions | sound | plays the sound of the given name | | | bank | selects the sound bank | | | cpm | sets the tempo in cycles per minute | | +| n | select sample number | | ## Examples diff --git a/website/src/pages/workshop/intro.mdx b/website/src/pages/workshop/intro.mdx index e7b075b4c..9e18bbfec 100644 --- a/website/src/pages/workshop/intro.mdx +++ b/website/src/pages/workshop/intro.mdx @@ -4,3 +4,19 @@ layout: ../../layouts/MainLayout.astro --- # Introduction + +## goals + +- be beginner friendly +- teach a representative subset of strudel / tidal +- introduce one new thing at a time +- give practical / musical examples +- encourage self-experimentation +- hands on learning > walls of text +- maintain flow state +- no setup required + +## inspired by + +- https://github.com/tidalcycles/tidal-workshop/blob/master/workshop.tidal +- https://learningmusic.ableton.com diff --git a/website/src/pages/workshop/pattern-effects.mdx b/website/src/pages/workshop/pattern-effects.mdx new file mode 100644 index 000000000..7e028b6f8 --- /dev/null +++ b/website/src/pages/workshop/pattern-effects.mdx @@ -0,0 +1,194 @@ +--- +title: Pattern Effects +layout: ../../layouts/MainLayout.astro +--- + +import { MiniRepl } from '@src/docs/MiniRepl'; +import Box from '@components/Box.astro'; +import QA from '@components/QA'; + +# Pattern Effects + +Up until now, most of the functions we've seen are what other music programs are typically capable of: sequencing sounds, playing notes, controlling effects. + +In this chapter, we are going to look at functions that are more unique to tidal. + +**reverse patterns with rev** + + + +**play pattern left and modify it right with jux** + + + +This is the same as: + + + +Let's visualize what happens here: + + + + + +Try commenting out one of the two by adding `//` before a line + + + +**multiple tempos** + + + +This is like doing + + + + + +Try commenting out one or more by adding `//` before a line + + + +**add** + +>")) +.color(">").adsr("[.1 0]:.2:[1 0]") +.sound("gm_acoustic_bass").room(.5)`} + punchcard +/> + + + +If you add a number to a note, the note will be treated as if it was a number + + + +We can add as often as we like: + +>").add("0,7")) +.color(">").adsr("[.1 0]:.2:[1 0]") +.sound("gm_acoustic_bass").room(.5)`} + punchcard +/> + +**add with scale** + + [~ <4 1>]>*2".add("<0 [0,2,4]>/4")) +.scale("C5:minor").release(.5) +.sound("gm_xylophone").room(.5)`} + punchcard +/> + +**time to stack** + + [~ <4 1>]>*2".add("<0 [0,2,4]>/4")) + .scale("C5:minor") + .sound("gm_xylophone") + .room(.4).delay(.125), + note("c2 [eb3,g3]".add("<0 <1 -1>>")) + .adsr("[.1 0]:.2:[1 0]") + .sound("gm_acoustic_bass") + .room(.5), + n("0 1 [2 3] 2").sound("jazz").jux(rev).slow(2) +)`} +/> + +**ply** + + + +this is like writing: + + + + + +Try patterning the `ply` function, for example using `"<1 2 1 3>"` + + + +**off** + +] <2 3> [~ 1]>" + .off(1/8, x=>x.add(4)) + //.off(1/4, x=>x.add(7)) +).scale("/4") +.s("triangle").room(.5).ds(".1:0").delay(.5)`} + punchcard +/> + + + +In the notation `x=>x.`, the `x` is the shifted pattern, which where modifying. + + + +The above is like writing: + +] <2 3> [~ 1]>*2").color("cyan"), + n("<0 [4 <3 2>] <2 3> [~ 1]>*2".add(7).late(1/8)).color("magenta") +).scale("/2") +.s("triangle").adsr(".01:.1:0").room(.5)`} + punchcard +/> + +off is also useful for sounds: + +x.speed(1.5).gain(.25))`} +/> + +| name | description | example | +| ---- | ------------------------------ | ---------------------------------------------------------------------------------------------- | +| rev | reverse | | +| jux | split left/right, modify right | | +| add | add numbers / notes | ")).scale("C:minor")`} /> | +| ply | speed up each event n times | ")`} /> | +| off | copy, shift time & modify | x.speed(2))`} /> | diff --git a/website/src/pages/workshop/recap.mdx b/website/src/pages/workshop/recap.mdx new file mode 100644 index 000000000..bc9c4648c --- /dev/null +++ b/website/src/pages/workshop/recap.mdx @@ -0,0 +1,98 @@ +--- +title: Recap +layout: ../../layouts/MainLayout.astro +--- + +import { MiniRepl } from '../../docs/MiniRepl'; + +# Workshop Recap + +This page is just a listing of all functions covered in the workshop! + +## Mini Notation + +| Concept | Syntax | Example | +| ----------------- | -------- | -------------------------------------------------------------------------------- | +| Sequence | space | | +| Sample Number | :x | | +| Rests | ~ | | +| Sub-Sequences | \[\] | | +| Sub-Sub-Sequences | \[\[\]\] | | +| Speed up | \* | | +| Parallel | , | | +| Slow down | \/ | | +| Alternate | \<\> | ")`} /> | +| Elongate | @ | | +| Replicate | ! | | + +## Sounds + +| Name | Description | Example | +| ----- | --------------------------------- | ---------------------------------------------------------------------------------- | +| sound | plays the sound of the given name | | +| bank | selects the sound bank | | +| n | select sample number | | + +## Notes + +| Name | Description | Example | +| --------- | ----------------------------------- | -------------------------------------------------------------------------------------------- | +| note | set pitch as number or letter | | +| n + scale | set note in scale | | +| stack | play patterns in parallel (read on) | | + +## Audio Effects + +| name | example | +| ----- | -------------------------------------------------------------------------------------------------- | +| lpf | ")`} /> | +| vowel | ")`} /> | +| gain | | +| delay | | +| room | | +| pan | | +| speed | ")`} /> | +| range | | + +## Pattern Effects + +| name | description | example | +| ---- | ----------------------------------- | ---------------------------------------------------------------------------------------------- | +| cpm | sets the tempo in cycles per minute | | +| fast | speed up | | +| slow | slow down | | +| rev | reverse | | +| jux | split left/right, modify right | | +| add | add numbers / notes | ")).scale("C:minor")`} /> | +| ply | speed up each event n times | ")`} /> | +| off | copy, shift time & modify | x.speed(2))`} /> | + +## Samples + +``` +casio control crow techno house jazz +metal east jvbass juno insect space wind +bd sd sn cp hh +piano +``` + +## Synths + +``` +gm_electric_guitar_muted gm_acoustic_bass +gm_voice_oohs gm_blown_bottle sawtooth square triangle +gm_xylophone gm_synth_bass_1 gm_synth_strings_1 +``` + +## Banks + +``` +RolandTR909 +``` + +## Scales + +``` +major minor dorian mixolydian +minor:pentatonic major:pentatonic +``` From 61a9b01062f9952eabc8b178c27f8d8d1795ccd8 Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Mon, 5 Jun 2023 23:48:04 +0200 Subject: [PATCH 17/33] started german translation of workshop --- .../components/LeftSidebar/LeftSidebar.astro | 4 +- website/src/config.ts | 11 + .../src/pages/de/workshop/first-effects.mdx | 323 +++++++++++++++ website/src/pages/de/workshop/first-notes.mdx | 388 ++++++++++++++++++ .../src/pages/de/workshop/first-sounds.mdx | 310 ++++++++++++++ website/src/pages/de/workshop/index.astro | 3 + website/src/pages/de/workshop/intro.mdx | 22 + website/src/pages/de/workshop/langebank.mdx | 154 +++++++ .../src/pages/de/workshop/mini-notation.mdx | 69 ++++ .../src/pages/de/workshop/pattern-effects.mdx | 194 +++++++++ website/src/pages/de/workshop/recap.mdx | 98 +++++ 11 files changed, 1574 insertions(+), 2 deletions(-) create mode 100644 website/src/pages/de/workshop/first-effects.mdx create mode 100644 website/src/pages/de/workshop/first-notes.mdx create mode 100644 website/src/pages/de/workshop/first-sounds.mdx create mode 100644 website/src/pages/de/workshop/index.astro create mode 100644 website/src/pages/de/workshop/intro.mdx create mode 100644 website/src/pages/de/workshop/langebank.mdx create mode 100644 website/src/pages/de/workshop/mini-notation.mdx create mode 100644 website/src/pages/de/workshop/pattern-effects.mdx create mode 100644 website/src/pages/de/workshop/recap.mdx diff --git a/website/src/components/LeftSidebar/LeftSidebar.astro b/website/src/components/LeftSidebar/LeftSidebar.astro index 18327ebed..ce4dbb800 100644 --- a/website/src/components/LeftSidebar/LeftSidebar.astro +++ b/website/src/components/LeftSidebar/LeftSidebar.astro @@ -1,5 +1,5 @@ --- -// import { getLanguageFromURL } from '../../languages'; +import { getLanguageFromURL } from '../../languages'; import { SIDEBAR } from '../../config'; type Props = { @@ -10,7 +10,7 @@ const { currentPage } = Astro.props as Props; const { BASE_URL } = import.meta.env; let currentPageMatch = currentPage.slice(BASE_URL.length, currentPage.endsWith('/') ? -1 : undefined); -const langCode = 'en'; // getLanguageFromURL(currentPage); +const langCode = getLanguageFromURL(currentPage) || 'en'; const sidebar = SIDEBAR[langCode]; --- diff --git a/website/src/config.ts b/website/src/config.ts index a3629fe34..e824f35b4 100644 --- a/website/src/config.ts +++ b/website/src/config.ts @@ -24,6 +24,7 @@ export type Frontmatter = { export const KNOWN_LANGUAGES = { English: 'en', + German: 'de', } as const; export const KNOWN_LANGUAGE_CODES = Object.values(KNOWN_LANGUAGES); @@ -41,6 +42,16 @@ export const ALGOLIA = { export type SidebarLang = Record; export type Sidebar = Record<(typeof KNOWN_LANGUAGE_CODES)[number], SidebarLang>; export const SIDEBAR: Sidebar = { + de: { + Workshop: [ + { text: 'Intro', link: 'de/workshop/intro' }, + { text: 'Erste Sounds', link: 'de/workshop/first-sounds' }, + { text: 'Erste Töne', link: 'de/workshop/first-notes' }, + { text: 'Erste Effekte', link: 'de/workshop/first-effects' }, + { text: 'Pattern Effekte', link: 'de/workshop/pattern-effects' }, + { text: 'Rückblick', link: 'de/workshop/recap' }, + ], + }, en: { Workshop: [ { text: 'Intro', link: 'workshop/intro' }, diff --git a/website/src/pages/de/workshop/first-effects.mdx b/website/src/pages/de/workshop/first-effects.mdx new file mode 100644 index 000000000..d547548db --- /dev/null +++ b/website/src/pages/de/workshop/first-effects.mdx @@ -0,0 +1,323 @@ +--- +title: First Effects +layout: ../../../layouts/MainLayout.astro +--- + +import { MiniRepl } from '../../../docs/MiniRepl'; +import QA from '@components/QA'; + +# First Effects + +import Box from '@components/Box.astro'; + +We have sounds, we have notes, now let's look at effects! + +## Some basic effects + +**low-pass filter** + +/2") +.sound("sawtooth").lpf(800)`} +/> + + + +lpf = **l**ow **p**ass **f**ilter + +- Change lpf to 200. Notice how it gets muffled. Think of it as standing in front of the club with the door closed 🚪. +- Now let's open the door... change it to 5000. Notice how it gets brighter ✨🪩 + + + +**pattern the filter** + +/2") +.sound("sawtooth").lpf("200 1000")`} +/> + + + +- Try adding more values +- Notice how the pattern in lpf does not change the overall rhythm + +We will learn how to automate with waves later... + + + +**vowel** + +/2") +.sound("sawtooth").vowel("/2")`} +/> + +**gain** + + + + + +Rhythm is all about dynamics! + +- Remove `.gain(...)` and notice how flat it sounds. +- Bring it back by undoing (ctrl+z) + + + +**stacks within stacks** + +Let's combine all of the above into a little tune: + +/2") + .sound("sawtooth").lpf("200 1000"), + note("<[c3,g3,e4] [bb2,f3,d4] [a2,f3,c4] [bb2,g3,eb4]>/2") + .sound("sawtooth").vowel("/2") +) `} +/> + + + +Try to identify the individual parts of the stacks, pay attention to where the commas are. +The 3 parts (drums, bassline, chords) are exactly as earlier, just stacked together, separated by comma. + + + +**shape the sound with an adsr envelope** + +") +.sound("sawtooth").lpf(600) +.attack(.1) +.decay(.1) +.sustain(.25) +.release(.2)`} +/> + + + +Try to find out what the numbers do.. Compare the following + +- attack: `.5` vs `0` +- decay: `.5` vs `0` +- sustain: `1` vs `.25` vs `0` +- release: `0` vs `.5` vs `1` + +Can you guess what they do? + + + + + +- attack: time it takes to fade in +- decay: time it takes to fade to sustain +- sustain: level after decay +- release: time it takes to fade out after note is finished + +![ADSR](https://upload.wikimedia.org/wikipedia/commons/thumb/e/ea/ADSR_parameter.svg/1920px-ADSR_parameter.svg.png) + + + +**adsr short notation** + +") +.sound("sawtooth").lpf(600) +.adsr(".1:.1:.5:.2") +`} +/> + +**delay** + + ~]") + .sound("gm_electric_guitar_muted"), + sound("").bank("RolandTR707") +).delay(".5")`} +/> + + + +Try some `delay` values between 0 and 1. Btw, `.5` is short for `0.5` + +What happens if you use `.delay(".8:.125")` ? Can you guess what the second number does? + +What happens if you use `.delay(".8:.06:.8")` ? Can you guess what the third number does? + + + +**room aka reverb** + + ~@16] ~>/2") +.scale("D4:minor").sound("gm_accordion:2") +.room(2)`} +/> + + + +Try different values! + +Add a delay too! + + + +**little dub tune** + + ~]") + .sound("gm_electric_guitar_muted").delay(.5), + sound("").bank("RolandTR707").delay(.5), + n("<4 [3@3 4] [<2 0> ~@16] ~>/2") + .scale("D4:minor").sound("gm_accordion:2") + .room(2).gain(.5) +)`} +/> + +Let's add a bass to make this complete: + + ~]") + .sound("gm_electric_guitar_muted").delay(.5), + sound("").bank("RolandTR707").delay(.5), + n("<4 [3@3 4] [<2 0> ~@16] ~>/2") + .scale("D4:minor").sound("gm_accordion:2") + .room(2).gain(.4), + n("<0 [~ 0] 4 [3 2] [0 ~] [0 ~] <0 2> ~>*2") + .scale("D2:minor") + .sound("sawtooth,triangle").lpf(800) +)`} +/> + + + +Try adding `.hush()` at the end of one of the patterns in the stack... + + + +**pan** + + + +**speed** + +").room(.2)`} /> + +**fast and slow** + +We can use `fast` and `slow` to change the tempo of a pattern outside of Mini-Notation: + + + + + +Change the `slow` value. Try replacing it with `fast`. + +What happens if you use a pattern like `.fast("<1 [2 4]>")`? + + + +By the way, inside Mini-Notation, `fast` is `*` and slow is `/`. + +")`} /> + +## automation with signals + +Instead of changing values stepwise, we can also control them with signals: + + + + + +The basic waveforms for signals are `sine`, `saw`, `square`, `tri` 🌊 + +Try also random signals `rand` and `perlin`! + +The gain is visualized as transparency in the pianoroll. + + + +**setting a range** + +By default, waves oscillate between 0 to 1. We can change that with `range`: + + + + + +What happens if you flip the range values? + + + +We can change the automation speed with slow / fast: + +/2") +.sound("sawtooth") +.lpf(sine.range(100, 2000).slow(8))`} +/> + + + +The whole automation will now take 8 cycles to repeat. + + + +## Recap + +| name | example | +| ----- | -------------------------------------------------------------------------------------------------- | +| lpf | ")`} /> | +| vowel | ")`} /> | +| gain | | +| delay | | +| room | | +| pan | | +| speed | ")`} /> | +| range | | diff --git a/website/src/pages/de/workshop/first-notes.mdx b/website/src/pages/de/workshop/first-notes.mdx new file mode 100644 index 000000000..c33fbb1a8 --- /dev/null +++ b/website/src/pages/de/workshop/first-notes.mdx @@ -0,0 +1,388 @@ +--- +title: First Notes +layout: ../../../layouts/MainLayout.astro +--- + +import { MiniRepl } from '@src/docs/MiniRepl'; +import { midi2note } from '@strudel.cycles/core/'; +import Box from '@components/Box.astro'; +import QA from '@components/QA'; + +# Erste Töne + +Jetzt schauen wir uns an wie man mit Tönen mit der `note` Funktion spielt. + +## Zahlen und Noten + +**Töne mit Zahlen** + + [midi2note(i + 36), i + 36]), + )} +/> + + + +Probiere verschiedene Zahlen aus! + +Versuch auch mal Kommazahlen, z.B. 55.5 (beachte die englische Schreibweise von Kommazahlen mit "." anstatt ",") + + + +**Töne mit Buchstaben** + + [n, n.split('')[0]]))} +/> + + + +Versuch verschiedene Buchstaben aus (a - g). + +Findest du Melodien die auch gleichzeitig ein Wort sind? Tipp: ☕ 🙈 🧚 + + + +**Vorzeichen** + + [n, n.split('').slice(0, 2).join('')]), + )} +/> + + [n, n.split('').slice(0, 2).join('')]), + )} +/> + +**Andere Oktaven** + + [n, n]))} + claviatureLabels={Object.fromEntries( + Array(49) + .fill() + .map((_, i) => [midi2note(i + 36), midi2note(i + 36)]), + )} +/> + + + +Probiere verschiedene Oktaven aus (1-8) + + + +Normalerweise kommen Leute die keine Noten besser mit Zahlen anstatt mit Buchstaben zurecht. +Daher benutzen die folgenden Beispiele meistens Zahlen. +Später sehen wir auch noch ein paar Tricks die es uns erleichtern Töne zu spielen die zueinander passen. + +## Den Sound verändern + +Genau wie bei geräuschhaften Sounds können wir den Klang unserer Töne mit `sound` verändern: + + + + + +Probier ein paar sounds aus: + +- gm_electric_guitar_muted - E-Gitarre +- gm_acoustic_bass - Kontrabass +- gm_voice_oohs - Chords +- gm_blown_bottle - Flasche +- sawtooth - Sägezahn-Welle +- square - Rechteck-Welle +- triangle - Dreieck-Welle +- Was ist mit bd, sd oder hh? +- Entferne `.sound('...')` komplett + + + +**Zwischen Sounds hin und her wechseln** + + + +**Gleichzeitige Sounds** + + + + + +Die patterns in `note` und `sound` werden kombiniert! + +Wir schauen uns später noch mehr Möglichkeiten an wie man patterns kombiniert. + + + +## Längere Sequenzen + +**Divide sequences with `/` to slow them down** + +{/* [c2 bb1 f2 eb2] */} + + + + + +The `/4` plays the sequence in brackets over 4 cycles (=4s). + +So each of the 4 notes is 1s long. + +Try adding more notes inside the brackets and notice how it gets faster. + + + +Because it is so common to just play one thing per cycle, you can.. + +**Play one per cycle with \< \>** + +").sound("gm_acoustic_bass")`} punchcard /> + + + +Try adding more notes inside the brackets and notice how it does **not** get faster. + + + +**Play one sequence per cycle** + +{/* <[c2 c3]*4 [bb1 bb2]*4 [f2 f3]*4 [eb2 eb3]*4>/2 */} + +/2") +.sound("gm_acoustic_bass")`} + punchcard +/> + +**Alternate between multiple things** + +") +.sound("gm_xylophone")`} + punchcard +/> + +This is also useful for unpitched sounds: + +, [~ hh]*2") +.bank("RolandTR909")`} + punchcard +/> + +## Scales + +Finding the right notes can be difficult.. Scales are here to help: + +") +.scale("C:minor").sound("piano")`} + punchcard +/> + + + +Try out different numbers. Any number should sound good! + +Try out different scales: + +- C:major +- A2:minor +- D:dorian +- G:mixolydian +- A2:minor:pentatonic +- F:major:pentatonic + + + +**automate scales** + +Just like anything, we can automate the scale with a pattern: + +, 2 4 <[6,8] [7,9]>") +.scale("/4") +.sound("piano")`} + punchcard +/> + + + +If you have no idea what these scale mean, don't worry. +These are just labels for different sets of notes that go well together. + +Take your time and you'll find scales you like! + + + +## Repeat & Elongate + +**Elongate with @** + + + + + +Not using `@` is like using `@1`. In the above example, c is 3 units long and eb is 1 unit long. + +Try changing that number! + + + +**Elongate within sub-sequences** + +*2") +.scale("/4") +.sound("gm_acoustic_bass")`} + punchcard +/> + + + +This groove is called a `shuffle`. +Each beat has two notes, where the first is twice as long as the second. +This is also sometimes called triplet swing. You'll often find it in blues and jazz. + + + +**Replicate** + +]").sound("piano")`} punchcard /> + + + +Try switching between `!`, `*` and `@` + +What's the difference? + + + +## Recap + +Let's recap what we've learned in this chapter: + +| Concept | Syntax | Example | +| --------- | ------ | ------------------------------------------------------------------- | +| Slow down | \/ | | +| Alternate | \<\> | ")`} /> | +| Elongate | @ | | +| Replicate | ! | | + +New functions: + +| Name | Description | Example | +| ----- | ----------------------------------- | -------------------------------------------------------------------------------------------- | +| note | set pitch as number or letter | | +| scale | interpret `n` as scale degree | | +| stack | play patterns in parallel (read on) | | + +## Examples + +**Classy Bassline** + +/2") +.sound("gm_synth_bass_1") +.lpf(800) // <-- we'll learn about this soon`} +/> + +**Classy Melody** + +*2\`).scale("C4:minor") +.sound("gm_synth_strings_1")`} +/> + +**Classy Drums** + +, [~ hh]*2") +.bank("RolandTR909")`} +/> + +**If there just was a way to play all the above at the same time.......** + + + +It's called `stack` 😙 + + + +/2") + .sound("gm_synth_bass_1").lpf(800), + n(\`< + [~ 0] 2 [0 2] [~ 2] + [~ 0] 1 [0 1] [~ 1] + [~ 0] 3 [0 3] [~ 3] + [~ 0] 2 [0 2] [~ 2] + >*2\`).scale("C4:minor") + .sound("gm_synth_strings_1"), + sound("bd*2, ~ , [~ hh]*2") + .bank("RolandTR909") +)`} +/> + +This is starting to sound like actual music! We have sounds, we have notes, now the last piece of the puzzle is missing: [effects](/workshop/first-effects) diff --git a/website/src/pages/de/workshop/first-sounds.mdx b/website/src/pages/de/workshop/first-sounds.mdx new file mode 100644 index 000000000..0f132bec0 --- /dev/null +++ b/website/src/pages/de/workshop/first-sounds.mdx @@ -0,0 +1,310 @@ +--- +title: Erste Sounds +layout: ../../../layouts/MainLayout.astro +--- + +import { MiniRepl } from '@src/docs/MiniRepl'; +import Box from '@components/Box.astro'; +import QA from '@components/QA'; + +## Erste Sounds + +{/* Let's start by making some noise: */} + +Los geht's mit ein paar Sounds: + + + + + +1. ⬆️ Klicke in das obige Textfeld ⬆️ +2. Drücke `Strg`+`Enter` zum Abspielen +3. Ändere `house` in `casio` +4. Drücke `Strg`+`Enter` zum Aktualisieren +5. Drücke `Strg`+`.` zum Stoppen + + + +Glückwunsch, du bist nun am live coden! + +**Probiere mehr Sounds aus** + +Mit ":" kannst du einen anderen Sound aus dem Set wählen: + + + + + +Ändere `east:1` in `east:2` um einen anderen Sound aus dem Set `east` zu hören. + +Du kannst auch andere Zahlen ausprobieren! Es kann sein dass du kurz nichts hörst während ein neuer Sound lädt. + + + +Hier sind ein paar mehr Sounds zum ausprobieren: + +``` +casio control crow techno house jazz +metal east jvbass juno insect space wind +``` + +Jetzt weißt du wie man verschiedene Sounds benutzt. +Vorerst bleiben wir bei den voreingestellten Sounds, später erfahren wir noch wie man eigene benutzt. + +## Drum Sounds + +Strudel kommt von Haus aus mit einer breiten Auswahl an Drum Sounds: + + + +Diese 2-Buchstaben Kombinationen stehen für verschiedene Teile eines Drumsets: + +- `bd` = **b**ass **d**rum - Basstrommel +- `sd` = **s**nare **d**rum - Schnarrtrommel +- `sn` = **sn**are +- `rim` = **rim**shot - Rahmenschlag +- `hh` = **h**i**h**at +- `oh` = **o**pen **h**ihat - Offenes Hi-Hat + +Wir können den Charakter des Drum Sounds verändern, indem wir mit `bank` die Drum Machine auswählen: + +{/* To change the sound character of our drums, we can use `bank` to change the drum machine: */} + + + +In diesem Beispiel ist `RolandTR909` der Name der Drum Machine, welche eine prägende Rolle für House und Techno Musik spielte. + + + +Ändere `RolandTR909` in + +- `AkaiLinn` +- `RhythmAce` +- `RolandTR808` +- `RolandTR707` +- `ViscoSpaceDrum` + +Es gibt noch viel mehr, aber das sollte fürs Erste reichen.. + + + +## Sequenzen / Sequences + +Im letzten Beispiel haben wir schon gesehen dass man mehrere Sounds hintereinander abspielen kann wenn man sie durch Leerzeichen trennt: + + + +Beachte wie der aktuell gespielte Sound im Code markiert und auch darunter visualisiert wird. + + + +Versuch noch mehr Sounds hinzuzfügen! + + + +**Je länger die Sequence, desto schneller** + + + +Der Inhalt einer Sequence wird in einen sogenannten Cycle (=Zyklus) zusammengequetscht. + +**Tempo ändern mit `cpm`** + + + + + +cpm = **c**ycles per **m**inute = Cycles pro Minute + +Das Tempo ist standardmäßig auf 60cpm eingestellt, also 1 Cycle pro Sekunde. + + + +Wir werden später noch mehr Möglichkeiten kennen lernen wie man das Tempo verändert. + +**Pausen mit '~'** + + + +**Unter-Sequenzen mit [Klammern]** + + + + + +Füge noch mehr Sounds in die Klammern ein! + + + +Genau wie bei der ganzen Sequence wird der eine Unter-Sequence schneller je mehr drin ist. + +**Multiplikation: Dinge schneller machen** + + + +**Multiplikation: Unter-Sequences schneller machen** + + + +**Multiplikation: Vieeeeeeel schneller** + + + + + +Tonhöhe = sehr schneller Rhythmus + + + +**Unter-Unter-Sequenzen mit [[Klammern]]** + + + + + +Du kannst so tief verschachteln wie du willst! + + + +**Parallele Sequenzen mit Komma** + + + +Du kannst soviele Kommas benutzen wie du magst: + + + +Kommas können auch in Unter-Sequenzen verwendet werden: + + + + + +Ist dir aufgefallen dass sich die letzten beiden Beispiele gleich anhören? + +Es kommt öfter vor dass man die gleiche Idee auf verschiedene Arten ausdrücken kann. + + + +**Mehrere Zeilen mit \`** + + + +**Sound Nummer separat auswählen** + +Anstatt mit ":" kann man die Sound Nummer auch separat mir der `n` Funktion steuern: + + + +Das ist kürzer und lesbarer als: + + + +## Rückblick + +Wir haben jetzt die Grundlagen der sogenannten Mini-Notation gelernt, der Rhythmus-Sprache von Tidal. + +Das haben wir bisher gelernt: + +| Concept | Syntax | Example | +| --------------------- | ----------- | -------------------------------------------------------------------------------- | +| Sequenz | Leerzeichen | | +| Sound Nummer | :x | | +| Pausen | ~ | | +| Unter-Sequenzen | \[\] | | +| Unter-Unter-Sequenzen | \[\[\]\] | | +| Schneller | \* | | +| Parallel | , | | + +Die mit Apostrophen umgebene Mini-Notation benutzt man normalerweise in eine sogenannten Funktion. +Die folgenden Funktionen haben wir bereits gesehen: + +| Name | Description | Example | +| ----- | -------------------------------------- | ---------------------------------------------------------------------------------- | +| sound | Spielt den Sound mit dem Namen | | +| bank | Wählt die Soundbank / Drum Machine | | +| cpm | Tempo in **C**ycles **p**ro **M**inute | | +| n | Sample Nummer | | + +## Beispiele + +**Einfacher Rock Beat** + + + +**Klassischer House** + + + + + +Ist die aufgefallen dass die letzten 2 Patterns extrem ähnlich sind? +Bestimmte Drum Patterns werden oft genreübergreifend wiederverwendet. + + + +We Will Rock you + + + +**Yellow Magic Orchestra - Firecracker** + + + +**Nachahmung eines 16 step sequencers** + + + +**Noch eins** + + + +**Nicht so typische Drums** + + + +Jetzt haben wir eine grundlegende Ahnung davon wie man mit Strudel Beats baut! +Im nächsten Kapitel werden wir ein paar [Töne spielen](/workshop/first-notes). diff --git a/website/src/pages/de/workshop/index.astro b/website/src/pages/de/workshop/index.astro new file mode 100644 index 000000000..9f79e4c22 --- /dev/null +++ b/website/src/pages/de/workshop/index.astro @@ -0,0 +1,3 @@ + diff --git a/website/src/pages/de/workshop/intro.mdx b/website/src/pages/de/workshop/intro.mdx new file mode 100644 index 000000000..5688476be --- /dev/null +++ b/website/src/pages/de/workshop/intro.mdx @@ -0,0 +1,22 @@ +--- +title: Introduction +layout: ../../../layouts/MainLayout.astro +--- + +# Introduction + +## goals + +- be beginner friendly +- teach a representative subset of strudel / tidal +- introduce one new thing at a time +- give practical / musical examples +- encourage self-experimentation +- hands on learning > walls of text +- maintain flow state +- no setup required + +## inspired by + +- https://github.com/tidalcycles/tidal-workshop/blob/master/workshop.tidal +- https://learningmusic.ableton.com diff --git a/website/src/pages/de/workshop/langebank.mdx b/website/src/pages/de/workshop/langebank.mdx new file mode 100644 index 000000000..7a1ca6977 --- /dev/null +++ b/website/src/pages/de/workshop/langebank.mdx @@ -0,0 +1,154 @@ + + +1. press play button to start +2. change `house` to `casio` +3. press refresh button to update +4. press stop button to stop + + + +**Change tempo** + + + +adding your own samples + + + +").slow(3)`} + punchcard +/> + +n(run(8)).sound("east") + +Shorter variant: + + + +polyrythms & polymeters + +-- This can make for flexible time signatures: + +d1 $ sound "[bd bd sn:5] [bd sn:3]" + +-- You can put subsequences inside subsequences: +d1 $ sound "[[bd bd] bd sn:5] [bd sn:3]" + +-- Keep going.. +d1 $ sound "[[bd [bd bd bd bd]] bd sn:5] [bd sn:3]" + +-- \* Polymetric / polyrhythmic sequences + +-- Play two subsequences at once by separating with a comma: + +d1 $ sound "[voodoo voodoo:3, arpy arpy:4 arpy:2]" + +-- compare how [,] and {,} work: + +d1 $ sound "[voodoo voodoo:3, arpy arpy:4 arpy:2]" + +d1 $ sound "{voodoo voodoo:3, arpy arpy:4 arpy:2}" + +d1 $ sound "[drum bd hh bd, can can:2 can:3 can:4 can:2]" + +d1 $ sound "{drum bd hh bd, can can:2 can:3 can:4 can:2}" + +d1 $ sound "[bd sn, can:2 can:3 can:1, arpy arpy:1 arpy:2 arpy:3 arpy:5]" + +d1 $ sound "{bd sn, can:2 can:3 can:1, arpy arpy:1 arpy:2 arpy:3 arpy:5}" + +**Play X per cycle with \{ \}** + + + + + +Try different numbers after `%` + +`{ ... }%1` is the same as `< ... >` + + + +## Bracket Recap + +- `[]` squeezes contents to 1 cycle +- `<>` plays one item per cycle +- `{}%x` plays x items per cycle + +/2")) +.sound("gm_synth_bass_1")`} +/> + +vertical + + +< 4 4 4 3> +<[2,7] [2,6] [1,6] [1,6]> +< 4 4 4 3> +>*2\`) +.scale("/4") +.sound("piano")`} +/> + +horizontal + +*2\`) +.scale("/4") +.sound("piano")`} +/> diff --git a/website/src/pages/de/workshop/mini-notation.mdx b/website/src/pages/de/workshop/mini-notation.mdx new file mode 100644 index 000000000..86bef096d --- /dev/null +++ b/website/src/pages/de/workshop/mini-notation.mdx @@ -0,0 +1,69 @@ +--- +title: First Sounds +layout: ../../../layouts/MainLayout.astro +--- + +import { MiniRepl } from '../../docs/MiniRepl'; + +# Mini Notation + +Mini Notation is everything between the quotes. It the short rhythm language of Tidal. + +## Cycles + +**The longer the sequence, the faster it runs** + + + +**Play less sounds per cycle with \{curly braces\}** + + + +**Use \`backticks\` for multiple lines** + + + +**Play one sounds per cycle with \** + +")`} punchcard /> + +This is the same as `{...}%1` + +## Operators + +**Multiplication: Speed things up** + + + +**Division: Slow things down** + + + +`bd` will play only every second time + +## Combining it all + +**Speed up Sub-Sequences** + + + +**Slow down Sequences** + + + +**Parallel Sub-Sequences** + + + +**Sample Numbers on groups** + + diff --git a/website/src/pages/de/workshop/pattern-effects.mdx b/website/src/pages/de/workshop/pattern-effects.mdx new file mode 100644 index 000000000..4be0a77a3 --- /dev/null +++ b/website/src/pages/de/workshop/pattern-effects.mdx @@ -0,0 +1,194 @@ +--- +title: Pattern Effects +layout: ../../../layouts/MainLayout.astro +--- + +import { MiniRepl } from '@src/docs/MiniRepl'; +import Box from '@components/Box.astro'; +import QA from '@components/QA'; + +# Pattern Effects + +Up until now, most of the functions we've seen are what other music programs are typically capable of: sequencing sounds, playing notes, controlling effects. + +In this chapter, we are going to look at functions that are more unique to tidal. + +**reverse patterns with rev** + + + +**play pattern left and modify it right with jux** + + + +This is the same as: + + + +Let's visualize what happens here: + + + + + +Try commenting out one of the two by adding `//` before a line + + + +**multiple tempos** + + + +This is like doing + + + + + +Try commenting out one or more by adding `//` before a line + + + +**add** + +>")) +.color(">").adsr("[.1 0]:.2:[1 0]") +.sound("gm_acoustic_bass").room(.5)`} + punchcard +/> + + + +If you add a number to a note, the note will be treated as if it was a number + + + +We can add as often as we like: + +>").add("0,7")) +.color(">").adsr("[.1 0]:.2:[1 0]") +.sound("gm_acoustic_bass").room(.5)`} + punchcard +/> + +**add with scale** + + [~ <4 1>]>*2".add("<0 [0,2,4]>/4")) +.scale("C5:minor").release(.5) +.sound("gm_xylophone").room(.5)`} + punchcard +/> + +**time to stack** + + [~ <4 1>]>*2".add("<0 [0,2,4]>/4")) + .scale("C5:minor") + .sound("gm_xylophone") + .room(.4).delay(.125), + note("c2 [eb3,g3]".add("<0 <1 -1>>")) + .adsr("[.1 0]:.2:[1 0]") + .sound("gm_acoustic_bass") + .room(.5), + n("0 1 [2 3] 2").sound("jazz").jux(rev).slow(2) +)`} +/> + +**ply** + + + +this is like writing: + + + + + +Try patterning the `ply` function, for example using `"<1 2 1 3>"` + + + +**off** + +] <2 3> [~ 1]>" + .off(1/8, x=>x.add(4)) + //.off(1/4, x=>x.add(7)) +).scale("/4") +.s("triangle").room(.5).ds(".1:0").delay(.5)`} + punchcard +/> + + + +In the notation `x=>x.`, the `x` is the shifted pattern, which where modifying. + + + +The above is like writing: + +] <2 3> [~ 1]>*2").color("cyan"), + n("<0 [4 <3 2>] <2 3> [~ 1]>*2".add(7).late(1/8)).color("magenta") +).scale("/2") +.s("triangle").adsr(".01:.1:0").room(.5)`} + punchcard +/> + +off is also useful for sounds: + +x.speed(1.5).gain(.25))`} +/> + +| name | description | example | +| ---- | ------------------------------ | ---------------------------------------------------------------------------------------------- | +| rev | reverse | | +| jux | split left/right, modify right | | +| add | add numbers / notes | ")).scale("C:minor")`} /> | +| ply | speed up each event n times | ")`} /> | +| off | copy, shift time & modify | x.speed(2))`} /> | diff --git a/website/src/pages/de/workshop/recap.mdx b/website/src/pages/de/workshop/recap.mdx new file mode 100644 index 000000000..85f3e015d --- /dev/null +++ b/website/src/pages/de/workshop/recap.mdx @@ -0,0 +1,98 @@ +--- +title: Recap +layout: ../../../layouts/MainLayout.astro +--- + +import { MiniRepl } from '../../../docs/MiniRepl'; + +# Workshop Recap + +This page is just a listing of all functions covered in the workshop! + +## Mini Notation + +| Concept | Syntax | Example | +| ----------------- | -------- | -------------------------------------------------------------------------------- | +| Sequence | space | | +| Sample Number | :x | | +| Rests | ~ | | +| Sub-Sequences | \[\] | | +| Sub-Sub-Sequences | \[\[\]\] | | +| Speed up | \* | | +| Parallel | , | | +| Slow down | \/ | | +| Alternate | \<\> | ")`} /> | +| Elongate | @ | | +| Replicate | ! | | + +## Sounds + +| Name | Description | Example | +| ----- | --------------------------------- | ---------------------------------------------------------------------------------- | +| sound | plays the sound of the given name | | +| bank | selects the sound bank | | +| n | select sample number | | + +## Notes + +| Name | Description | Example | +| --------- | ----------------------------------- | -------------------------------------------------------------------------------------------- | +| note | set pitch as number or letter | | +| n + scale | set note in scale | | +| stack | play patterns in parallel (read on) | | + +## Audio Effects + +| name | example | +| ----- | -------------------------------------------------------------------------------------------------- | +| lpf | ")`} /> | +| vowel | ")`} /> | +| gain | | +| delay | | +| room | | +| pan | | +| speed | ")`} /> | +| range | | + +## Pattern Effects + +| name | description | example | +| ---- | ----------------------------------- | ---------------------------------------------------------------------------------------------- | +| cpm | sets the tempo in cycles per minute | | +| fast | speed up | | +| slow | slow down | | +| rev | reverse | | +| jux | split left/right, modify right | | +| add | add numbers / notes | ")).scale("C:minor")`} /> | +| ply | speed up each event n times | ")`} /> | +| off | copy, shift time & modify | x.speed(2))`} /> | + +## Samples + +``` +casio control crow techno house jazz +metal east jvbass juno insect space wind +bd sd sn cp hh +piano +``` + +## Synths + +``` +gm_electric_guitar_muted gm_acoustic_bass +gm_voice_oohs gm_blown_bottle sawtooth square triangle +gm_xylophone gm_synth_bass_1 gm_synth_strings_1 +``` + +## Banks + +``` +RolandTR909 +``` + +## Scales + +``` +major minor dorian mixolydian +minor:pentatonic major:pentatonic +``` From a88759ba9462d20e1d7ef8248858e512a09718ef Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Tue, 6 Jun 2023 22:43:51 +0200 Subject: [PATCH 18/33] translate notes chapter --- website/src/pages/de/workshop/first-notes.mdx | 104 +++++++++--------- 1 file changed, 53 insertions(+), 51 deletions(-) diff --git a/website/src/pages/de/workshop/first-notes.mdx b/website/src/pages/de/workshop/first-notes.mdx index c33fbb1a8..7cf16205e 100644 --- a/website/src/pages/de/workshop/first-notes.mdx +++ b/website/src/pages/de/workshop/first-notes.mdx @@ -151,7 +151,7 @@ Wir schauen uns später noch mehr Möglichkeiten an wie man patterns kombiniert. ## Längere Sequenzen -**Divide sequences with `/` to slow them down** +**Sequenzen verlangsamen mit `/`** {/* [c2 bb1 f2 eb2] */} @@ -159,27 +159,27 @@ Wir schauen uns später noch mehr Möglichkeiten an wie man patterns kombiniert. -The `/4` plays the sequence in brackets over 4 cycles (=4s). +Das `/4` spielt die Sequenz 4 mal so langsam, also insgesamt 4 cycles = 4s. -So each of the 4 notes is 1s long. +Jede Note ist nun also 1s lang. -Try adding more notes inside the brackets and notice how it gets faster. +Schreib noch mehr Töne in die Klammern und achte darauf dass es schneller wird. -Because it is so common to just play one thing per cycle, you can.. +Wenn eine Sequenz unabhängig von ihrem Inhalt immer gleich schnell bleiben soll, gibt es noch eine andere Art Klammern: -**Play one per cycle with \< \>** +**Eins pro Cycle per \< \>** ").sound("gm_acoustic_bass")`} punchcard /> -Try adding more notes inside the brackets and notice how it does **not** get faster. +Füg noch mehr Töne hinzu und achte darauf wie das tempo gleich bleibt! -**Play one sequence per cycle** +**Eine Sequenz pro Cycle** {/* <[c2 c3]*4 [bb1 bb2]*4 [f2 f3]*4 [eb2 eb3]*4>/2 */} @@ -191,7 +191,7 @@ Try adding more notes inside the brackets and notice how it does **not** get fas punchcard /> -**Alternate between multiple things** +**Alternativen** -This is also useful for unpitched sounds: +Das ist auch praktisch für atonale Sounds: -## Scales +## Skalen -Finding the right notes can be difficult.. Scales are here to help: +Es kann mühsam sein die richtigen Noten zu finden wenn man alle zur Verfügung hat. +Mit Skalen ist das einfacher: -Try out different numbers. Any number should sound good! +Probier verschiedene Zahlen aus. Jede klingt gut! -Try out different scales: +Probier verschiedene Skalen: - C:major - A2:minor @@ -238,9 +239,9 @@ Try out different scales: -**automate scales** +**Automatisierte Skalen** -Just like anything, we can automate the scale with a pattern: +Wie alle Funktionen können auch Skalen mit einem Pattern automatisiert werden: -If you have no idea what these scale mean, don't worry. -These are just labels for different sets of notes that go well together. +Wenn du keine Ahnung hast was die Skalen bedeuten, keine Sorge. +Es sind einfach nur Namen für verschiedene Gruppen von Tönen die gut zusammenpassen. -Take your time and you'll find scales you like! +Nimm dir Zeit um herauszufinden welche Skalen du magst. -## Repeat & Elongate +## Wiederholen und Verlängern -**Elongate with @** +**Verlängern mit @** -Not using `@` is like using `@1`. In the above example, c is 3 units long and eb is 1 unit long. +Ein Element ohne `@` ist gleichbedeutend mit `@1`. Im Beispiel ist `c` drei Einheiten lang, `eb` nur eine. -Try changing that number! +Spiel mit der Länge! -**Elongate within sub-sequences** +**Unter-Sequenzen verlängern** -This groove is called a `shuffle`. -Each beat has two notes, where the first is twice as long as the second. -This is also sometimes called triplet swing. You'll often find it in blues and jazz. +Dieser Groove wird auch `shuffle` genannt. +Jeder Schlag enthält 2 Töne, wobei der erste doppelt so lang wie der zweite ist. +Das nennt man auch manchmal `triolen swing`. Es ist ein typischer Rhythmus im Blues und Jazz. -**Replicate** +**Wiederholen** ]").sound("piano")`} punchcard /> -Try switching between `!`, `*` and `@` +Wechsel zwischen `!`, `*` und `@` hin und her. -What's the difference? +Was ist der Unterschied? -## Recap +## Rückblick -Let's recap what we've learned in this chapter: +Das haben wir in diesem Kapitel gelernt: -| Concept | Syntax | Example | -| --------- | ------ | ------------------------------------------------------------------- | -| Slow down | \/ | | -| Alternate | \<\> | ")`} /> | -| Elongate | @ | | -| Replicate | ! | | +| Concept | Syntax | Example | +| ------------ | ------ | ------------------------------------------------------------------- | +| Verlangsamen | \/ | | +| Alternativen | \<\> | ")`} /> | +| Verlängern | @ | | +| Wiederholen | ! | | -New functions: +Neue Funktionen: -| Name | Description | Example | -| ----- | ----------------------------------- | -------------------------------------------------------------------------------------------- | -| note | set pitch as number or letter | | -| scale | interpret `n` as scale degree | | -| stack | play patterns in parallel (read on) | | +| Name | Description | Example | +| ----- | --------------------------------------- | -------------------------------------------------------------------------------------------- | +| note | Tonhöhe als Buchstabe oder Zahl | | +| scale | Interpretiert `n` als Skalenstufe | | +| stack | Spiele mehrere Patterns parallel (s.u.) | | -## Examples +## Beispiele -**Classy Bassline** +**Bassline** -**Classy Melody** +**Melodie** -**Classy Drums** +**Drums** -**If there just was a way to play all the above at the same time.......** +**Wenn es doch nur einen Weg gäbe das alles gleichzeitig zu spielen.......** -It's called `stack` 😙 +Das geht mit `stack` 😙 @@ -385,4 +386,5 @@ It's called `stack` 😙 )`} /> -This is starting to sound like actual music! We have sounds, we have notes, now the last piece of the puzzle is missing: [effects](/workshop/first-effects) +Das hört sich doch langsam nach echter Musik an! +Wir haben Sounds, wir haben Töne.. noch ein Puzzleteil fehlt: [Effekte](/workshop/first-effects) From 06950a6bd8fb2f6dccc725d5e3c2ce9c4534e6a5 Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Wed, 7 Jun 2023 16:50:54 +0200 Subject: [PATCH 19/33] translate rest of workshop to german --- .../src/pages/de/workshop/first-effects.mdx | 125 ++++++++++-------- website/src/pages/de/workshop/first-notes.mdx | 2 +- .../src/pages/de/workshop/first-sounds.mdx | 21 ++- website/src/pages/de/workshop/intro.mdx | 63 +++++++-- .../src/pages/de/workshop/pattern-effects.mdx | 60 +++++---- website/src/pages/de/workshop/recap.mdx | 72 +++++----- website/src/pages/workshop/first-effects.mdx | 12 +- website/src/pages/workshop/first-sounds.mdx | 24 ++-- website/src/pages/workshop/intro.mdx | 65 +++++++-- website/src/pages/workshop/recap.mdx | 10 +- website/src/repl/prebake.mjs | 2 +- 11 files changed, 277 insertions(+), 179 deletions(-) diff --git a/website/src/pages/de/workshop/first-effects.mdx b/website/src/pages/de/workshop/first-effects.mdx index d547548db..71b1d3933 100644 --- a/website/src/pages/de/workshop/first-effects.mdx +++ b/website/src/pages/de/workshop/first-effects.mdx @@ -1,18 +1,16 @@ --- -title: First Effects +title: Erste Effekte layout: ../../../layouts/MainLayout.astro --- import { MiniRepl } from '../../../docs/MiniRepl'; import QA from '@components/QA'; -# First Effects +# Erste Effekte import Box from '@components/Box.astro'; -We have sounds, we have notes, now let's look at effects! - -## Some basic effects +## Ein paar grundlegende Effekte **low-pass filter** @@ -27,12 +25,12 @@ We have sounds, we have notes, now let's look at effects! lpf = **l**ow **p**ass **f**ilter -- Change lpf to 200. Notice how it gets muffled. Think of it as standing in front of the club with the door closed 🚪. -- Now let's open the door... change it to 5000. Notice how it gets brighter ✨🪩 +- Ändere `lpf` in 200. Hörst du wie der Bass dumpfer klingt? Es klingt so ähnlich als würde die Musik hinter einer geschlossenen Tür laufen 🚪 +- Lass uns nun die Tür öffnen: Ändere `lpf` in 5000. Der Klang wird dadurch viel heller und schärfer ✨🪩 -**pattern the filter** +**filter automatisieren** -- Try adding more values -- Notice how the pattern in lpf does not change the overall rhythm +- Füg noch mehr `lpf` Werte hinzu +- Das pattern in `lpf` ändert nicht den Rhythmus der Bassline -We will learn how to automate with waves later... +Später sehen wir wie man mit Wellenformen Dinge automatisieren kann. -**vowel** +**vowel = Vokal** /2")`} /> -**gain** +**gain = Verstärkung** -Rhythm is all about dynamics! +Bei Rhythmen ist die Dynamik (= Veränderungen der Lautstärke) sehr wichtig. -- Remove `.gain(...)` and notice how flat it sounds. -- Bring it back by undoing (ctrl+z) +- Entferne `.gain(...)` und achte darauf wie es viel flacher klingt. +- Mach es rückgängig (strg+z dann strg+enter) -**stacks within stacks** +**stacks in stacks** -Let's combine all of the above into a little tune: +Lass uns die obigen Beispiele kombinieren: -Try to identify the individual parts of the stacks, pay attention to where the commas are. -The 3 parts (drums, bassline, chords) are exactly as earlier, just stacked together, separated by comma. +Versuche die einzelnen Teile innerhalb `stack` zu erkennen, schau dir an wie die Kommas gesetzt sind. + +Die 3 Teile (Drums, Bass, Akkorde) sind genau wie vorher, nur in einem `stack`, getrennt durch Kommas -**shape the sound with an adsr envelope** +**Den Sound formen mit ADSR Hüllkurve** -Try to find out what the numbers do.. Compare the following +Versuche herauszufinden was die Zahlen machen. Probier folgendes: - attack: `.5` vs `0` - decay: `.5` vs `0` - sustain: `1` vs `.25` vs `0` - release: `0` vs `.5` vs `1` -Can you guess what they do? +Kannst du erraten was die einzelnen Werte machen? - + -- attack: time it takes to fade in -- decay: time it takes to fade to sustain -- sustain: level after decay -- release: time it takes to fade out after note is finished +- attack (anschlagen): Zeit des Aufbaus +- decay (zerfallen): Zeit des Abfalls +- sustain (erhalten): Lautstärke nach Abfall +- release (loslassen): Zeit des Abfalls nach dem Ende ![ADSR](https://upload.wikimedia.org/wikipedia/commons/thumb/e/ea/ADSR_parameter.svg/1920px-ADSR_parameter.svg.png) -**adsr short notation** +**adsr Kurznotation** -**delay** +**delay = Verzögerung** -Try some `delay` values between 0 and 1. Btw, `.5` is short for `0.5` +Probier verschiedene `delay` Werte zwischen 0 und 1. Übrigens: `.5` ist kurz für `0.5`. -What happens if you use `.delay(".8:.125")` ? Can you guess what the second number does? +Was passiert wenn du `.delay(".8:.125")` schreibst? Kannst du erraten was die zweite Zahl macht? -What happens if you use `.delay(".8:.06:.8")` ? Can you guess what the third number does? +Was passiert wenn du `.delay(".8:.06:.8")` schreibst? Kannst du erraten was die dritte Zahl macht? -**room aka reverb** + + +`delay("a:b:c")`: + +- a: Lautstärke des Delays +- b: Verzögerungszeit +- c: Feedback (je kleiner desto schneller verschwindet das Delay) + + + +**room aka reverb = Hall** -Try different values! +Spiel mit verschiedenen Werten. -Add a delay too! +Füg auch ein Delay hinzu! -**little dub tune** +**kleiner dub tune** -Let's add a bass to make this complete: +Für echten Dub fehlt noch der Bass: -Try adding `.hush()` at the end of one of the patterns in the stack... +Füg `.hush()` ans ende eines Patterns im stack... -**pan** +**pan = Panorama** -**speed** +**speed = Geschwindigkeit** ").room(.2)`} /> -**fast and slow** +**fast and slow = schnell und langsam** -We can use `fast` and `slow` to change the tempo of a pattern outside of Mini-Notation: +Mit `fast` und `slow` kann man das tempo eines patterns außerhalb der Mini-Notation ändern: -Change the `slow` value. Try replacing it with `fast`. +Ändere den `slow` Wert. Tausche `slow` durch `fast`. -What happens if you use a pattern like `.fast("<1 [2 4]>")`? +Was passiert wenn du den Wert automatisierst? z.b. `.fast("<1 [2 4]>")` ? -By the way, inside Mini-Notation, `fast` is `*` and slow is `/`. +Übrigens, innerhalb der Mini-Notation, `fast` ist `*` und `slow` ist `/`. ")`} /> -## automation with signals +## Automation mit Signalen -Instead of changing values stepwise, we can also control them with signals: +Anstatt Werte schrittweise zu automatisieren können wir auch sogenannte Signale benutzen: -The basic waveforms for signals are `sine`, `saw`, `square`, `tri` 🌊 +Die grundlegenden Wellenformen sind `sine`, `saw`, `square`, `tri` 🌊 -Try also random signals `rand` and `perlin`! +Probiere auch die zufälligen Signale `rand` und `perlin`! -The gain is visualized as transparency in the pianoroll. +Der `gain`-Wert (Verstärkung) wird in der Visualisierung als Transparenz dargestellt. -**setting a range** +**Bereich ändern mit `range`** -By default, waves oscillate between 0 to 1. We can change that with `range`: +Signale bewegen sich standardmäßig zwischen 0 und 1. Wir können das mit `range` ändern: +`range` ist nützlich wenn wir Funktionen mit einem anderen Wertebereich als 0 und 1 automatisieren wollen (z.b. lpf) + -What happens if you flip the range values? +Was passiert wenn du die beiden Werte vertauschst? -We can change the automation speed with slow / fast: +Wir können die Geschwindigkeit der Automation mit slow / fast ändern: -The whole automation will now take 8 cycles to repeat. +Die ganze Automation braucht nun 8 cycle bis sie sich wiederholt. -## Recap +## Rückblick | name | example | | ----- | -------------------------------------------------------------------------------------------------- | diff --git a/website/src/pages/de/workshop/first-notes.mdx b/website/src/pages/de/workshop/first-notes.mdx index 7cf16205e..93ba90315 100644 --- a/website/src/pages/de/workshop/first-notes.mdx +++ b/website/src/pages/de/workshop/first-notes.mdx @@ -1,5 +1,5 @@ --- -title: First Notes +title: Erste Töne layout: ../../../layouts/MainLayout.astro --- diff --git a/website/src/pages/de/workshop/first-sounds.mdx b/website/src/pages/de/workshop/first-sounds.mdx index 0f132bec0..6c3fb6fd9 100644 --- a/website/src/pages/de/workshop/first-sounds.mdx +++ b/website/src/pages/de/workshop/first-sounds.mdx @@ -61,7 +61,6 @@ Diese 2-Buchstaben Kombinationen stehen für verschiedene Teile eines Drumsets: - `bd` = **b**ass **d**rum - Basstrommel - `sd` = **s**nare **d**rum - Schnarrtrommel -- `sn` = **sn**are - `rim` = **rim**shot - Rahmenschlag - `hh` = **h**i**h**at - `oh` = **o**pen **h**ihat - Offenes Hi-Hat @@ -104,13 +103,13 @@ Versuch noch mehr Sounds hinzuzfügen! **Je länger die Sequence, desto schneller** - + Der Inhalt einer Sequence wird in einen sogenannten Cycle (=Zyklus) zusammengequetscht. **Tempo ändern mit `cpm`** - + @@ -128,7 +127,7 @@ Wir werden später noch mehr Möglichkeiten kennen lernen wie man das Tempo ver **Unter-Sequenzen mit [Klammern]** - + @@ -140,15 +139,15 @@ Genau wie bei der ganzen Sequence wird der eine Unter-Sequence schneller je mehr **Multiplikation: Dinge schneller machen** - + **Multiplikation: Unter-Sequences schneller machen** - + **Multiplikation: Vieeeeeeel schneller** - + @@ -158,7 +157,7 @@ Tonhöhe = sehr schneller Rhythmus **Unter-Unter-Sequenzen mit [[Klammern]]** - + @@ -216,12 +215,12 @@ Das haben wir bisher gelernt: | Concept | Syntax | Example | | --------------------- | ----------- | -------------------------------------------------------------------------------- | -| Sequenz | Leerzeichen | | +| Sequenz | Leerzeichen | | | Sound Nummer | :x | | | Pausen | ~ | | | Unter-Sequenzen | \[\] | | -| Unter-Unter-Sequenzen | \[\[\]\] | | -| Schneller | \* | | +| Unter-Unter-Sequenzen | \[\[\]\] | | +| Schneller | \* | | | Parallel | , | | Die mit Apostrophen umgebene Mini-Notation benutzt man normalerweise in eine sogenannten Funktion. diff --git a/website/src/pages/de/workshop/intro.mdx b/website/src/pages/de/workshop/intro.mdx index 5688476be..47f90b639 100644 --- a/website/src/pages/de/workshop/intro.mdx +++ b/website/src/pages/de/workshop/intro.mdx @@ -3,20 +3,57 @@ title: Introduction layout: ../../../layouts/MainLayout.astro --- -# Introduction +# Welcome -## goals +Welcome to the Strudel documentation pages! +You've come to the right place if you want to learn how to make music with code. -- be beginner friendly -- teach a representative subset of strudel / tidal -- introduce one new thing at a time -- give practical / musical examples -- encourage self-experimentation -- hands on learning > walls of text -- maintain flow state -- no setup required +## What is Strudel? -## inspired by +With Strudel, you can expressively write dynamic music pieces. +It is an official port of the [Tidal Cycles](https://tidalcycles.org/) pattern language to JavaScript. +You don't need to know JavaScript or Tidal Cycles to make music with Strudel. +This interactive tutorial will guide you through the basics of Strudel. +The best place to actually make music with Strudel is the [Strudel REPL](https://strudel.tidalcycles.org/) -- https://github.com/tidalcycles/tidal-workshop/blob/master/workshop.tidal -- https://learningmusic.ableton.com +## What can you do with Strudel? + +- live code music: make music with code in real time +- algorithmic composition: compose music using tidal's unique approach to pattern manipulation +- teaching: focussing on a low barrier of entry, Strudel is a good fit for teaching music and code at the same time. +- integrate into your existing music setup: either via MIDI or OSC, you can use Strudel as a really flexible sequencer + +## Example + +Here is an example of how strudel can sound: + +],hh*8") + .speed(perlin.range(.8,.9)), // random sample speed variation + // bassline + "" + .off(1/8,x=>x.add(12).degradeBy(.5)) // random octave jumps + .add(perlin.range(0,.5)) // random pitch variation + .superimpose(add(.05)) // add second, slightly detuned voice + .note() // wrap in "note" + .decay(.15).sustain(0) // make each note of equal length + .s('sawtooth') // waveform + .gain(.4) // turn down + .cutoff(sine.slow(7).range(300,5000)), // automate cutoff + // chords + ">".voicings('lefthand') + .superimpose(x=>x.add(.04)) // add second, slightly detuned voice + .add(perlin.range(0,.5)) // random pitch variation + .note() // wrap in "note" + .s('sawtooth') // waveform + .gain(.16) // turn down + .cutoff(500) // fixed cutoff + .attack(1) // slowly fade in +) +.slow(3/2)`} +/> + +To hear more, go to the [Strudel REPL](https://strudel.tidalcycles.org/) and press shuffle to hear a random example pattern. diff --git a/website/src/pages/de/workshop/pattern-effects.mdx b/website/src/pages/de/workshop/pattern-effects.mdx index 4be0a77a3..f25afdd74 100644 --- a/website/src/pages/de/workshop/pattern-effects.mdx +++ b/website/src/pages/de/workshop/pattern-effects.mdx @@ -1,5 +1,5 @@ --- -title: Pattern Effects +title: Pattern Effekte layout: ../../../layouts/MainLayout.astro --- @@ -7,21 +7,21 @@ import { MiniRepl } from '@src/docs/MiniRepl'; import Box from '@components/Box.astro'; import QA from '@components/QA'; -# Pattern Effects +# Pattern Effekte -Up until now, most of the functions we've seen are what other music programs are typically capable of: sequencing sounds, playing notes, controlling effects. +Bis jetzt sind die meisten Funktionen die wir kennengelernt haben ähnlich wie Funktionen in anderen Musik Programmen: Sequencing von Sounds, Noten und Effekten. -In this chapter, we are going to look at functions that are more unique to tidal. +In diesem Kapitel beschäftigen wir uns mit Funktionen die weniger herkömmlich oder auch enzigartig sind. -**reverse patterns with rev** +**rev = rückwärts abspielen** -**play pattern left and modify it right with jux** +**jux = einen stereo kanal modifizieren** -This is the same as: +So würde man das ohne jux schreiben: -Let's visualize what happens here: +Lass uns visualisieren was hier passiert: -Try commenting out one of the two by adding `//` before a line +Schreibe `//` vor eine der beiden Zeilen im `stack`! -**multiple tempos** +**mehrere tempos** -This is like doing +Das hat den gleichen Effekt wie: -Try commenting out one or more by adding `//` before a line +Schreibe wieder `//` vor eine oder mehrere Zeilen im `stack`. -**add** +**add = addieren** -If you add a number to a note, the note will be treated as if it was a number +Addiert man eine Zahl zu einer Note, verhält sich diese wie eine Zahl. + +z.B. c4 = 60, also ist c4 + 2 = 62 -We can add as often as we like: +Man kann auch mehrmals addieren: -**add with scale** +**add + scale** -**time to stack** +**Alles zusammen** -this is like writing: +das ist wie: -Try patterning the `ply` function, for example using `"<1 2 1 3>"` +Probier `ply` mit einem pattern zu automatisieren, z.b. `"<1 2 1 3>"` @@ -159,11 +161,11 @@ Try patterning the `ply` function, for example using `"<1 2 1 3>"` -In the notation `x=>x.`, the `x` is the shifted pattern, which where modifying. +In der notation `x=>x.`, das `x` ist das pattern das wir bearbeiten. -The above is like writing: +Das Beispiel oben sieht ohne `off` so aus: -off is also useful for sounds: +`off` ist auch nützlich für sounds: x.speed(1.5).gain(.25))`} /> -| name | description | example | -| ---- | ------------------------------ | ---------------------------------------------------------------------------------------------- | -| rev | reverse | | -| jux | split left/right, modify right | | -| add | add numbers / notes | ")).scale("C:minor")`} /> | -| ply | speed up each event n times | ")`} /> | -| off | copy, shift time & modify | x.speed(2))`} /> | +| name | description | example | +| ---- | --------------------------------- | ---------------------------------------------------------------------------------------------- | +| rev | rückwärts | | +| jux | ein stereo-kanal modifizieren | | +| add | addiert zahlen oder noten | ")).scale("C:minor")`} /> | +| ply | multipliziert jedes element x mal | ")`} /> | +| off | verzögert eine modifizierte kopie | x.speed(2))`} /> | diff --git a/website/src/pages/de/workshop/recap.mdx b/website/src/pages/de/workshop/recap.mdx index 85f3e015d..8341c9372 100644 --- a/website/src/pages/de/workshop/recap.mdx +++ b/website/src/pages/de/workshop/recap.mdx @@ -5,43 +5,43 @@ layout: ../../../layouts/MainLayout.astro import { MiniRepl } from '../../../docs/MiniRepl'; -# Workshop Recap +# Workshop Rückblick -This page is just a listing of all functions covered in the workshop! +Diese Seite ist eine Auflistung aller im Workshop enthaltenen Funktionen. ## Mini Notation -| Concept | Syntax | Example | -| ----------------- | -------- | -------------------------------------------------------------------------------- | -| Sequence | space | | -| Sample Number | :x | | -| Rests | ~ | | -| Sub-Sequences | \[\] | | -| Sub-Sub-Sequences | \[\[\]\] | | -| Speed up | \* | | -| Parallel | , | | -| Slow down | \/ | | -| Alternate | \<\> | ")`} /> | -| Elongate | @ | | -| Replicate | ! | | +| Concept | Syntax | Example | +| --------------------- | -------- | -------------------------------------------------------------------------------- | +| Sequence | space | | +| Sample Nummer | :x | | +| Pausen | ~ | | +| Unter-Sequences | \[\] | | +| Unter-Unter-Sequences | \[\[\]\] | | +| Schneller | \* | | +| Slow down | \/ | | +| Parallel | , | | +| Alternieren | \<\> | ")`} /> | +| Verlängern | @ | | +| Wiederholen | ! | | ## Sounds -| Name | Description | Example | -| ----- | --------------------------------- | ---------------------------------------------------------------------------------- | -| sound | plays the sound of the given name | | -| bank | selects the sound bank | | -| n | select sample number | | +| Name | Description | Example | +| ----- | -------------------------- | ---------------------------------------------------------------------------------- | +| sound | spielt den sound mit namen | | +| bank | wählt die soundbank | | +| n | wählt sample mit nummer | | ## Notes -| Name | Description | Example | -| --------- | ----------------------------------- | -------------------------------------------------------------------------------------------- | -| note | set pitch as number or letter | | -| n + scale | set note in scale | | -| stack | play patterns in parallel (read on) | | +| Name | Description | Example | +| --------- | ---------------------------------- | -------------------------------------------------------------------------------------------- | +| note | wählt note per zahl oder buchstabe | | +| n + scale | wählt note n in skala | | +| stack | spielt mehrere patterns parallel | | -## Audio Effects +## Audio Effekte | name | example | | ----- | -------------------------------------------------------------------------------------------------- | @@ -56,16 +56,16 @@ This page is just a listing of all functions covered in the workshop! ## Pattern Effects -| name | description | example | -| ---- | ----------------------------------- | ---------------------------------------------------------------------------------------------- | -| cpm | sets the tempo in cycles per minute | | -| fast | speed up | | -| slow | slow down | | -| rev | reverse | | -| jux | split left/right, modify right | | -| add | add numbers / notes | ")).scale("C:minor")`} /> | -| ply | speed up each event n times | ")`} /> | -| off | copy, shift time & modify | x.speed(2))`} /> | +| name | description | example | +| ---- | --------------------------------- | ---------------------------------------------------------------------------------------------- | +| cpm | tempo in cycles pro minute | | +| fast | schneller | | +| slow | langsamer | | +| rev | rückwärts | | +| jux | ein stereo-kanal modifizieren | | +| add | addiert zahlen oder noten | ")).scale("C:minor")`} /> | +| ply | jedes element schneller machen | ")`} /> | +| off | verzögert eine modifizierte kopie | x.speed(2))`} /> | ## Samples diff --git a/website/src/pages/workshop/first-effects.mdx b/website/src/pages/workshop/first-effects.mdx index 1428e2bdf..ab65ffe3b 100644 --- a/website/src/pages/workshop/first-effects.mdx +++ b/website/src/pages/workshop/first-effects.mdx @@ -176,6 +176,16 @@ What happens if you use `.delay(".8:.06:.8")` ? Can you guess what the third num + + +`delay("a:b:c")`: + +- a: delay volume +- b: delay time +- c: feedback (smaller number = quicker fade) + + + **room aka reverb** ")`? -By the way, inside Mini-Notation, `fast` is `*` and slow is `/`. +By the way, inside Mini-Notation, `fast` is `*` and `slow` is `/`. ")`} /> diff --git a/website/src/pages/workshop/first-sounds.mdx b/website/src/pages/workshop/first-sounds.mdx index 618943339..8c421dd92 100644 --- a/website/src/pages/workshop/first-sounds.mdx +++ b/website/src/pages/workshop/first-sounds.mdx @@ -13,7 +13,7 @@ import QA from '@components/QA'; Let's start by making some noise: - + @@ -61,7 +61,7 @@ These letter combinations stand for different parts of a drum set: - `bd` = **b**ass **d**rum - `sd` = **s**nare **d**rum -- `sn` = **sn**are +- `sd` = **sd**are - `rim` = **rim**shot - `hh` = **h**i**h**at - `oh` = **o**pen **h**ihat @@ -103,13 +103,13 @@ Try adding more sounds to the sequence! **The longer the sequence, the faster it runs** - + The content of a sequence will be squished into what's called a cycle. **One way to change the tempo is using `cpm`** - + @@ -127,7 +127,7 @@ We will look at other ways to change the tempo later! **Sub-Sequences with [brackets]** - + @@ -139,15 +139,15 @@ Similar to the whole sequence, the content of a sub-sequence will be squished to **Multiplication: Speed things up** - + **Multiplication: Speed up sequences** - + **Multiplication: Speeeeeeeeed things up** - + @@ -157,7 +157,7 @@ Pitch = really fast rhythm **Sub-Sub-Sequences with [[brackets]]** - + @@ -214,12 +214,12 @@ This is what we've leared so far: | Concept | Syntax | Example | | ----------------- | -------- | -------------------------------------------------------------------------------- | -| Sequence | space | | +| Sequence | space | | | Sample Number | :x | | | Rests | ~ | | | Sub-Sequences | \[\] | | -| Sub-Sub-Sequences | \[\[\]\] | | -| Speed up | \* | | +| Sub-Sub-Sequences | \[\[\]\] | | +| Speed up | \* | | | Parallel | , | | The Mini-Notation is usually used inside some function. These are the functions we've seen so far: diff --git a/website/src/pages/workshop/intro.mdx b/website/src/pages/workshop/intro.mdx index 9e18bbfec..0de7779ea 100644 --- a/website/src/pages/workshop/intro.mdx +++ b/website/src/pages/workshop/intro.mdx @@ -3,20 +3,59 @@ title: Introduction layout: ../../layouts/MainLayout.astro --- -# Introduction +import { MiniRepl } from '../../docs/MiniRepl'; -## goals +# Welcome -- be beginner friendly -- teach a representative subset of strudel / tidal -- introduce one new thing at a time -- give practical / musical examples -- encourage self-experimentation -- hands on learning > walls of text -- maintain flow state -- no setup required +Welcome to the Strudel documentation pages! +You've come to the right place if you want to learn how to make music with code. -## inspired by +## What is Strudel? -- https://github.com/tidalcycles/tidal-workshop/blob/master/workshop.tidal -- https://learningmusic.ableton.com +With Strudel, you can expressively write dynamic music pieces.
+It is an official port of the [Tidal Cycles](https://tidalcycles.org/) pattern language to JavaScript. +You don't need to know JavaScript or Tidal Cycles to make music with Strudel. +This interactive tutorial will guide you through the basics of Strudel.
+The best place to actually make music with Strudel is the [Strudel REPL](https://strudel.tidalcycles.org/) + +## What can you do with Strudel? + +- live code music: make music with code in real time +- algorithmic composition: compose music using tidal's unique approach to pattern manipulation +- teaching: focussing on a low barrier of entry, Strudel is a good fit for teaching music and code at the same time. +- integrate into your existing music setup: either via MIDI or OSC, you can use Strudel as a really flexible sequencer + +## Example + +Here is an example of how strudel can sound: + +],hh*8") + .speed(perlin.range(.8,.9)), // random sample speed variation + // bassline + "" + .off(1/8,x=>x.add(12).degradeBy(.5)) // random octave jumps + .add(perlin.range(0,.5)) // random pitch variation + .superimpose(add(.05)) // add second, slightly detuned voice + .note() // wrap in "note" + .decay(.15).sustain(0) // make each note of equal length + .s('sawtooth') // waveform + .gain(.4) // turn down + .cutoff(sine.slow(7).range(300,5000)), // automate cutoff + // chords + ">".voicings('lefthand') + .superimpose(x=>x.add(.04)) // add second, slightly detuned voice + .add(perlin.range(0,.5)) // random pitch variation + .note() // wrap in "note" + .s('sawtooth') // waveform + .gain(.16) // turn down + .cutoff(500) // fixed cutoff + .attack(1) // slowly fade in +) +.slow(3/2)`} +/> + +To hear more, go to the [Strudel REPL](https://strudel.tidalcycles.org/) and press shuffle to hear a random example pattern. diff --git a/website/src/pages/workshop/recap.mdx b/website/src/pages/workshop/recap.mdx index bc9c4648c..6ebbd3f9b 100644 --- a/website/src/pages/workshop/recap.mdx +++ b/website/src/pages/workshop/recap.mdx @@ -35,11 +35,11 @@ This page is just a listing of all functions covered in the workshop! ## Notes -| Name | Description | Example | -| --------- | ----------------------------------- | -------------------------------------------------------------------------------------------- | -| note | set pitch as number or letter | | -| n + scale | set note in scale | | -| stack | play patterns in parallel (read on) | | +| Name | Description | Example | +| --------- | ----------------------------- | -------------------------------------------------------------------------------------------- | +| note | set pitch as number or letter | | +| n + scale | set note in scale | | +| stack | play patterns in parallel | | ## Audio Effects diff --git a/website/src/repl/prebake.mjs b/website/src/repl/prebake.mjs index f8a4e4770..a534ba7c8 100644 --- a/website/src/repl/prebake.mjs +++ b/website/src/repl/prebake.mjs @@ -23,7 +23,7 @@ export async function prebake() { }), samples(`./EmuSP12.json`, `./EmuSP12/`, { prebake: true, tag: 'drum-machines' }), ]); - await samples('github:tidalcycles/Dirt-Samples/master'); + await samples('github:tidalcycles/Dirt-Samples/master'); // TODO: remove } const maxPan = noteToMidi('C8'); From 105193a45223555d39fa69ae069ba679304d9587 Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Wed, 7 Jun 2023 21:22:01 +0200 Subject: [PATCH 20/33] replace tutorial with workshop + move parts of tutorial to more + move more before Pattern Functions --- website/public/icons/strudel_icon.png | Bin 0 -> 23070 bytes website/src/config.ts | 27 ++- .../src/pages/de/workshop/first-sounds.mdx | 2 +- website/src/pages/de/workshop/langebank.mdx | 154 ------------------ website/src/pages/learn/code.mdx | 30 ++-- website/src/pages/learn/factories.mdx | 4 +- website/src/pages/learn/mini-notation.mdx | 14 +- website/src/pages/workshop/first-sounds.mdx | 2 + .../{intro.mdx => getting-started.mdx} | 13 +- website/src/pages/workshop/langebank.mdx | 36 ++++ 10 files changed, 87 insertions(+), 195 deletions(-) create mode 100644 website/public/icons/strudel_icon.png delete mode 100644 website/src/pages/de/workshop/langebank.mdx rename website/src/pages/workshop/{intro.mdx => getting-started.mdx} (85%) diff --git a/website/public/icons/strudel_icon.png b/website/public/icons/strudel_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..ec9ad8e172ae44243f66ecfb081c46ba4eb293ee GIT binary patch literal 23070 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 - -1. press play button to start -2. change `house` to `casio` -3. press refresh button to update -4. press stop button to stop - -
- -**Change tempo** - - - -adding your own samples - - - -").slow(3)`} - punchcard -/> - -n(run(8)).sound("east") - -Shorter variant: - - - -polyrythms & polymeters - --- This can make for flexible time signatures: - -d1 $ sound "[bd bd sn:5] [bd sn:3]" - --- You can put subsequences inside subsequences: -d1 $ sound "[[bd bd] bd sn:5] [bd sn:3]" - --- Keep going.. -d1 $ sound "[[bd [bd bd bd bd]] bd sn:5] [bd sn:3]" - --- \* Polymetric / polyrhythmic sequences - --- Play two subsequences at once by separating with a comma: - -d1 $ sound "[voodoo voodoo:3, arpy arpy:4 arpy:2]" - --- compare how [,] and {,} work: - -d1 $ sound "[voodoo voodoo:3, arpy arpy:4 arpy:2]" - -d1 $ sound "{voodoo voodoo:3, arpy arpy:4 arpy:2}" - -d1 $ sound "[drum bd hh bd, can can:2 can:3 can:4 can:2]" - -d1 $ sound "{drum bd hh bd, can can:2 can:3 can:4 can:2}" - -d1 $ sound "[bd sn, can:2 can:3 can:1, arpy arpy:1 arpy:2 arpy:3 arpy:5]" - -d1 $ sound "{bd sn, can:2 can:3 can:1, arpy arpy:1 arpy:2 arpy:3 arpy:5}" - -**Play X per cycle with \{ \}** - - - - - -Try different numbers after `%` - -`{ ... }%1` is the same as `< ... >` - - - -## Bracket Recap - -- `[]` squeezes contents to 1 cycle -- `<>` plays one item per cycle -- `{}%x` plays x items per cycle - -/2")) -.sound("gm_synth_bass_1")`} -/> - -vertical - - -< 4 4 4 3> -<[2,7] [2,6] [1,6] [1,6]> -< 4 4 4 3> ->*2\`) -.scale("/4") -.sound("piano")`} -/> - -horizontal - -*2\`) -.scale("/4") -.sound("piano")`} -/> diff --git a/website/src/pages/learn/code.mdx b/website/src/pages/learn/code.mdx index 678d4ccc1..6ac1d3892 100644 --- a/website/src/pages/learn/code.mdx +++ b/website/src/pages/learn/code.mdx @@ -6,31 +6,31 @@ layout: ../../layouts/MainLayout.astro import { MiniRepl } from '../../docs/MiniRepl'; import { JsDoc } from '../../docs/JsDoc'; -# Strudel Code +# Coding Syntax -Now that we have played some notes using different sounds, let's take a step back and look how we actually achieved this using _code_. +Let's take a step back and understand how the syntax in Strudel works. -Let's look at this simple example again. What do we notice? +Take a look at this simple example: - + -- We have a word `freq` which is followed by some brackets `()` with some words/letters/numbers inside, surrounded by quotes `"220 275 330 440"` (corresponding to the pitches a3, c#4, e4, a4). -- Then we have a dot `.` followed by another similar piece of code `s("sine")`. -- We can also see these texts are _highlighted_ using colours: word `freq` is purple, the brackets `()` are grey, and the content inside the `""` are green. +- We have a word `note` which is followed by some brackets `()` with some words/letters/numbers inside, surrounded by quotes `"c a f e"` +- Then we have a dot `.` followed by another similar piece of code `s("piano")`. +- We can also see these texts are _highlighted_ using colours: word `note` is purple, the brackets `()` are grey, and the content inside the `""` are green. (The colors could be different if you've changed the default theme) What happens if we try to 'break' this pattern in different ways? - + - + - + Ok, none of these seem to work... - + -This one does work, but now we can't hear the four different events and frequencies anymore. +This one does work, but now we only hear the first note... So what is going on here? @@ -69,14 +69,12 @@ You can also use the keyboard shortcut `cmd-/` to toggle comments on and off. # Strings -Ok, so what about the content inside the quotes (e.g. `"a3 c#4 e4 a4"`)? +Ok, so what about the content inside the quotes (e.g. `"c a f e"`)? In JavaScript, as in most programming languages, this content is referred to as being a [_string_](). A string is simply a sequence of individual characters. In TidalCycles, double quoted strings are used to write _patterns_ using the mini-notation, and you may hear the phrase _pattern string_ from time to time. If you want to create a regular string and not a pattern, you can use single quotes, e.g. `'C minor'` will not be parsed as Mini Notation. -The good news is, that this covers 99% of the JavaScript syntax needed for Strudel! - -Let's now look at the way we can express [Rhythms](/learn/mini-notation)... +The good news is, that this covers most of the JavaScript syntax needed for Strudel!
diff --git a/website/src/pages/learn/factories.mdx b/website/src/pages/learn/factories.mdx index 46567e347..0d93fb21a 100644 --- a/website/src/pages/learn/factories.mdx +++ b/website/src/pages/learn/factories.mdx @@ -1,12 +1,12 @@ --- -title: Pattern Constructors +title: Creating Patterns layout: ../../layouts/MainLayout.astro --- import { MiniRepl } from '../../docs/MiniRepl'; import { JsDoc } from '../../docs/JsDoc'; -# Pattern Constructors +# Creating Patterns The following functions will return a pattern. These are the equivalents used by the Mini Notation: diff --git a/website/src/pages/learn/mini-notation.mdx b/website/src/pages/learn/mini-notation.mdx index 79e81fc4e..d0844f457 100644 --- a/website/src/pages/learn/mini-notation.mdx +++ b/website/src/pages/learn/mini-notation.mdx @@ -8,11 +8,17 @@ import { JsDoc } from '../../docs/JsDoc'; # Mini-notation -Similar to [Haskell Tidal Cycles](https://tidalcycles.org/docs/), Strudel has an "embedded mini-notation" (also called a [domain-specific language, or DSL](https://en.wikipedia.org/wiki/Domain-specific_language)) that is designed for writing rhythmic patterns using little amounts of text. -If you've seen any Tidal code before, you may have noticed the mini-notation and wondered what it's all about. -It's one of the main features of Tidal, and although it might look like a strange way to notate music and other patterns, you will soon see how powerful it can be. +Just like [Tidal Cycles](https://tidalcycles.org/), Strudel uses a so called "Mini-Notation", which is a custom language that is designed for writing rhythmic patterns using little amounts of text. -Before diving deeper into the details, here is a flavour of how the mini-notation looks like: +## Note + +This page just explains the entirety of the Mini-Notation syntax. +If you are just getting started with Strudel, you can learn the basics of the Mini-Notation in a more practical manner in the [workshop](http://localhost:3000/workshop/first-sounds). +After that, you can come back here if you want to understand every little detail. + +## Example + +Before diving deeper into the details, here is a flavour of how the Mini-Notation looks like: + Welcome to the Strudel documentation pages! You've come to the right place if you want to learn how to make music with code. ## What is Strudel? With Strudel, you can expressively write dynamic music pieces.
-It is an official port of the [Tidal Cycles](https://tidalcycles.org/) pattern language to JavaScript. +It is an official port of the [Tidal Cycles](https://tidalcycles.org/) pattern language to JavaScript.
You don't need to know JavaScript or Tidal Cycles to make music with Strudel. This interactive tutorial will guide you through the basics of Strudel.
The best place to actually make music with Strudel is the [Strudel REPL](https://strudel.tidalcycles.org/) +
+ ## What can you do with Strudel? - live code music: make music with code in real time @@ -59,3 +63,8 @@ Here is an example of how strudel can sound: /> To hear more, go to the [Strudel REPL](https://strudel.tidalcycles.org/) and press shuffle to hear a random example pattern. + +## Getting Started + +The best way to start learning Strudel is the workshop. +If you're ready to dive in, let's start with your [first sounds](/workshop/first-sounds) diff --git a/website/src/pages/workshop/langebank.mdx b/website/src/pages/workshop/langebank.mdx index 7a1ca6977..c38888aa7 100644 --- a/website/src/pages/workshop/langebank.mdx +++ b/website/src/pages/workshop/langebank.mdx @@ -152,3 +152,39 @@ n(\`< .scale("/4") .sound("piano")`} /> + +# dinge die es im alten tutorial gab, die jetzt noch nicht im workshop sind + +## `freq` + +To get maximum freedom, you can also use `freq` to directly control the frequency: + + + +## Hearing and frequency + +In the above example, we play A3 (220Hz), C#4 natural (275Hz), E4 (330Hz) and A4 (440Hz), mirroring our previous examples. + +But can you hear the difference between these individual frequencies? + + + +How about these? + + + +The higher we go up... + + + +The less distance we can hear between the frequencies! + + + +Why is this? [Human hearing operates logarithmically](https://www.audiocheck.net/soundtests_nonlinear.php). + +## coding syntax + +## getting-started + +## sounds \ No newline at end of file From 119a66acd0c53642b17b40c30d20ac1c67e238d1 Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Wed, 7 Jun 2023 21:49:57 +0200 Subject: [PATCH 21/33] - translate getting-started - fix de links - link english docs / german workshop --- website/src/config.ts | 4 +- .../src/pages/de/workshop/first-effects.mdx | 2 + website/src/pages/de/workshop/first-notes.mdx | 2 +- .../src/pages/de/workshop/first-sounds.mdx | 4 +- .../src/pages/de/workshop/getting-started.mdx | 74 +++++++++++++++++++ website/src/pages/de/workshop/intro.mdx | 59 --------------- website/src/pages/workshop/first-effects.mdx | 2 + 7 files changed, 84 insertions(+), 63 deletions(-) create mode 100644 website/src/pages/de/workshop/getting-started.mdx delete mode 100644 website/src/pages/de/workshop/intro.mdx diff --git a/website/src/config.ts b/website/src/config.ts index 794639115..28d33c77a 100644 --- a/website/src/config.ts +++ b/website/src/config.ts @@ -44,12 +44,13 @@ export type Sidebar = Record<(typeof KNOWN_LANGUAGE_CODES)[number], SidebarLang> export const SIDEBAR: Sidebar = { de: { Workshop: [ - { text: 'Intro', link: 'de/workshop/intro' }, + { text: 'Intro', link: 'de/workshop/getting-started' }, { text: 'Erste Sounds', link: 'de/workshop/first-sounds' }, { text: 'Erste Töne', link: 'de/workshop/first-notes' }, { text: 'Erste Effekte', link: 'de/workshop/first-effects' }, { text: 'Pattern Effekte', link: 'de/workshop/pattern-effects' }, { text: 'Rückblick', link: 'de/workshop/recap' }, + { text: 'More Pages in English', link: 'workshop/getting-started' }, ], }, en: { @@ -60,6 +61,7 @@ export const SIDEBAR: Sidebar = { { text: 'First Effects', link: 'workshop/first-effects' }, { text: 'Pattern Effects', link: 'workshop/pattern-effects' }, { text: 'Recap', link: 'workshop/recap' }, + { text: 'Workshop in German', link: 'de/workshop/getting-started' }, ], 'Making Sound': [ { text: 'Samples', link: 'learn/samples' }, diff --git a/website/src/pages/de/workshop/first-effects.mdx b/website/src/pages/de/workshop/first-effects.mdx index 71b1d3933..9d4d22d0d 100644 --- a/website/src/pages/de/workshop/first-effects.mdx +++ b/website/src/pages/de/workshop/first-effects.mdx @@ -332,3 +332,5 @@ Die ganze Automation braucht nun 8 cycle bis sie sich wiederholt. | pan | | | speed | ")`} /> | | range | | + +Lass uns nun die für Tidal typischen [Pattern Effekte anschauen](/de/workshop/pattern-effects). diff --git a/website/src/pages/de/workshop/first-notes.mdx b/website/src/pages/de/workshop/first-notes.mdx index 93ba90315..3c50db3cf 100644 --- a/website/src/pages/de/workshop/first-notes.mdx +++ b/website/src/pages/de/workshop/first-notes.mdx @@ -387,4 +387,4 @@ Das geht mit `stack` 😙 /> Das hört sich doch langsam nach echter Musik an! -Wir haben Sounds, wir haben Töne.. noch ein Puzzleteil fehlt: [Effekte](/workshop/first-effects) +Wir haben Sounds, wir haben Töne.. noch ein Puzzleteil fehlt: [Effekte](/de/workshop/first-effects) diff --git a/website/src/pages/de/workshop/first-sounds.mdx b/website/src/pages/de/workshop/first-sounds.mdx index 8207765c5..d272bb30c 100644 --- a/website/src/pages/de/workshop/first-sounds.mdx +++ b/website/src/pages/de/workshop/first-sounds.mdx @@ -7,7 +7,7 @@ import { MiniRepl } from '@src/docs/MiniRepl'; import Box from '@components/Box.astro'; import QA from '@components/QA'; -## Erste Sounds +# Erste Sounds Dies ist das erste Kapitel im Strudel Workshop, schön dich an Bord zu haben! @@ -306,4 +306,4 @@ insect [crow metal] ~ ~, /> Jetzt haben wir eine grundlegende Ahnung davon wie man mit Strudel Beats baut! -Im nächsten Kapitel werden wir ein paar [Töne spielen](/workshop/first-notes). +Im nächsten Kapitel werden wir ein paar [Töne spielen](/de/workshop/first-notes). diff --git a/website/src/pages/de/workshop/getting-started.mdx b/website/src/pages/de/workshop/getting-started.mdx new file mode 100644 index 000000000..c341b73fb --- /dev/null +++ b/website/src/pages/de/workshop/getting-started.mdx @@ -0,0 +1,74 @@ +--- +title: Intro +layout: ../../../layouts/MainLayout.astro +--- + +import { MiniRepl } from '../../../docs/MiniRepl'; + +# Willkommen + + + +Willkommen zum Strudel Workshop! +Du hast den richtigen Ort gefunden wenn du lernen möchstest wie man mit Code Musik macht. + +## Was ist Strudel + +Mit Strudel kann man dynamische Musikstücke in Echtzeit schreiben. +Es ist eine in JavaScript entwickelte Version von [Tidal Cycles](https://tidalcycles.org/) und wurde 2022 von Alex McLean und Felix Roos initiiert. +Tidal Cycles, auch bekannt unter dem Namen Tidal, ist eine Computersprache für algorithmische Muster. +Obwohl sie meistens für die Erzeugung von Musik eingesetzt wird, kann sie für jede Art von Tätigkeit eingesetzt werden, +in der Muster eine Rolle spielen. + +Du brauchst keine Erfahrung in JavaScript oder Tidal Cycles um mit Strudel Musik zu machen. +Dieser interaktive Workshop leitet dich spielerisch durch die Grundlagen von Strudel. +Der beste Ort um mit Strudel Musik zu machen ist das [Strudel REPL](https://strudel.tidalcycles.org/). + +## Was kann man mit Strudel machen? + +- Musik Live Coding: In Echtzeit mit Code Musik machen +- Algorithmische Komposition: Schreibe Musik mithilfe Tidals einzigartiger Sprache für Muster +- Lehren: Strudel eignet sich gut für Lehrende, da keine Installation nötig ist und die Sprache kein theoretisches Vorwissen erfordert. +- Mit anderen Musik-Anwendungen kombinieren: Per MIDI oder OSC kann Strudel als flexibler Sequencer mit jedem Setup kombiniert werden + +## Beispiel + +Hier ist ein Beispiel wie Strudel klingen kann: + +],hh*8") + .speed(perlin.range(.8,.9)), // random sample speed variation + // bassline + "" + .off(1/8,x=>x.add(12).degradeBy(.5)) // random octave jumps + .add(perlin.range(0,.5)) // random pitch variation + .superimpose(add(.05)) // add second, slightly detuned voice + .note() // wrap in "note" + .decay(.15).sustain(0) // make each note of equal length + .s('sawtooth') // waveform + .gain(.4) // turn down + .cutoff(sine.slow(7).range(300,5000)), // automate cutoff + // chords + ">".voicings('lefthand') + .superimpose(x=>x.add(.04)) // add second, slightly detuned voice + .add(perlin.range(0,.5)) // random pitch variation + .note() // wrap in "note" + .s('sawtooth') // waveform + .gain(.16) // turn down + .cutoff(500) // fixed cutoff + .attack(1) // slowly fade in +) +.slow(3/2)`} +/> + +Mehr Beispiele gibt es [hier](/examples). + +Du kannst auch im [Strudel REPL](https://strudel.tidalcycles.org/) auf `shuffle` klicken um ein zufälliges Beispiel zu hören. + +## Workshop + +Der beste Weg um Strudel zu lernen ist der nun folgende Workshop. +Wenn du bereit bist, lass uns loslegen mit deinen [ersten Sounds](/de/workshop/first-sounds). diff --git a/website/src/pages/de/workshop/intro.mdx b/website/src/pages/de/workshop/intro.mdx deleted file mode 100644 index 47f90b639..000000000 --- a/website/src/pages/de/workshop/intro.mdx +++ /dev/null @@ -1,59 +0,0 @@ ---- -title: Introduction -layout: ../../../layouts/MainLayout.astro ---- - -# Welcome - -Welcome to the Strudel documentation pages! -You've come to the right place if you want to learn how to make music with code. - -## What is Strudel? - -With Strudel, you can expressively write dynamic music pieces. -It is an official port of the [Tidal Cycles](https://tidalcycles.org/) pattern language to JavaScript. -You don't need to know JavaScript or Tidal Cycles to make music with Strudel. -This interactive tutorial will guide you through the basics of Strudel. -The best place to actually make music with Strudel is the [Strudel REPL](https://strudel.tidalcycles.org/) - -## What can you do with Strudel? - -- live code music: make music with code in real time -- algorithmic composition: compose music using tidal's unique approach to pattern manipulation -- teaching: focussing on a low barrier of entry, Strudel is a good fit for teaching music and code at the same time. -- integrate into your existing music setup: either via MIDI or OSC, you can use Strudel as a really flexible sequencer - -## Example - -Here is an example of how strudel can sound: - -],hh*8") - .speed(perlin.range(.8,.9)), // random sample speed variation - // bassline - "" - .off(1/8,x=>x.add(12).degradeBy(.5)) // random octave jumps - .add(perlin.range(0,.5)) // random pitch variation - .superimpose(add(.05)) // add second, slightly detuned voice - .note() // wrap in "note" - .decay(.15).sustain(0) // make each note of equal length - .s('sawtooth') // waveform - .gain(.4) // turn down - .cutoff(sine.slow(7).range(300,5000)), // automate cutoff - // chords - ">".voicings('lefthand') - .superimpose(x=>x.add(.04)) // add second, slightly detuned voice - .add(perlin.range(0,.5)) // random pitch variation - .note() // wrap in "note" - .s('sawtooth') // waveform - .gain(.16) // turn down - .cutoff(500) // fixed cutoff - .attack(1) // slowly fade in -) -.slow(3/2)`} -/> - -To hear more, go to the [Strudel REPL](https://strudel.tidalcycles.org/) and press shuffle to hear a random example pattern. diff --git a/website/src/pages/workshop/first-effects.mdx b/website/src/pages/workshop/first-effects.mdx index ab65ffe3b..6ffa2170e 100644 --- a/website/src/pages/workshop/first-effects.mdx +++ b/website/src/pages/workshop/first-effects.mdx @@ -331,3 +331,5 @@ The whole automation will now take 8 cycles to repeat. | pan | | | speed | ")`} /> | | range | | + +Let us now take a look at some of Tidal's typical [pattern effects](/de/workshop/pattern-effects). From 37c454146897d25e7549973d7a7e772375d8964b Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Wed, 7 Jun 2023 21:50:26 +0200 Subject: [PATCH 22/33] translate link --- website/src/config.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/src/config.ts b/website/src/config.ts index 28d33c77a..612589f33 100644 --- a/website/src/config.ts +++ b/website/src/config.ts @@ -50,7 +50,7 @@ export const SIDEBAR: Sidebar = { { text: 'Erste Effekte', link: 'de/workshop/first-effects' }, { text: 'Pattern Effekte', link: 'de/workshop/pattern-effects' }, { text: 'Rückblick', link: 'de/workshop/recap' }, - { text: 'More Pages in English', link: 'workshop/getting-started' }, + { text: 'Mehr Seiten auf Englisch', link: 'workshop/getting-started' }, ], }, en: { From eccce6fa84e5612dac568f90f46f2be015da5121 Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Thu, 8 Jun 2023 17:48:54 +0200 Subject: [PATCH 23/33] remove dirt samples + load a small selection for workshop instead --- .../src/pages/de/workshop/first-sounds.mdx | 31 +++++----- website/src/pages/de/workshop/recap.mdx | 30 ---------- website/src/pages/workshop/first-sounds.mdx | 35 ++++++----- website/src/pages/workshop/recap.mdx | 29 --------- website/src/repl/prebake.mjs | 59 ++++++++++++++++++- 5 files changed, 94 insertions(+), 90 deletions(-) diff --git a/website/src/pages/de/workshop/first-sounds.mdx b/website/src/pages/de/workshop/first-sounds.mdx index d272bb30c..8fa2ddaa4 100644 --- a/website/src/pages/de/workshop/first-sounds.mdx +++ b/website/src/pages/de/workshop/first-sounds.mdx @@ -13,13 +13,13 @@ Dies ist das erste Kapitel im Strudel Workshop, schön dich an Bord zu haben! Los geht's mit ein paar Sounds: - + 1. ⬆️ Klicke in das obige Textfeld ⬆️ 2. Drücke `Strg`+`Enter` zum Abspielen -3. Ändere `house` in `casio` +3. Ändere `casio` in `metal` 4. Drücke `Strg`+`Enter` zum Aktualisieren 5. Drücke `Strg`+`.` zum Stoppen @@ -27,27 +27,30 @@ Los geht's mit ein paar Sounds: Glückwunsch, du bist nun am live coden! +Die ganze Seite ist voller interaktiver Textfelder. +In jedes kannst du hineinklicken und mit `Strg`+`Enter` starten / aktualisieren und mit `Strg+.` stoppen. + **Probiere mehr Sounds aus** Mit ":" kannst du einen anderen Sound aus dem Set wählen: - + -Ändere `east:1` in `east:2` um einen anderen Sound aus dem Set `east` zu hören. - -Du kannst auch andere Zahlen ausprobieren! Es kann sein dass du kurz nichts hörst während ein neuer Sound lädt. - - +Ändere `casio:0` in `casio:1` um einen anderen Sound aus dem Set `casio` zu hören. +Ohne Zahl ist gleichbedeutend mit `:0` Hier sind ein paar mehr Sounds zum ausprobieren: ``` -casio control crow techno house jazz -metal east jvbass juno insect space wind +insect wind jazz metal east crow casio ``` +Probier verschiedene Kombinationen von Sounds und Nummern! Es kann sein dass du kurz nichts hörst während ein neuer Sound lädt. + + + Jetzt weißt du wie man verschiedene Sounds benutzt. Vorerst bleiben wir bei den voreingestellten Sounds, später erfahren wir noch wie man eigene benutzt. @@ -103,13 +106,13 @@ Versuch noch mehr Sounds hinzuzfügen! **Je länger die Sequence, desto schneller** - + Der Inhalt einer Sequence wird in einen sogenannten Cycle (=Zyklus) zusammengequetscht. **Tempo ändern mit `cpm`** - + @@ -127,7 +130,7 @@ Wir werden später noch mehr Möglichkeiten kennen lernen wie man das Tempo ver **Unter-Sequenzen mit [Klammern]** - + @@ -157,7 +160,7 @@ Tonhöhe = sehr schneller Rhythmus **Unter-Unter-Sequenzen mit [[Klammern]]** - + diff --git a/website/src/pages/de/workshop/recap.mdx b/website/src/pages/de/workshop/recap.mdx index 8341c9372..db392b8b0 100644 --- a/website/src/pages/de/workshop/recap.mdx +++ b/website/src/pages/de/workshop/recap.mdx @@ -66,33 +66,3 @@ Diese Seite ist eine Auflistung aller im Workshop enthaltenen Funktionen. | add | addiert zahlen oder noten | ")).scale("C:minor")`} /> | | ply | jedes element schneller machen | ")`} /> | | off | verzögert eine modifizierte kopie | x.speed(2))`} /> | - -## Samples - -``` -casio control crow techno house jazz -metal east jvbass juno insect space wind -bd sd sn cp hh -piano -``` - -## Synths - -``` -gm_electric_guitar_muted gm_acoustic_bass -gm_voice_oohs gm_blown_bottle sawtooth square triangle -gm_xylophone gm_synth_bass_1 gm_synth_strings_1 -``` - -## Banks - -``` -RolandTR909 -``` - -## Scales - -``` -major minor dorian mixolydian -minor:pentatonic major:pentatonic -``` diff --git a/website/src/pages/workshop/first-sounds.mdx b/website/src/pages/workshop/first-sounds.mdx index 6cd55283a..e7badb122 100644 --- a/website/src/pages/workshop/first-sounds.mdx +++ b/website/src/pages/workshop/first-sounds.mdx @@ -15,13 +15,13 @@ This is the first chapter of the Strudel Workshop, nice to have you on board! Let's start by making some noise: - + 1. ⬆️ click into the text field above ⬆️ 2. press `ctrl`+`enter` to play -3. change `house` to `casio` +3. change `casio` to `metal` 4. press `ctrl`+`enter` to update 5. press `ctrl`+`.` to stop @@ -29,27 +29,30 @@ Let's start by making some noise: Congratulations, you are now live coding! +The whole page is filled with these text fields to interact with. +You can always click inside and hit `ctrl`+`enter` to start / update and `ctrl+.` to stop. + **Try more Sounds** You can pick a different sample from the same set, with ':' - + -Try changing `east:1` to `east:2` to hear a different sound in the `east` set. - -You can try other numbers too! You might hear a little pause while the sound is loading - - +Try changing `casio:0` to `casio:1` to hear a different sound in the `casio` set. +Not using a number is like doing `:0` Here are some more sound sets to try: ``` -casio control crow techno house jazz -metal east jvbass juno insect space wind +insect wind jazz metal east crow casio ``` +Try out different Combinations of sounds and numbers! You might hear a little pause while the sound is loading + + + Now you know how to use different sounds. For now we'll stick to this little selection of sounds, but we'll find out how to load your own sounds later. @@ -105,13 +108,13 @@ Try adding more sounds to the sequence! **The longer the sequence, the faster it runs** - + The content of a sequence will be squished into what's called a cycle. **One way to change the tempo is using `cpm`** - + @@ -141,15 +144,15 @@ Similar to the whole sequence, the content of a sub-sequence will be squished to **Multiplication: Speed things up** - + **Multiplication: Speed up sequences** - + **Multiplication: Speeeeeeeeed things up** - + @@ -159,7 +162,7 @@ Pitch = really fast rhythm **Sub-Sub-Sequences with [[brackets]]** - + diff --git a/website/src/pages/workshop/recap.mdx b/website/src/pages/workshop/recap.mdx index 6ebbd3f9b..fc1fb602b 100644 --- a/website/src/pages/workshop/recap.mdx +++ b/website/src/pages/workshop/recap.mdx @@ -67,32 +67,3 @@ This page is just a listing of all functions covered in the workshop! | ply | speed up each event n times | ")`} /> | | off | copy, shift time & modify | x.speed(2))`} /> | -## Samples - -``` -casio control crow techno house jazz -metal east jvbass juno insect space wind -bd sd sn cp hh -piano -``` - -## Synths - -``` -gm_electric_guitar_muted gm_acoustic_bass -gm_voice_oohs gm_blown_bottle sawtooth square triangle -gm_xylophone gm_synth_bass_1 gm_synth_strings_1 -``` - -## Banks - -``` -RolandTR909 -``` - -## Scales - -``` -major minor dorian mixolydian -minor:pentatonic major:pentatonic -``` diff --git a/website/src/repl/prebake.mjs b/website/src/repl/prebake.mjs index a534ba7c8..5b31ff42c 100644 --- a/website/src/repl/prebake.mjs +++ b/website/src/repl/prebake.mjs @@ -22,8 +22,65 @@ export async function prebake() { tag: 'drum-machines', }), samples(`./EmuSP12.json`, `./EmuSP12/`, { prebake: true, tag: 'drum-machines' }), + samples( + { + casio: ['casio/high.wav', 'casio/low.wav', 'casio/noise.wav'], + crow: ['crow/000_crow.wav', 'crow/001_crow2.wav', 'crow/002_crow3.wav', 'crow/003_crow4.wav'], + insect: [ + 'insect/000_everglades_conehead.wav', + 'insect/001_robust_shieldback.wav', + 'insect/002_seashore_meadow_katydid.wav', + ], + wind: [ + 'wind/000_wind1.wav', + 'wind/001_wind10.wav', + 'wind/002_wind2.wav', + 'wind/003_wind3.wav', + 'wind/004_wind4.wav', + 'wind/005_wind5.wav', + 'wind/006_wind6.wav', + 'wind/007_wind7.wav', + 'wind/008_wind8.wav', + 'wind/009_wind9.wav', + ], + jazz: [ + 'jazz/000_BD.wav', + 'jazz/001_CB.wav', + 'jazz/002_FX.wav', + 'jazz/003_HH.wav', + 'jazz/004_OH.wav', + 'jazz/005_P1.wav', + 'jazz/006_P2.wav', + 'jazz/007_SN.wav', + ], + metal: [ + 'metal/000_0.wav', + 'metal/001_1.wav', + 'metal/002_2.wav', + 'metal/003_3.wav', + 'metal/004_4.wav', + 'metal/005_5.wav', + 'metal/006_6.wav', + 'metal/007_7.wav', + 'metal/008_8.wav', + 'metal/009_9.wav', + ], + east: [ + 'east/000_nipon_wood_block.wav', + 'east/001_ohkawa_mute.wav', + 'east/002_ohkawa_open.wav', + 'east/003_shime_hi.wav', + 'east/004_shime_hi_2.wav', + 'east/005_shime_mute.wav', + 'east/006_taiko_1.wav', + 'east/007_taiko_2.wav', + 'east/008_taiko_3.wav', + ], + }, + 'github:tidalcycles/Dirt-Samples/master/', + ), ]); - await samples('github:tidalcycles/Dirt-Samples/master'); // TODO: remove + // await samples('github:tidalcycles/Dirt-Samples/master'); } const maxPan = noteToMidi('C8'); From f8c3e3d5aa35e9548df20ef58490b0caac5af7e4 Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Thu, 8 Jun 2023 20:43:45 +0200 Subject: [PATCH 24/33] add missing sounds by hand --- .../src/pages/de/workshop/first-sounds.mdx | 9 +++--- .../src/pages/de/workshop/pattern-effects.mdx | 15 +-------- website/src/pages/workshop/first-sounds.mdx | 9 ++---- .../src/pages/workshop/pattern-effects.mdx | 13 -------- website/src/repl/prebake.mjs | 31 +++++++++++++++++++ 5 files changed, 39 insertions(+), 38 deletions(-) diff --git a/website/src/pages/de/workshop/first-sounds.mdx b/website/src/pages/de/workshop/first-sounds.mdx index 8fa2ddaa4..104cf4d0d 100644 --- a/website/src/pages/de/workshop/first-sounds.mdx +++ b/website/src/pages/de/workshop/first-sounds.mdx @@ -25,14 +25,14 @@ Los geht's mit ein paar Sounds: -Glückwunsch, du bist nun am live coden! +Glückwunsch, du kannst nun live coden! Die ganze Seite ist voller interaktiver Textfelder. In jedes kannst du hineinklicken und mit `Strg`+`Enter` starten / aktualisieren und mit `Strg+.` stoppen. **Probiere mehr Sounds aus** -Mit ":" kannst du einen anderen Sound aus dem Set wählen: +Mit `:` gefolgt von einer Zahl kannst du einen anderen Sound aus dem Set wählen: @@ -44,7 +44,7 @@ Ohne Zahl ist gleichbedeutend mit `:0` Hier sind ein paar mehr Sounds zum ausprobieren: ``` -insect wind jazz metal east crow casio +insect wind jazz metal east crow casio space numbers ``` Probier verschiedene Kombinationen von Sounds und Nummern! Es kann sein dass du kurz nichts hörst während ein neuer Sound lädt. @@ -195,8 +195,7 @@ Es kommt öfter vor dass man die gleiche Idee auf verschiedene Arten ausdrücken client:visible tune={`sound(\`bd*2, ~ cp, ~ ~ ~ oh, hh*4, -[~ perc:1*2]*2, -[~ jvbass]*2\`)`} +[~ sawtooth]*2\`)`} punchcard /> diff --git a/website/src/pages/de/workshop/pattern-effects.mdx b/website/src/pages/de/workshop/pattern-effects.mdx index f25afdd74..b701958a8 100644 --- a/website/src/pages/de/workshop/pattern-effects.mdx +++ b/website/src/pages/de/workshop/pattern-effects.mdx @@ -161,23 +161,10 @@ Probier `ply` mit einem pattern zu automatisieren, z.b. `"<1 2 1 3>"` -In der notation `x=>x.`, das `x` ist das pattern das wir bearbeiten. +In der notation `x=>x.`, das `x` ist das Pattern das wir bearbeiten. -Das Beispiel oben sieht ohne `off` so aus: - -] <2 3> [~ 1]>*2").color("cyan"), - n("<0 [4 <3 2>] <2 3> [~ 1]>*2".add(7).late(1/8)).color("magenta") -).scale("/2") -.s("triangle").adsr(".01:.1:0").room(.5)`} - punchcard -/> - `off` ist auch nützlich für sounds: @@ -34,7 +32,7 @@ You can always click inside and hit `ctrl`+`enter` to start / update and `ctrl+. **Try more Sounds** -You can pick a different sample from the same set, with ':' +You can pick a different sample from the same set, with `:`, followed by a number: @@ -46,7 +44,7 @@ Not using a number is like doing `:0` Here are some more sound sets to try: ``` -insect wind jazz metal east crow casio +insect wind jazz metal east crow casio space numbers ``` Try out different Combinations of sounds and numbers! You might hear a little pause while the sound is loading @@ -197,8 +195,7 @@ It is quite common that there are many ways to express the same idea. client:visible tune={`sound(\`bd*2, ~ cp, ~ ~ ~ oh, hh*4, -[~ perc:1*2]*2, -[~ jvbass]*2\`)`} +[~ sawtooth]*2\`)`} punchcard /> diff --git a/website/src/pages/workshop/pattern-effects.mdx b/website/src/pages/workshop/pattern-effects.mdx index 7e028b6f8..23346ccb7 100644 --- a/website/src/pages/workshop/pattern-effects.mdx +++ b/website/src/pages/workshop/pattern-effects.mdx @@ -163,19 +163,6 @@ In the notation `x=>x.`, the `x` is the shifted pattern, which where modifying. -The above is like writing: - -] <2 3> [~ 1]>*2").color("cyan"), - n("<0 [4 <3 2>] <2 3> [~ 1]>*2".add(7).late(1/8)).color("magenta") -).scale("/2") -.s("triangle").adsr(".01:.1:0").room(.5)`} - punchcard -/> - off is also useful for sounds: Date: Thu, 8 Jun 2023 20:55:26 +0200 Subject: [PATCH 25/33] fix: format --- website/src/pages/workshop/langebank.mdx | 2 +- website/src/pages/workshop/recap.mdx | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/website/src/pages/workshop/langebank.mdx b/website/src/pages/workshop/langebank.mdx index c38888aa7..6981fee75 100644 --- a/website/src/pages/workshop/langebank.mdx +++ b/website/src/pages/workshop/langebank.mdx @@ -187,4 +187,4 @@ Why is this? [Human hearing operates logarithmically](https://www.audiocheck.net ## getting-started -## sounds \ No newline at end of file +## sounds diff --git a/website/src/pages/workshop/recap.mdx b/website/src/pages/workshop/recap.mdx index fc1fb602b..fad14fb4f 100644 --- a/website/src/pages/workshop/recap.mdx +++ b/website/src/pages/workshop/recap.mdx @@ -66,4 +66,3 @@ This page is just a listing of all functions covered in the workshop! | add | add numbers / notes | ")).scale("C:minor")`} /> | | ply | speed up each event n times | ")`} /> | | off | copy, shift time & modify | x.speed(2))`} /> | - From 1fec2f7a466e20d6e0d68f00c5d59ce07b4dcfd8 Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Thu, 8 Jun 2023 21:31:32 +0200 Subject: [PATCH 26/33] fix: build --- website/package.json | 4 +- .../src/pages/de/workshop/mini-notation.mdx | 69 ------- website/src/pages/workshop/langebank.mdx | 190 ------------------ website/src/pages/workshop/mini-notation.mdx | 69 ------- 4 files changed, 2 insertions(+), 330 deletions(-) delete mode 100644 website/src/pages/de/workshop/mini-notation.mdx delete mode 100644 website/src/pages/workshop/langebank.mdx delete mode 100644 website/src/pages/workshop/mini-notation.mdx diff --git a/website/package.json b/website/package.json index d6100625d..c595f5a6d 100644 --- a/website/package.json +++ b/website/package.json @@ -4,11 +4,11 @@ "version": "0.6.0", "private": true, "scripts": { - "dev": "astro dev", + "dev": "astro dev --host 0.0.0.0", "start": "astro dev", "check": "astro check && tsc", "build": "astro build", - "preview": "astro preview --port 3009", + "preview": "astro preview --port 3009 --host 0.0.0.0", "astro": "astro" }, "dependencies": { diff --git a/website/src/pages/de/workshop/mini-notation.mdx b/website/src/pages/de/workshop/mini-notation.mdx deleted file mode 100644 index 86bef096d..000000000 --- a/website/src/pages/de/workshop/mini-notation.mdx +++ /dev/null @@ -1,69 +0,0 @@ ---- -title: First Sounds -layout: ../../../layouts/MainLayout.astro ---- - -import { MiniRepl } from '../../docs/MiniRepl'; - -# Mini Notation - -Mini Notation is everything between the quotes. It the short rhythm language of Tidal. - -## Cycles - -**The longer the sequence, the faster it runs** - - - -**Play less sounds per cycle with \{curly braces\}** - - - -**Use \`backticks\` for multiple lines** - - - -**Play one sounds per cycle with \** - -")`} punchcard /> - -This is the same as `{...}%1` - -## Operators - -**Multiplication: Speed things up** - - - -**Division: Slow things down** - - - -`bd` will play only every second time - -## Combining it all - -**Speed up Sub-Sequences** - - - -**Slow down Sequences** - - - -**Parallel Sub-Sequences** - - - -**Sample Numbers on groups** - - diff --git a/website/src/pages/workshop/langebank.mdx b/website/src/pages/workshop/langebank.mdx deleted file mode 100644 index 6981fee75..000000000 --- a/website/src/pages/workshop/langebank.mdx +++ /dev/null @@ -1,190 +0,0 @@ - - -1. press play button to start -2. change `house` to `casio` -3. press refresh button to update -4. press stop button to stop - - - -**Change tempo** - - - -adding your own samples - - - -").slow(3)`} - punchcard -/> - -n(run(8)).sound("east") - -Shorter variant: - - - -polyrythms & polymeters - --- This can make for flexible time signatures: - -d1 $ sound "[bd bd sn:5] [bd sn:3]" - --- You can put subsequences inside subsequences: -d1 $ sound "[[bd bd] bd sn:5] [bd sn:3]" - --- Keep going.. -d1 $ sound "[[bd [bd bd bd bd]] bd sn:5] [bd sn:3]" - --- \* Polymetric / polyrhythmic sequences - --- Play two subsequences at once by separating with a comma: - -d1 $ sound "[voodoo voodoo:3, arpy arpy:4 arpy:2]" - --- compare how [,] and {,} work: - -d1 $ sound "[voodoo voodoo:3, arpy arpy:4 arpy:2]" - -d1 $ sound "{voodoo voodoo:3, arpy arpy:4 arpy:2}" - -d1 $ sound "[drum bd hh bd, can can:2 can:3 can:4 can:2]" - -d1 $ sound "{drum bd hh bd, can can:2 can:3 can:4 can:2}" - -d1 $ sound "[bd sn, can:2 can:3 can:1, arpy arpy:1 arpy:2 arpy:3 arpy:5]" - -d1 $ sound "{bd sn, can:2 can:3 can:1, arpy arpy:1 arpy:2 arpy:3 arpy:5}" - -**Play X per cycle with \{ \}** - - - - - -Try different numbers after `%` - -`{ ... }%1` is the same as `< ... >` - - - -## Bracket Recap - -- `[]` squeezes contents to 1 cycle -- `<>` plays one item per cycle -- `{}%x` plays x items per cycle - -/2")) -.sound("gm_synth_bass_1")`} -/> - -vertical - - -< 4 4 4 3> -<[2,7] [2,6] [1,6] [1,6]> -< 4 4 4 3> ->*2\`) -.scale("/4") -.sound("piano")`} -/> - -horizontal - -*2\`) -.scale("/4") -.sound("piano")`} -/> - -# dinge die es im alten tutorial gab, die jetzt noch nicht im workshop sind - -## `freq` - -To get maximum freedom, you can also use `freq` to directly control the frequency: - - - -## Hearing and frequency - -In the above example, we play A3 (220Hz), C#4 natural (275Hz), E4 (330Hz) and A4 (440Hz), mirroring our previous examples. - -But can you hear the difference between these individual frequencies? - - - -How about these? - - - -The higher we go up... - - - -The less distance we can hear between the frequencies! - - - -Why is this? [Human hearing operates logarithmically](https://www.audiocheck.net/soundtests_nonlinear.php). - -## coding syntax - -## getting-started - -## sounds diff --git a/website/src/pages/workshop/mini-notation.mdx b/website/src/pages/workshop/mini-notation.mdx deleted file mode 100644 index df1c8cbee..000000000 --- a/website/src/pages/workshop/mini-notation.mdx +++ /dev/null @@ -1,69 +0,0 @@ ---- -title: First Sounds -layout: ../../layouts/MainLayout.astro ---- - -import { MiniRepl } from '../../docs/MiniRepl'; - -# Mini Notation - -Mini Notation is everything between the quotes. It the short rhythm language of Tidal. - -## Cycles - -**The longer the sequence, the faster it runs** - - - -**Play less sounds per cycle with \{curly braces\}** - - - -**Use \`backticks\` for multiple lines** - - - -**Play one sounds per cycle with \** - -")`} punchcard /> - -This is the same as `{...}%1` - -## Operators - -**Multiplication: Speed things up** - - - -**Division: Slow things down** - - - -`bd` will play only every second time - -## Combining it all - -**Speed up Sub-Sequences** - - - -**Slow down Sequences** - - - -**Parallel Sub-Sequences** - - - -**Sample Numbers on groups** - - From 51cc69208f0254877a2f4596767e3254e51fea64 Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Fri, 9 Jun 2023 00:25:14 +0200 Subject: [PATCH 27/33] fix: repl link to docs was old --- website/src/repl/Header.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/src/repl/Header.jsx b/website/src/repl/Header.jsx index 213e336e9..53623466a 100644 --- a/website/src/repl/Header.jsx +++ b/website/src/repl/Header.jsx @@ -122,7 +122,7 @@ export function Header({ context }) { {!isEmbedded && ( From 3ccbd35fadab69c16da4b00a330a953c04cf924e Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Fri, 9 Jun 2023 00:25:54 +0200 Subject: [PATCH 28/33] add label support to pianoroll --- packages/core/pianoroll.mjs | 18 ++++++++++++++++++ packages/react/src/components/MiniRepl.jsx | 5 ++++- website/src/docs/MiniRepl.jsx | 5 ++++- 3 files changed, 26 insertions(+), 2 deletions(-) diff --git a/packages/core/pianoroll.mjs b/packages/core/pianoroll.mjs index 2b5af1a79..66b56dc88 100644 --- a/packages/core/pianoroll.mjs +++ b/packages/core/pianoroll.mjs @@ -50,6 +50,7 @@ Pattern.prototype.pianoroll = function ({ timeframe: timeframeProp, fold = 0, vertical = 0, + labels = 0, } = {}) { const ctx = getDrawContext(); const w = ctx.canvas.width; @@ -114,6 +115,14 @@ Pattern.prototype.pianoroll = function ({ ]; } isActive ? ctx.strokeRect(...coords) : ctx.fillRect(...coords); + if (labels) { + const label = event.value.note ?? event.value.s + (event.value.n ? `:${event.value.n}` : ''); + ctx.font = `${barThickness * 0.75}px monospace`; + ctx.strokeStyle = 'black'; + ctx.fillStyle = isActive ? 'white' : 'black'; + ctx.textBaseline = 'top'; + ctx.fillText(label, ...coords); + } }); ctx.globalAlpha = 1; // reset! const playheadPosition = scale(-from / timeExtent, ...timeRange); @@ -181,6 +190,7 @@ export function pianoroll({ timeframe: timeframeProp, fold = 0, vertical = 0, + labels = false, ctx, } = {}) { const w = ctx.canvas.width; @@ -267,6 +277,14 @@ export function pianoroll({ ]; } isActive ? ctx.strokeRect(...coords) : ctx.fillRect(...coords); + if (labels) { + const label = event.value.note ?? event.value.s + (event.value.n ? `:${event.value.n}` : ''); + ctx.font = `${barThickness * 0.75}px monospace`; + ctx.strokeStyle = 'black'; + ctx.fillStyle = isActive ? 'white' : 'black'; + ctx.textBaseline = 'top'; + ctx.fillText(label, ...coords); + } }); ctx.globalAlpha = 1; // reset! const playheadPosition = scale(-from / timeExtent, ...timeRange); diff --git a/packages/react/src/components/MiniRepl.jsx b/packages/react/src/components/MiniRepl.jsx index c13ff28ed..1a6cce944 100644 --- a/packages/react/src/components/MiniRepl.jsx +++ b/packages/react/src/components/MiniRepl.jsx @@ -21,6 +21,7 @@ export function MiniRepl({ onTrigger, drawTime, punchcard, + punchcardLabels, onPaint, canvasHeight = 200, fontSize = 18, @@ -28,6 +29,7 @@ export function MiniRepl({ hideHeader = false, theme, keybindings, + isLineNumbersDisplayed, }) { drawTime = drawTime || (punchcard ? [0, 4] : undefined); const evalOnMount = !!drawTime; @@ -61,7 +63,7 @@ export function MiniRepl({ if (onPaint) { pat = pat.onPaint(onPaint); } else if (punchcard) { - pat = pat.punchcard(); + pat = pat.punchcard({ labels: punchcardLabels }); } return pat; }, @@ -160,6 +162,7 @@ export function MiniRepl({ fontFamily={fontFamily} fontSize={fontSize} keybindings={keybindings} + isLineNumbersDisplayed={isLineNumbersDisplayed} /> )} {error &&
{error.message}
} diff --git a/website/src/docs/MiniRepl.jsx b/website/src/docs/MiniRepl.jsx index 6dfaf28e0..7c5079a0b 100644 --- a/website/src/docs/MiniRepl.jsx +++ b/website/src/docs/MiniRepl.jsx @@ -32,6 +32,7 @@ export function MiniRepl({ tune, drawTime, punchcard, + punchcardLabels = true, span = [0, 4], canvasHeight = 100, hideHeader, @@ -39,7 +40,7 @@ export function MiniRepl({ claviatureLabels, }) { const [Repl, setRepl] = useState(); - const { theme, keybindings, fontSize, fontFamily } = useSettings(); + const { theme, keybindings, fontSize, fontFamily, isLineNumbersDisplayed } = useSettings(); const [activeNotes, setActiveNotes] = useState([]); useEffect(() => { // we have to load this package on the client @@ -55,6 +56,7 @@ export function MiniRepl({ hideOutsideView={true} drawTime={claviature ? [0, 0] : drawTime} punchcard={punchcard} + punchcardLabels={punchcardLabels} span={span} canvasHeight={canvasHeight} theme={themes[theme]} @@ -62,6 +64,7 @@ export function MiniRepl({ keybindings={keybindings} fontFamily={fontFamily} fontSize={fontSize} + isLineNumbersDisplayed={isLineNumbersDisplayed} onPaint={ claviature ? (ctx, time, haps, drawTime) => { From c287ff554c4d6976b42cf2f40fd2ce9328bb6071 Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Fri, 9 Jun 2023 00:26:40 +0200 Subject: [PATCH 29/33] optimize sounds chapter after teach test --- .../src/pages/de/workshop/first-effects.mdx | 2 +- .../src/pages/de/workshop/first-sounds.mdx | 128 +++++++++++++----- website/src/pages/workshop/first-effects.mdx | 2 +- website/src/pages/workshop/first-sounds.mdx | 2 +- 4 files changed, 97 insertions(+), 37 deletions(-) diff --git a/website/src/pages/de/workshop/first-effects.mdx b/website/src/pages/de/workshop/first-effects.mdx index 9d4d22d0d..7719249aa 100644 --- a/website/src/pages/de/workshop/first-effects.mdx +++ b/website/src/pages/de/workshop/first-effects.mdx @@ -278,7 +278,7 @@ Was passiert wenn du den Wert automatisierst? z.b. `.fast("<1 [2 4]>")` ? Anstatt Werte schrittweise zu automatisieren können wir auch sogenannte Signale benutzen: - + diff --git a/website/src/pages/de/workshop/first-sounds.mdx b/website/src/pages/de/workshop/first-sounds.mdx index 104cf4d0d..0ac6cc21a 100644 --- a/website/src/pages/de/workshop/first-sounds.mdx +++ b/website/src/pages/de/workshop/first-sounds.mdx @@ -11,7 +11,9 @@ import QA from '@components/QA'; Dies ist das erste Kapitel im Strudel Workshop, schön dich an Bord zu haben! -Los geht's mit ein paar Sounds: +## Textfelder + +Der Workshop ist voller interaktiver Textfelder. Lass uns lernen wie sie funktionieren. Hier ist eins: @@ -21,37 +23,51 @@ Los geht's mit ein paar Sounds: 2. Drücke `Strg`+`Enter` zum Abspielen 3. Ändere `casio` in `metal` 4. Drücke `Strg`+`Enter` zum Aktualisieren -5. Drücke `Strg`+`.` zum Stoppen +5. Drücke `Strg`+`Punkt` zum Stoppen + +Mac: `Strg` = `control` oder auch `option` Glückwunsch, du kannst nun live coden! -Die ganze Seite ist voller interaktiver Textfelder. -In jedes kannst du hineinklicken und mit `Strg`+`Enter` starten / aktualisieren und mit `Strg+.` stoppen. +## Sounds -**Probiere mehr Sounds aus** +Gerade haben wir schon den ersten sound mit `sound` abgespielt: -Mit `:` gefolgt von einer Zahl kannst du einen anderen Sound aus dem Set wählen: - - + -Ändere `casio:0` in `casio:1` um einen anderen Sound aus dem Set `casio` zu hören. -Ohne Zahl ist gleichbedeutend mit `:0` +`casio` ist einer von vielen Stanard Sounds. -Hier sind ein paar mehr Sounds zum ausprobieren: +Probier ein paar andere Sounds aus: ``` insect wind jazz metal east crow casio space numbers ``` -Probier verschiedene Kombinationen von Sounds und Nummern! Es kann sein dass du kurz nichts hörst während ein neuer Sound lädt. +Es kann sein, dass du kurz nichts hörst während ein neuer Sound lädt. + + + +**Sample Nummer ändern mit :** + +Ein Sound kann mehrere Samples (Audio Dateien) enthalten. + +Du kannst ein anderes Sample wählen, indem du `:` und eine Zahl an den Sound-Namen anhängst: + + + + + +Probiere verschiedene Sound / Zahlen Kombinationen. + +Ohne Zahl ist gleichbedeutend mit `:0` -Jetzt weißt du wie man verschiedene Sounds benutzt. +Jetzt weißt du wie man Sounds abspielt und ihre Sample Nummer einstellt. Vorerst bleiben wir bei den voreingestellten Sounds, später erfahren wir noch wie man eigene benutzt. ## Drum Sounds @@ -60,21 +76,25 @@ Strudel kommt von Haus aus mit einer breiten Auswahl an Drum Sounds: -Diese 2-Buchstaben Kombinationen stehen für verschiedene Teile eines Drumsets: + + +Diese 2-Buchstaben Kombinationen stehen für verschiedene Teile eines Schlagzeugs: - `bd` = **b**ass **d**rum - Basstrommel - `sd` = **s**nare **d**rum - Schnarrtrommel - `rim` = **rim**shot - Rahmenschlag -- `hh` = **h**i**h**at -- `oh` = **o**pen **h**ihat - Offenes Hi-Hat +- `hh` = **h**i**h**at - Hallo Hut +- `oh` = **o**pen **h**ihat - Offener Hallo Hut -Wir können den Charakter des Drum Sounds verändern, indem wir mit `bank` die Drum Machine auswählen: +Probier verschiedene Sounds aus! -{/* To change the sound character of our drums, we can use `bank` to change the drum machine: */} + + +Wir können den Charakter des Drum Sounds verändern, indem wir mit `bank` die Drum Machine auswählen: -In diesem Beispiel ist `RolandTR909` der Name der Drum Machine, welche eine prägende Rolle für House und Techno Musik spielte. +In diesem Beispiel ist `RolandTR909` der Name der Drum Machine, die eine prägende Rolle für House und Techno Musik spielte. @@ -88,6 +108,9 @@ In diesem Beispiel ist `RolandTR909` der Name der Drum Machine, welche eine prä Es gibt noch viel mehr, aber das sollte fürs Erste reichen.. +🦥 Tipp für faule: Mach Doppel-Klick auf einen Namen um ihn zu markieren. +Dann kannst du ihn mit `Strg`+`C` kopieren und mit `Strg`+`V` einfügen. + ## Sequenzen / Sequences @@ -120,34 +143,43 @@ cpm = **c**ycles per **m**inute = Cycles pro Minute Das Tempo ist standardmäßig auf 60cpm eingestellt, also 1 Cycle pro Sekunde. +`cpm` ist angelehnt an `bpm` (=beats per minute). + -Wir werden später noch mehr Möglichkeiten kennen lernen wie man das Tempo verändert. +Wir werden später noch mehr Möglichkeiten kennen lernen das Tempo zu verändern. **Pausen mit '~'** + + +Tilde tippen: + +- Windows / Linux: `Alt Gr` + `~` +- Mac: `option` + `N` + + + **Unter-Sequenzen mit [Klammern]** - + +Der Inhalt der Klammer wird ebenfalls zusammengequetscht! + Füge noch mehr Sounds in die Klammern ein! -Genau wie bei der ganzen Sequence wird der eine Unter-Sequence schneller je mehr drin ist. +Genau wie bei der ganzen Sequence wird eine Unter-Sequence schneller je mehr drin ist. **Multiplikation: Dinge schneller machen** -**Multiplikation: Unter-Sequences schneller machen** - - - **Multiplikation: Vieeeeeeel schneller** @@ -158,6 +190,20 @@ Tonhöhe = sehr schneller Rhythmus +**Multiplikation: Ganze Unter-Sequences schneller machen** + + + +Bolero: + + + **Unter-Unter-Sequenzen mit [[Klammern]]** @@ -172,7 +218,7 @@ Du kannst so tief verschachteln wie du willst! -Du kannst soviele Kommas benutzen wie du magst: +Du kannst so viele Kommas benutzen wie du möchtest: @@ -184,31 +230,37 @@ Kommas können auch in Unter-Sequenzen verwendet werden: Ist dir aufgefallen dass sich die letzten beiden Beispiele gleich anhören? -Es kommt öfter vor dass man die gleiche Idee auf verschiedene Arten ausdrücken kann. +Es kommt öfter vor, dass man die gleiche Idee auf verschiedene Arten ausdrücken kann. -**Mehrere Zeilen mit \`** +**Mehrere Zeilen schreiben mit \` (backtick)** -**Sound Nummer separat auswählen** + -Anstatt mit ":" kann man die Sound Nummer auch separat mir der `n` Funktion steuern: +Ob man " oder \` benutzt ist nur eine Frage der Übersichtlichkeit. - + + +**Sample Nummer separat auswählen** -Das ist kürzer und lesbarer als: +Benutzt man nur einen Sound mit unterschiedlichen Sample Nummer sieht das so aus: +Das gleiche kann man auch so schreiben: + + + ## Rückblick Wir haben jetzt die Grundlagen der sogenannten Mini-Notation gelernt, der Rhythmus-Sprache von Tidal. @@ -309,3 +361,11 @@ insect [crow metal] ~ ~, Jetzt haben wir eine grundlegende Ahnung davon wie man mit Strudel Beats baut! Im nächsten Kapitel werden wir ein paar [Töne spielen](/de/workshop/first-notes). + +--- + +- vllt mal das wörtchen `sound` behandeln +- was ist überhaupt casio?? +- Strg = ctrl on mac "+" ist verwirrend +- cursor ist sehr undeutlich wenn nicht in emacs mode +- wieviele zahlen gibt es diff --git a/website/src/pages/workshop/first-effects.mdx b/website/src/pages/workshop/first-effects.mdx index 6ffa2170e..6e323f4ca 100644 --- a/website/src/pages/workshop/first-effects.mdx +++ b/website/src/pages/workshop/first-effects.mdx @@ -279,7 +279,7 @@ By the way, inside Mini-Notation, `fast` is `*` and `slow` is `/`. Instead of changing values stepwise, we can also control them with signals: - + diff --git a/website/src/pages/workshop/first-sounds.mdx b/website/src/pages/workshop/first-sounds.mdx index 95d3a6f51..ef50714da 100644 --- a/website/src/pages/workshop/first-sounds.mdx +++ b/website/src/pages/workshop/first-sounds.mdx @@ -195,7 +195,7 @@ It is quite common that there are many ways to express the same idea. client:visible tune={`sound(\`bd*2, ~ cp, ~ ~ ~ oh, hh*4, -[~ sawtooth]*2\`)`} +[~ casio]*2\`)`} punchcard /> From ae868c6372680bdf7880379ecf9a60d188062f84 Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Fri, 9 Jun 2023 00:46:04 +0200 Subject: [PATCH 30/33] hide gutter in mini repl --- website/src/docs/MiniRepl.css | 7 ++++++- website/src/pages/de/workshop/first-sounds.mdx | 2 +- website/src/repl/Repl.css | 6 +----- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/website/src/docs/MiniRepl.css b/website/src/docs/MiniRepl.css index 5e5206714..8ec75d4d8 100644 --- a/website/src/docs/MiniRepl.css +++ b/website/src/docs/MiniRepl.css @@ -1,4 +1,5 @@ -.cm-activeLine { +.cm-activeLine, +.cm-activeLineGutter { background-color: transparent !important; } @@ -11,3 +12,7 @@ .cm-scroller { font-family: inherit !important; } + +.cm-gutters { + display: none !important; +} diff --git a/website/src/pages/de/workshop/first-sounds.mdx b/website/src/pages/de/workshop/first-sounds.mdx index 0ac6cc21a..ecf8037ff 100644 --- a/website/src/pages/de/workshop/first-sounds.mdx +++ b/website/src/pages/de/workshop/first-sounds.mdx @@ -29,7 +29,7 @@ Mac: `Strg` = `control` oder auch `option` -Glückwunsch, du kannst nun live coden! +Glückwunsch, du kannst jetzt live coden! ## Sounds diff --git a/website/src/repl/Repl.css b/website/src/repl/Repl.css index ddedad6f6..6815966be 100644 --- a/website/src/repl/Repl.css +++ b/website/src/repl/Repl.css @@ -22,12 +22,8 @@ opacity: 0.5; } -#code .cm-content { - padding-top: 12px !important; - padding-left: 8px !important; -} - #code .cm-scroller { + padding-top: 10px !important; padding-bottom: 50vh; font-family: inherit; } From 89a4a855891f7619da61f4886092b2b0965d68c5 Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Fri, 9 Jun 2023 17:58:05 +0200 Subject: [PATCH 31/33] more friendly heading --- website/src/pages/functions/intro.mdx | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/website/src/pages/functions/intro.mdx b/website/src/pages/functions/intro.mdx index d396543c8..2e1bb7eb9 100644 --- a/website/src/pages/functions/intro.mdx +++ b/website/src/pages/functions/intro.mdx @@ -6,23 +6,24 @@ layout: ../../layouts/MainLayout.astro import { MiniRepl } from '../../docs/MiniRepl'; import { JsDoc } from '../../docs/JsDoc'; -# Functional JavaScript API +# Pattern Functions -While the mini notation is powerful on its own, there is much more to discover. -Internally, the mini notation will expand to use the actual functional JavaScript API. +Let's learn all about functions to create and modify patterns. +At the core of Strudel, everything is made of functions. -For example, this Pattern in Mini Notation: +For example, everything you can do with the Mini-Notation can also be done with a function. +This Pattern in Mini Notation: is equivalent to this Pattern without Mini Notation: - + Similarly, there is an equivalent function for every aspect of the mini notation. -Which representation to use is a matter of context. As a rule of thumb, you can think of the JavaScript API -to fit better for the larger context, while mini notation is more practical for individiual rhythms. +Which representation to use is a matter of context. As a rule of thumb, functions +are better suited in a larger context, while mini notation is more practical for individiual rhythms. ## Limits of Mini Notation @@ -46,10 +47,10 @@ You can freely mix JS patterns, mini patterns and values! For example, this patt @@ -72,4 +73,4 @@ You can freely mix JS patterns, mini patterns and values! For example, this patt While mini notation is almost always shorter, it only has a handful of modifiers: \* / ! @. When using JS patterns, there is a lot more you can do. -What [Pattern Constructors](/learn/factories) does Strudel offer? +Next, let's look at how you can [create patterns](/learn/factories) From 7dc2a0091beebb562167d9e38d3b654cff247098 Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Fri, 9 Jun 2023 17:59:08 +0200 Subject: [PATCH 32/33] more detail --- website/src/pages/de/workshop/first-notes.mdx | 22 +++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/website/src/pages/de/workshop/first-notes.mdx b/website/src/pages/de/workshop/first-notes.mdx index 3c50db3cf..c44969dfb 100644 --- a/website/src/pages/de/workshop/first-notes.mdx +++ b/website/src/pages/de/workshop/first-notes.mdx @@ -175,13 +175,29 @@ Wenn eine Sequenz unabhängig von ihrem Inhalt immer gleich schnell bleiben soll -Füg noch mehr Töne hinzu und achte darauf wie das tempo gleich bleibt! +Füg noch mehr Töne hinzu und achte darauf wie das Tempo gleich bleibt! + +Tatsächlich sind diese Klammern nur eine Abkürzung: + +`
` = `[a b c]/3` + +`` = `[a b c d]/4` + +usw.. **Eine Sequenz pro Cycle** -{/* <[c2 c3]*4 [bb1 bb2]*4 [f2 f3]*4 [eb2 eb3]*4>/2 */} +") +.sound("gm_acoustic_bass")`} + punchcard +/> + +oder auch... ` innerhalb einer Sequenz verwendet werden: + Date: Fri, 9 Jun 2023 20:59:40 +0200 Subject: [PATCH 33/33] bring de improvements to en workshop --- .../src/pages/de/workshop/first-sounds.mdx | 2 +- website/src/pages/workshop/first-sounds.mdx | 44 ++++++++++++++----- 2 files changed, 34 insertions(+), 12 deletions(-) diff --git a/website/src/pages/de/workshop/first-sounds.mdx b/website/src/pages/de/workshop/first-sounds.mdx index ecf8037ff..7654a2200 100644 --- a/website/src/pages/de/workshop/first-sounds.mdx +++ b/website/src/pages/de/workshop/first-sounds.mdx @@ -39,7 +39,7 @@ Gerade haben wir schon den ersten sound mit `sound` abgespielt: -`casio` ist einer von vielen Stanard Sounds. +`casio` ist einer von vielen Standard Sounds. Probier ein paar andere Sounds aus: diff --git a/website/src/pages/workshop/first-sounds.mdx b/website/src/pages/workshop/first-sounds.mdx index ef50714da..893a563dd 100644 --- a/website/src/pages/workshop/first-sounds.mdx +++ b/website/src/pages/workshop/first-sounds.mdx @@ -11,7 +11,9 @@ import QA from '@components/QA'; This is the first chapter of the Strudel Workshop, nice to have you on board! -Let's start by making some noise: +## Code Fields + +The workshop is full of interactive code fields. Let's learn how to use those. Here is one: @@ -27,27 +29,39 @@ Let's start by making some noise: Congratulations, you are now live coding! -The whole page is filled with these text fields to interact with. -You can always click inside and hit `ctrl`+`enter` to start / update and `ctrl+.` to stop. - -**Try more Sounds** +## Sounds -You can pick a different sample from the same set, with `:`, followed by a number: +We have just played a sound with `sound` like this: - + -Try changing `casio:0` to `casio:1` to hear a different sound in the `casio` set. -Not using a number is like doing `:0` +`casio` is one of many standard sounds. -Here are some more sound sets to try: +Try out a few other sounds: ``` insect wind jazz metal east crow casio space numbers ``` -Try out different Combinations of sounds and numbers! You might hear a little pause while the sound is loading +You might hear a little pause while the sound is loading + + + +**Change Sample Number with :** + +One Sound can contain multiple samples (audio files). + +You can select the sample by appending `:` followed by a number to the name: + + + + + +Try different sound / sample number combinations. + +Not adding a number is like doing `:0` @@ -60,6 +74,8 @@ By default, Strudel comes with a wide selection of drum sounds: + + These letter combinations stand for different parts of a drum set: - `bd` = **b**ass **d**rum @@ -69,6 +85,10 @@ These letter combinations stand for different parts of a drum set: - `hh` = **h**i**h**at - `oh` = **o**pen **h**ihat +Try out different drum sounds! + + + To change the sound character of our drums, we can use `bank` to change the drum machine: @@ -88,6 +108,8 @@ Try changing `RolandTR909` to one of There are a lot more, but let's keep it simple for now +🦥 Pro-Tip: Mark a name via double click. Then just copy and paste! + ## Sequences