From 858f4f74b333c476d110cd5aa20a6996e81012a0 Mon Sep 17 00:00:00 2001 From: Jack Armitage Date: Sun, 25 Dec 2022 16:21:18 +0000 Subject: [PATCH] tutorial updates --- package-lock.json | 4 - package.json | 2 +- website/src/config.ts | 11 +- website/src/pages/learn/code.mdx | 81 ++++++ website/src/pages/learn/effects.mdx | 65 +++++ website/src/pages/learn/getting-started.mdx | 131 +++------- .../learn/{outputs.mdx => input-output.mdx} | 22 +- website/src/pages/learn/mini-notation.mdx | 194 ++++++++++---- website/src/pages/learn/notes.mdx | 88 +++++++ website/src/pages/learn/samples.mdx | 215 ++++++++++++++++ website/src/pages/learn/sounds.mdx | 40 +++ .../pages/learn/synths-samples-effects.mdx | 236 ------------------ website/src/pages/learn/synths.mdx | 41 +++ website/src/styles/index.css | 4 + 14 files changed, 744 insertions(+), 390 deletions(-) create mode 100644 website/src/pages/learn/code.mdx create mode 100644 website/src/pages/learn/effects.mdx rename website/src/pages/learn/{outputs.mdx => input-output.mdx} (71%) create mode 100644 website/src/pages/learn/notes.mdx create mode 100644 website/src/pages/learn/samples.mdx create mode 100644 website/src/pages/learn/sounds.mdx delete mode 100644 website/src/pages/learn/synths-samples-effects.mdx create mode 100644 website/src/pages/learn/synths.mdx diff --git a/package-lock.json b/package-lock.json index ad4cb98b..bf61b018 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12273,7 +12273,6 @@ "version": "0.5.0", "license": "AGPL-3.0-or-later", "dependencies": { - "@strudel.cycles/core": "^0.5.0", "acorn": "^8.8.1", "escodegen": "^2.0.0", "estree-walker": "^3.0.1" @@ -12302,7 +12301,6 @@ "version": "0.5.0", "license": "AGPL-3.0-or-later", "dependencies": { - "@strudel.cycles/core": "^0.5.0", "WebDirt": "github:dktr0/WebDirt" } }, @@ -13884,7 +13882,6 @@ "@strudel.cycles/transpiler": { "version": "file:packages/transpiler", "requires": { - "@strudel.cycles/core": "^0.5.0", "acorn": "^8.8.1", "escodegen": "^2.0.0", "estree-walker": "^3.0.1" @@ -13904,7 +13901,6 @@ "@strudel.cycles/webdirt": { "version": "file:packages/webdirt", "requires": { - "@strudel.cycles/core": "^0.5.0", "WebDirt": "github:dktr0/WebDirt" } }, diff --git a/package.json b/package.json index 27fa5f66..2ad13a46 100644 --- a/package.json +++ b/package.json @@ -10,7 +10,7 @@ "test-ui": "vitest --ui", "test-coverage": "vitest --coverage", "bootstrap": "lerna bootstrap", - "setup": "npm i && npm run bootstrap && cd website && npm i", + "setup": "npm i && npm run jsdoc-json && npm run bootstrap && cd website && npm i", "snapshot": "vitest run -u --silent", "repl": "cd website && npm run dev", "osc": "cd packages/osc && npm run server", diff --git a/website/src/config.ts b/website/src/config.ts index 7df00f70..422fe40d 100644 --- a/website/src/config.ts +++ b/website/src/config.ts @@ -45,12 +45,17 @@ export const SIDEBAR: Sidebar = { en: { Tutorial: [ { text: 'Getting Started', link: 'learn/getting-started' }, - { text: 'Mini Notation', link: 'learn/mini-notation' }, - { text: 'Synths, Samples & FX', link: 'learn/synths-samples-effects' }, + { text: 'Notes', link: 'learn/notes' }, + { text: 'Sounds', link: 'learn/sounds' }, + { text: 'Coding syntax', link: 'learn/code' }, + { text: 'Mini-notation', link: 'learn/mini-notation' }, + { text: 'Samples', link: 'learn/samples' }, + { text: 'Synths', link: 'learn/synths' }, + { text: 'Audio effects', link: 'learn/effects' }, { text: 'Functions', link: 'learn/functions' }, { text: 'Signals', link: 'learn/signals' }, { text: 'Tonal', link: 'learn/tonal' }, - { text: 'Outputs', link: 'learn/outputs' }, + { text: 'MIDI & OSC', link: 'learn/input-output' }, ], }, }; diff --git a/website/src/pages/learn/code.mdx b/website/src/pages/learn/code.mdx new file mode 100644 index 00000000..470565df --- /dev/null +++ b/website/src/pages/learn/code.mdx @@ -0,0 +1,81 @@ +--- +title: Coding syntax +description: Strudel Tutorial - Coding syntax +layout: ../../layouts/MainLayout.astro +--- + +import { MiniRepl } from '../../docs/MiniRepl'; +import { JsDoc } from '../../docs/JsDoc'; + +# Strudel Code + +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 look at this simple example again. What do we notice? + + + +- We have a word `freq` which is followed by some brackets `()` with some words/letters/numbers inside, surrounded by quotes `"a3 c#4 e4 a4"`. +- Then we have a dot `.` followed by another similar piece of code `s("sawtooth")`. +- 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. + +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. + +So what is going on here? + +# Functions, arguments and chaining + +So far, we've seen the following syntax: + +``` +xxx("foo").yyy("bar") +``` + +Generally, `xxx` and `yyy` are called [_functions_](https://en.wikipedia.org/wiki/Function_(computer_programming)), while `foo` and `bar` are called function [_arguments_ or _parameters_](https://en.wikipedia.org/wiki/Parameter_(computer_programming)). +So far, we've used the functions to declare which aspect of the sound we want to control, and their arguments for the actual data. +The `yyy` function is called a [_chained_ function](https://en.wikipedia.org/wiki/Method_chaining), because it is appended with a dot (`.`). + +Generally, the idea with chaining is that code such as `a("this").b("that").c("other")` allows `a`, `b` and `c` functions to happen in a specified order, without needing to write them as three separate lines of code. +You can think of this as being similar to chaining audio effects together using guitar pedals or digital audio effects. + +Strudel makes heavy use of chained functions. Here is a more sophisticated example: + + + +# Comments + +The `//` in the example above is a line comment, resulting in the `delay` function being ignored. +It is a handy way to quickly turn code on and off. +Try uncommenting this line by deleting `//` and refreshing the pattern. +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"`)? +In JavaScript, as in most programming languages, this content is referred to as being a [_string_](https://en.wikipedia.org/wiki/String_(computer_science)). +A string is simply a sequence of individual characters. +In TidalCycles, strings are used to write _patterns_ using the mini-notation, and you may hear the phrase _pattern string_ from time to time. + +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)... + +
\ No newline at end of file diff --git a/website/src/pages/learn/effects.mdx b/website/src/pages/learn/effects.mdx new file mode 100644 index 00000000..a73e140a --- /dev/null +++ b/website/src/pages/learn/effects.mdx @@ -0,0 +1,65 @@ +--- +title: Audio effects +description: Strudel Tutorial - Audio effects +layout: ../../layouts/MainLayout.astro +--- + +import { MiniRepl } from '../../docs/MiniRepl'; +import { JsDoc } from '../../docs/JsDoc'; + +# Audio Effects + +Wether you're using a synth or a sample, you can apply any of the following built-in audio effects. +As you might suspect, the effects can be chained together, and they accept a pattern string as their argument. + +# bandf + + + +# bandq + + + +# coarse + + + +# crush + + + +# cutoff + + + +# gain + + + +# hcutoff + + + +# hresonance + + + +# pan + + + +# resonance + + + +# shape + + + +# velocity + + + +# vowel + + diff --git a/website/src/pages/learn/getting-started.mdx b/website/src/pages/learn/getting-started.mdx index 69846f1a..6e718ab7 100644 --- a/website/src/pages/learn/getting-started.mdx +++ b/website/src/pages/learn/getting-started.mdx @@ -1,26 +1,49 @@ --- title: Getting Started -description: Strudel Tutorial +description: Strudel Tutorial - Getting Started layout: ../../layouts/MainLayout.astro --- import { MiniRepl } from '../../docs/MiniRepl'; import { JsDoc } from '../../docs/JsDoc'; +# Welcome + +Welcome to the Strudel documentation pages! + + +These pages will introduce you to [Strudel](https://strudel.tidalcycles.org/), a web-based [live coding](https://github.com/toplap/awesome-livecoding/) environment that implements the [Tidal Cycles](https://tidalcycles.org) algorithmic pattern language. + # What is Strudel? +[Strudel](https://strudel.tidalcycles.org/) is a version of [Tidal Cycles](https://tidalcycles.org) written in [JavaScript](https://developer.mozilla.org/en-US/docs/Web/JavaScript), initiated by [Alex McLean](https://slab.org) and [Felix Roos](https://github.com/felixroos) in 2022. +Tidal Cycles, also known as Tidal, is a language for [algorithmic pattern](https://algorithmicpattern.org), and though it is most commonly used for [making music](https://tidalcycles.org/docs/showcase), it can be used for any kind of pattern making activity, including [weaving](https://www.youtube.com/watch?v=TfEmEsusXjU). + +Tidal was first implemented as a library written in the [Haskell](https://www.haskell.org/) functional programming language, and by itself it does not make any sound. +To make sound, it has to be connected to a sound engine, and by default this is a [SuperCollider](https://supercollider.github.io/) plugin called [SuperDirt](https://github.com/musikinformatik/SuperDirt/). +As such, it can be difficult for first-time users to install both Tidal Cycles and SuperDirt, as there are many small details to get right. +Strudel however runs directly in your web browser, does not require any custom software installation, and can make sound all by itself. + +# Strudel REPL and MiniREPL + +The main place to actually make music with Strudel is the [Strudel REPL](https://strudel.tidalcycles.org/) ([what is a REPL?](https://en.wikipedia.org/wiki/Read%E2%80%93eval%E2%80%93print_loop)), but in these pages you will also encounter interactive "MiniREPLs" where you can listen to and edit Strudel patterns. +Try clicking the play icon below: + + + +Then edit the text so it reads `s("bd sn cp hh")` and click the refresh icon. +Congratulations, you have now live coded your first Strudel pattern! + With Strudel, you can expressively write dynamic music pieces. -It aims to be [Tidal Cycles](https://tidalcycles.org/) for JavaScript (started by the same author). - 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/). +# Show me some demos! -## Show me a Demo +To see and hear what Strudel can do, visit the [Strudel REPL](https://strudel.tidalcycles.org/) and click the Shuffle icon in the top menu bar. +You can get a feel for Strudel by browsing and editing these examples and clicking the Refresh icon to update. -To get a taste of what Strudel can do, check out this track: +Alternatively, you can get a taste of what Strudel can do by clicking play on this track: ],hh(3,4)") // drums .slow(3/2)`} /> -## Disclaimer +# Strudel is a work in progress 🚧 -- This project is still in its experimental state. In the future, parts of it might change significantly. -- This tutorial is far from complete. +Please note that this project is still in its experimental state. +In the future, parts of it might change significantly. +This tutorial is also far from complete. +You can contribute to it clicking 'Edit this page' in the top right, or by visiting the [Strudel GitHub page](https://github.com/tidalcycles/strudel/). -# Playing Pitches +# What's next? -Pitches are an essential building block for music. In Strudel, there are 3 different options to express a pitch: +Head on over to the [Notes](/learn/notes) page. -- `note`: letter notation -- `n`: number notation -- `freq`: frequency notation - -## note - -Notes are notated with the note letter, followed by the octave number. You can notate flats with `b` and sharps with `#`. - - - -By the way, you can edit the contents of the player, and press "update" to hear your change! -You can also press "play" on the next player without needing to stop the last one. - -## n - -If you don't like notes, you can also use numbers with `n` instead: - - - -These numbers are interpreted as so called midi numbers, where adjacent whole numbers are 1 semitone apart. -You could also write decimal numbers to get microtonal pitches: - - - -## freq - -To get maximum freedom, you can also use `freq` to directly control the frequency: - - - -In this example, we play A3 (220Hz), C#4 natural (275Hz), E4 (330Hz) and A4 (440Hz). - -
- -# Playing Sounds - -Instead of pitches, we can also play sounds with `s`: - - - -Similarly, we can also use `s` to change the sound of our pitches: - - - -Try changing the sound to `square`, `triangle` or `sine`! - -We will go into the defails of sounds and synths [later](/learn/synths-samples-effects). - -
- -# Syntax - -So far, we've seen the following syntax: - -``` -xxx("foo").yyy("bar") -``` - -Generally, `xxx` and `yyy` are called functions, while `foo` and `bar` are called function arguments. -So far, we've used the functions to declare which aspect of the sound we want to control, and their arguments for the actual data. -The `yyy` function is called a chained function, because it is appended with a dot. - -Strudel makes heavy use of chained functions. Here is a more extreme example: - - - -The `//` is a line comment, resulting in the `delay` function being ignored. -It is a handy way to quickly turn stuff on and off. Try uncommenting this line by deleting `//`! - -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.. - -
+
\ No newline at end of file diff --git a/website/src/pages/learn/outputs.mdx b/website/src/pages/learn/input-output.mdx similarity index 71% rename from website/src/pages/learn/outputs.mdx rename to website/src/pages/learn/input-output.mdx index 6a264487..27ae5ef7 100644 --- a/website/src/pages/learn/outputs.mdx +++ b/website/src/pages/learn/input-output.mdx @@ -7,16 +7,16 @@ layout: ../../layouts/MainLayout.astro import { MiniRepl } from '../../docs/MiniRepl'; import { JsDoc } from '../../docs/JsDoc'; -# Alternative Outputs +# MIDI and OSC -The default audio output of Strudel uses the Web Audio API. -It is also possible to use strudel with MIDI and OSC / Superdirt instead. +The default audio output of Strudel uses the [Web Audio API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API). +It is also possible to use Strudel with MIDI and OSC / [SuperDirt](https://github.com/musikinformatik/SuperDirt/) instead. # MIDI API Strudel also supports midi via [webmidi](https://npmjs.com/package/webmidi). -### midi(outputName?) +## midi(outputName?) Either connect a midi device or use the IAC Driver (Mac) or Midi Through Port (Linux) for internal midi messages. If no outputName is given, it uses the first midi output it finds. @@ -29,14 +29,14 @@ If no outputName is given, it uses the first midi output it finds. In the console, you will see a log of the available MIDI devices as soon as you run the code, e.g. `Midi connected! Using "Midi Through Port-0".` -# Superdirt API +# SuperDirt API -In mainline tidal, the actual sound is generated via Superdirt, which runs inside Supercollider. -Strudel also supports using Superdirt as a backend, although it requires some developer tooling to run. +In mainline tidal, the actual sound is generated via [SuperDirt](https://github.com/musikinformatik/SuperDirt/), which runs inside SuperCollider. +Strudel also supports using [SuperDirt](https://github.com/musikinformatik/SuperDirt/) as a backend, although it requires some developer tooling to run. ## Prequisites -Getting Superdirt to work with Strudel, you need to +Getting [SuperDirt](https://github.com/musikinformatik/SuperDirt/) to work with Strudel, you need to 1. install SuperCollider + sc3 plugins, see [Tidal Docs](https://tidalcycles.org/docs/) (Install Tidal) for more info. 2. install [node.js](https://nodejs.org/en/) @@ -61,10 +61,12 @@ If you now hear sound, congratulations! If not, you can get help on the [#strude -## Superdirt Params +## SuperDirt Params -The following functions can be used with superdirt: +The following functions can be used with [SuperDirt](https://github.com/musikinformatik/SuperDirt/): `s n note freq channel orbit cutoff resonance hcutoff hresonance bandf bandq djf vowel cut begin end loop fadeTime speed unitA gain amp accelerate crush coarse delay lock leslie lrate lsize pan panspan pansplay room size dry shape squiz waveloss attack decay octave detune tremolodepth` Please refer to [Tidal Docs](https://tidalcycles.org/) for more info. + +
\ No newline at end of file diff --git a/website/src/pages/learn/mini-notation.mdx b/website/src/pages/learn/mini-notation.mdx index 0424fd56..8690f844 100644 --- a/website/src/pages/learn/mini-notation.mdx +++ b/website/src/pages/learn/mini-notation.mdx @@ -6,10 +6,13 @@ layout: ../../layouts/MainLayout.astro import { MiniRepl } from '../../docs/MiniRepl'; import { JsDoc } from '../../docs/JsDoc'; -# Mini Notation +# Mini-notation -Similar to Tidal Cycles, Strudel has an embedded mini language that is designed to write rhythmic patterns in a short manner. -Before diving deeper into the details, here is a flavor of how the mini language looks like: +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. + +Before diving deeper into the details, here is a flavour of how the mini-notation looks like: -The snippet above is enclosed in backticks (`), which allows you to write multi-line strings. -You can also use double quotes (") for single line mini notation. +Note that the snippet above is enclosed in backticks (`), which allows you to write multi-line strings. -## Sequences +You can also use regular double quotes (`"`) for single line mini-notation, as we have done already. + +# Sequences of events in a cycle We can play more notes by separating them with spaces: - + Here, those four notes are squashed into one cycle, so each note is a quarter second long. Try adding or removing notes and notice how the tempo changes! -## Division + -We can slow the sequence down by enclosing it in brackets and dividing it by a number: +Note that the overall duration of time does not change, and instead each note length descreases. +This is a key idea, as it illustrates the 'Cycle' in TidalCycles! - +Each space-separated note in this sequence is an _event_. +The time duration of each event is based on the speed or tempo of the cycle, and how many events are present. +Taking the two examples above, we have four and eight events respectively, and since they have the same cycle duration, they each have to fit their events inside the same amount of time. + +This is perhaps counter-intuitive if you are used to adding notes in a sequencer or piano roll and the overall length increasing. +But, it will begin to make sense as we go through more elements of mini-notation. + +# Division + +We can slow the sequence down by enclosing it in brackets and dividing it by a number (`/2`): + + The division by two means that the sequence will be played over the course of two cycles. -You can also use decimal numbers for any tempo you like. +You can also use decimal numbers for any tempo you like (`/2.75`). -## Angle Brackets + -Using angle brackets, we can define the sequence length based on the number of children: +# Angle Brackets -")`} /> +Using angle brackets `<>`, we can define the sequence length based on the number of events: + +")`} /> The above snippet is the same as: - + -The advantage of the angle brackets, is that we can add more children without needing to change the number at the end. +The advantage of the angle brackets, is that we can add more events without needing to change the number at the end. -## Multiplication +")`} /> -Contrary to division, a sequence can be sped up by multiplying it by a number: +")`} /> - +This is more similar to traditional music sequencers and piano rolls, where adding a note increases the perceived overall duration. -The multiplication by 2 here means that the sequence will play twice a cycle. +# Multiplication -## Bracket Nesting +Contrary to division, a sequence can be sped up by multiplying it by a number using the asterisk symbol (`*`): -To create more interesting rhythms, you can nest sequences with brackets, like this: + - +The multiplication by two here means that the sequence will play twice a cycle. -## Rests +As with divisions, multiplications can be decimal (`*2.75`): -The "~" represents a rest: + - +Actually, this is not true, but this will be [fixed](https://github.com/tidalcycles/strudel/issues/314) :) -## Parallel +# Subdividing time with bracket nesting -Using commas, we can play chords: +To create more interesting rhythms, you can _nest_ or _enclose_ sequences (put sequences inside sequences) with brackets `[]`, like this: - +Compare the difference between the following: -To play multiple chords in a sequence, we have to wrap them in brackets: + + + + + -")`} /> +What's going on here? When we nest/enclose multiple events inside brackets (`[]`), their duration becomes the length of one event in the outer sequence. -## Elongation +This is a very simple change to make, but it has profound consequences. +Remember what we said earlier about how the cycles in tidal stay the same length, and the individual event lengths are divided up in this cycle? +Well, what this means is that in TidalCycles, not only can you divide time any way you want, and you can also subdivide time any way you want! + +# Rests + +The "~" represents a rest, and will create silence between other events: + + + +# Parallel / polyphony + +Using commas, we can play chords. +The following are the same: + + + + +But to play multiple chords in a sequence, we have to wrap them in brackets: + +")`} /> + +# Elongation With the "@" symbol, we can specify temporal "weight" of a sequence child: -")`} /> +")`} /> Here, the first chord has a weight of 2, making it twice the length of the other chords. The default weight is 1. -## Replication +# Replication Using "!" we can repeat without speeding up: -")`} /> +")`} /> In essence, the `x!n` is like a shortcut for `[x*n]@n`. -## Euclidian +# Mini-notation review -Using round brackets, we can create rhythmical sub-divisions based on three parameters: beats, segments and offset. -The first parameter controls how may beats will be played. -The second parameter controls the total amount of segments the beats will be distributed over. -The third (optional) parameter controls the starting position for distributing the beats. -One popular Euclidian rhythm (going by various names, such as "Pop Clave") is "(3,8,0)" or simply "(3,8)", -resulting in a rhythmical structure of "x ~ ~ x ~ ~ x ~" (3 beats over 8 segments, starting on position 1). +To recap what we've learned so far, compare the following patterns: - +")`} /> +")`} /> +")`} /> +")`} /> +")`} /> +")`} /> +")`} /> + +# Euclidian rhythms + +Using round brackets after an event, we can create rhythmical sub-divisions based on three parameters: `beats`, `segments` and `offset`. +This algorithm can be found in many different types of music software, and is often referred to as a [Euclidean rhythm](https://en.wikipedia.org/wiki/Euclidean_rhythm) sequencer, after computer scientist Godfriend Toussaint. +Why is it interesting? Well, consider the following simple example: + + + +Sound familiar? +This is a popular Euclidian rhythm going by various names, such as "Pop Clave". +These rhythms can be found in all musical cultures, and the Euclidian rhythm algorithm allows us to express them extremely easily. +Writing this rhythm out in full require describing: + + + +But using the Euclidian rhythm notation, we only need to express "3 beats over 8 segments, starting on position 1". + +This makes it easy to write patterns with interesting rhythmic structures and variations that still sound familiar: + + + +Note that since the example above does not use the third `offset` parameter, it can be written simply as `"(3,8)"`. + + + +Let's look at those three parameters in detail. + +## Beats + +`beats`: the first parameter controls how may beats will be played. +Compare these: + + + + + +## Segments + +`segments`: the second parameter controls the total amount of segments the beats will be distributed over: + + + + + +## Offsets + +`offset`: the third (optional) parameter controls the starting position for distributing the beats. +We need a secondary rhythm to hear the difference: + + + + + +# Mini-notation exercise + +The most fun thing about the mini-notation, is that everything you have just learned can be combined in various ways! + +Starting with this one `n`, can you make a _pattern string_ that uses every single mini-notation element above? + + + +
diff --git a/website/src/pages/learn/notes.mdx b/website/src/pages/learn/notes.mdx new file mode 100644 index 00000000..6d711d98 --- /dev/null +++ b/website/src/pages/learn/notes.mdx @@ -0,0 +1,88 @@ +--- +title: Notes +description: Strudel Tutorial - Notes +layout: ../../layouts/MainLayout.astro +--- + +import { MiniRepl } from '../../docs/MiniRepl'; +import { JsDoc } from '../../docs/JsDoc'; + +# Notes + +Pitches are an essential building block for music. +In Strudel, there are three different ways to express a pitch, `note`, `n` and `freq`. +Here's the same pattern written in three different ways: + +- `note`: letter notation, good for those who are familiar with western music theory: + + +- `n`: number notation, good for those who want to use recognisable pitches, but don't care about music theory: + + +- `freq`: frequency notation, good for those who want to go beyond standardised tuning systems: + + +Let's look at `note`, `n` and `freq` in more detail... + +# `note` + +Notes are notated with the note letter, followed by the octave number. You can notate flats with `b` and sharps with `#`. + + + +By the way, you can edit the contents of the player, and press "update" to hear your change! +You can also press "play" on the next player without needing to stop the last one. + +# `n` + +If you prefer, you can also use numbers with `n` instead: + + + +These numbers are interpreted as so called [MIDI numbers](https://www.inspiredacoustics.com/en/MIDI_note_numbers_and_center_frequencies), where adjacent whole numbers are one 'semitone' apart. + +You could also write decimal numbers to get 'microtonal' pitches (in between the black and white piano notes): + + + +# `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). + +# From notes to sounds + +In this page, when we played a pattern of notes like this: + + + +We heard a simple synthesised sound, in fact we heard a [square wave oscillator](https://en.wikipedia.org/wiki/Square_wave). + +This is the default synthesiser used by Strudel, but how do we then make different sounds in Strudel? + +Let's find out in the next page on [Sounds](/learn/sounds). + +
\ No newline at end of file diff --git a/website/src/pages/learn/samples.mdx b/website/src/pages/learn/samples.mdx new file mode 100644 index 00000000..bedcebba --- /dev/null +++ b/website/src/pages/learn/samples.mdx @@ -0,0 +1,215 @@ +--- +title: Notes +description: Strudel Tutorial - Notes +layout: ../../layouts/MainLayout.astro +--- + +import { MiniRepl } from '../../docs/MiniRepl'; +import { JsDoc } from '../../docs/JsDoc'; + +# Samples + +# Default Sample Map + +As we have seen, `s` can play back audio samples: + + + +These sounds come from Strudels in-built default "sample map". +To know which sounds are available, open the [default sample map](https://strudel.tidalcycles.org/EmuSP12.json). + +# Custom Sample Maps + +You can load your own sample map using the `samples` function. +In this example we create a map using sounds from the default sample map: + + + +When you load your own samples, you can choose the names that you will then refer to in your pattern string inside the `s` function. +Compare with this example which uses the same samples, but with different names. + + + +Here we have changed the "map" to include longer sample names. + +# Loading Custom Samples + +The `samples` function has two arguments: +- A [JavaScript object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object) that maps sound names to audio file paths. +- A base URL that comes before each path describing where the sample folder can be found online. + - Make sure your base URL ends with a slash, while your sample paths do **not** begin with one! + +To see how this looks in practice, compare the [DirtSamples GitHub repo](https://github.com/tidalcycles/Dirt-Samples) with the previous sample map example. + +Because GitHub is a popular place for uploading open source samples, it has its own shortcut: + + + +The format is `github:user/repo/branch/`. + +Let's see another example, this time based on the following GitHub repo: https://github.com/jarmitage/jarmitage.github.io. +We can see there are some guitar samples inside the `/samples` folder, so let's try to load them: + + + +# Loading Multiple Samples per Sound + +It is also possible, to declare multiple files for one sound, using the array notation: + +,~ ,[hh:0 hh:1]*2")`} +/> + +The `:0` `:1` etc. are the indices of the array. +The sample number can also be set using `n`: + +")`} +/> + +In that case, we might load our guitar sample map a different way: + + + +And as above, we can choose the sample number using `n` for even more flexibility: + +").s("guitar")`} +/> + +# Pitched Sounds + +For pitched sounds, you can use `note`, just like with synths: + +@2").s('gtr').gain(.5)`} +/> + +Here, the guitar samples will overlap, because they always play till the end. +If we want them to behave more like a synth, we can add `clip(1)`: + +@2").s('gtr').clip(1) + .gain(.5)`} +/> + +# Base Pitch + +If we have 2 samples with different base pitches, we can make them in tune by specifying the pitch like this: + +@2").s("gtr,moog").clip(1) + .gain(.5)`} +/> + +If a sample has no pitch set, `c3` is the default. + +We can also declare different samples for different regions of the keyboard: + +!2, g4 f4]>") + .s('moog').clip(1) + .gain(.5)`} +/> + +The sampler will always pick the closest matching sample for the current note! + +# Sampler Effects + +Below are four different examples of sampler "effects" which are functions that can be used to change the behaviour of sample playback. +Note that most of what you've learned already about Tidal mini-notation can be used with these functions too. +Almost everything in Tidal can be patterned using strings! + +### `begin` + + + +### `end` + + + +### `loopAt` + + + +### `chop` + + + +
\ No newline at end of file diff --git a/website/src/pages/learn/sounds.mdx b/website/src/pages/learn/sounds.mdx new file mode 100644 index 00000000..cd1f4751 --- /dev/null +++ b/website/src/pages/learn/sounds.mdx @@ -0,0 +1,40 @@ +--- +title: Sounds +description: Strudel Tutorial - Sounds +layout: ../../layouts/MainLayout.astro +--- + +import { MiniRepl } from '../../docs/MiniRepl'; +import { JsDoc } from '../../docs/JsDoc'; + +# Sounds + +We can play sounds with `s`, in two different ways: +- `s` can trigger audio samples, where a sound file is loaded in the background and played back: + +- `s` can trigger audio synthesisers, which are synthesised in real-time using code also running in the background: + + +You can learn more about both of these approaches in the pages [Synths](/learn/synths) and [Samples](/learn/samples). + +# Combining notes and sounds + +In both of the above cases, we are no longer directly controlling the `note`/`n`/`freq` of the sound heard via `s`, as we were in the [Notes](/strudel/notes) page. + +So how can we both control the sound and the pitch? We can _combine_ `note`/`n`/`freq` with `s` to change the sound of our pitches: + + + + + + + +What about combining different notes with different sounds at the same time? + + + +Hmm, something interesting is going on there, related to there being five notes and three sounds. + +Let's now take a step back and think about the Strudel [Code](/learn/code) we've been hearing so far. + +
\ No newline at end of file diff --git a/website/src/pages/learn/synths-samples-effects.mdx b/website/src/pages/learn/synths-samples-effects.mdx deleted file mode 100644 index f98fdb0f..00000000 --- a/website/src/pages/learn/synths-samples-effects.mdx +++ /dev/null @@ -1,236 +0,0 @@ ---- -title: Synths, Samples & FX -description: Strudel Tutorial -layout: ../../layouts/MainLayout.astro ---- - -import { MiniRepl } from '../../docs/MiniRepl'; -import { JsDoc } from '../../docs/JsDoc'; - -# Synths, Samples & Effects - -Let's take a closer look at how we can control synths, sounds and effects. - -## Synths - -So far, all the mini notation examples all used the same sound, which is kind of boring. -We can change the sound, using the `s` function: - ->").s('sawtooth')`} /> - -Here, we are wrapping our notes inside `note` and set the sound using `s`, connected by a dot. - -Those functions are only 2 of many ways to alter the properties, or _params_ of a sound. -The power of patterns allows us to sequence any _param_ independently: - ->").s("")`} /> - -Now we not only pattern the notes, but the sound as well! -`sawtooth` `square` and `triangle` are the basic waveforms available in `s`. - -### Envelope - -You can control the envelope of a synth using the `attack`, `decay`, `sustain` and `release` functions: - ->").s('sawtooth') - .attack(.1).decay(.1).sustain(.2).release(.1)`} -/> - -## Samples - -Besides Synths, `s` can also play back samples: - - - -To know which sounds are available, open the [default sample map](https://strudel.tidalcycles.org/EmuSP12.json) - -### Custom Sample Maps - -You can load your own sample map like this: - - - -The `samples` function takes an object that maps sound names to audio file paths. -The second argument is the base URL that comes before each path. Make sure your base URL ends with a slash, while your sample paths do **not** begin with one. - -Because github is a popular choice to dump samples, there is a shortcut for that: - - - -The format is `github:user/repo/branch/`. - -### Multiple Samples per Sound - -It is also possible, to declare multiple files for one sound, using the array notation: - -,~ ,[hh:0 hh:1]*2")`} -/> - -The `:0` `:1` etc. are the indices of the array. -The sample number can also be set using `n`: - -")`} -/> - -### Pitched Sounds - -For pitched sounds, you can use `note`, just like with synths: - -@2").s('gtr').gain(.5)`} -/> - -Here, the guitar samples will overlap, because they always play till the end. -If we want them to behave more like a synth, we can add `clip(1)`: - -@2").s('gtr').clip(1) - .gain(.5)`} -/> - -### Base Pitch - -If we have 2 samples with different base pitches, we can make them in tune by specifying the pitch like this: - -@2").s("gtr,moog").clip(1) - .gain(.5)`} -/> - -If a sample has no pitch set, `c3` is the default. - -We can also declare different samples for different regions of the keyboard: - -!2, g4 f4]>") - .s('moog').clip(1) - .gain(.5)`} -/> - -The sampler will always pick the closest matching sample for the current note! - -## Sampler Effects - -### begin - - - -### end - - - -### loopAt - - - -### chop - - - -## Audio Effects - -Wether you're using a synth or a sample, you can apply these effects: - -### gain - - - -### velocity - - - -### cutoff - - - -### resonance - - - -### hcutoff - - - -### hresonance - - - -### bandf - - - -### bandq - - - -### vowel - - - -### pan - - - -### coarse - - - -### shape - - - -### crush - - diff --git a/website/src/pages/learn/synths.mdx b/website/src/pages/learn/synths.mdx new file mode 100644 index 00000000..d7ca747c --- /dev/null +++ b/website/src/pages/learn/synths.mdx @@ -0,0 +1,41 @@ +--- +title: Synths +description: Strudel Tutorial - Synths +layout: ../../layouts/MainLayout.astro +--- + +import { MiniRepl } from '../../docs/MiniRepl'; +import { JsDoc } from '../../docs/JsDoc'; + +# Synths + +For now, [samples](/learn/samples) are the main way to play with Strudel. +In future, more powerful synthesis capabilities will be added. +If in the meantime you want to dive deeper into audio synthesis with Tidal, you will need to [install SuperCollider and SuperDirt](https://tidalcycles.org/docs/). + +## Playing synths with `s` + +We can change the sound, using the `s` function: + +>").s('sawtooth')`} /> + +Here, we are wrapping our notes inside `note` and set the sound using `s`, connected by a dot. + +Those functions are only 2 of many ways to alter the properties, or _params_ of a sound. +The power of patterns allows us to sequence any _param_ independently: + +>").s("")`} /> + +Now we not only pattern the notes, but the sound as well! +`sawtooth` `square` and `triangle` are the basic waveforms available in `s`. + +## Ampltude Envelope + +You can control the envelope of a synth using the `attack`, `decay`, `sustain` and `release` functions: + +>").s('sawtooth') + .attack(.1).decay(.1).sustain(.2).release(.1)`} +/> + +
\ No newline at end of file diff --git a/website/src/styles/index.css b/website/src/styles/index.css index dabed423..8e07d0cf 100644 --- a/website/src/styles/index.css +++ b/website/src/styles/index.css @@ -7,3 +7,7 @@ body { .cm-gutters { display: none !important; } + +h1 { + padding-top: 30px; +}