diff --git a/packages/core/controls.mjs b/packages/core/controls.mjs index 0edc4dfcf..aff33a5f6 100644 --- a/packages/core/controls.mjs +++ b/packages/core/controls.mjs @@ -4,7 +4,8 @@ Copyright (C) 2022 Strudel contributors - see . */ -import { Pattern, sequence } from './pattern.mjs'; +import pattern from './pattern.mjs'; +const { Pattern, sequence } = pattern; const controls = {}; const generic_params = [ diff --git a/packages/core/draw.mjs b/packages/core/draw.mjs index 9ef34e3ab..f63acdf3f 100644 --- a/packages/core/draw.mjs +++ b/packages/core/draw.mjs @@ -4,7 +4,8 @@ Copyright (C) 2022 Strudel contributors - see . */ -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); diff --git a/packages/core/euclid.mjs b/packages/core/euclid.mjs index 45a59783e..5d7d6789f 100644 --- a/packages/core/euclid.mjs +++ b/packages/core/euclid.mjs @@ -4,7 +4,8 @@ Copyright (C) 2022 Strudel contributors - see . */ -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'; diff --git a/packages/core/evaluate.mjs b/packages/core/evaluate.mjs index 35c47e422..f2879a55d 100644 --- a/packages/core/evaluate.mjs +++ b/packages/core/evaluate.mjs @@ -4,7 +4,8 @@ Copyright (C) 2022 Strudel contributors - see . */ -import { isPattern, Pattern } from './index.mjs'; +import { pattern } from './index.mjs'; +const { isPattern, Pattern } = pattern; let scoped = false; export const evalScope = async (...args) => { diff --git a/packages/core/index.mjs b/packages/core/index.mjs index b9fd70618..0a6c32a82 100644 --- a/packages/core/index.mjs +++ b/packages/core/index.mjs @@ -4,13 +4,13 @@ Copyright (C) 2022 Strudel contributors - see . */ +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'; diff --git a/packages/core/pattern.mjs b/packages/core/pattern.mjs index c7a80b59b..abd89fd56 100644 --- a/packages/core/pattern.mjs +++ b/packages/core/pattern.mjs @@ -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() // "".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; + diff --git a/packages/core/pianoroll.mjs b/packages/core/pianoroll.mjs index f9c198e94..c383dfe2c 100644 --- a/packages/core/pianoroll.mjs +++ b/packages/core/pianoroll.mjs @@ -4,7 +4,8 @@ Copyright (C) 2022 Strudel contributors - see . */ -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) => { diff --git a/packages/core/signal.mjs b/packages/core/signal.mjs index d92d51fe8..3f2da134d 100644 --- a/packages/core/signal.mjs +++ b/packages/core/signal.mjs @@ -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'; diff --git a/packages/core/speak.mjs b/packages/core/speak.mjs index 2e9ba80ac..96c8f8a78 100644 --- a/packages/core/speak.mjs +++ b/packages/core/speak.mjs @@ -4,7 +4,8 @@ Copyright (C) 2022 Strudel contributors - see . */ -import { Pattern, patternify2 } from './index.mjs'; +import { pattern } from './index.mjs'; +const {Pattern, patternify2} = pattern; let synth; try { diff --git a/packages/core/test/drawLine.test.mjs b/packages/core/test/drawLine.test.mjs index 84359a7cf..5f2a968dc 100644 --- a/packages/core/test/drawLine.test.mjs +++ b/packages/core/test/drawLine.test.mjs @@ -4,7 +4,8 @@ Copyright (C) 2022 Strudel contributors - see . */ -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'; diff --git a/packages/core/test/pattern.test.mjs b/packages/core/test/pattern.test.mjs index 72365d131..036053bc2 100644 --- a/packages/core/test/pattern.test.mjs +++ b/packages/core/test/pattern.test.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'; diff --git a/packages/core/test/util.test.mjs b/packages/core/test/util.test.mjs index 303a3645a..4cef2d4b8 100644 --- a/packages/core/test/util.test.mjs +++ b/packages/core/test/util.test.mjs @@ -4,7 +4,8 @@ Copyright (C) 2022 Strudel contributors - see . */ -import { pure } from '../pattern.mjs'; +import pattern from '../pattern.mjs'; +const { pure } = pattern; import { isNote, tokenizeNote, diff --git a/packages/eval/shapeshifter.mjs b/packages/eval/shapeshifter.mjs index b8ffffd3f..b26841def 100644 --- a/packages/eval/shapeshifter.mjs +++ b/packages/eval/shapeshifter.mjs @@ -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); diff --git a/packages/eval/test/evaluate.test.mjs b/packages/eval/test/evaluate.test.mjs index 674c581bd..b85bbd0cc 100644 --- a/packages/eval/test/evaluate.test.mjs +++ b/packages/eval/test/evaluate.test.mjs @@ -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']); diff --git a/packages/midi/midi.mjs b/packages/midi/midi.mjs index c59757fb8..10ece6416 100644 --- a/packages/midi/midi.mjs +++ b/packages/midi/midi.mjs @@ -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: diff --git a/packages/mini/mini.mjs b/packages/mini/mini.mjs index 82ed4b86a..90a1cec1c 100644 --- a/packages/mini/mini.mjs +++ b/packages/mini/mini.mjs @@ -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') { diff --git a/packages/osc/osc.mjs b/packages/osc/osc.mjs index 15909203e..a9a28e52b 100644 --- a/packages/osc/osc.mjs +++ b/packages/osc/osc.mjs @@ -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 function connect() { diff --git a/packages/serial/serial.mjs b/packages/serial/serial.mjs index 4452195dd..8d7785bcd 100644 --- a/packages/serial/serial.mjs +++ b/packages/serial/serial.mjs @@ -4,7 +4,8 @@ Copyright (C) 2022 Strudel contributors - see . */ -import { Pattern, isPattern } from '@strudel.cycles/core'; +import { pattern } from '@strudel.cycles/core'; +const { Pattern, isPattern } = pattern; var serialWriter; var choosing = false; diff --git a/packages/soundfonts/sfumato.mjs b/packages/soundfonts/sfumato.mjs index 1cca2ffe5..d9770b1e8 100644 --- a/packages/soundfonts/sfumato.mjs +++ b/packages/soundfonts/sfumato.mjs @@ -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) { diff --git a/packages/tonal/test/tonal.test.mjs b/packages/tonal/test/tonal.test.mjs index f8a999571..cb293cf39 100644 --- a/packages/tonal/test/tonal.test.mjs +++ b/packages/tonal/test/tonal.test.mjs @@ -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', () => { diff --git a/packages/tonal/tonal.mjs b/packages/tonal/tonal.mjs index 4d8e0d821..973eeb437 100644 --- a/packages/tonal/tonal.mjs +++ b/packages/tonal/tonal.mjs @@ -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) { diff --git a/packages/tonal/voicings.mjs b/packages/tonal/voicings.mjs index 70a2f0e13..62d83457f 100644 --- a/packages/tonal/voicings.mjs +++ b/packages/tonal/voicings.mjs @@ -4,7 +4,9 @@ Copyright (C) 2022 Strudel contributors - see . */ -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) => diff --git a/packages/tone/test/tone.test.mjs b/packages/tone/test/tone.test.mjs index 42feb676b..586b11931 100644 --- a/packages/tone/test/tone.test.mjs +++ b/packages/tone/test/tone.test.mjs @@ -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', () => { diff --git a/packages/tone/tone.mjs b/packages/tone/tone.mjs index b5ea4b9ef..17f029fb6 100644 --- a/packages/tone/tone.mjs +++ b/packages/tone/tone.mjs @@ -4,7 +4,9 @@ Copyright (C) 2022 Strudel contributors - see . */ -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 diff --git a/packages/webaudio/webaudio.mjs b/packages/webaudio/webaudio.mjs index 52650d650..561ee9980 100644 --- a/packages/webaudio/webaudio.mjs +++ b/packages/webaudio/webaudio.mjs @@ -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'; diff --git a/packages/xen/tune.mjs b/packages/xen/tune.mjs index 5685e1a70..1429edfcc 100644 --- a/packages/xen/tune.mjs +++ b/packages/xen/tune.mjs @@ -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(); diff --git a/packages/xen/xen.mjs b/packages/xen/xen.mjs index ff5a13ebc..63e1ee44f 100644 --- a/packages/xen/xen.mjs +++ b/packages/xen/xen.mjs @@ -4,7 +4,8 @@ Copyright (C) 2022 Strudel contributors - see . */ -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)) { diff --git a/repl/src/App.jsx b/repl/src/App.jsx index ef2346c2e..0886bd115 100644 --- a/repl/src/App.jsx +++ b/repl/src/App.jsx @@ -4,7 +4,7 @@ Copyright (C) 2022 Strudel contributors - see . */ -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, ); diff --git a/repl/src/prebake.mjs b/repl/src/prebake.mjs index 97443dcf2..75b490a33 100644 --- a/repl/src/prebake.mjs +++ b/repl/src/prebake.mjs @@ -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 = '.' } = {}) { diff --git a/repl/src/runtime.mjs b/repl/src/runtime.mjs index 8945f1a81..d95c8f995 100644 --- a/repl/src/runtime.mjs +++ b/repl/src/runtime.mjs @@ -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,