mirror of
https://codeberg.org/uzu/strudel
synced 2026-09-05 06:57:35 -04:00
export pattern.mjs as single object
This commit is contained in:
@@ -4,7 +4,8 @@ Copyright (C) 2022 Strudel contributors - see <https://github.com/tidalcycles/st
|
||||
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';
|
||||
import pattern from './pattern.mjs';
|
||||
const { Pattern, sequence } = pattern;
|
||||
|
||||
const controls = {};
|
||||
const generic_params = [
|
||||
|
||||
@@ -4,7 +4,8 @@ Copyright (C) 2022 Strudel contributors - see <https://github.com/tidalcycles/st
|
||||
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, getTime } from './index.mjs';
|
||||
import { pattern, getTime } from './index.mjs';
|
||||
const { Pattern } = pattern;
|
||||
|
||||
export const getDrawContext = (id = 'test-canvas') => {
|
||||
let canvas = document.querySelector('#' + id);
|
||||
|
||||
@@ -4,7 +4,8 @@ Copyright (C) 2022 Strudel contributors - see <https://github.com/tidalcycles/st
|
||||
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, timeCat } from './pattern.mjs';
|
||||
import pattern from './pattern.mjs';
|
||||
const { Pattern, timeCat } = pattern;
|
||||
import bjork from 'bjork';
|
||||
import { rotate } from './util.mjs';
|
||||
import Fraction from './fraction.mjs';
|
||||
|
||||
@@ -4,7 +4,8 @@ Copyright (C) 2022 Strudel contributors - see <https://github.com/tidalcycles/st
|
||||
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 { isPattern, Pattern } from './index.mjs';
|
||||
import { pattern } from './index.mjs';
|
||||
const { isPattern, Pattern } = pattern;
|
||||
|
||||
let scoped = false;
|
||||
export const evalScope = async (...args) => {
|
||||
|
||||
@@ -4,13 +4,13 @@ Copyright (C) 2022 Strudel contributors - see <https://github.com/tidalcycles/st
|
||||
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 from './pattern.mjs';
|
||||
import controls from './controls.mjs';
|
||||
export * from './euclid.mjs';
|
||||
import Fraction from './fraction.mjs';
|
||||
import { logger } from './logger.mjs';
|
||||
export { Fraction, controls };
|
||||
export { Fraction, controls, pattern };
|
||||
export * from './hap.mjs';
|
||||
export * from './pattern.mjs';
|
||||
export * from './signal.mjs';
|
||||
export * from './state.mjs';
|
||||
export * from './timespan.mjs';
|
||||
|
||||
+82
-59
@@ -14,14 +14,18 @@ import { compose, removeUndefineds, flatten, id, listRange, curry, mod, numeralA
|
||||
import drawLine from './drawLine.mjs';
|
||||
import { logger } from './logger.mjs';
|
||||
|
||||
// monster object collecting everything to be exported
|
||||
const pattern = {};
|
||||
|
||||
let stringParser;
|
||||
|
||||
// parser is expected to turn a string into a pattern
|
||||
// if set, the reify function will parse all strings with it
|
||||
// intended to use with mini to automatically interpret all strings as mini notation
|
||||
export const setStringParser = (parser) => (stringParser = parser);
|
||||
pattern['setStringParser'] = (parser) => (stringParser = parser);
|
||||
|
||||
/** @class Class representing a pattern. */
|
||||
export class Pattern {
|
||||
class Pattern {
|
||||
_Pattern = true; // this property is used to detect if a pattern that fails instanceof Pattern is an instance of another Pattern
|
||||
/**
|
||||
* Create a pattern. As an end user, you will most likely not create a Pattern directly.
|
||||
@@ -1366,6 +1370,8 @@ export class Pattern {
|
||||
|
||||
}
|
||||
|
||||
pattern['Pattern'] = Pattern;
|
||||
|
||||
// TODO - adopt value.mjs fully..
|
||||
function _composeOp(a, b, func) {
|
||||
function _nonFunctionObject(x) {
|
||||
@@ -1550,10 +1556,6 @@ Pattern.prototype.patternified = [
|
||||
'velocity',
|
||||
];
|
||||
|
||||
// aliases
|
||||
export const polyrhythm = stack;
|
||||
export const pr = stack;
|
||||
|
||||
// methods that create patterns, which are added to patternified Pattern methods
|
||||
Pattern.prototype.factories = {
|
||||
pure,
|
||||
@@ -1574,7 +1576,8 @@ Pattern.prototype.factories = {
|
||||
// Elemental patterns
|
||||
|
||||
// Nothing
|
||||
export const silence = new Pattern((_) => []);
|
||||
const silence = new Pattern((_) => []);
|
||||
pattern['silence'] = silence;
|
||||
|
||||
/** A discrete value that repeats once per cycle.
|
||||
*
|
||||
@@ -1582,14 +1585,15 @@ export const silence = new Pattern((_) => []);
|
||||
* @example
|
||||
* pure('e4') // "e4"
|
||||
*/
|
||||
export function pure(value) {
|
||||
function pure(value) {
|
||||
function query(state) {
|
||||
return state.span.spanCycles.map((subspan) => new Hap(Fraction(subspan.begin).wholeCycle(), subspan, value));
|
||||
}
|
||||
return new Pattern(query);
|
||||
}
|
||||
pattern['pure'] = pure;
|
||||
|
||||
export function isPattern(thing) {
|
||||
function isPattern(thing) {
|
||||
// thing?.constructor?.name !== 'Pattern' // <- this will fail when code is mangled
|
||||
const is = thing instanceof Pattern || thing?._Pattern;
|
||||
if (!thing instanceof Pattern) {
|
||||
@@ -1601,8 +1605,9 @@ export function isPattern(thing) {
|
||||
}
|
||||
return is;
|
||||
}
|
||||
pattern['isPattern'] = isPattern;
|
||||
|
||||
export function reify(thing) {
|
||||
function reify(thing) {
|
||||
// Turns something into a pattern, unless it's already a pattern
|
||||
if (isPattern(thing)) {
|
||||
return thing;
|
||||
@@ -1612,6 +1617,7 @@ export function reify(thing) {
|
||||
}
|
||||
return pure(thing);
|
||||
}
|
||||
pattern['reify'] = reify;
|
||||
|
||||
/** The given items are played at the same time at the same length.
|
||||
*
|
||||
@@ -1619,12 +1625,20 @@ export function reify(thing) {
|
||||
* @example
|
||||
* stack(g3, b3, [e4, d4]).note() // "g3,b3,[e4,d4]".note()
|
||||
*/
|
||||
export function stack(...pats) {
|
||||
function stack(...pats) {
|
||||
// Array test here is to avoid infinite recursions..
|
||||
pats = pats.map((pat) => (Array.isArray(pat) ? sequence(...pat) : reify(pat)));
|
||||
const query = (state) => flatten(pats.map((pat) => pat.query(state)));
|
||||
return new Pattern(query);
|
||||
}
|
||||
pattern['stack'] = stack;
|
||||
function polyrhythm(...pats) {
|
||||
return stack(...pats);
|
||||
}
|
||||
function pr(...pats) {
|
||||
return stack(...pats);
|
||||
}
|
||||
pattern['pr'] = pattern['polyrhythm'] = pattern['stack'];
|
||||
|
||||
/** Concatenation: combines a list of patterns, switching between them successively, one per cycle:
|
||||
*
|
||||
@@ -1635,7 +1649,7 @@ export function stack(...pats) {
|
||||
* slowcat(e5, b4, [d5, c5])
|
||||
*
|
||||
*/
|
||||
export function slowcat(...pats) {
|
||||
function slowcat(...pats) {
|
||||
// Array test here is to avoid infinite recursions..
|
||||
pats = pats.map((pat) => (Array.isArray(pat) ? sequence(...pat) : reify(pat)));
|
||||
|
||||
@@ -1655,12 +1669,13 @@ export function slowcat(...pats) {
|
||||
};
|
||||
return new Pattern(query).splitQueries();
|
||||
}
|
||||
pattern['slowcat'] = slowcat;
|
||||
|
||||
/** Concatenation: combines a list of patterns, switching between them successively, one per cycle. Unlike slowcat, this version will skip cycles.
|
||||
* @param {...any} items - The items to concatenate
|
||||
* @return {Pattern}
|
||||
*/
|
||||
export function slowcatPrime(...pats) {
|
||||
function slowcatPrime(...pats) {
|
||||
pats = pats.map(reify);
|
||||
const query = function (state) {
|
||||
const pat_n = Math.floor(state.span.begin) % pats.length;
|
||||
@@ -1669,6 +1684,7 @@ export function slowcatPrime(...pats) {
|
||||
};
|
||||
return new Pattern(query).splitQueries();
|
||||
}
|
||||
pattern['slowcatPrime'] = slowcatPrime;
|
||||
|
||||
/** Concatenation: as with {@link slowcat}, but squashes a cycle from each pattern into one cycle
|
||||
*
|
||||
@@ -1681,9 +1697,10 @@ export function slowcatPrime(...pats) {
|
||||
* // sequence(e5, b4, [d5, c5])
|
||||
* // seq(e5, b4, [d5, c5])
|
||||
*/
|
||||
export function fastcat(...pats) {
|
||||
function fastcat(...pats) {
|
||||
return slowcat(...pats)._fast(pats.length);
|
||||
}
|
||||
pattern['fastcat'] = fastcat;
|
||||
|
||||
/** The given items are con**cat**enated, where each one takes one cycle. Synonym: slowcat
|
||||
*
|
||||
@@ -1693,16 +1710,17 @@ export function fastcat(...pats) {
|
||||
* cat(e5, b4, [d5, c5]).note() // "<e5 b4 [d5 c5]>".note()
|
||||
*
|
||||
*/
|
||||
export function cat(...pats) {
|
||||
function cat(...pats) {
|
||||
return slowcat(...pats);
|
||||
}
|
||||
pattern['cat'] = cat;
|
||||
|
||||
/** Like {@link seq}, but each step has a length, relative to the whole.
|
||||
* @return {Pattern}
|
||||
* @example
|
||||
* timeCat([3,e3],[1, g3]).note() // "e3@3 g3".note()
|
||||
*/
|
||||
export function timeCat(...timepats) {
|
||||
function timeCat(...timepats) {
|
||||
const total = timepats.map((a) => a[0]).reduce((a, b) => a.add(b), Fraction(0));
|
||||
let begin = Fraction(0);
|
||||
const pats = [];
|
||||
@@ -1713,20 +1731,23 @@ export function timeCat(...timepats) {
|
||||
}
|
||||
return stack(...pats);
|
||||
}
|
||||
pattern['timeCat'] = timeCat;
|
||||
|
||||
/** See {@link fastcat} */
|
||||
export function sequence(...pats) {
|
||||
function sequence(...pats) {
|
||||
return fastcat(...pats);
|
||||
}
|
||||
pattern['sequence'] = sequence;
|
||||
|
||||
/** Like **cat**, but the items are crammed into one cycle. Synonyms: fastcat, sequence
|
||||
* @example
|
||||
* seq(e5, b4, [d5, c5]).note() // "e5 b4 [d5 c5]".note()
|
||||
*
|
||||
*/
|
||||
export function seq(...pats) {
|
||||
function seq(...pats) {
|
||||
return fastcat(...pats);
|
||||
}
|
||||
pattern['seq'] = seq;
|
||||
|
||||
function _sequenceCount(x) {
|
||||
if (Array.isArray(x)) {
|
||||
@@ -1741,7 +1762,7 @@ function _sequenceCount(x) {
|
||||
return [reify(x), 1];
|
||||
}
|
||||
|
||||
export function polymeterSteps(steps, ...args) {
|
||||
function polymeterSteps(steps, ...args) {
|
||||
const seqs = args.map((a) => _sequenceCount(a));
|
||||
if (seqs.length == 0) {
|
||||
return silence;
|
||||
@@ -1762,57 +1783,49 @@ export function polymeterSteps(steps, ...args) {
|
||||
}
|
||||
return stack(...pats);
|
||||
}
|
||||
pattern['polymeterSteps'] = polymeterSteps;
|
||||
|
||||
export function polymeter(...args) {
|
||||
function polymeter(...args) {
|
||||
return polymeterSteps(0, ...args);
|
||||
}
|
||||
pattern['polymeter'] = polymeter;
|
||||
|
||||
// alias
|
||||
export function pm(...args) {
|
||||
polymeter(...args);
|
||||
function pm(...args) {
|
||||
return polymeter(...args);
|
||||
}
|
||||
pattern['pm'] = polymeter;
|
||||
|
||||
// arity 1
|
||||
for (const func of ['inv', 'invert', 'rev']) {
|
||||
pattern[func] = (pat) => pat[func]();
|
||||
}
|
||||
|
||||
export const add = curry((a, pat) => pat.add(a));
|
||||
export const chop = curry((a, pat) => pat.chop(a));
|
||||
export const chunk = curry((a, pat) => pat.chunk(a));
|
||||
export const chunkBack = curry((a, pat) => pat.chunkBack(a));
|
||||
export const div = curry((a, pat) => pat.div(a));
|
||||
export const early = curry((a, pat) => pat.early(a));
|
||||
export const echo = curry((a, b, c, pat) => pat.echo(a, b, c));
|
||||
export const every = curry((i, f, pat) => pat.every(i, f));
|
||||
export const fast = curry((a, pat) => pat.fast(a));
|
||||
export const inv = (pat) => pat.inv();
|
||||
export const invert = (pat) => pat.invert();
|
||||
export const iter = curry((a, pat) => pat.iter(a));
|
||||
export const iterBack = curry((a, pat) => pat.iterBack(a));
|
||||
export const jux = curry((f, pat) => pat.jux(f));
|
||||
export const juxBy = curry((by, f, pat) => pat.juxBy(by, f));
|
||||
export const late = curry((a, pat) => pat.late(a));
|
||||
export const linger = curry((a, pat) => pat.linger(a));
|
||||
export const mask = curry((a, pat) => pat.mask(a));
|
||||
export const mul = curry((a, pat) => pat.mul(a));
|
||||
export const off = curry((t, f, pat) => pat.off(t, f));
|
||||
export const ply = curry((a, pat) => pat.ply(a));
|
||||
export const range = curry((a, b, pat) => pat.range(a, b));
|
||||
export const rangex = curry((a, b, pat) => pat.rangex(a, b));
|
||||
export const range2 = curry((a, b, pat) => pat.range2(a, b));
|
||||
export const rev = (pat) => pat.rev();
|
||||
export const slow = curry((a, pat) => pat.slow(a));
|
||||
export const struct = curry((a, pat) => pat.struct(a));
|
||||
export const sub = curry((a, pat) => pat.sub(a));
|
||||
export const superimpose = curry((array, pat) => pat.superimpose(...array));
|
||||
export const set = curry((a, pat) => pat.set(a));
|
||||
export const when = curry((binary, f, pat) => pat.when(binary, f));
|
||||
// arity 2
|
||||
for (const func of ['add','chop','chunk','chunkBack','div','early','fast','iter','iterBack','jux','late','linger',
|
||||
'mask','mul','ply','slow','struct','sub','superimpose','set']
|
||||
) {
|
||||
pattern[func] = curry((a, pat) => pat[func](a));
|
||||
}
|
||||
|
||||
// arity 3
|
||||
for (const func of ['every','juxBy','off','range','rangex','range2','when']) {
|
||||
pattern[func] = curry((a, b, pat) => pat[func](a,b));
|
||||
}
|
||||
|
||||
// arity 4
|
||||
for (const func of ['echo']) {
|
||||
pattern[func] = curry((a, b, c, pat) => pat[func](a,b,c));
|
||||
}
|
||||
|
||||
// problem: curried functions with spread arguments must have pat at the beginning
|
||||
// with this, we cannot keep the pattern open at the end.. solution for now: use array to keep using pat as last arg
|
||||
|
||||
// these are the core composable functions. they are extended with Pattern.prototype.define below
|
||||
Pattern.prototype.composable = { fast, slow, early, late, superimpose };
|
||||
Pattern.prototype.composable = {fast: pattern.fast, slow: pattern.slow, early: pattern.early, late: pattern.late, superimpose: pattern.superimpose };
|
||||
|
||||
// adds Pattern.prototype.composable to given function as child functions
|
||||
// then you can do transpose(2).late(0.2) instead of x => x.transpose(2).late(0.2)
|
||||
export function makeComposable(func) {
|
||||
function makeComposable(func) {
|
||||
Object.entries(Pattern.prototype.composable).forEach(([functionName, composable]) => {
|
||||
// compose with dot
|
||||
func[functionName] = (...args) => {
|
||||
@@ -1825,25 +1838,31 @@ export function makeComposable(func) {
|
||||
});
|
||||
return func;
|
||||
}
|
||||
pattern['makeComposable'] = makeComposable;
|
||||
|
||||
export const patternify2 = (f) => (pata, patb, pat) =>
|
||||
const patternify2 = (f) => (pata, patb, pat) =>
|
||||
pata
|
||||
.fmap((a) => (b) => f.call(pat, a, b))
|
||||
.appLeft(patb)
|
||||
.innerJoin();
|
||||
export const patternify3 = (f) => (pata, patb, patc, pat) =>
|
||||
pattern['patternify2'] = patternify2;
|
||||
|
||||
const patternify3 = (f) => (pata, patb, patc, pat) =>
|
||||
pata
|
||||
.fmap((a) => (b) => (c) => f.call(pat, a, b, c))
|
||||
.appLeft(patb)
|
||||
.appLeft(patc)
|
||||
.innerJoin();
|
||||
export const patternify4 = (f) => (pata, patb, patc, patd, pat) =>
|
||||
pattern['patternify3'] = patternify3;
|
||||
|
||||
const patternify4 = (f) => (pata, patb, patc, patd, pat) =>
|
||||
pata
|
||||
.fmap((a) => (b) => (c) => (d) => f.call(pat, a, b, c, d))
|
||||
.appLeft(patb)
|
||||
.appLeft(patc)
|
||||
.appLeft(patd)
|
||||
.innerJoin();
|
||||
pattern['patternify4'] = patternify4;
|
||||
|
||||
Pattern.prototype.echo = function (...args) {
|
||||
args = args.map(reify);
|
||||
@@ -1974,3 +1993,7 @@ Pattern.prototype.define = (name, func, options = {}) => {
|
||||
// Pattern.prototype.define('early', (a, pat) => pat.early(a), { patternified: true, composable: true });
|
||||
Pattern.prototype.define('hush', (pat) => pat.hush(), { patternified: false, composable: true });
|
||||
Pattern.prototype.define('bypass', (pat) => pat.bypass(on), { patternified: true, composable: true });
|
||||
|
||||
|
||||
export default pattern;
|
||||
|
||||
|
||||
@@ -4,7 +4,8 @@ Copyright (C) 2022 Strudel contributors - see <https://github.com/tidalcycles/st
|
||||
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 } from './index.mjs';
|
||||
import { pattern } from './index.mjs';
|
||||
const { Pattern } = pattern;
|
||||
|
||||
const scale = (normalized, min, max) => normalized * (max - min) + min;
|
||||
const getValue = (e) => {
|
||||
|
||||
@@ -5,7 +5,8 @@ This program is free software: you can redistribute it and/or modify it under th
|
||||
*/
|
||||
|
||||
import { Hap } from './hap.mjs';
|
||||
import { Pattern, fastcat, reify, silence, stack, isPattern } from './pattern.mjs';
|
||||
import pattern from './pattern.mjs';
|
||||
const { Pattern, fastcat, reify, silence, stack, isPattern } = pattern;
|
||||
import Fraction from './fraction.mjs';
|
||||
import { id } from './util.mjs';
|
||||
|
||||
|
||||
@@ -4,7 +4,8 @@ Copyright (C) 2022 Strudel contributors - see <https://github.com/tidalcycles/st
|
||||
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, patternify2 } from './index.mjs';
|
||||
import { pattern } from './index.mjs';
|
||||
const {Pattern, patternify2} = pattern;
|
||||
|
||||
let synth;
|
||||
try {
|
||||
|
||||
@@ -4,7 +4,8 @@ Copyright (C) 2022 Strudel contributors - see <https://github.com/tidalcycles/st
|
||||
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 { fastcat, stack, slowcat, silence, pure } from '../pattern.mjs';
|
||||
import pattern from '../pattern.mjs';
|
||||
const { fastcat, stack, slowcat, silence, pure } = pattern;
|
||||
import { describe, it, expect } from 'vitest';
|
||||
import drawLine from '../drawLine.mjs';
|
||||
|
||||
|
||||
@@ -8,10 +8,24 @@ import Fraction from 'fraction.js';
|
||||
|
||||
import { describe, it, expect } from 'vitest';
|
||||
|
||||
import {
|
||||
TimeSpan,
|
||||
Hap,
|
||||
State,
|
||||
import { pattern,
|
||||
TimeSpan,
|
||||
Hap,
|
||||
State,
|
||||
saw,
|
||||
saw2,
|
||||
isaw,
|
||||
isaw2,
|
||||
sine,
|
||||
sine2,
|
||||
square,
|
||||
square2,
|
||||
tri,
|
||||
tri2,
|
||||
time,
|
||||
} from '../index.mjs';
|
||||
|
||||
const {
|
||||
Pattern,
|
||||
pure,
|
||||
stack,
|
||||
@@ -29,21 +43,10 @@ import {
|
||||
sub,
|
||||
mul,
|
||||
div,
|
||||
saw,
|
||||
saw2,
|
||||
isaw,
|
||||
isaw2,
|
||||
sine,
|
||||
sine2,
|
||||
square,
|
||||
square2,
|
||||
tri,
|
||||
tri2,
|
||||
id,
|
||||
ply,
|
||||
rev,
|
||||
time,
|
||||
} from '../index.mjs';
|
||||
} = pattern;
|
||||
|
||||
import { steady } from '../signal.mjs';
|
||||
|
||||
|
||||
@@ -4,7 +4,8 @@ Copyright (C) 2022 Strudel contributors - see <https://github.com/tidalcycles/st
|
||||
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 pattern from '../pattern.mjs';
|
||||
const { pure } = pattern;
|
||||
import {
|
||||
isNote,
|
||||
tokenizeNote,
|
||||
|
||||
@@ -23,7 +23,7 @@ const codegen = shiftCodegen.default || shiftCodegen; // parcel module resolutio
|
||||
|
||||
import * as strudel from '@strudel.cycles/core';
|
||||
|
||||
const { Pattern } = strudel;
|
||||
const { Pattern } = strudel.pattern;
|
||||
|
||||
const isNote = (name) => /^[a-gC-G][bs]?[0-9]$/.test(name);
|
||||
|
||||
|
||||
@@ -9,10 +9,11 @@ import { expect, describe, it } from 'vitest';
|
||||
import { evaluate } from '../evaluate.mjs';
|
||||
import { mini } from '@strudel.cycles/mini';
|
||||
import * as strudel from '@strudel.cycles/core';
|
||||
const { fastcat, evalScope } = strudel;
|
||||
const { pattern, evalScope } = strudel;
|
||||
const { fastcat } = pattern;
|
||||
|
||||
describe('evaluate', async () => {
|
||||
await evalScope({ mini }, strudel);
|
||||
await evalScope({ mini }, strudel, pattern);
|
||||
const ev = async (code) => (await evaluate(code)).pattern.firstCycleValues;
|
||||
it('Should evaluate strudel functions', async () => {
|
||||
expect(await ev('pure("c3")')).toEqual(['c3']);
|
||||
|
||||
@@ -5,7 +5,8 @@ This program is free software: you can redistribute it and/or modify it under th
|
||||
*/
|
||||
|
||||
import * as _WebMidi from 'webmidi';
|
||||
import { Pattern, isPattern, isNote, getPlayableNoteValue, logger } from '@strudel.cycles/core';
|
||||
import { pattern, logger } from '@strudel.cycles/core';
|
||||
const { Pattern, isPattern, isNote, getPlayableNoteValue } = pattern;
|
||||
import { getAudioContext } from '@strudel.cycles/webaudio';
|
||||
|
||||
// if you use WebMidi from outside of this package, make sure to import that instance:
|
||||
|
||||
@@ -5,10 +5,10 @@ This program is free software: you can redistribute it and/or modify it under th
|
||||
*/
|
||||
|
||||
import * as krill from './krill-parser.js';
|
||||
import * as strudel from '@strudel.cycles/core';
|
||||
import {pattern, rand, chooseInWith, Fraction} from '@strudel.cycles/core';
|
||||
// import { addMiniLocations } from '@strudel.cycles/eval/shapeshifter.mjs';
|
||||
|
||||
const { pure, Pattern, Fraction, stack, slowcat, sequence, timeCat, silence, reify } = strudel;
|
||||
const { pure, Pattern, stack, slowcat, sequence, timeCat, silence, reify } = pattern;
|
||||
|
||||
var _seedState = 0;
|
||||
const randOffset = 0.0002;
|
||||
@@ -30,7 +30,7 @@ const applyOptions = (parent) => (pat, i) => {
|
||||
return pat.euclid(operator.arguments_.pulse, operator.arguments_.step, operator.arguments_.rotation);
|
||||
case 'degradeBy':
|
||||
return reify(pat)._degradeByWith(
|
||||
strudel.rand.early(randOffset * _nextSeed()).segment(1),
|
||||
rand.early(randOffset * _nextSeed()).segment(1),
|
||||
operator.arguments_.amount,
|
||||
);
|
||||
// TODO: case 'fixed-step': "%"
|
||||
@@ -95,7 +95,7 @@ export function patternifyAST(ast) {
|
||||
return stack(...children);
|
||||
}
|
||||
if (alignment === 'r') {
|
||||
return strudel.chooseInWith(strudel.rand.early(randOffset * _nextSeed()).segment(1), children);
|
||||
return chooseInWith(rand.early(randOffset * _nextSeed()).segment(1), children);
|
||||
}
|
||||
const weightedChildren = ast.source_.some((child) => !!child.options_?.weight);
|
||||
if (!weightedChildren && alignment === 't') {
|
||||
|
||||
@@ -5,7 +5,8 @@ This program is free software: you can redistribute it and/or modify it under th
|
||||
*/
|
||||
|
||||
import OSC from 'osc-js';
|
||||
import { logger, parseNumeral, Pattern } from '@strudel.cycles/core';
|
||||
import { logger, parseNumeral, pattern } from '@strudel.cycles/core';
|
||||
const { Pattern } = pattern;
|
||||
|
||||
let connection; // Promise<OSC>
|
||||
function connect() {
|
||||
|
||||
@@ -4,7 +4,8 @@ Copyright (C) 2022 Strudel contributors - see <https://github.com/tidalcycles/st
|
||||
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, isPattern } from '@strudel.cycles/core';
|
||||
import { pattern } from '@strudel.cycles/core';
|
||||
const { Pattern, isPattern } = pattern;
|
||||
|
||||
var serialWriter;
|
||||
var choosing = false;
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
import { Pattern } from '@strudel.cycles/core';
|
||||
import { pattern } from '@strudel.cycles/core';
|
||||
const { Pattern } = pattern;
|
||||
|
||||
import { loadSoundfont as _loadSoundfont, startPresetNote } from 'sfumato';
|
||||
|
||||
Pattern.prototype.soundfont = function (sf, n = 0) {
|
||||
|
||||
@@ -7,7 +7,8 @@ This program is free software: you can redistribute it and/or modify it under th
|
||||
// import { strict as assert } from 'assert';
|
||||
|
||||
import '../tonal.mjs'; // need to import this to add prototypes
|
||||
import { pure } from '@strudel.cycles/core';
|
||||
import { pattern } from '@strudel.cycles/core';
|
||||
const { pure } = pattern;
|
||||
import { describe, it, expect } from 'vitest';
|
||||
|
||||
describe('tonal', () => {
|
||||
|
||||
@@ -5,7 +5,8 @@ This program is free software: you can redistribute it and/or modify it under th
|
||||
*/
|
||||
|
||||
import { Note, Interval, Scale } from '@tonaljs/tonal';
|
||||
import { Pattern, mod } from '@strudel.cycles/core';
|
||||
import { pattern, mod } from '@strudel.cycles/core';
|
||||
const { Pattern } = pattern;
|
||||
|
||||
// transpose note inside scale by offset steps
|
||||
// function scaleOffset(scale: string, offset: number, note: string) {
|
||||
|
||||
@@ -4,7 +4,9 @@ Copyright (C) 2022 Strudel contributors - see <https://github.com/tidalcycles/st
|
||||
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 as _Pattern, stack, Hap, reify } from '@strudel.cycles/core';
|
||||
import { pattern, Hap } from '@strudel.cycles/core';
|
||||
const { Pattern, stack, reify } = pattern
|
||||
|
||||
import _voicings from 'chord-voicings';
|
||||
const { dictionaryVoicing, minTopNoteDiff, lefthand } = _voicings.default || _voicings; // parcel module resolution fuckup
|
||||
|
||||
@@ -17,7 +19,7 @@ const getVoicing = (chord, lastVoicing, range = ['F3', 'A4']) =>
|
||||
lastVoicing,
|
||||
});
|
||||
|
||||
const Pattern = _Pattern;
|
||||
// const Pattern = _Pattern;
|
||||
|
||||
Pattern.prototype.fmapNested = function (func) {
|
||||
return new Pattern((span) =>
|
||||
|
||||
@@ -5,7 +5,8 @@ This program is free software: you can redistribute it and/or modify it under th
|
||||
*/
|
||||
|
||||
import '../tone.mjs';
|
||||
import { pure } from '@strudel.cycles/core';
|
||||
import { pattern } from '@strudel.cycles/core';
|
||||
const { pure } = pattern;
|
||||
import { describe, it, expect } from 'vitest';
|
||||
|
||||
describe('tone', () => {
|
||||
|
||||
@@ -4,7 +4,9 @@ Copyright (C) 2022 Strudel contributors - see <https://github.com/tidalcycles/st
|
||||
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 } from '@strudel.cycles/core';
|
||||
import { pattern } from '@strudel.cycles/core';
|
||||
const { Pattern } = pattern;
|
||||
|
||||
import * as _Tone from 'tone';
|
||||
|
||||
// import Tone from here, to make sure to get the same AudioContext
|
||||
|
||||
@@ -10,7 +10,7 @@ import { fromMidi, logger, toMidi } from '@strudel.cycles/core';
|
||||
import './feedbackdelay.mjs';
|
||||
import './reverb.mjs';
|
||||
import { getSampleBufferSource } from './sampler.mjs';
|
||||
const { Pattern } = strudel;
|
||||
const { Pattern } = strudel.pattern;
|
||||
import './vowel.mjs';
|
||||
import workletsUrl from './worklets.mjs?url';
|
||||
|
||||
|
||||
@@ -5,7 +5,8 @@ This program is free software: you can redistribute it and/or modify it under th
|
||||
*/
|
||||
|
||||
import Tune from './tunejs.js';
|
||||
import { Pattern } from '@strudel.cycles/core';
|
||||
import { pattern } from '@strudel.cycles/core';
|
||||
const { Pattern } = pattern;
|
||||
|
||||
Pattern.prototype._tune = function (scale, tonic = 220) {
|
||||
const tune = new Tune();
|
||||
|
||||
@@ -4,7 +4,8 @@ Copyright (C) 2022 Strudel contributors - see <https://github.com/tidalcycles/st
|
||||
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, mod } from '@strudel.cycles/core';
|
||||
import { pattern, mod } from '@strudel.cycles/core';
|
||||
const { Pattern } = pattern;
|
||||
|
||||
export function edo(name) {
|
||||
if (!/^[1-9]+[0-9]*edo$/.test(name)) {
|
||||
|
||||
+2
-1
@@ -4,7 +4,7 @@ Copyright (C) 2022 Strudel contributors - see <https://github.com/tidalcycles/st
|
||||
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 { cleanupDraw, cleanupUi, controls, evalScope, logger } from '@strudel.cycles/core';
|
||||
import { cleanupDraw, cleanupUi, controls, evalScope, logger, pattern } from '@strudel.cycles/core';
|
||||
import { CodeMirror, cx, flash, useHighlighting, useStrudel } from '@strudel.cycles/react';
|
||||
import {
|
||||
getAudioContext,
|
||||
@@ -47,6 +47,7 @@ const modules = [
|
||||
evalScope(
|
||||
// Tone,
|
||||
controls, // sadly, this cannot be exported from core direclty
|
||||
pattern,
|
||||
{ WebDirt },
|
||||
...modules,
|
||||
);
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { Pattern, toMidi } from '@strudel.cycles/core';
|
||||
import { pattern, toMidi } from '@strudel.cycles/core';
|
||||
const { Pattern } = pattern;
|
||||
import { samples } from '@strudel.cycles/webaudio';
|
||||
|
||||
export async function prebake({ isMock = false, baseDir = '.' } = {}) {
|
||||
|
||||
+15
-13
@@ -7,6 +7,7 @@
|
||||
import { evaluate } from '@strudel.cycles/transpiler';
|
||||
import { evalScope } from '@strudel.cycles/core';
|
||||
import * as strudel from '@strudel.cycles/core';
|
||||
const { Pattern } = strudel.pattern;
|
||||
import * as webaudio from '@strudel.cycles/webaudio';
|
||||
import controls from '@strudel.cycles/core/controls.mjs';
|
||||
// import gist from '@strudel.cycles/core/gist.js';
|
||||
@@ -85,48 +86,48 @@ const toneHelpersMocked = {
|
||||
highpass: mockNode,
|
||||
};
|
||||
|
||||
strudel.Pattern.prototype.osc = function () {
|
||||
Pattern.prototype.osc = function () {
|
||||
return this;
|
||||
};
|
||||
strudel.Pattern.prototype.tone = function () {
|
||||
Pattern.prototype.tone = function () {
|
||||
return this;
|
||||
};
|
||||
strudel.Pattern.prototype.webdirt = function () {
|
||||
Pattern.prototype.webdirt = function () {
|
||||
return this;
|
||||
};
|
||||
|
||||
// draw mock
|
||||
strudel.Pattern.prototype.pianoroll = function () {
|
||||
Pattern.prototype.pianoroll = function () {
|
||||
return this;
|
||||
};
|
||||
|
||||
// speak mock
|
||||
strudel.Pattern.prototype.speak = function () {
|
||||
Pattern.prototype.speak = function () {
|
||||
return this;
|
||||
};
|
||||
|
||||
// webaudio mock
|
||||
strudel.Pattern.prototype.wave = function () {
|
||||
Pattern.prototype.wave = function () {
|
||||
return this;
|
||||
};
|
||||
strudel.Pattern.prototype.filter = function () {
|
||||
Pattern.prototype.filter = function () {
|
||||
return this;
|
||||
};
|
||||
strudel.Pattern.prototype.adsr = function () {
|
||||
Pattern.prototype.adsr = function () {
|
||||
return this;
|
||||
};
|
||||
strudel.Pattern.prototype.out = function () {
|
||||
Pattern.prototype.out = function () {
|
||||
return this;
|
||||
};
|
||||
strudel.Pattern.prototype.soundfont = function () {
|
||||
Pattern.prototype.soundfont = function () {
|
||||
return this;
|
||||
};
|
||||
// tune mock
|
||||
strudel.Pattern.prototype.tune = function () {
|
||||
Pattern.prototype.tune = function () {
|
||||
return this;
|
||||
};
|
||||
|
||||
strudel.Pattern.prototype.midi = function () {
|
||||
Pattern.prototype.midi = function () {
|
||||
return this;
|
||||
};
|
||||
|
||||
@@ -156,7 +157,8 @@ const loadSoundfont = () => {};
|
||||
evalScope(
|
||||
// Tone,
|
||||
strudel,
|
||||
strudel.Pattern.prototype.bootstrap(),
|
||||
strudel.pattern,
|
||||
Pattern.prototype.bootstrap(),
|
||||
toneHelpersMocked,
|
||||
uiHelpersMocked,
|
||||
controls,
|
||||
|
||||
Reference in New Issue
Block a user