Compare commits

..

13 Commits

Author SHA1 Message Date
Felix Roos 11be5db628 Publish
- @strudel.cycles/core@0.0.2
 - @strudel.cycles/eval@0.0.2
 - @strudel.cycles/midi@0.0.2
 - @strudel.cycles/mini@0.0.2
 - @strudel.cycles/tonal@0.0.2
 - @strudel.cycles/tone@0.0.2
 - @strudel.cycles/xen@0.0.2
2022-03-27 23:44:26 +02:00
Felix Roos 779d303572 simplify import 2022-03-27 23:43:30 +02:00
Felix Roos 788f344012 simplify onEvent call 2022-03-27 23:43:20 +02:00
Felix Roos 33c9326427 add missing dependency 2022-03-27 23:43:06 +02:00
Felix Roos 9ef57152e4 add duration getter 2022-03-27 23:42:47 +02:00
Felix Roos f8f2fb608d add tonal example 2022-03-27 22:49:06 +02:00
Felix Roos 1cf6b37ee4 add mini example 2022-03-27 22:41:37 +02:00
Felix Roos 76822717f4 add eval example 2022-03-27 22:35:55 +02:00
Felix Roos 4142b113e9 add core example 2022-03-27 22:25:48 +02:00
Felix Roos 3c123538e9 repl readme 2022-03-27 22:21:51 +02:00
Felix Roos 73996997e5 add install commands 2022-03-27 22:17:07 +02:00
Felix Roos c4d14594ce remove node 14 test 2022-03-27 22:12:05 +02:00
Felix Roos 657960024d independent mode 2022-03-27 21:52:26 +02:00
27 changed files with 2962 additions and 75 deletions
+1 -1
View File
@@ -7,7 +7,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [14, 16, 17]
node-version: [16, 17]
steps:
- uses: actions/checkout@v2
-8
View File
@@ -19,11 +19,3 @@ cd repl
npm install
npm run start
```
## Build
```bash
cd repl
npm run build
npm run static # <- test static build
```
+1 -1
View File
@@ -2,5 +2,5 @@
"packages": [
"packages/*"
],
"version": "0.0.1"
"version": "independent"
}
+33
View File
@@ -1,3 +1,36 @@
# @strudel.cycles/core
This package contains the bare essence of strudel.
## Install
```sh
npm i @strudel.cycles/core --save
```
## Example
```js
import { sequence, State, TimeSpan } from '@strudel.cycles/core';
const pattern = sequence('a', ['b', 'c']);
const events = pattern.query(new State(new TimeSpan(0, 2)));
const spans = events.map(
(event) => `${event.value}: ${event.whole.begin.toFraction()} - ${event.whole.end.toFraction()} `,
);
```
spans:
```log
a: 0 - 1/2
b: 1/2 - 3/4
c: 3/4 - 1
a: 1 - 3/2
b: 3/2 - 7/4
c: 7/4 - 2
```
[play with @strudel.cycles/core on codesandbox](https://codesandbox.io/s/strudel-core-test-qmz6qr?file=/src/index.js).
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@strudel.cycles/core",
"version": "0.0.1",
"version": "0.0.2",
"lockfileVersion": 2,
"requires": true,
"packages": {
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@strudel.cycles/core",
"version": "0.0.1",
"version": "0.0.2",
"description": "Port of Tidal Cycles to JavaScript",
"main": "strudel.mjs",
"type": "module",
+4 -1
View File
@@ -138,6 +138,10 @@ class Hap {
}
}
get duration() {
return this.whole.end.sub(this.whole.begin).valueOf();
}
withSpan(func) {
// Returns a new event with the function f applies to the event timespan.
const whole = this.whole ? func(this.whole) : undefined
@@ -1034,7 +1038,6 @@ Pattern.prototype.bootstrap = function() {
}
return [functionName, curry(composable, makeComposable)];
}));
// note: this === Pattern.prototypetgh6z
this.patternified.forEach((prop) => {
// the following will patternify all functions in Pattern.prototype.patternified
+33
View File
@@ -3,6 +3,39 @@
This package contains the strudel code transformer and evaluator.
It allows creating strudel patterns from input code that is optimized for minimal keystrokes and human readability.
## Install
```sh
npm i @strudel.cycles/eval --save
```
## Example
```js
import { evaluate, extend } from '@strudel.cycles/eval';
import * as strudel from '@strudel.cycles/core';
extend(strudel); // add strudel to eval scope
async function run(code) {
const { pattern } = await evaluate(code);
const events = pattern.firstCycle();
console.log(events.map((e) => e.show()).join('\n'));
}
run('sequence([a3, [b3, c4]])');
```
yields:
```js
(0/1 -> 1/2, 0/1 -> 1/2, a3)
(1/2 -> 3/4, 1/2 -> 3/4, b3)
(3/4 -> 1/1, 3/4 -> 1/1, c4)
```
[play with @strudel.cycles/eval on codesandbox](https://codesandbox.io/s/strudel-eval-example-ndz1d8?file=/src/index.js)
## Dev Notes
shift-traverser is currently monkey patched because its package.json uses estraverse@^4.2.0,
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@strudel.cycles/eval",
"version": "0.0.1",
"version": "0.0.2",
"lockfileVersion": 2,
"requires": true,
"packages": {
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "@strudel.cycles/eval",
"version": "0.0.1",
"version": "0.0.2",
"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.1",
"@strudel.cycles/core": "^0.0.2",
"estraverse": "^5.3.0",
"shift-ast": "^6.1.0",
"shift-codegen": "^7.0.3",
+6
View File
@@ -1,3 +1,9 @@
# @strudel.cycles/midi
This package adds midi functionality to strudel Patterns.
## Install
```sh
npm i @strudel.cycles/midi --save
```
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@strudel.cycles/midi",
"version": "0.0.1",
"version": "0.0.2",
"lockfileVersion": 2,
"requires": true,
"packages": {
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "@strudel.cycles/midi",
"version": "0.0.1",
"version": "0.0.2",
"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.1",
"@strudel.cycles/tone": "^0.0.2",
"tone": "^14.7.77",
"webmidi": "^2.5.2"
}
+34
View File
@@ -1,3 +1,37 @@
# @strudel.cycles/mini
This package contains the mini notation parser and pattern generator.
## Install
```sh
npm i @strudel.cycles/mini --save
```
## Example
```js
import { mini } from '@strudel.cycles/mini';
const pattern = mini('a [b c*2]');
const events = pattern.firstCycle().map((e) => e.show());
console.log(events);
document.getElementById('app').innerHTML = events.join('<br/>');
```
yields:
```log
(0/1 -> 1/2, 0/1 -> 1/2, a)
(1/2 -> 3/4, 1/2 -> 3/4, b)
(3/4 -> 7/8, 3/4 -> 7/8, c)
(7/8 -> 1/1, 7/8 -> 1/1, c)
```
[Play with @strudel.cycles/mini codesandbox](https://codesandbox.io/s/strudel-mini-example-oe9wcu?file=/src/index.js)
## Mini Notation API
See "Mini Notation" in the [Strudel Tutorial](https://strudel.tidalcycles.org/tutorial/)
+3 -3
View File
@@ -1,6 +1,6 @@
{
"name": "@strudel.cycles/mini",
"version": "0.0.1",
"version": "0.0.2",
"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.1",
"@strudel.cycles/tone": "^0.0.1"
"@strudel.cycles/eval": "^0.0.2",
"@strudel.cycles/tone": "^0.0.2"
}
}
+31
View File
@@ -1,3 +1,34 @@
# @strudel.cycles/tonal
This package adds tonal / harmonic functions to strudel Patterns.
## Install
```sh
npm i @strudel.cycles/tonal --save
```
## Example
```js
import { sequence } from '@strudel.cycles/core';
import '@strudel.cycles/tonal';
const pattern = sequence(0, [1, 2]).scale('C major');
const events = pattern.firstCycle().map((e) => e.show());
```
yields:
```js
(0/1 -> 1/2, 0/1 -> 1/2, C3)
(1/2 -> 3/4, 1/2 -> 3/4, D3)
(3/4 -> 1/1, 3/4 -> 1/1, E3)
```
[play with @strudel.cycles/tonal codesandbox](https://codesandbox.io/s/strudel-tonal-example-rgc5if?file=/src/index.js)
## Tonal API
See "Tonal API" in the [Strudel Tutorial](https://strudel.tidalcycles.org/tutorial/)
+2756
View File
File diff suppressed because it is too large Load Diff
+4 -2
View File
@@ -1,6 +1,6 @@
{
"name": "@strudel.cycles/tonal",
"version": "0.0.1",
"version": "0.0.2",
"description": "Tonal functions for strudel",
"main": "tonal.mjs",
"type": "module",
@@ -25,6 +25,8 @@
},
"homepage": "https://github.com/tidalcycles/strudel#readme",
"dependencies": {
"@strudel.cycles/core": "^0.0.1"
"@strudel.cycles/core": "^0.0.2",
"@tonaljs/tonal": "^4.6.5",
"webmidi": "^3.0.15"
}
}
+1 -3
View File
@@ -1,9 +1,7 @@
import { Note, Interval, Scale } from '@tonaljs/tonal';
import { Pattern as _Pattern } from '@strudel.cycles/core/strudel.mjs';
import { Pattern } from '@strudel.cycles/core';
import { mod } from '@strudel.cycles/core/util.mjs';
const Pattern = _Pattern; // as any;
// transpose note inside scale by offset steps
// function scaleTranspose(scale: string, offset: number, note: string) {
export function scaleTranspose(scale, offset, note) {
+6
View File
@@ -2,6 +2,12 @@
This package adds Tone.js functions to strudel Patterns.
## Install
```sh
npm i @strudel.cycles/tone --save
```
## Dev Notes
- `@tonejs/piano` has peer dependency on `webmidi@^2.5.1`! A newer version of webmidi will break.
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@strudel.cycles/tone",
"version": "0.0.1",
"version": "0.0.2",
"lockfileVersion": 2,
"requires": true,
"packages": {
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "@strudel.cycles/tone",
"version": "0.0.1",
"version": "0.0.2",
"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.1",
"@strudel.cycles/core": "^0.0.2",
"@tonejs/piano": "^0.2.1",
"chord-voicings": "^0.0.1",
"tone": "^14.7.77"
+1 -34
View File
@@ -1,4 +1,4 @@
import { Pattern as _Pattern } from '@strudel.cycles/core';
import { Pattern } from '@strudel.cycles/core';
import * as _Tone from 'tone';
// import Tone from here, to make sure to get the same AudioContext
@@ -41,11 +41,8 @@ defaultSynth.set({
// what about
// https://www.charlie-roberts.com/gibberish/playground/
const Pattern = _Pattern;
// with this function, you can play the pattern with any tone synth
Pattern.prototype.tone = function (instrument) {
// instrument.toDestination();
return this._withEvent((event) => {
const onTrigger = (time, event) => {
let note;
@@ -74,36 +71,6 @@ Pattern.prototype.tone = function (instrument) {
note = getPlayableNoteValue(event);
instrument.triggerAttackRelease(note, event.duration, time, velocity);
}
/* switch (instrument.constructor.name) {
case 'PluckSynth':
note = getPlayableNoteValue(event);
instrument.triggerAttack(note, time);
break;
case 'NoiseSynth':
instrument.triggerAttackRelease(event.duration, time); // noise has no value
break;
case 'Piano':
note = getPlayableNoteValue(event);
instrument.keyDown({ note, time, velocity });
instrument.keyUp({ note, time: time + event.duration, velocity });
break;
case 'Sampler':
note = getPlayableNoteValue(event);
instrument.triggerAttackRelease(note, event.duration, time, velocity);
break;
case 'Players':
if (!instrument.has(event.value)) {
throw new Error(`name "${event.value}" not defined for players`);
}
const player = instrument.player(event.value);
// velocity ?
player.start(time);
player.stop(time + event.duration);
break;
default:
note = getPlayableNoteValue(event);
instrument.triggerAttackRelease(note, event.duration, time, velocity);
} */
};
return event.setContext({ ...event.context, instrument, onTrigger });
});
+6
View File
@@ -1,3 +1,9 @@
# @strudel.cycles/xen
This package adds xenharmonic / microtonal functions to strudel Patterns.
## Install
```sh
npm i @strudel.cycles/xen --save
```
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "@strudel.cycles/xen",
"version": "0.0.1",
"version": "0.0.2",
"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.1"
"@strudel.cycles/core": "^0.0.2"
}
}
+27 -1
View File
@@ -1,6 +1,32 @@
# Strudel REPL
TBD
This is the REPL for Strudel. REPL stands for
- Read
- Evaluate
- Play!
- Loop
The REPL is deployed at [strudel.tidalcycles.org](https://strudel.tidalcycles.org/).
## Run REPL locally
```bash
# from project root
npm install
npx lerna bootstrap
cd repl
npm install
npm run start
```
## Build REPL
```bash
cd repl
npm run build # <- builds repl + tutorial to ../docs
npm run static # <- test static build
```
## Dev Notes
+2 -8
View File
@@ -42,16 +42,10 @@ function useCycle(props) {
?.filter((event) => event.part.begin.equals(event.whole.begin))
.forEach((event) => {
Tone.getTransport().schedule((time) => {
const toneEvent = {
time: event.whole.begin.valueOf(),
duration: event.whole.end.sub(event.whole.begin).valueOf(),
value: event.value,
context: event.context,
};
onEvent(time, toneEvent);
onEvent(time, event);
Tone.Draw.schedule(() => {
// do drawing or DOM manipulation here
onDraw?.(time, toneEvent);
onDraw?.(time, event);
}, time);
}, event.part.begin.valueOf());
});