Compare commits

...

3 Commits

Author SHA1 Message Date
Felix Roos cd1c4632d7 build to single file 2022-11-23 14:00:31 +01:00
Felix Roos f1a850e133 forgot tonal pkg import 2022-11-22 21:43:30 +01:00
Felix Roos 53b61b8d85 add workshop seed project 2022-11-22 21:33:47 +01:00
13 changed files with 6220 additions and 0 deletions
+24
View File
@@ -0,0 +1,24 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*
node_modules
dist
dist-ssr
*.local
# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
+33
View File
@@ -0,0 +1,33 @@
# Strudel Workshop
This may become a resource to teach strudel in workshop format.
## Install
From the root of the strudel repo:
```sh
npm i # install strudel project dependencies
cd workshop && npm i # install workshop dependencies
npm run dev # run dev server
```
This assumes you have node 16+ installed.
## How to write
While running the dev server, go to `workshop.mdx` to write!
When the file is saved, the browser will hot reload the file and reveal the changes instantly.
You can use normal markdown + JSX, which enables using the MiniRepl component.
You could also add any react component and import it to the mdx file.
## Build
Running
```sh
npm run build
```
..will output a single `index.html` file to `dist`. This file can either be opened directly in the browser (locally) or uploaded to some server.
+12
View File
@@ -0,0 +1,12 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Strudel Workshop</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.jsx"></script>
</body>
</html>
+5982
View File
File diff suppressed because it is too large Load Diff
+29
View File
@@ -0,0 +1,29 @@
{
"name": "workshop",
"private": true,
"version": "0.0.0",
"type": "module",
"scripts": {
"dev": "vite --open",
"build": "vite build",
"preview": "vite preview"
},
"dependencies": {
"react": "^17.0.2",
"react-dom": "^17.0.2"
},
"devDependencies": {
"@mdx-js/mdx": "^1.6.22",
"@mdx-js/react": "^1.6.22",
"@tailwindcss/typography": "^0.5.8",
"@types/react": "^18.0.24",
"@types/react-dom": "^18.0.8",
"@vitejs/plugin-react": "^2.2.0",
"autoprefixer": "^10.4.13",
"postcss": "^8.4.19",
"tailwindcss": "^3.2.4",
"vite": "^3.2.3",
"vite-plugin-mdx": "^3.5.11",
"vite-plugin-singlefile": "^0.13.1"
}
}
+6
View File
@@ -0,0 +1,6 @@
module.exports = {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
}
+16
View File
@@ -0,0 +1,16 @@
import { initAudioOnFirstClick } from '@strudel.cycles/webaudio';
import Workshop from './workshop.mdx';
initAudioOnFirstClick();
function App() {
return (
<div className="bg-slate-900 w-screen h-screen overflow-auto">
<main className="p-4 pl-6 max-w-3xl prose prose-invert">
<Workshop />
</main>
</div>
);
}
export default App;
+22
View File
@@ -0,0 +1,22 @@
import { evalScope, controls } from '@strudel.cycles/core';
import { MiniRepl as _MiniRepl } from '@strudel.cycles/react';
import { samples } from '@strudel.cycles/webaudio';
import '@strudel.cycles/react/dist/style.css';
samples('github:tidalcycles/Dirt-Samples/master')
evalScope(
controls,
import('@strudel.cycles/core'),
// import('@strudel.cycles/tone'),
import('@strudel.cycles/tonal'),
import('@strudel.cycles/mini'),
import('@strudel.cycles/midi'),
// import('@strudel.cycles/xen'),
import('@strudel.cycles/webaudio'),
import('@strudel.cycles/osc'),
);
export function MiniRepl({ tune }) {
return <_MiniRepl tune={tune} hideOutsideView={true} />;
}
+3
View File
@@ -0,0 +1,3 @@
@tailwind base;
@tailwind components;
@tailwind utilities;
+11
View File
@@ -0,0 +1,11 @@
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import './index.css';
ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,
document.getElementById('root'),
);
+49
View File
@@ -0,0 +1,49 @@
import { MiniRepl } from './MiniRepl';
# Workshop
> This is a starter project for any type of teaching material using strudel!
## What is Strudel?
1. A pastry made with fruit or cheese rolled up in layers of thin sheets of dough and then baked.
2. a pastry made from multiple, thin layers of dough rolled up and filled with fruit, etc.
3. thin sheet of filled dough rolled and baked
## Some REPLs:
Small REPL:
<MiniRepl tune={`s("bd sd,hh*8")`} />
Big REPL:
<MiniRepl
tune={`await samples({
bd: ['bd/BT0AADA.wav','bd/BT0AAD0.wav','bd/BT0A0DA.wav','bd/BT0A0D3.wav','bd/BT0A0D0.wav','bd/BT0A0A7.wav'],
sd: ['sd/rytm-01-classic.wav','sd/rytm-00-hard.wav'],
hh: ['hh27/000_hh27closedhh.wav','hh/000_hh3closedhh.wav'],
}, 'github:tidalcycles/Dirt-Samples/master/');
stack(
s("bd,[~ <sd!3 sd(3,4,2)>],hh(3,4)") // drums
.speed(perlin.range(.7,.9)) // random sample speed variation
,"<a1 b1\*2 a1(3,8) e2>" // 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
.n() // wrap in "n"
.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
,"<Am7!3 <Em7 E7b13 Em7 Ebm7b5>>".voicings() // chords
.superimpose(x=>x.add(.04)) // add second, slightly detuned voice
.add(perlin.range(0,.5)) // random pitch variation
.n() // wrap in "n"
.s('sawtooth') // waveform
.gain(.16) // turn down
.cutoff(500) // fixed cutoff
.attack(1) // slowly fade in
)
.slow(3/2)`}
/>
+8
View File
@@ -0,0 +1,8 @@
/** @type {import('tailwindcss').Config} */
module.exports = {
content: ['./index.html', './src/**/*.{js,ts,jsx,tsx,mdx}'],
theme: {
extend: {},
},
plugins: [require('@tailwindcss/typography')],
};
+25
View File
@@ -0,0 +1,25 @@
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import _mdx from 'vite-plugin-mdx';
import { viteSingleFile } from 'vite-plugin-singlefile';
// import remarkToc from 'remark-toc';
// import rehypeSlug from 'rehype-slug';
// import rehypeAutolinkHeadings from 'rehype-autolink-headings';
const mdx = _mdx.default || _mdx;
// `options` are passed to `@mdx-js/mdx`
const options = {
// See https://mdxjs.com/advanced/plugins
remarkPlugins: [
// remarkToc,
// E.g. `remark-frontmatter`
],
rehypePlugins: [
// rehypeSlug, rehypeAutolinkHeadings
],
};
// https://vitejs.dev/config/
export default defineConfig({
plugins: [react(), mdx(options), viteSingleFile()],
});