remove all occurrences of .out()

This commit is contained in:
Felix Roos 2022-10-27 19:47:07 +02:00
parent 5c230c2d65
commit ecc4e1803c
10 changed files with 139 additions and 172 deletions

View File

@ -23,7 +23,7 @@ const generic_params = [
* @name s
* @param {string | Pattern} sound The sound / pattern of sounds to pick
* @example
* s("bd hh").out()
* s("bd hh")
*
*/
['s', 's', 'sound'],
@ -67,7 +67,7 @@ const generic_params = [
* @name gain
* @param {number | Pattern} amount gain.
* @example
* s("hh*8").gain(".4!2 1 .4!2 1 .4 1").out()
* s("hh*8").gain(".4!2 1 .4!2 1 .4 1")
*
*/
[
@ -129,7 +129,7 @@ const generic_params = [
* @name bandf
* @param {number | Pattern} frequency center frequency
* @example
* s("bd sd,hh*3").bandf("<1000 2000 4000 8000>").out()
* s("bd sd,hh*3").bandf("<1000 2000 4000 8000>")
*
*/
['f', 'bandf', 'A pattern of numbers from 0 to 1. Sets the center frequency of the band-pass filter.'],
@ -140,7 +140,7 @@ const generic_params = [
* @name bandq
* @param {number | Pattern} q q factor
* @example
* s("bd sd").bandf(500).bandq("<0 1 2 3>").out()
* s("bd sd").bandf(500).bandq("<0 1 2 3>")
*
*/
['f', 'bandq', 'a pattern of anumbers from 0 to 1. Sets the q-factor of the band-pass filter.'],
@ -152,7 +152,7 @@ const generic_params = [
* @param {number | Pattern} amount between 0 and 1, where 1 is the length of the sample
* @example
* samples({ rave: 'rave/AREUREADY.wav' }, 'github:tidalcycles/Dirt-Samples/master/')
* s("rave").begin("<0 .25 .5 .75>").out()
* s("rave").begin("<0 .25 .5 .75>")
*
*/
[
@ -167,7 +167,7 @@ const generic_params = [
* @name end
* @param {number | Pattern} length 1 = whole sample, .5 = half sample, .25 = quarter sample etc..
* @example
* s("bd*2,ho*4").end("<.1 .2 .5 1>").out()
* s("bd*2,ho*4").end("<.1 .2 .5 1>")
*
*/
[
@ -205,7 +205,7 @@ const generic_params = [
* @name crush
* @param {number | Pattern} depth between 1 (for drastic reduction in bit-depth) to 16 (for barely no reduction).
* @example
* s("<bd sd>,hh*3").fast(2).crush("<16 8 7 6 5 4 3 2>").out()
* s("<bd sd>,hh*3").fast(2).crush("<16 8 7 6 5 4 3 2>")
*
*/
[
@ -219,7 +219,7 @@ const generic_params = [
* @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>").out()
* s("bd sd,hh*4").coarse("<1 4 8 16 32>")
*
*/
[
@ -256,7 +256,7 @@ const generic_params = [
* @name cutoff
* @param {number | Pattern} frequency audible between 0 and 20000
* @example
* s("bd sd,hh*3").cutoff("<4000 2000 1000 500 200 100>").out()
* s("bd sd,hh*3").cutoff("<4000 2000 1000 500 200 100>")
*
*/
// TODO: add lpf synonym
@ -267,7 +267,7 @@ const generic_params = [
* @name hcutoff
* @param {number | Pattern} frequency audible between 0 and 20000
* @example
* s("bd sd,hh*4").hcutoff("<4000 2000 1000 500 200 100>").out()
* s("bd sd,hh*4").hcutoff("<4000 2000 1000 500 200 100>")
*
*/
// TODO: add hpf synonym
@ -282,7 +282,7 @@ const generic_params = [
* @name hresonance
* @param {number | Pattern} q resonance factor between 0 and 1
* @example
* s("bd sd,hh*4").hcutoff(2000).hresonance("<0 10 20 30>").out()
* s("bd sd,hh*4").hcutoff(2000).hresonance("<0 10 20 30>")
*
*/
[
@ -297,7 +297,7 @@ const generic_params = [
* @name resonance
* @param {number | Pattern} q resonance factor between 0 and 1
* @example
* s("bd sd,hh*4").cutoff(2000).resonance("<0 10 20 30>").out()
* s("bd sd,hh*4").cutoff(2000).resonance("<0 10 20 30>")
*
*/
['f', 'resonance', 'a pattern of numbers from 0 to 1. Specifies the resonance of the low-pass filter.'],
@ -496,7 +496,7 @@ const generic_params = [
* @name pan
* @param {number | Pattern} pan between 0 and 1, from left to right (assuming stereo), once round a circle (assuming multichannel)
* @example
* s("[bd hh]*2").pan("<.5 1 .5 0>").out()
* s("[bd hh]*2").pan("<.5 1 .5 0>")
*
*/
[
@ -599,7 +599,7 @@ const generic_params = [
* @name shape
* @param {number | Pattern} distortion between 0 and 1
* @example
* s("bd sd,hh*4").shape("<0 .2 .4 .6 .8>").out()
* s("bd sd,hh*4").shape("<0 .2 .4 .6 .8>")
*
*/
[
@ -665,7 +665,7 @@ const generic_params = [
* @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>>").out()
* .vowel("<a e i <o u>>")
*
*/
[

View File

@ -32,7 +32,7 @@ const euclid = (pulses, steps, rotation = 0) => {
* @returns Pattern
* @example
* // The Cuban tresillo pattern.
* n("c3").euclid(3,8).out()
* n("c3").euclid(3,8)
*/
/**
@ -88,7 +88,7 @@ Pattern.prototype.euclid = function (pulses, steps, rotation = 0) {
* @name euclidLegato
* @memberof Pattern
* @example
* n("g2").decay(.1).sustain(.3).euclidLegato(3,8).out()
* n("g2").decay(.1).sustain(.3).euclidLegato(3,8)
*/
Pattern.prototype.euclidLegato = function (pulses, steps, rotation = 0) {
const bin_pat = euclid(pulses, steps, rotation);

View File

@ -524,7 +524,7 @@ export class Pattern {
* @memberof Pattern
* @returns Pattern
* @example
* s("bd sd,hh*4").cutoff(sine.range(500,2000).slow(4)).out()
* s("bd sd,hh*4").cutoff(sine.range(500,2000).slow(4))
*/
_range(min, max) {
return this.mul(max - min).add(min);
@ -718,7 +718,7 @@ export class Pattern {
* @example
* "<0 2 4 6 ~ 4 ~ 2 0!3 ~!5>*4"
* .layer(x=>x.add("0,2"))
* .scale('C minor').note().out()
* .scale('C minor').note()
*/
layer(...funcs) {
return stack(...funcs.map((func) => func(this)));
@ -756,11 +756,13 @@ export class Pattern {
const cycle = begin.sam();
const beginPos = begin.sub(cycle).div(factor).min(1);
const endPos = end.sub(cycle).div(factor).min(1);
const newPart = new TimeSpan(cycle.add(beginPos), cycle.add(endPos))
const newWhole = !hap.whole ? undefined : new TimeSpan(
newPart.begin.sub(begin.sub(hap.whole.begin).div(factor)),
newPart.end.add(hap.whole.end.sub(end).div(factor))
);
const newPart = new TimeSpan(cycle.add(beginPos), cycle.add(endPos));
const newWhole = !hap.whole
? undefined
: new TimeSpan(
newPart.begin.sub(begin.sub(hap.whole.begin).div(factor)),
newPart.end.add(hap.whole.end.sub(end).div(factor)),
);
return new Hap(newWhole, newPart, hap.value, hap.context);
};
return this.withQuerySpan(qf)._withHap(ef)._splitQueries();
@ -796,7 +798,7 @@ export class Pattern {
* @param {number | Pattern} factor speed up factor
* @returns Pattern
* @example
* s("<bd sd> hh").fast(2).out() // s("[<bd sd> hh]*2").out()
* s("<bd sd> hh").fast(2) // s("[<bd sd> hh]*2")
*/
_fast(factor) {
const fastQuery = this.withQueryTime((t) => t.mul(factor));
@ -811,7 +813,7 @@ export class Pattern {
* @param {number | Pattern} factor slow down factor
* @returns Pattern
* @example
* s("<bd sd> hh").slow(2).out() // s("[<bd sd> hh]/2").out()
* s("<bd sd> hh").slow(2) // s("[<bd sd> hh]/2")
*/
_slow(factor) {
return this._fast(Fraction(1).div(factor));
@ -841,7 +843,7 @@ export class Pattern {
* .chop(4)
* .rev() // reverse order of chops
* .loopAt(4,1) // fit sample into 4 cycles
* .out()
*
*/
_chop(n) {
const slices = Array.from({ length: n }, (x, i) => i);
@ -872,7 +874,7 @@ export class Pattern {
* @param {number | Pattern} cycles number of cycles to nudge left
* @returns Pattern
* @example
* "bd ~".stack("hh ~".early(.1)).s().out()
* "bd ~".stack("hh ~".early(.1)).s()
*/
_early(offset) {
offset = Fraction(offset);
@ -887,7 +889,7 @@ export class Pattern {
* @param {number | Pattern} cycles number of cycles to nudge right
* @returns Pattern
* @example
* "bd ~".stack("hh ~".late(.1)).s().out()
* "bd ~".stack("hh ~".late(.1)).s()
*/
_late(offset) {
offset = Fraction(offset);
@ -925,7 +927,7 @@ export class Pattern {
* @example
* "c3,eb3,g3"
* .struct("x ~ x ~ ~ x ~ x ~ ~ ~ x ~ x ~ ~")
* .slow(4).note().out()
* .slow(4).note()
*/
// struct(...binary_pats) {
// // Re structure the pattern according to a binary pattern (false values are dropped)
@ -1015,7 +1017,7 @@ export class Pattern {
* @param {function} func function to apply
* @returns Pattern
* @example
* note("c3 d3 e3 g3").every(4, x=>x.rev()).out()
* note("c3 d3 e3 g3").every(4, x=>x.rev())
*/
every(n, func) {
const pat = this;
@ -1032,7 +1034,7 @@ export class Pattern {
* @param {function} func function to apply
* @returns Pattern
* @example
* note("c3 d3 e3 g3").every(4, x=>x.rev()).out()
* note("c3 d3 e3 g3").every(4, x=>x.rev())
*/
every(n, func) {
const pat = this;
@ -1049,7 +1051,7 @@ export class Pattern {
* @param {function} func function to apply
* @returns Pattern
* @example
* note("c3 d3 e3 g3").every(4, x=>x.rev()).out()
* note("c3 d3 e3 g3").every(4, x=>x.rev())
*/
each(n, func) {
const pat = this;
@ -1126,7 +1128,7 @@ export class Pattern {
* @example
* s("hh*2").stack(
* n("c2(3,8)")
* ).out()
* )
*/
stack(...pats) {
return stack(this, ...pats);
@ -1143,7 +1145,7 @@ export class Pattern {
* @example
* s("hh*2").seq(
* n("c2(3,8)")
* ).out()
* )
*/
seq(...pats) {
return sequence(this, ...pats);
@ -1156,7 +1158,7 @@ export class Pattern {
* @example
* s("hh*2").cat(
* n("c2(3,8)")
* ).out()
* )
*/
cat(...pats) {
return cat(this, ...pats);
@ -1178,7 +1180,7 @@ export class Pattern {
* @example
* "<0 2 4 6 ~ 4 ~ 2 0!3 ~!5>*4"
* .superimpose(x=>x.add(2))
* .scale('C minor').note().out()
* .scale('C minor').note()
*/
superimpose(...funcs) {
return this.stack(...funcs.map((func) => func(this)));
@ -1203,7 +1205,7 @@ export class Pattern {
* @example
* "<0 [2 4]>"
* .echoWith(4, 1/8, (p,n) => p.add(n*2))
* .scale('C minor').note().legato(.2).out()
* .scale('C minor').note().legato(.2)
*/
_echoWith(times, time, func) {
return stack(...listRange(0, times - 1).map((i) => func(this.late(Fraction(time).mul(i)), i)));
@ -1218,7 +1220,7 @@ export class Pattern {
* @param {number} time cycle offset between iterations
* @param {number} feedback velocity multiplicator for each iteration
* @example
* s("bd sd").echo(3, 1/6, .8).out()
* s("bd sd").echo(3, 1/6, .8)
*/
_echo(times, time, feedback) {
return this._echoWith(times, time, (pat, i) => pat.velocity(Math.pow(feedback, i)));
@ -1230,7 +1232,7 @@ export class Pattern {
* @memberof Pattern
* @returns Pattern
* @example
* note("0 1 2 3".scale('A minor')).iter(4).out()
* note("0 1 2 3".scale('A minor')).iter(4)
*/
iter(times, back = false) {
return slowcat(...listRange(0, times - 1).map((i) => (back ? this.late(i / times) : this.early(i / times))));
@ -1242,7 +1244,7 @@ export class Pattern {
* @memberof Pattern
* @returns Pattern
* @example
* note("0 1 2 3".scale('A minor')).iterBack(4).out()
* note("0 1 2 3".scale('A minor')).iterBack(4)
*/
iterBack(times) {
return this.iter(times, true);
@ -1254,7 +1256,7 @@ export class Pattern {
* @memberof Pattern
* @returns Pattern
* @example
* "0 1 2 3".chunk(4, x=>x.add(7)).scale('A minor').note().out()
* "0 1 2 3".chunk(4, x=>x.add(7)).scale('A minor').note()
*/
_chunk(n, func, back = false) {
const binary = Array(n - 1).fill(false);
@ -1269,7 +1271,7 @@ export class Pattern {
* @memberof Pattern
* @returns Pattern
* @example
* "0 1 2 3".chunkBack(4, x=>x.add(7)).scale('A minor').note().out()
* "0 1 2 3".chunkBack(4, x=>x.add(7)).scale('A minor').note()
*/
_chunkBack(n, func) {
return this._chunk(n, func, true);
@ -1295,7 +1297,7 @@ export class Pattern {
* @name legato
* @memberof Pattern
* @example
* n("c3 eb3 g3 c4").legato("<.25 .5 1 2>").out()
* n("c3 eb3 g3 c4").legato("<.25 .5 1 2>")
*/
_legato(value) {
return this.withHapSpan((span) => new TimeSpan(span.begin, span.begin.add(span.end.sub(span.begin).mul(value))));
@ -1308,7 +1310,7 @@ export class Pattern {
* @example
* s("hh*8")
* .gain(".4!2 1 .4!2 1 .4 1")
* .velocity(".4 1").out()
* .velocity(".4 1")
*/
_velocity(velocity) {
return this._withContext((context) => ({ ...context, velocity: (context.velocity || 1) * velocity }));
@ -1321,7 +1323,7 @@ export class Pattern {
* @returns Pattern
* @example
* samples({ rhodes: 'https://cdn.freesound.org/previews/132/132051_316502-lq.mp3' })
* s("rhodes").loopAt(4,1).out()
* s("rhodes").loopAt(4,1)
*/
_loopAt(factor, cps = 1) {
return this.speed((1 / factor) * cps)
@ -1411,7 +1413,7 @@ function _composeOp(a, b, func) {
* @name mul
* @memberof Pattern
* @example
* "1 1.5 [1.66, <2 2.33>]".mul(150).freq().out()
* "1 1.5 [1.66, <2 2.33>]".mul(150).freq()
*/
mul: [(a, b) => a * b, num],
/**

View File

@ -120,7 +120,7 @@ const timeToRands = (t, n) => timeToRandsPrime(timeToIntSeed(t), n);
* @name rand
* @example
* // randomly change the cutoff
* s("bd sd,hh*4").cutoff(rand.range(500,2000)).out()
* s("bd sd,hh*4").cutoff(rand.range(500,2000))
*
*/
export const rand = signal(timeToRand);
@ -142,7 +142,7 @@ export const _irand = (i) => rand.fmap((x) => Math.trunc(x * i));
* @param {number} n max value (exclusive)
* @example
* // randomly select scale notes from 0 - 7 (= C to C)
* irand(8).struct("x(3,8)").scale('C minor').note().out()
* irand(8).struct("x(3,8)").scale('C minor').note()
*
*/
export const irand = (ipat) => reify(ipat).fmap(_irand).innerJoin();
@ -208,9 +208,9 @@ Pattern.prototype.choose2 = function (...xs) {
* Picks one of the elements at random each cycle.
* @returns {Pattern}
* @example
* chooseCycles("bd", "hh", "sd").s().fast(4).out()
* chooseCycles("bd", "hh", "sd").s().fast(4)
* @example
* "bd | hh | sd".s().fast(4).out()
* "bd | hh | sd".s().fast(4)
*/
export const chooseCycles = (...xs) => chooseInWith(rand.segment(1), xs);
@ -252,7 +252,7 @@ export const perlinWith = (pat) => {
* @name perlin
* @example
* // randomly change the cutoff
* s("bd sd,hh*4").cutoff(perlin.range(500,2000)).out()
* s("bd sd,hh*4").cutoff(perlin.range(500,2000))
*
*/
export const perlin = perlinWith(time);
@ -271,9 +271,9 @@ Pattern.prototype._degradeByWith = function (withPat, x) {
* @param {number} amount - a number between 0 and 1
* @returns Pattern
* @example
* s("hh*8").degradeBy(0.2).out()
* s("hh*8").degradeBy(0.2)
* @example
* s("[hh?0.2]*8").out()
* s("[hh?0.2]*8")
*/
Pattern.prototype._degradeBy = function (x) {
return this._degradeByWith(rand, x);
@ -287,9 +287,9 @@ Pattern.prototype._degradeBy = function (x) {
* @memberof Pattern
* @returns Pattern
* @example
* s("hh*8").degrade().out()
* s("hh*8").degrade()
* @example
* s("[hh?]*8").out()
* s("[hh?]*8")
*/
Pattern.prototype.degrade = function () {
return this._degradeBy(0.5);
@ -306,7 +306,7 @@ Pattern.prototype.degrade = function () {
* @param {number} amount - a number between 0 and 1
* @returns Pattern
* @example
* s("hh*8").undegradeBy(0.2).out()
* s("hh*8").undegradeBy(0.2)
*/
Pattern.prototype._undegradeBy = function (x) {
return this._degradeByWith(
@ -340,7 +340,7 @@ Pattern.prototype._sometimesBy = function (x, func) {
* @param {function} function - the transformation to apply
* @returns Pattern
* @example
* s("hh(3,8)").sometimesBy(.4, x=>x.speed("0.5")).out()
* s("hh(3,8)").sometimesBy(.4, x=>x.speed("0.5"))
*/
Pattern.prototype.sometimesBy = function (patx, func) {
const pat = this;
@ -370,7 +370,7 @@ Pattern.prototype.sometimesByPre = function (patx, func) {
* @param {function} function - the transformation to apply
* @returns Pattern
* @example
* s("hh*4").sometimes(x=>x.speed("0.5")).out()
* s("hh*4").sometimes(x=>x.speed("0.5"))
*/
Pattern.prototype.sometimes = function (func) {
return this._sometimesBy(0.5, func);
@ -398,7 +398,7 @@ Pattern.prototype._someCyclesBy = function (x, func) {
* @param {function} function - the transformation to apply
* @returns Pattern
* @example
* s("hh(3,8)").someCyclesBy(.3, x=>x.speed("0.5")).out()
* s("hh(3,8)").someCyclesBy(.3, x=>x.speed("0.5"))
*/
Pattern.prototype.someCyclesBy = function (patx, func) {
const pat = this;
@ -415,7 +415,7 @@ Pattern.prototype.someCyclesBy = function (patx, func) {
* @memberof Pattern
* @returns Pattern
* @example
* s("hh(3,8)").someCycles(x=>x.speed("0.5")).out()
* s("hh(3,8)").someCycles(x=>x.speed("0.5"))
*/
Pattern.prototype.someCycles = function (func) {
return this._someCyclesBy(0.5, func);
@ -429,7 +429,7 @@ Pattern.prototype.someCycles = function (func) {
* @memberof Pattern
* @returns Pattern
* @example
* s("hh*8").often(x=>x.speed("0.5")).out()
* s("hh*8").often(x=>x.speed("0.5"))
*/
Pattern.prototype.often = function (func) {
return this.sometimesBy(0.75, func);
@ -443,7 +443,7 @@ Pattern.prototype.often = function (func) {
* @memberof Pattern
* @returns Pattern
* @example
* s("hh*8").rarely(x=>x.speed("0.5")).out()
* s("hh*8").rarely(x=>x.speed("0.5"))
*/
Pattern.prototype.rarely = function (func) {
return this.sometimesBy(0.25, func);
@ -457,7 +457,7 @@ Pattern.prototype.rarely = function (func) {
* @memberof Pattern
* @returns Pattern
* @example
* s("hh*8").almostNever(x=>x.speed("0.5")).out()
* s("hh*8").almostNever(x=>x.speed("0.5"))
*/
Pattern.prototype.almostNever = function (func) {
return this.sometimesBy(0.1, func);
@ -471,7 +471,7 @@ Pattern.prototype.almostNever = function (func) {
* @memberof Pattern
* @returns Pattern
* @example
* s("hh*8").almostAlways(x=>x.speed("0.5")).out()
* s("hh*8").almostAlways(x=>x.speed("0.5"))
*/
Pattern.prototype.almostAlways = function (func) {
return this.sometimesBy(0.9, func);
@ -485,7 +485,7 @@ Pattern.prototype.almostAlways = function (func) {
* @memberof Pattern
* @returns Pattern
* @example
* s("hh*8").never(x=>x.speed("0.5")).out()
* s("hh*8").never(x=>x.speed("0.5"))
*/
Pattern.prototype.never = function (func) {
return this;
@ -499,7 +499,7 @@ Pattern.prototype.never = function (func) {
* @memberof Pattern
* @returns Pattern
* @example
* s("hh*8").always(x=>x.speed("0.5")).out()
* s("hh*8").always(x=>x.speed("0.5"))
*/
Pattern.prototype.always = function (func) {
return func(this);

View File

@ -18,7 +18,6 @@ Either install with `npm i @strudel.cycles/embed` or just use a cdn to import th
.legato(sine.range(0.3, 2).slow(28))
.wave("sawtooth square".fast(2))
.filter('lowpass', cosine.range(500,4000).slow(16))
.out()
.pianoroll({minMidi:20,maxMidi:120,background:'#202124'})
-->
</strudel-repl>

View File

@ -10,7 +10,6 @@
.legato(sine.range(0.3, 2).slow(28))
.wave("sawtooth square".fast(2))
.filter('lowpass', cosine.range(500,4000).slow(16))
.out()
.pianoroll({minMidi:20,maxMidi:120,background:'#202124'})
-->
</strudel-repl>

View File

@ -15,13 +15,13 @@ npm i @strudel.cycles/webaudio --save
import { Scheduler, getAudioContext } from '@strudel.cycles/webaudio';
const scheduler = new Scheduler({
audioContext: getAudioContext(),
interval: 0.1,
onEvent: (e) => e.context?.createAudioNode?.(e),
});
const pattern = sequence([55, 99], 110).osc('sawtooth').out()
audioContext: getAudioContext(),
interval: 0.1,
onEvent: (e) => e.context?.createAudioNode?.(e),
});
const pattern = sequence([55, 99], 110).osc('sawtooth');
scheduler.setPattern(pattern);
scheduler.start()
scheduler.start();
//scheduler.stop()
```

View File

@ -98,7 +98,7 @@ export const loadGithubSamples = async (path, nameFn) => {
* bd: '808bd/BD0000.WAV',
* sd: '808sd/SD0010.WAV'
* }, 'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/');
* s("[bd ~]*2, [~ hh]*2, ~ sd").out()
* s("[bd ~]*2, [~ hh]*2, ~ sd")
*
*/

View File

@ -155,7 +155,7 @@ export const zeldasRescue = `stack(
.gain(.1)
.s('triangle')
.room(1)
.out()`;
`;
export const caverave = `const keys = x => x.s('sawtooth').cutoff(1200).gain(.5).attack(0).decay(.16).sustain(.3).release(.1);
@ -186,7 +186,7 @@ const synths = stack(
stack(
drums.fast(2),
synths
).slow(2).out()`;
).slow(2)`;
export const sampleDrums = `samples({
bd: 'bd/BT0A0D0.wav',
@ -198,7 +198,7 @@ stack(
"<bd!3 bd(3,4,2)>",
"hh*4",
"~ <sn!3 sn(3,4,1)>"
).s().out()
).s()
`;
// TODO:
@ -290,7 +290,7 @@ export const barryHarris = `backgroundImage(
.scale('C bebop major')
.transpose("<0 1 2 1>/8")
.slow(2)
.note().piano().out()
.note().piano()
`;
export const blippyRhodes = `samples({
@ -331,7 +331,7 @@ stack(
.slow(2).superimpose(x=>x.add(.02))
.note().gain(.3)
.s('sawtooth').cutoff(600),
).fast(3/2).out()`;
).fast(3/2)`;
export const wavyKalimba = `samples({
'kalimba': { c5:'https://freesound.org/data/previews/536/536549_11935698-lq.mp3' }
@ -359,7 +359,7 @@ stack(
.clip(1)
.s('kalimba')
.delay(.2)
.out()`;
`;
// TODO: rework tune to use freq
/*
@ -401,7 +401,7 @@ stack(
.scaleTranspose("0 4 0 6".early(".125 .5")).layer(scaleTranspose("0,<2 [4,6] [5,7]>/4"))
).slow(2)
.velocity(sine.struct("x*8").add(3/5).mul(2/5).fast(8))
.note().piano().out()`;
.note().piano()`;
// iter, echo, echoWith
export const undergroundPlumber = `backgroundImage('https://images.nintendolife.com/news/2016/08/video_exploring_the_funky_inspiration_for_the_super_mario_bros_underground_theme/large.jpg',{ className:'darken' })
@ -425,7 +425,7 @@ stack(
.echoWith(4, 1/8, (x,n)=>x.transpose(n*12).velocity(Math.pow(.4,n)))
.legato(.1)
.layer(h).note()
).out()
)
.fast(2/3)
.pianoroll({})`;
@ -444,7 +444,7 @@ stack(
).transpose(-1).note().piano(),
s("mad").slow(2)
).cpm(78).slow(4)
.out()
.pianoroll()
`;
@ -463,7 +463,7 @@ stack(
.scale(scale)
.scaleTranspose("<0>".slow(4))
.transpose(5)
.note().piano().out()
.note().piano()
.velocity(.8)
.slow(2)
.pianoroll({maxMidi:100,minMidi:20})`;
@ -475,7 +475,7 @@ export const echoPiano = `"<0 2 [4 6](3,4,1) 3*2>"
.off(1/2, x=>x.scaleTranspose(6).color('steelblue'))
.legato(.5)
.echo(4, 1/8, .5)
.note().piano().out()
.note().piano()
.pianoroll()`;
export const sml1 = `
@ -511,7 +511,7 @@ stack(
f3!2 e3!2 ab3!2 ~!2
>\`
.legato(.5)
).fast(2) // .note().piano().out()`;
).fast(2) // .note().piano()`;
/*
// TODO: does not work on linux (at least for me..)
@ -554,7 +554,7 @@ stack(
"<D2 A2 G2 F2>".euclidLegato(6,8,1).note().s('bass').clip(1).gain(.8)
)
.slow(6)
.out()
.pianoroll({minMidi:20,maxMidi:120,background:'transparent'})
`;
@ -570,7 +570,7 @@ export const waa2 = `n(
.cutoff(cosine.range(500,4000).slow(16))
.gain(.5)
.room(.5)
.out()`;
`;
export const hyperpop = `const lfo = cosine.slow(15);
const lfo2 = sine.slow(16);
@ -618,7 +618,7 @@ stack(
"~ sn",
"[~ hh3]*2"
).s().fast(2).gain(.7)
).slow(2).out()
).slow(2)
// strudel disable-highlighting`;
export const festivalOfFingers3 = `"[-7*3],0,2,6,[8 7]"
@ -634,7 +634,7 @@ export const festivalOfFingers3 = `"[-7*3],0,2,6,[8 7]"
.scale(cat('D dorian','G mixolydian','C dorian','F mixolydian'))
.legato(1)
.slow(2)
.note().piano().out()
.note().piano()
//.pianoroll({maxMidi:160})`;
export const bossa = `
@ -642,7 +642,7 @@ const scales = sequence('C minor', ['D locrian', 'G phrygian'], 'Bb2 minor', ['C
stack(
"<Cm7 [Dm7b5 G7b9] Bbm7 [Cm7b5 F7b9]>".fast(2).struct("x ~ x@3 x ~ x ~ ~ ~ x ~ x@3".late(1/8)).early(1/8).slow(2).voicings(),
"[~ [0 ~]] 0 [~ [4 ~]] 4".sub(7).restart(scales).scale(scales).early(.25)
).note().piano().out().slow(2)`;
).note().piano().slow(2)`;
/*
export const customTrigger = `stack(
freq("55 [110,165] 110 [220,275]".mul("<1 <3/4 2/3>>").struct("x(3,8)").layer(x=>x.mul("1.006,.995"))),
@ -701,7 +701,7 @@ stack(
.echoWith(4,.125,(x,n)=>x.gain(.15*1/(n+1))) // echo notes
//.hush()
)
.out()
.slow(3/2)`;
export const swimmingWithSoundfonts = `stack(
@ -763,7 +763,7 @@ export const swimmingWithSoundfonts = `stack(
"[G2 C2 F2 F2]"
).s('Acoustic Bass: Bass')
).slow(51)
.out()`;
`;
export const outroMusic = `samples({
bd: ['bd/BT0AADA.wav','bd/BT0AAD0.wav','bd/BT0A0DA.wav','bd/BT0A0D3.wav','bd/BT0A0D0.wav','bd/BT0A0A7.wav'],
@ -790,7 +790,7 @@ export const outroMusic = `samples({
.n(3).color('gray')
).slow(3/2)
//.pianoroll({autorange:1,vertical:1,fold:0})
.out()`;
`;
export const bassFuge = `samples({ flbass: ['00_c2_finger_long_neck.wav','01_c2_finger_short_neck.wav','02_c2_finger_long_bridge.wav','03_c2_finger_short_bridge.wav','04_c2_pick_long.wav','05_c2_pick_short.wav','06_c2_palm_mute.wav'] },
'github:cleary/samples-flbass/main/')
@ -814,7 +814,7 @@ x=>x.add(7).color('steelblue')
//.hcutoff(400)
.clip(1)
.stack(s("bd:1*2,~ sd:0,[~ hh:0]*2"))
.out()
.pianoroll({vertical:1})`;
export const bossaRandom = `const chords = "<Am7 Am7 Dm7 E7>"
@ -826,7 +826,7 @@ stack(
x? ~ ~ x@3 ~ x |
x? ~ ~ x ~ x@3\`),
roots.struct("x [~ x?0.2] x [~ x?] | x!4 | x@2 ~ ~ ~ x x x").transpose("0 7")
).slow(2).pianoroll().note().piano().out()`;
).slow(2).pianoroll().note().piano()`;
export const chop = `samples({ p: 'https://cdn.freesound.org/previews/648/648433_11943129-lq.mp3' })
@ -837,14 +837,14 @@ s("p")
.shape(.4)
.decay(.1)
.sustain(.6)
.out()`;
`;
export const delay = `stack(
s("bd <sd cp>")
.delay("<0 .5>")
.delaytime(".16 | .33")
.delayfeedback(".6 | .8")
).sometimes(x=>x.speed("-1")).out()`;
).sometimes(x=>x.speed("-1"))`;
export const orbit = `stack(
s("bd <sd cp>")
@ -856,4 +856,4 @@ export const orbit = `stack(
.delaytime(.08)
.delayfeedback(.7)
.orbit(2)
).sometimes(x=>x.speed("-1")).out()`;
).sometimes(x=>x.speed("-1"))`;

View File

@ -18,34 +18,33 @@ The best place to actually make music with Strudel is the [Strudel REPL](https:/
To get a taste of what Strudel can do, check out this track:
<MiniRepl
tune={`const delay = new FeedbackDelay(1/8, .4).chain(vol(0.5), out());
const kick = new MembraneSynth().chain(vol(.8), out());
const snare = new NoiseSynth().chain(vol(.8), out());
const hihat = new MetalSynth().set(adsr(0, .08, 0, .1)).chain(vol(.3).connect(delay),out());
const bass = new Synth().set({ ...osc('sawtooth'), ...adsr(0, .1, .4) }).chain(lowpass(900), vol(.5), out());
const keys = new PolySynth().set({ ...osc('sawtooth'), ...adsr(0, .5, .2, .7) }).chain(lowpass(1200), vol(.5), out());
const drums = stack(
"c1*2".tone(kick).bypass("<0@7 1>/8"),
"~ <x!7 [x@3 x]>".tone(snare).bypass("<0@7 1>/4"),
"[~ c4]*2".tone(hihat)
);
const thru = (x) => x.transpose("<0 1>/8").transpose(-1);
const synths = stack(
"<eb4 d4 c4 b3>/2".scale(timeCat([3,'C minor'],[1,'C melodic minor']).slow(8)).struct("[~ x]\*2")
.layer(
scaleTranspose(0).early(0),
scaleTranspose(2).early(1/8),
scaleTranspose(7).early(1/4),
scaleTranspose(8).early(3/8)
).layer(thru).tone(keys).bypass("<1 0>/16"),
"<C2 Bb1 Ab1 [G1 [G2 G1]]>/2".struct("[x [~ x] <[~ [~ x]]!3 [x x]>@2]/2".fast(2)).layer(thru).tone(bass),
"<Cm7 Bb7 Fm7 G7b13>/2".struct("~ [x@0.1 ~]".fast(2)).voicings().layer(thru).every(2, early(1/8)).tone(keys).bypass("<0@7 1>/8".early(1/4))
)
tune={`samples({
bd: ['bd/BT0AADA.wav','bd/BT0AAD0.wav','bd/BT0A0DA.wav','bd/BT0A0D3.wav','bd/BT0A0D0.wav','bd/BT0A0A7.wav'],
sd: ['sd/rytm-01-classic.wav','sd/rytm-00-hard.wav'],
hh: ['hh27/000_hh27closedhh.wav','hh/000_hh3closedhh.wav'],
}, 'github:tidalcycles/Dirt-Samples/master/');
stack(
drums.fast(2),
synths
).slow(2);
`}
s("bd,[~ <sd!3 sd(3,4,2)>],hh(3,4)") // drums
.speed(perlin.range(.7,.9)) // random sample speed variation
,"<a1 b1\*2 a1(3,8) e2>" // bassline
.off(1/8,x=>x.add(12).degradeBy(.5)) // random octave jumps
.add(perlin.range(0,.5)) // random pitch variation
.superimpose(add(.05)) // add second, slightly detuned voice
.n() // wrap in "n"
.decay(.15).sustain(0) // make each note of equal length
.s('sawtooth') // waveform
.gain(.4) // turn down
.cutoff(sine.slow(7).range(300,5000)) // automate cutoff
,"<Am7!3 <Em7 E7b13 Em7 Ebm7b5>>".voicings() // chords
.superimpose(x=>x.add(.04)) // add second, slightly detuned voice
.add(perlin.range(0,.5)) // random pitch variation
.n() // wrap in "n"
.s('sawtooth') // waveform
.gain(.16) // turn down
.cutoff(500) // fixed cutoff
.attack(1) // slowly fade in
)
.slow(3/2)`}
/>
[Open this track in the REPL](https://strudel.tidalcycles.org/#KCkgPT4gewogIGNvbnN0IGRlbGF5ID0gbmV3IEZlZWRiYWNrRGVsYXkoMS84LCAuNCkuY2hhaW4odm9sKDAuNSksIG91dCk7CiAgY29uc3Qga2ljayA9IG5ldyBNZW1icmFuZVN5bnRoKCkuY2hhaW4odm9sKC44KSwgb3V0KTsKICBjb25zdCBzbmFyZSA9IG5ldyBOb2lzZVN5bnRoKCkuY2hhaW4odm9sKC44KSwgb3V0KTsKICBjb25zdCBoaWhhdCA9IG5ldyBNZXRhbFN5bnRoKCkuc2V0KGFkc3IoMCwgLjA4LCAwLCAuMSkpLmNoYWluKHZvbCguMykuY29ubmVjdChkZWxheSksb3V0KTsKICBjb25zdCBiYXNzID0gbmV3IFN5bnRoKCkuc2V0KHsgLi4ub3NjKCdzYXd0b290aCcpLCAuLi5hZHNyKDAsIC4xLCAuNCkgfSkuY2hhaW4obG93cGFzcyg5MDApLCB2b2woLjUpLCBvdXQpOwogIGNvbnN0IGtleXMgPSBuZXcgUG9seVN5bnRoKCkuc2V0KHsgLi4ub3NjKCdzYXd0b290aCcpLCAuLi5hZHNyKDAsIC41LCAuMiwgLjcpIH0pLmNoYWluKGxvd3Bhc3MoMTIwMCksIHZvbCguNSksIG91dCk7CiAgCiAgY29uc3QgZHJ1bXMgPSBzdGFjaygKICAgICdjMSoyJy5tLnRvbmUoa2ljaykuYnlwYXNzKCc8MEA3IDE%2BLzgnLm0pLAogICAgJ34gPHghNyBbeEAzIHhdPicubS50b25lKHNuYXJlKS5ieXBhc3MoJzwwQDcgMT4vNCcubSksCiAgICAnW34gYzRdKjInLm0udG9uZShoaWhhdCkKICApOwogIAogIGNvbnN0IHRocnUgPSAoeCkgPT4geC50cmFuc3Bvc2UoJzwwIDE%2BLzgnLm0pLnRyYW5zcG9zZSgtMSk7CiAgY29uc3Qgc3ludGhzID0gc3RhY2soCiAgICAnPGViNCBkNCBjNCBiMz4vMicubS5zY2FsZSh0aW1lQ2F0KFszLCdDIG1pbm9yJ10sWzEsJ0MgbWVsb2RpYyBtaW5vciddKS5zbG93KDgpKS5ncm9vdmUoJ1t%2BIHhdKjInLm0pCiAgICAuZWRpdCgKICAgICAgc2NhbGVUcmFuc3Bvc2UoMCkuZWFybHkoMCksCiAgICAgIHNjYWxlVHJhbnNwb3NlKDIpLmVhcmx5KDEvOCksCiAgICAgIHNjYWxlVHJhbnNwb3NlKDcpLmVhcmx5KDEvNCksCiAgICAgIHNjYWxlVHJhbnNwb3NlKDgpLmVhcmx5KDMvOCkKICAgICkuZWRpdCh0aHJ1KS50b25lKGtleXMpLmJ5cGFzcygnPDEgMD4vMTYnLm0pLAogICAgJzxDMiBCYjEgQWIxIFtHMSBbRzIgRzFdXT4vMicubS5ncm9vdmUoJ1t4IFt%2BIHhdIDxbfiBbfiB4XV0hMyBbeCB4XT5AMl0vMicubS5mYXN0KDIpKS5lZGl0KHRocnUpLnRvbmUoYmFzcyksCiAgICAnPENtNyBCYjcgRm03IEc3YjEzPi8yJy5tLmdyb292ZSgnfiBbeEAwLjEgfl0nLm0uZmFzdCgyKSkudm9pY2luZ3MoKS5lZGl0KHRocnUpLmV2ZXJ5KDIsIGVhcmx5KDEvOCkpLnRvbmUoa2V5cykuYnlwYXNzKCc8MEA3IDE%2BLzgnLm0uZWFybHkoMS80KSkKICApCiAgcmV0dXJuIHN0YWNrKAogICAgZHJ1bXMuZmFzdCgyKSwgCiAgICBzeW50aHMKICApLnNsb3coMik7Cn0%3D)
@ -191,52 +190,20 @@ resulting in a rhythmical structure of "x ~ ~ x ~ ~ x ~" (3 beats over 8 segment
# Web Audio Output
The default way to output sound is by using the Web Audio Output.
Here is a little beat to show some of the possibilities:
<MiniRepl
tune={`samples({
bd: ['bd/BT0AADA.wav','bd/BT0AAD0.wav','bd/BT0A0DA.wav','bd/BT0A0D3.wav','bd/BT0A0D0.wav','bd/BT0A0A7.wav'],
sd: ['sd/rytm-01-classic.wav','sd/rytm-00-hard.wav'],
hh: ['hh27/000_hh27closedhh.wav','hh/000_hh3closedhh.wav'],
}, 'github:tidalcycles/Dirt-Samples/master/');
stack(
s("bd,[~ <sd!3 sd(3,4,2)>],hh(3,4)") // drums
.speed(perlin.range(.7,.9)) // random sample speed variation
,"<a1 b1\*2 a1(3,8) e2>" // bassline
.off(1/8,x=>x.add(12).degradeBy(.5)) // random octave jumps
.add(perlin.range(0,.5)) // random pitch variation
.superimpose(add(.05)) // add second, slightly detuned voice
.n() // wrap in "n"
.decay(.15).sustain(0) // make each note of equal length
.s('sawtooth') // waveform
.gain(.4) // turn down
.cutoff(sine.slow(7).range(300,5000)) // automate cutoff
,"<Am7!3 <Em7 E7b13 Em7 Ebm7b5>>".voicings() // chords
.superimpose(x=>x.add(.04)) // add second, slightly detuned voice
.add(perlin.range(0,.5)) // random pitch variation
.n() // wrap in "n"
.s('sawtooth') // waveform
.gain(.16) // turn down
.cutoff(500) // fixed cutoff
.attack(1) // slowly fade in
)
.slow(3/2)
.out()`}
/>
## Synths
So far, all the mini notation examples all used the same sound, which is kind of boring.
We can change the sound, using the `s` function:
<MiniRepl tune={`note("c2 <eb2 <g2 g1>>").s('sawtooth').out()`} />
<MiniRepl tune={`note("c2 <eb2 <g2 g1>>").s('sawtooth')`} />
Here, we are wrapping our notes inside `note` and set the sound using `s`, connected by a dot.
Those functions are only 2 of many ways to alter the properties, or _params_ of a sound.
The power of patterns allows us to sequence any _param_ independently:
<MiniRepl tune={`note("c2 <eb2 <g2 g1>>").s("<sawtooth square triangle>").out()`} />
<MiniRepl tune={`note("c2 <eb2 <g2 g1>>").s("<sawtooth square triangle>")`} />
Now we not only pattern the notes, but the sound as well!
`sawtooth` `square` and `triangle` are the basic waveforms available in `s`.
@ -247,14 +214,14 @@ You can control the envelope of a synth using the `attack`, `decay`, `sustain` a
<MiniRepl
tune={`note("c2 <eb2 <g2 g1>>").s('sawtooth')
.attack(.1).decay(.1).sustain(.2).release(.1).out()`}
.attack(.1).decay(.1).sustain(.2).release(.1)`}
/>
## Samples
Besides Synths, `s` can also play back samples:
<MiniRepl tune={`s("bd sd,hh*8,misc/2").out()`} />
<MiniRepl tune={`s("bd sd,hh*8,misc/2")`} />
To know which sounds are available, open the [default sample map](https://strudel.tidalcycles.org/EmuSP12.json)
@ -268,7 +235,7 @@ You can load your own sample map like this:
sd: 'sd/rytm-01-classic.wav',
hh: 'hh27/000_hh27closedhh.wav',
}, 'https://raw.githubusercontent.com/tidalcycles/Dirt-Samples/master/');
s("bd sd,hh*8").out()`}
s("bd sd,hh*8")`}
/>
The `samples` function takes an object that maps sound names to audio file paths.
@ -282,7 +249,7 @@ Because github is a popular choice to dump samples, there is a shortcut for that
sd: 'sd/rytm-01-classic.wav',
hh: 'hh27/000_hh27closedhh.wav',
}, 'github:tidalcycles/Dirt-Samples/master/');
s("bd sd,hh*8").out()`}
s("bd sd,hh*8")`}
/>
The format is `github:user/repo/branch/`.
@ -297,7 +264,7 @@ It is also possible, to declare multiple files for one sound, using the array no
sd: ['sd/rytm-01-classic.wav','sd/rytm-00-hard.wav'],
hh: ['hh27/000_hh27closedhh.wav','hh/000_hh3closedhh.wav'],
}, 'github:tidalcycles/Dirt-Samples/master/');
s("<bd:0 bd:1>,~ <sd:0 sd:1>,[hh:0 hh:1]*2").out()`}
s("<bd:0 bd:1>,~ <sd:0 sd:1>,[hh:0 hh:1]*2")`}
/>
The `:0` `:1` etc. are the indices of the array.
@ -309,7 +276,7 @@ The sample number can also be set using `n`:
sd: ['sd/rytm-01-classic.wav','sd/rytm-00-hard.wav'],
hh: ['hh27/000_hh27closedhh.wav','hh/000_hh3closedhh.wav'],
}, 'github:tidalcycles/Dirt-Samples/master/');
s("bd,~ sd,hh*4").n("<0 1>").out()`}
s("bd,~ sd,hh*4").n("<0 1>")`}
/>
### Pitched Sounds
@ -320,7 +287,7 @@ For pitched sounds, you can use `note`, just like with synths:
tune={`samples({
"gtr": 'gtr/0001_cleanC.wav',
}, 'github:tidalcycles/Dirt-Samples/master/');
note("g3 [bb3 c4] <g4 f4 eb4 f3>@2").s('gtr').gain(.5).out()`}
note("g3 [bb3 c4] <g4 f4 eb4 f3>@2").s('gtr').gain(.5)`}
/>
Here, the guitar samples will overlap, because they always play till the end.
@ -331,7 +298,7 @@ If we want them to behave more like a synth, we can add `clip(1)`:
"gtr": 'gtr/0001_cleanC.wav',
}, 'github:tidalcycles/Dirt-Samples/master/');
note("g3 [bb3 c4] <g4 f4 eb4 f3>@2").s('gtr').clip(1)
.gain(.5).out()`}
.gain(.5)`}
/>
### Base Pitch
@ -344,7 +311,7 @@ If we have 2 samples with different base pitches, we can make them in tune by sp
"moog": { 'g3': 'moog/005_Mighty%20Moog%20G3.wav' },
}, 'github:tidalcycles/Dirt-Samples/master/');
note("g3 [bb3 c4] <g4 f4 eb4 f3>@2").s("gtr,moog").clip(1)
.gain(.5).out()`}
.gain(.5)`}
/>
If a sample has no pitch set, `c3` is the default.
@ -360,7 +327,7 @@ We can also declare different samples for different regions of the keyboard:
}}, 'github:tidalcycles/Dirt-Samples/master/');
note("g2!2 <bb2 c3>!2, <c4@3 [<eb4 bb3> g4 f4]>")
.s('moog').clip(1)
.gain(.5).out()`}
.gain(.5)`}
/>
The sampler will always pick the closest matching sample for the current note!