* add and simplify control aliases, fixes#496
* roomsize now alias of room
* simplify webaudio param handling
---------
Co-authored-by: Felix Roos <flix91@gmail.com>
Summary of changes:
- Made unary functions composable, including controls. So e.g. s("bd sd").every(3,fast(2).iter(4).n(4)) works the same as s("bd sd").every(3,x => x.fast(2).iter(4).n(4))
- Made operators/alignments composable too, so s("bd sd").every(3, set.squeeze.n(3, 4)) works
- Patterns are not treated as functions, so s("bd sd").every(3, n(5)) is an annoying runtime error. s("bd sd").every(3, set.n(5)) does work though.
Other minor changes:
- standardised alignment 'squeezeOut' as lowercase 'squeezeout'
- made firstCycleValues turn haps sorted in order of 'part'
* port Rohan Drape's Bjorklund implementation, add Toussaint's tests
* fix euclidLegato, simplifying a bit now that bjork results should always begin with an 'on'
* migrate euclid numbers in tunes
- 3,4 +1
- 5,8 -1
- 6,8 +3
Co-authored-by: Felix Roos <flix91@gmail.com>
* patternify the mininotation bjorklund, and fast (*) slow (/) and pattern step (%) parameters
* simplify replicate (!), should be closer to tidal now
* highlight atoms rather than elements
* tests
* rename parser stuff to be more explicit and fit with tidal concepts. qualify all strudel function calls
* Add {,}%n polymeter support, with a few tests
'toplevel first' regime
* loopAt has its optional cps parameter removed, with loopAtCps added for supporting that usage.
* rename bitlevel operations e.g. _and -> band
Co-authored-by: Felix Roos <flix91@gmail.com>
* remove _ prefixes except for functions to be patternified
* categorise pattern methods
* experimental support for `.add.squeeze` and friends as alternative to `.addSqueeze`
* `every` is now an alias for `firstOf` with additional `lastOf` (which every will become an alias for next)
This avoids (without fixing) #184).
Note that the offset in tidal is currently 0.0001, but using this
would result in excess correlation between sequential uses of
random, which would manifest in failure of the 'supports the randome
choice operator with nesting' test. So I just used 0.0002 instead
The tests are probabilistic, so it is possible that if the
pseudo-random number generator changes in the future, we might
get results that fail. They work for the current PRNG, though,
and use boundaries for the number of values of different types
such that there should only be about a 1% probability that the
tests would fail by chance assuming that the PRNG returns
evenly distributed values.
This would no longer match with Tidal (which uses
0.0001), but reduces the correlation among the
the different random streams in the mini-notation's
parsing of ? and |
- samples with obejct format for pitch declaration
- support note to repitch samples
- support choke to fit samples to hap duration
- support "legacy" context.velocity in .out
- support ":" inside s or note to set n
- fix sample fadeout for soundfonts and choke
- move gain before filters
2. open command palette and run "Format Document With..."
3. Choose "Configure Default Formatter..."
4. Select prettier
## ESLint
To prevent unwanted runtime errors, this project uses [eslint](https://eslint.org/).
- You can check for lint errors by running `pnpm lint`
There are also eslint extensions / plugins for most editors.
## Running Tests
- Run all tests with `pnpm test`
- Run all tests with UI using `pnpm test-ui`
## Running all CI Checks
When opening a PR, the CI runner will automatically check the code style and eslint, as well as run all tests.
You can run the same check with `pnpm check`
## Package Workflow
The project is split into multiple [packages](https://github.com/tidalcycles/strudel/tree/main/packages) with independent versioning.
When you run `pnpm i` on the root folder, [pnpm workspaces](https://pnpm.io/workspaces) will install all dependencies of all subpackages. This will allow any js file to import `@strudel.cycles/<package-name>` to get the local version,
allowing to develop multiple packages at the same time.
## Package Publishing
To publish all packages that have been changed since the last release, run:
```sh
npm login
npx lerna publish
```
To manually publish a single package, increase the version in the `package.json`, then run `pnpm publish`.
Important: Always publish with `pnpm`, as `npm` does not support overriding main files in `publishConfig`, which is done in all the packages.
### New Packages
To add a new package, you have to publish it manually the first time, using:
```sh
cd packages/<package-name> && pnpm publish --access public
```
## Have Fun
Remember to have fun, and that this project is driven by the passion of volunteers!
[](https://github.com/tidalcycles/strudel/actions)
An experiment in making a [Tidal](https://github.com/tidalcycles/tidal/) using web technologies. This is unstable software, please tread carefully.
An experiment in making a [Tidal](https://github.com/tidalcycles/tidal/) using web technologies. This software is slowly stabilising, but please continue to tread carefully.
Try it here: https://strudel.tidalcycles.org/
-Try it here: <https://strudel.tidalcycles.org/>
- Docs: <https://strudel.tidalcycles.org/learn/>
- Technical Blog Post: <https://loophole-letters.vercel.app/strudel>
- 1 Year of Strudel Blog Post: <https://loophole-letters.vercel.app/strudel1year>
This will publish all packages that changed since the last version.
Click on the package names to find out more about each one.
## Style
## Contributing
For now, please try to copy the style of surrounding code. VS Code users can install the 'prettier' add-on which will use the .prettierrc configuration file for automatic formatting.
There are many ways to contribute to this project! See [contribution guide](./CONTRIBUTING.md).
<!doctype html><htmllang="en"><head><metacharset="utf-8"/><linkrel="icon"href="/favicon.ico"/><metaname="viewport"content="width=device-width,initial-scale=1"/><metaname="theme-color"content="#000000"/><metaname="description"content="Strudel REPL"/><title>Strudel REPL</title><scriptdefer="defer"src="/static/js/main.77e38ada.js"></script><linkhref="/static/css/main.0d689283.css"rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><divid="root"></div></body></html>
<!DOCTYPE html><htmllang="en"><head><metacharset="utf-8"><linkrel="icon"href="/tutorial/favicon.e3ab9dd9.ico"><linkrel="stylesheet"type="text/css"href="/tutorial/index.999678aa.css"><metaname="viewport"content="width=device-width, initial-scale=1"><metaname="description"content="Strudel REPL"><title>Strudel Tutorial</title></head><body><divid="root"></div><noscript>You need to enable JavaScript to run this app.</noscript><scriptsrc="/tutorial/index.097d520a.js"defer></script></body></html>
- go to settings -> pages and select "Github Actions" as source
- go to settings -> environments -> github-pages and press the edit button next to `main` and type in `patternuary` (under "Deployment branches")
- go to Actions -> `Build and Deploy` and click `Run workflow` with branch `patternuary`
### 9. view your patterns at `<your-username>.github.io/strudel/swatch/`
Alternatively, github pages allows you to use a custom domain, like https://mycooldomain.org/swatch/. [See their documentation for details](https://docs.github.com/en/pages/configuring-a-custom-domain-for-your-github-pages-site).
### 10. optional: automatic deployment
If you want to automatically deploy your site on push, go to `deploy.yml` and change `workflow_dispatch` to `push`.
## running locally
- install dependencies with `npm run setup`
- run dev server with `npm run repl` and open `http://localhost:3000/strudel/swatch/`
## tests fail?
Your tests might fail if the code does not follow prettiers format.
In that case, run `npm run codeformat`. To disable that, remove `npm run format-check` from `test.yml`
## updating your fork
To update your fork, you can pull the main branch and merge it into your `patternuary` branch.
Each folder represents one of the @strudel.cycles/* packages [published to npm](https://www.npmjs.com/org/strudel.cycles).
To understand how those pieces connect, refer to the [Technical Manual](https://github.com/tidalcycles/strudel/wiki/Technical-Manual) or the individual READMEs.
This is a graphical view of all the packages: [full screen](https://raw.githubusercontent.com/tidalcycles/strudel/main/dependencies.svg)
Copyright (C) 2022 Strudel contributors - see <https://github.com/tidalcycles/strudel/blob/main/packages/core/controls.mjs>
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import{Pattern,sequence}from'./pattern.mjs';
constcontrols={};
constgeneric_params=[
/**
* Select a sound / sample by name.
*
* @name s
* @param {string | Pattern} sound The sound / pattern of sounds to pick
* @synonyms sound
* @example
* s("bd hh")
*
*/
['s','sound'],
/**
* Selects the given index from the sample map.
* Numbers too high will wrap around.
* `n` can also be used to play midi numbers, but it is recommended to use `note` instead.
*
* @name n
* @param {number | Pattern} value sample index starting from 0
* @example
* s("bd sd,hh*3").n("<0 1>")
*/
// also see https://github.com/tidalcycles/strudel/pull/63
['n'],
/**
* Plays the given note name or midi number. A note name consists of
* fake-resampling for lowering the sample rate. Caution: This effect seems to only work in chromium based browsers
*
* @name coarse
* @param {number | Pattern} factor 1 for original 2 for half, 3 for a third and so on.
* @example
* s("bd sd,hh*4").coarse("<1 4 8 16 32>")
*
*/
['coarse'],
/**
* choose the channel the pattern is sent to in superdirt
*
* @name channel
* @param {number | Pattern} channel channel number
*
*/
['channel'],
/**
* In the style of classic drum-machines, `cut` will stop a playing sample as soon as another samples with in same cutgroup is to be played. An example would be an open hi-hat followed by a closed one, essentially muting the open.
*
* @name cut
* @param {number | Pattern} group cut group number
* @example
* s("rd*4").cut(1)
*
*/
['cut'],
/**
* Applies the cutoff frequency of the **l**ow-**p**ass **f**ilter.
*
* @name lpf
* @param {number | Pattern} frequency audible between 0 and 20000
* Specifies whether delaytime is calculated relative to cps.
*
* @name lock
* @param {number | Pattern} enable When set to 1, delaytime is a direct multiple of a cycle.
* @example
* s("sd").delay().lock(1).osc()
*
*/
['lock'],
/**
* Set detune of oscillators. Works only with some synths, see <a target="_blank" href="https://tidalcycles.org/docs/patternlib/tutorials/synthesizers">tidal doc</a>
*
* @name detune
* @param {number | Pattern} amount between 0 and 1
// .. does not work. Is it because room is only one effect?
['size','sz','roomsize'],
// ['sagogo'],
// ['sclap'],
// ['sclaves'],
// ['scrash'],
/**
* Wave shaping distortion. CAUTION: it might get loud
*
* @name shape
* @param {number | Pattern} distortion between 0 and 1
* @example
* s("bd sd,hh*4").shape("<0 .2 .4 .6 .8>")
*
*/
['shape'],
/**
* Changes the speed of sample playback, i.e. a cheap way of changing pitch.
*
* @name speed
* @param {number | Pattern} speed -inf to inf, negative numbers play the sample backwards.
* @example
* s("bd").speed("<1 2 4 1 -2 -4>")
* @example
* speed("1 1.5*2 [2 1.1]").s("piano").clip(1)
*
*/
['speed'],
/**
* Used in conjunction with {@link speed}, accepts values of "r" (rate, default behavior), "c" (cycles), or "s" (seconds). Using `unit "c"` means `speed` will be interpreted in units of cycles, e.g. `speed "1"` means samples will be stretched to fill a cycle. Using `unit "s"` means the playback speed will be adjusted so that the duration is the number of seconds specified by `speed`.
*
* @name unit
* @param {number | string | Pattern} unit see description above
* @example
* speed("1 2 .5 3").s("bd").unit("c").osc()
* @superdirtOnly
*
*/
['unit'],
/**
* Made by Calum Gunn. Reminiscent of some weird mixture of filter, ring-modulator and pitch-shifter. The SuperCollider manual defines Squiz as:
*
* "A simplistic pitch-raising algorithm. It's not meant to sound natural; its sound is reminiscent of some weird mixture of filter, ring-modulator and pitch-shifter, depending on the input. The algorithm works by cutting the signal into fragments (delimited by upwards-going zero-crossings) and squeezing those fragments in the time domain (i.e. simply playing them back faster than they came in), leaving silences inbetween. All the parameters apart from memlen can be modulated."
*
* @name squiz
* @param {number | Pattern} squiz Try passing multiples of 2 to it - 2, 4, 8 etc.
* @example
* squiz("2 4/2 6 [8 16]").s("bd").osc()
* @superdirtOnly
*
*/
['squiz'],
// ['stutterdepth'], // TODO: what is this? not found in tidal doc
// ['stuttertime'], // TODO: what is this? not found in tidal doc
// ['timescale'], // TODO: what is this? not found in tidal doc
// ['timescalewin'], // TODO: what is this? not found in tidal doc
// ['tomdecay'],
// ['vcfegint'],
// ['vcoegint'],
// TODO: Use a rest (~) to override the effect <- vowel
/**
*
* Formant filter to make things sound like vowels.
*
* @name vowel
* @param {string | Pattern} vowel You can use a e i o u.
* @example
* note("c2 <eb2 <g2 g1>>").s('sawtooth')
* .vowel("<a e i <o u>>")
*
*/
['vowel'],
/* // TODO: find out how it works
* Made by Calum Gunn. Divides an audio stream into tiny segments, using the signal's zero-crossings as segment boundaries, and discards a fraction of them. Takes a number between 1 and 100, denoted the percentage of segments to drop. The SuperCollider manual describes the Waveloss effect this way:
*
* Divide an audio stream into tiny segments, using the signal's zero-crossings as segment boundaries, and discard a fraction of them (i.e. replace them with silence of the same length). The technique was described by Trevor Wishart in a lecture. Parameters: the filter drops drop out of out of chunks. mode can be 1 to drop chunks in a simple deterministic fashion (e.g. always dropping the first 30 out of a set of 40 segments), or 2 to drop chunks randomly but in an appropriate proportion.)
*
* mode: ?
* waveloss: ?
*
* @name waveloss
*/
['waveloss'],
// TODO: midi effects?
['dur'],
// ['modwheel'],
['expression'],
['sustainpedal'],
/* // TODO: doesn't seem to do anything
*
* Tremolo Audio DSP effect
*
* @name tremolodepth
* @param {number | Pattern} depth between 0 and 1
* @example
* n("0,4,7").tremolodepth("<0 .3 .6 .9>").osc()
*
*/
['tremolodepth','tremdp'],
['tremolorate','tremr'],
// TODO: doesn't seem to do anything
['phaserdepth','phasdp'],
['phaserrate','phasr'],
['fshift'],
['fshiftnote'],
['fshiftphase'],
['triode'],
['krush'],
['kcutoff'],
['octer'],
['octersub'],
['octersubsub'],
['ring'],
['ringf'],
['ringdf'],
['distort'],
['freeze'],
['xsdelay'],
['tsdelay'],
['real'],
['imag'],
['enhance'],
['partials'],
['comb'],
['smear'],
['scram'],
['binshift'],
['hbrick'],
['lbrick'],
['midichan'],
['control'],
['ccn'],
['ccv'],
['polyTouch'],
['midibend'],
['miditouch'],
['ctlNum'],
['frameRate'],
['frames'],
['hours'],
['midicmd'],
['minutes'],
['progNum'],
['seconds'],
['songPtr'],
['uid'],
['val'],
['cps'],
/**
* If set to 1, samples will be cut to the duration of their event.
* In tidal, this would be done with legato, which [is about to land in strudel too](https://github.com/tidalcycles/strudel/issues/111)
Copyright (C) 2022 Strudel contributors - see <https://github.com/tidalcycles/strudel/blob/main/packages/core/cyclist.mjs>
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
Copyright (C) 2022 Strudel contributors - see <https://github.com/tidalcycles/strudel/blob/main/packages/tone/draw.mjs>
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
Copyright (C) 2022 Strudel contributors - see <https://github.com/tidalcycles/strudel/blob/main/packages/core/drawLine.mjs>
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
importFraction,{gcd}from'./fraction.mjs';
/**
* Intended for a debugging, drawLine renders the pattern as a string, where each character represents the same time span.
* Should only be used with single characters as values, otherwise the character slots will be messed up.
* Character legend:
*
* - "|" cycle separator
* - "-" hold previous value
* - "." silence
*
* @param {Pattern} pattern the pattern to use
* @param {number} chars max number of characters (approximately)
Copyright (C) 2023 Rohan Drape and strudel contributors
See <https://github.com/tidalcycles/strudel/blob/main/packages/core/euclid.mjs> for authors of this file.
The Bjorklund algorithm implementation is ported from the Haskell Music Theory Haskell module by Rohan Drape -
https://rohandrape.net/?t=hmt
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
Copyright (C) 2022 Strudel contributors - see <https://github.com/tidalcycles/strudel/blob/main/packages/eval/evaluate.mjs>
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
This folder demonstrates how to set up a strudel repl using vite and vanilla JS. Run it using:
```sh
npm i
npm run dev
```
or view it [live on githack](https://rawcdn.githack.com/tidalcycles/strudel/5fb36acb046ead7cd6ad3cd10f532e7f585f536a/packages/core/examples/vite-vanilla-repl/dist/index.html)
Copyright (C) 2022 Strudel contributors - see <https://github.com/tidalcycles/strudel/blob/main/packages/core/fraction.mjs>
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
importFractionfrom'fraction.js';
import{TimeSpan}from'./strudel.mjs';
import{TimeSpan}from'./timespan.mjs';
// Returns the start of the cycle.
Fraction.prototype.sam=function(){
@@ -16,6 +22,11 @@ Fraction.prototype.wholeCycle = function () {
returnnewTimeSpan(this.sam(),this.nextSam());
};
// The position of a time value relative to the start of its cycle.
Fraction.prototype.cyclePos=function(){
returnthis.sub(this.sam());
};
Fraction.prototype.lt=function(other){
returnthis.compare(other)<0;
};
@@ -44,7 +55,8 @@ Fraction.prototype.min = function (other) {
Copyright (C) 2022 Strudel contributors - see <https://github.com/tidalcycles/strudel/blob/main/packages/core/gist.js>
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
// this is a shortcut to eval code from a gist
// why? to be able to shorten strudel code + e.g. be able to change instruments after links have been generated
Copyright (C) 2022 Strudel contributors - see <https://github.com/tidalcycles/strudel/blob/main/packages/core/hap.mjs>
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
exportclassHap{
/*
Event class, representing a value active during the timespan
'part'. This might be a fragment of an event, in which case the
timespan will be smaller than the 'whole' timespan, otherwise the
two timespans will be the same. The 'part' must never extend outside of the
'whole'. If the event represents a continuously changing value
then the whole will be returned as None, in which case the given
value will have been sampled from the point halfway between the
start and end of the 'part' timespan.
The context is to store a list of source code locations causing the event.
The word 'Event' is more or less a reserved word in javascript, hence this
Copyright (C) 2022 Strudel contributors - see <https://github.com/tidalcycles/strudel/blob/main/packages/core/index.mjs>
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
importcontrolsfrom'./controls.mjs';
export*from'./euclid.mjs';
importFractionfrom'./fraction.mjs';
import{logger}from'./logger.mjs';
export{Fraction,controls};
export*from'./hap.mjs';
export*from'./pattern.mjs';
export*from'./signal.mjs';
export*from'./state.mjs';
export*from'./timespan.mjs';
export*from'./util.mjs';
export*from'./speak.mjs';
export*from'./evaluate.mjs';
export*from'./repl.mjs';
export*from'./logger.mjs';
export*from'./time.mjs';
export*from'./draw.mjs';
export*from'./animate.mjs';
export*from'./pianoroll.mjs';
export*from'./ui.mjs';
export{defaultasdrawLine}from'./drawLine.mjs';
export{defaultasgist}from'./gist.js';
// below won't work with runtime.mjs (json import fails)
/* import * as p from './package.json';
export const version = p.version; */
logger('🌀 @strudel.cycles/core loaded 🌀');
if(globalThis._strudelLoaded){
console.warn(
`@strudel.cycles/core was loaded more than once...
This might happen when you have multiple versions of strudel installed.
Please check with "npm ls @strudel.cycles/core".`,
Copyright (C) 2022 Strudel contributors - see <https://github.com/tidalcycles/strudel/blob/main/packages/tone/pianoroll.mjs>
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
Copyright (C) 2022 Strudel contributors - see <https://github.com/tidalcycles/strudel/blob/main/packages/core/signal.mjs>
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
Copyright (C) 2022 Strudel contributors - see <https://github.com/tidalcycles/strudel/blob/main/packages/core/speak.mjs>
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import{register}from'./index.mjs';
letsynth;
try{
synth=window?.speechSynthesis;
}catch(err){
console.warn('cannot use window: not in browser?');
Copyright (C) 2022 Strudel contributors - see <https://github.com/tidalcycles/strudel/blob/main/packages/core/state.mjs>
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
Copyright (C) 2022 Strudel contributors - see <https://github.com/tidalcycles/strudel/blob/main/packages/core/test/drawLine.test.mjs>
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
Copyright (C) 2022 Strudel contributors - see <https://github.com/tidalcycles/strudel/blob/main/packages/core/test/fraction.test.mjs>
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
Copyright (C) 2022 Strudel contributors - see <https://github.com/tidalcycles/strudel/blob/main/packages/core/test/util.test.mjs>
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import{pure}from'../pattern.mjs';
import{
isNote,
tokenizeNote,
toMidi,
fromMidi,
freqToMidi,
_mod,
compose,
getFrequency,
getPlayableNoteValue,
parseNumeral,
parseFractional,
numeralArgs,
fractionalArgs,
}from'../util.mjs';
import{describe,it,expect}from'vitest';
describe('isNote',()=>{
it('should recognize notes without accidentals',()=>{
Copyright (C) 2022 Strudel contributors - see <https://github.com/tidalcycles/strudel/blob/main/packages/core/test/value.test.mjs>
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
Copyright (C) 2022 Strudel contributors - see <https://github.com/tidalcycles/strudel/blob/main/packages/core/timespan.mjs>
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
importFractionfrom'./fraction.mjs';
exportclassTimeSpan{
constructor(begin,end){
this.begin=Fraction(begin);
this.end=Fraction(end);
}
getspanCycles(){
constspans=[];
varbegin=this.begin;
constend=this.end;
constend_sam=end.sam();
// Support zero-width timespans
if(begin.equals(end)){
return[newTimeSpan(begin,end)];
}
while(end.gt(begin)){
// If begin and end are in the same cycle, we're done.
if(begin.sam().equals(end_sam)){
spans.push(newTimeSpan(begin,this.end));
break;
}
// add a timespan up to the next sam
constnext_begin=begin.nextSam();
spans.push(newTimeSpan(begin,next_begin));
// continue with the next cycle
begin=next_begin;
}
returnspans;
}
getduration(){
returnthis.end.sub(this.begin);
}
cycleArc(){
// Shifts a timespan to one of equal duration that starts within cycle zero.
// (Note that the output timespan probably does not start *at* Time 0 --
// that only happens when the input Arc starts at an integral Time.)
constb=this.begin.cyclePos();
conste=b.add(this.duration);
returnnewTimeSpan(b,e);
}
withTime(func_time){
// Applies given function to both the begin and end time of the timespan"""
Copyright (C) 2022 Strudel contributors - see <https://github.com/tidalcycles/strudel/blob/main/packages/core/util.mjs>
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
Copyright (C) 2022 Strudel contributors - see <https://github.com/tidalcycles/strudel/blob/main/packages/core/value.mjs>
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
Copyright (C) 2022 Strudel contributors - see <https://github.com/tidalcycles/strudel/blob/main/packages/eval/evaluate.mjs>
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
// TODO: find a way to make args available to eval without adding it to global scope...
// sadly, "with" does not work in strict mode
Object.assign(globalThis,...args);
};
exportconstevaluate=async(code)=>{
constshapeshifted=shapeshifter(code);// transform syntactically correct js code to semantically usable code
letevaluated=awaiteval(shapeshifted);
if(!isPattern(evaluated)){
console.log('evaluated',evaluated);
constmessage=`got "${typeofevaluated}" instead of pattern`;
thrownewError(message+(typeofevaluated==='function'?', did you forget to call a function?':'.'));
}
return{mode:'javascript',pattern:evaluated};
return_evaluate(code,shapeshifter);
};
Some files were not shown because too many files have changed in this diff
Show More
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.