diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 00000000..2f7e5ba3 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,111 @@ +# 🌀 Contributing to Strudel 🌀 + +Thanks for wanting to contribute!!! There are many ways you can add value to this project + +## Communication Channels + +To get in touch with the contributors, either + +- open a [github discussion](https://github.com/tidalcycles/strudel/discussions) or +- [join the Tidal Discord Channel](https://discord.gg/remJ6gQA) and go to the #strudel channel +- Find related discussions on the [tidal club forum](https://club.tidalcycles.org/) + +## Ask a Question + +If you have any questions about strudel, make sure you've read the +[tutorial](https://strudel.tidalcycles.org/tutorial/) to find out if it answers your question. +If not, use one of the Communication Channels above! + +Don't be afraid to ask! Your question might be of great value for other people too. + +## Give Feedback + +No matter if you've used the Strudel REPL or if you are using the strudel packages, we are happy to hear some feedback. +Use one of the Communication Channels listed above and drop us a line or two! + +## Share Music + +If you made some music with strudel, you can give back some love and share what you've done! +Your creation could also be part of the random selection in the REPL if you want. +Use one of the Communication Channels listed above. + +## Improve the Tutorial + +If you find some weak spots in the [tutorial](https://strudel.tidalcycles.org/), +you are welcome to improve them by editing [this file](https://github.com/tidalcycles/strudel/blob/main/repl/src/tutorial/tutorial.mdx). +This will even work without setting up a development environment, only a github account is required. + +## Propose a Feature + +If you want a specific feature that is not part of strudel yet, feel free to use one of the communication channels above. +Maybe you even want to help with the implementation of that feature! + +## Report a Bug + +If you've found a bug, or some behaviour that does not seem right, you are welcome to file an [issue](https://github.com/tidalcycles/strudel/issues). +Please check that it has not been reported before. + +## Fix a Bug + +To fix a bug that has been reported, + +1. check that nobody else is already fixing it and respond to the issue to let people know you're on it +3. fork the repository +4. make sure you've setup the project (see below) +5. hopefully fix the bug +6. make sure the tests pass +7. send a pull request + +## Write Tests + +There are still many tests that have not been written yet! Reading and writing tests is a great opportunity to get familiar with the codebase. +You can find the tests in each package in the `test` folder. To run all tests, run `npm test` from the root folder. + +## Project Setup + +To get the project up and running for development, make sure you have installed: + +- git +- node, preferably v16 + +then, do the following: + +```sh +git clone https://github.com/tidalcycles/strudel.git && cd strudel +npm i # install at root to symlink packages +npx lerna bootstrap # install all dependencies in packages +cd repl && npm i # install repl dependencies +npm run start # start repl +``` + +Those commands might look slightly different for your OS. +Please report any problems you've had with the setup instructions! + +## Code Style + +To make sure the code changes only where it should, we are using prettier to unify the code style. +If you use VSCode, you can + +1. install [the prettier extension](https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode) +2. open command palette and run "Format Document With..." +3. Choose "Configure Default Formatter..." +4. Select prettier + +## Package Workflow + +The project is split into multiple [packages](https://github.com/tidalcycles/strudel/tree/main/packages) with independent versioning. +When you run `npm i` on the root folder, [npm workspaces](https://docs.npmjs.com/cli/v7/using-npm/workspaces) will symlink all packages +in the `node_modules` folder. This will allow any js file to import `@strudel.cycles/` to get the local version, +which allows developing multiple packages at the same time + +## Package Publishing + +To publish all packages that have been changed since the last release, run: + +```sh +npx lerna publish +``` + +## Have Fun + +Remember to have fun, and that this project is driven by the passion of volunteers! diff --git a/README.md b/README.md index 09485654..fb0ab91f 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,7 @@ npm run start To publish, just run: ```sh -npx lerna version +npx lerna publish ``` This will publish all packages that changed since the last version. diff --git a/featurelist.md b/featurelist.md index d52f9796..5135e511 100644 --- a/featurelist.md +++ b/featurelist.md @@ -6,7 +6,7 @@ - [ ] setcps - [ ] naming patterns? block based evaluation? - [ ] once -- [ ] silence +- [x] silence - [x] hush - [ ] panic @@ -30,22 +30,23 @@ https://tidalcycles.org/docs/patternlib/tour/concatenation - [ ] overlay => like stack? "The overlay function is similar to cat" => wrong? - [ ] `<>` operator (=== overlay) - [x] stack -- [x] superimpose => strudel supports multiple args => is this layer? -- [ ] layer => is this like superimpose but with multiple args? +- [x] superimpose +- [x] layer - [ ] steps ? -- [ ] iter, iter' +- [x] iter +- [x] iter' = iterBack ## Alteration - [ ] range, rangex - [ ] quantise - [ ] ply -- [ ] stutter +- [x] stutter = echo - [ ] stripe, slowstripe - [ ] palindrome = every(2, rev) - [ ] trunc - [ ] linger -- [ ] chunk, chunk' +- [x] chunk, chunk' - [ ] shuffle - [ ] scramble - [ ] rot @@ -68,7 +69,8 @@ https://tidalcycles.org/docs/patternlib/tour/concatenation - [ ] select, selectF - [ ] pickF - [ ] squeeze -- [ ] euclid, euclidInv, euclidFull +- [x] euclid, euclidLegato +- [ ] euclidInv, euclidFull - [ ] ifp ## Time @@ -83,7 +85,8 @@ https://tidalcycles.org/docs/patternlib/tour/concatenation - [x] off - [ ] rotL / rotR - [x] rev -- [ ] jux / juxBy +- [x] jux +- [ ] juxBy - [ ] swingBy / swing - [ ] ghost - [ ] inside / outside @@ -114,7 +117,7 @@ https://tidalcycles.org/docs/patternlib/tour/concatenation - [ ] chop - [ ] striate / striateBy - [ ] loopAt -- [ ] segment +- [x] segment - [ ] discretise ## Randomness diff --git a/packages/core/package-lock.json b/packages/core/package-lock.json index 4e34b644..1c42d2b3 100644 --- a/packages/core/package-lock.json +++ b/packages/core/package-lock.json @@ -1,6 +1,6 @@ { "name": "@strudel.cycles/core", - "version": "0.0.2", + "version": "0.0.3", "lockfileVersion": 2, "requires": true, "packages": { diff --git a/packages/core/package.json b/packages/core/package.json index bf1ae2e8..740ddf68 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -1,6 +1,6 @@ { "name": "@strudel.cycles/core", - "version": "0.0.2", + "version": "0.0.3", "description": "Port of Tidal Cycles to JavaScript", "main": "strudel.mjs", "type": "module", diff --git a/packages/core/strudel.mjs b/packages/core/strudel.mjs index f6c4f7f9..d4a003d4 100644 --- a/packages/core/strudel.mjs +++ b/packages/core/strudel.mjs @@ -780,7 +780,7 @@ class Pattern { // known as iter' in tidalcycles iterBack(times) { - return this.iter(times, true) + return this.iter(times, true); } _chunk(n, func, back = false) { @@ -791,7 +791,7 @@ class Pattern { } _chunkBack(n, func) { - return this._chunk(n, func, true) + return this._chunk(n, func, true); } edit(...funcs) { diff --git a/packages/eval/package-lock.json b/packages/eval/package-lock.json index 645bc308..de28d321 100644 --- a/packages/eval/package-lock.json +++ b/packages/eval/package-lock.json @@ -1,6 +1,6 @@ { "name": "@strudel.cycles/eval", - "version": "0.0.2", + "version": "0.0.3", "lockfileVersion": 2, "requires": true, "packages": { diff --git a/packages/eval/package.json b/packages/eval/package.json index e2b6552e..342e016b 100644 --- a/packages/eval/package.json +++ b/packages/eval/package.json @@ -1,6 +1,6 @@ { "name": "@strudel.cycles/eval", - "version": "0.0.2", + "version": "0.0.3", "description": "Code evaluator for strudel", "main": "evaluate.mjs", "directories": { @@ -28,7 +28,7 @@ }, "homepage": "https://github.com/tidalcycles/strudel#readme", "dependencies": { - "@strudel.cycles/core": "^0.0.2", + "@strudel.cycles/core": "^0.0.3", "estraverse": "^5.3.0", "shift-ast": "^6.1.0", "shift-codegen": "^7.0.3", diff --git a/packages/midi/package-lock.json b/packages/midi/package-lock.json index 6a25b3e9..12a9b2bf 100644 --- a/packages/midi/package-lock.json +++ b/packages/midi/package-lock.json @@ -1,6 +1,6 @@ { "name": "@strudel.cycles/midi", - "version": "0.0.3", + "version": "0.0.4", "lockfileVersion": 2, "requires": true, "packages": { diff --git a/packages/midi/package.json b/packages/midi/package.json index e6a04232..f1b11890 100644 --- a/packages/midi/package.json +++ b/packages/midi/package.json @@ -1,6 +1,6 @@ { "name": "@strudel.cycles/midi", - "version": "0.0.3", + "version": "0.0.4", "description": "Midi API for strudel", "main": "midi.mjs", "repository": { @@ -21,7 +21,7 @@ }, "homepage": "https://github.com/tidalcycles/strudel#readme", "dependencies": { - "@strudel.cycles/tone": "^0.0.3", + "@strudel.cycles/tone": "^0.0.4", "tone": "^14.7.77", "webmidi": "^2.5.2" } diff --git a/packages/mini/package.json b/packages/mini/package.json index c4c7c877..e865d0ff 100644 --- a/packages/mini/package.json +++ b/packages/mini/package.json @@ -1,6 +1,6 @@ { "name": "@strudel.cycles/mini", - "version": "0.0.3", + "version": "0.0.4", "description": "Mini notation for strudel", "main": "mini.mjs", "type": "module", @@ -25,7 +25,7 @@ }, "homepage": "https://github.com/tidalcycles/strudel#readme", "dependencies": { - "@strudel.cycles/eval": "^0.0.2", - "@strudel.cycles/tone": "^0.0.3" + "@strudel.cycles/eval": "^0.0.3", + "@strudel.cycles/tone": "^0.0.4" } } diff --git a/packages/tonal/package-lock.json b/packages/tonal/package-lock.json index 3b0a20de..2a9c7eb4 100644 --- a/packages/tonal/package-lock.json +++ b/packages/tonal/package-lock.json @@ -1,6 +1,6 @@ { "name": "@strudel.cycles/tonal", - "version": "0.0.2", + "version": "0.0.3", "lockfileVersion": 2, "requires": true, "packages": { diff --git a/packages/tonal/package.json b/packages/tonal/package.json index 7dfceba8..7c607188 100644 --- a/packages/tonal/package.json +++ b/packages/tonal/package.json @@ -1,6 +1,6 @@ { "name": "@strudel.cycles/tonal", - "version": "0.0.2", + "version": "0.0.3", "description": "Tonal functions for strudel", "main": "tonal.mjs", "type": "module", @@ -25,7 +25,7 @@ }, "homepage": "https://github.com/tidalcycles/strudel#readme", "dependencies": { - "@strudel.cycles/core": "^0.0.2", + "@strudel.cycles/core": "^0.0.3", "@tonaljs/tonal": "^4.6.5", "webmidi": "^3.0.15" } diff --git a/packages/tone/package-lock.json b/packages/tone/package-lock.json index bdfa56c1..c6311743 100644 --- a/packages/tone/package-lock.json +++ b/packages/tone/package-lock.json @@ -1,6 +1,6 @@ { "name": "@strudel.cycles/tone", - "version": "0.0.3", + "version": "0.0.4", "lockfileVersion": 2, "requires": true, "packages": { diff --git a/packages/tone/package.json b/packages/tone/package.json index 89e45c42..50aadaa8 100644 --- a/packages/tone/package.json +++ b/packages/tone/package.json @@ -1,6 +1,6 @@ { "name": "@strudel.cycles/tone", - "version": "0.0.3", + "version": "0.0.4", "description": "Tone.js API for strudel", "main": "tone.mjs", "type": "module", @@ -22,7 +22,7 @@ }, "homepage": "https://github.com/tidalcycles/strudel#readme", "dependencies": { - "@strudel.cycles/core": "^0.0.2", + "@strudel.cycles/core": "^0.0.3", "@tonejs/piano": "^0.2.1", "chord-voicings": "^0.0.1", "tone": "^14.7.77" diff --git a/packages/tone/tone.mjs b/packages/tone/tone.mjs index 34d19dc4..5ad55edc 100644 --- a/packages/tone/tone.mjs +++ b/packages/tone/tone.mjs @@ -30,13 +30,16 @@ import { getPlayableNoteValue } from '@strudel.cycles/core/util.mjs'; // "balanced" | "interactive" | "playback"; // Tone.setContext(new Tone.Context({ latencyHint: 'playback', lookAhead: 1 })); -export const defaultSynth = new PolySynth().chain(new Gain(0.5), getDestination()); -defaultSynth.set({ - oscillator: { type: 'triangle' }, - envelope: { - release: 0.01, - }, -}); +export const getDefaultSynth = () => { + const s = new PolySynth().chain(new Gain(0.5), getDestination()); + s.set({ + oscillator: { type: 'triangle' }, + envelope: { + release: 0.01, + }, + }); + return s; +}; // what about // https://www.charlie-roberts.com/gibberish/playground/ diff --git a/packages/xen/package.json b/packages/xen/package.json index c0f78126..6c75e1c9 100644 --- a/packages/xen/package.json +++ b/packages/xen/package.json @@ -1,6 +1,6 @@ { "name": "@strudel.cycles/xen", - "version": "0.0.2", + "version": "0.0.3", "description": "Xenharmonic API for strudel", "main": "xen.mjs", "scripts": { @@ -24,6 +24,6 @@ }, "homepage": "https://github.com/tidalcycles/strudel#readme", "dependencies": { - "@strudel.cycles/core": "^0.0.2" + "@strudel.cycles/core": "^0.0.3" } } diff --git a/repl/src/App.js b/repl/src/App.js index 0a928ce0..10fdfcd7 100644 --- a/repl/src/App.js +++ b/repl/src/App.js @@ -3,7 +3,7 @@ import CodeMirror, { markEvent, markParens } from './CodeMirror'; import cx from './cx'; import logo from './logo.svg'; import playStatic from './static.mjs'; -import { defaultSynth } from '@strudel.cycles/tone'; +import { getDefaultSynth } from '@strudel.cycles/tone'; import * as tunes from './tunes.mjs'; import useRepl from './useRepl.mjs'; import { useWebMidi } from './useWebMidi'; @@ -54,6 +54,7 @@ function getRandomTune() { } const randomTune = getRandomTune(); +const defaultSynth = getDefaultSynth(); function App() { const [editor, setEditor] = useState(); diff --git a/repl/src/static.mjs b/repl/src/static.mjs index dc0d76e2..0fc70537 100644 --- a/repl/src/static.mjs +++ b/repl/src/static.mjs @@ -2,7 +2,9 @@ import { Tone } from '@strudel.cycles/tone'; import { State, TimeSpan } from '@strudel.cycles/core'; import { getPlayableNoteValue } from '@strudel.cycles/core/util.mjs'; import { evaluate } from '@strudel.cycles/eval'; -import { defaultSynth } from '@strudel.cycles/tone'; +import { getDefaultSynth } from '@strudel.cycles/tone'; + +const defaultSynth = getDefaultSynth(); // this is a test to play back events with as less runtime code as possible.. // the code asks for the number of seconds to prequery diff --git a/repl/src/tutorial/tutorial.mdx b/repl/src/tutorial/tutorial.mdx index 7687221e..989268ac 100644 --- a/repl/src/tutorial/tutorial.mdx +++ b/repl/src/tutorial/tutorial.mdx @@ -99,7 +99,7 @@ You can also press "play" on the next player without needing to stop the last on ## Sequences -We can play more notes by seperating them with spaces: +We can play more notes by separating them with spaces: @@ -640,7 +640,7 @@ Patternified autofilter: "")`} + .synth('sawtooth16').autofilter("<1 4 8>")`} /> ## Tonal API