mirror of
https://github.com/eliasstepanik/strudel-docker.git
synced 2026-01-11 13:48:34 +00:00
Merge pull request #228 from tidalcycles/just-another-docs-branch
Just another docs branch
This commit is contained in:
commit
2ed290a214
@ -62,12 +62,12 @@ const generic_params = [
|
||||
*/
|
||||
['f', 'accelerate', 'a pattern of numbers that speed up (or slow down) samples while they play.'],
|
||||
/**
|
||||
* Like {@link amp}, but exponential.
|
||||
* Controls the gain by an exponential amount.
|
||||
*
|
||||
* @name gain
|
||||
* @param {number | Pattern} amount gain.
|
||||
* @example
|
||||
* s("bd*8").gain(".7*2 1 .7*2 1 .7 1").osc()
|
||||
* s("hh*8").gain(".4!2 1 .4!2 1 .4 1").out()
|
||||
*
|
||||
*/
|
||||
[
|
||||
@ -147,10 +147,12 @@ const generic_params = [
|
||||
/**
|
||||
* a pattern of numbers from 0 to 1. Skips the beginning of each sample, e.g. `0.25` to cut off the first quarter from each sample.
|
||||
*
|
||||
* @memberof Pattern
|
||||
* @name begin
|
||||
* @param {number | Pattern} amount between 0 and 1, where 1 is the length of the sample
|
||||
* @example
|
||||
* s("rave").begin("<0 .25 .5 .75>").osc()
|
||||
* samples({ rave: 'rave/AREUREADY.wav' }, 'github:tidalcycles/Dirt-Samples/master/')
|
||||
* s("rave").begin("<0 .25 .5 .75>").out()
|
||||
*
|
||||
*/
|
||||
[
|
||||
@ -159,12 +161,13 @@ const generic_params = [
|
||||
'a pattern of numbers from 0 to 1. Skips the beginning of each sample, e.g. `0.25` to cut off the first quarter from each sample.',
|
||||
],
|
||||
/**
|
||||
* The same as {@link begin}, but cuts off the end off each sample.
|
||||
* The same as .begin, but cuts off the end off each sample.
|
||||
*
|
||||
* @memberof Pattern
|
||||
* @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>").osc()
|
||||
* s("bd*2,ho*4").end("<.1 .2 .5 1>").out()
|
||||
*
|
||||
*/
|
||||
[
|
||||
|
||||
@ -25,14 +25,19 @@ const euclid = (pulses, steps, rotation = 0) => {
|
||||
* describe a large number of rhythms used in the most important music world traditions.
|
||||
*
|
||||
* @memberof Pattern
|
||||
* @name euclid
|
||||
* @param {number} pulses the number of onsets / beats
|
||||
* @param {number} steps the number of steps to fill
|
||||
* @param {number} rotation (optional) offset in steps
|
||||
* @returns Pattern
|
||||
* @example // The Cuban tresillo pattern.
|
||||
* "c3".euclid(3,8)
|
||||
* @example
|
||||
* // The Cuban tresillo pattern.
|
||||
* n("c3").euclid(3,8).out()
|
||||
*/
|
||||
|
||||
/**
|
||||
* @example // A thirteenth century Persian rhythm called Khafif-e-ramal.
|
||||
* "c3".euclid(2,5)
|
||||
* n("c3").euclid(2,5)
|
||||
* @example // The archetypal pattern of the Cumbia from Colombia, as well as a Calypso rhythm from Trinidad.
|
||||
* "c3".euclid(3,4)
|
||||
* @example // Another thirteenth century Persian rhythm by the name of Khafif-e-ramal, as well as a Rumanian folk-dance rhythm.
|
||||
@ -79,7 +84,11 @@ Pattern.prototype.euclid = function (pulses, steps, rotation = 0) {
|
||||
};
|
||||
|
||||
/**
|
||||
* Similar to {@link Pattern#euclid}, but each pulse is held until the next pulse, so there will be no gaps.
|
||||
* Similar to `.euclid`, but each pulse is held until the next pulse, so there will be no gaps.
|
||||
* @name euclidLegato
|
||||
* @memberof Pattern
|
||||
* @example
|
||||
* n("g2").decay(.1).sustain(.3).euclidLegato(3,8).out()
|
||||
*/
|
||||
Pattern.prototype.euclidLegato = function (pulses, steps, rotation = 0) {
|
||||
const bin_pat = euclid(pulses, steps, rotation);
|
||||
|
||||
@ -468,7 +468,11 @@ export class Pattern {
|
||||
/**
|
||||
* Assumes a numerical pattern. Returns a new pattern with all values rounded
|
||||
* to the nearest integer.
|
||||
* @name round
|
||||
* @memberof Pattern
|
||||
* @returns Pattern
|
||||
* @example
|
||||
* "0.5 1.5 2.5".round().scale('C major')
|
||||
*/
|
||||
round() {
|
||||
return this._asNumber().fmap((v) => Math.round(v));
|
||||
@ -695,6 +699,13 @@ export class Pattern {
|
||||
return this.fmap(func)._squeezeJoin();
|
||||
}
|
||||
|
||||
/**
|
||||
* Like layer, but with a single function:
|
||||
* @name apply
|
||||
* @memberof Pattern
|
||||
* @example
|
||||
* "<c3 eb3 g3>".scale('C minor').apply(scaleTranspose("0,2,4"))
|
||||
*/
|
||||
_apply(func) {
|
||||
return func(this);
|
||||
}
|
||||
@ -772,7 +783,7 @@ export class Pattern {
|
||||
_focus(b, e) {
|
||||
return this._fast(Fraction(1).div(e.sub(b))).late(b.cyclePos());
|
||||
}
|
||||
|
||||
|
||||
_focusSpan(span) {
|
||||
return this._focus(span.begin, span.end);
|
||||
}
|
||||
@ -818,6 +829,20 @@ export class Pattern {
|
||||
return this.fmap((x) => pure(x)._fast(factor))._squeezeJoin();
|
||||
}
|
||||
|
||||
/**
|
||||
* Cuts each sample into the given number of parts, allowing you to explore a technique known as 'granular synthesis'.
|
||||
* It turns a pattern of samples into a pattern of parts of samples.
|
||||
* @name chop
|
||||
* @memberof Pattern
|
||||
* @returns Pattern
|
||||
* @example
|
||||
* samples({ rhodes: 'https://cdn.freesound.org/previews/132/132051_316502-lq.mp3' })
|
||||
* s("rhodes")
|
||||
* .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);
|
||||
const slice_objects = slices.map((i) => ({ begin: i / n, end: (i + 1) / n }));
|
||||
@ -1189,6 +1214,9 @@ export class Pattern {
|
||||
* @name echo
|
||||
* @memberof Pattern
|
||||
* @returns Pattern
|
||||
* @param {number} times how many times to repeat
|
||||
* @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()
|
||||
*/
|
||||
@ -1261,16 +1289,40 @@ export class Pattern {
|
||||
return this.withHapSpan((span) => new TimeSpan(span.begin, span.begin.add(value)));
|
||||
}
|
||||
|
||||
// sets hap relative duration of haps
|
||||
/**
|
||||
*
|
||||
* Multiplies the hap duration with the given factor.
|
||||
* @name legato
|
||||
* @memberof Pattern
|
||||
* @example
|
||||
* n("c3 eb3 g3 c4").legato("<.25 .5 1 2>").out()
|
||||
*/
|
||||
_legato(value) {
|
||||
return this.withHapSpan((span) => new TimeSpan(span.begin, span.begin.add(span.end.sub(span.begin).mul(value))));
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Sets the velocity from 0 to 1. Is multiplied together with gain.
|
||||
* @name velocity
|
||||
* @example
|
||||
* s("hh*8")
|
||||
* .gain(".4!2 1 .4!2 1 .4 1")
|
||||
* .velocity(".4 1").out()
|
||||
*/
|
||||
_velocity(velocity) {
|
||||
return this._withContext((context) => ({ ...context, velocity: (context.velocity || 1) * velocity }));
|
||||
}
|
||||
|
||||
// move this to controls? (speed and unit are controls)
|
||||
/**
|
||||
* Makes the sample fit the given number of cycles by changing the speed.
|
||||
* @name loopAt
|
||||
* @memberof Pattern
|
||||
* @returns Pattern
|
||||
* @example
|
||||
* samples({ rhodes: 'https://cdn.freesound.org/previews/132/132051_316502-lq.mp3' })
|
||||
* s("rhodes").loopAt(4,1).out()
|
||||
*/
|
||||
_loopAt(factor, cps = 1) {
|
||||
return this.speed((1 / factor) * cps)
|
||||
.unit('c')
|
||||
@ -1326,9 +1378,48 @@ function _composeOp(a, b, func) {
|
||||
keepif: [(a, b) => (b ? a : undefined)],
|
||||
|
||||
// numerical functions
|
||||
/**
|
||||
*
|
||||
* Assumes a pattern of numbers. Adds the given number to each item in the pattern.
|
||||
* @name add
|
||||
* @memberof Pattern
|
||||
* @example
|
||||
* // Here, the triad 0, 2, 4 is shifted by different amounts
|
||||
* "0 2 4".add("<0 3 4 0>").scale('C major')
|
||||
* // Without add, the equivalent would be:
|
||||
* // "<[0 2 4] [3 5 7] [4 6 8] [0 2 4]>".scale('C major')
|
||||
* @example
|
||||
* // You can also use add with notes:
|
||||
* "c3 e3 g3".add("<0 5 7 0>")
|
||||
* // Behind the scenes, the notes are converted to midi numbers:
|
||||
* // "48 52 55".add("<0 5 7 0>")
|
||||
*/
|
||||
add: [(a, b) => a + b, numOrString], // support string concatenation
|
||||
/**
|
||||
*
|
||||
* Like add, but the given numbers are subtracted.
|
||||
* @name sub
|
||||
* @memberof Pattern
|
||||
* @example
|
||||
* "0 2 4".sub("<0 1 2 3>").scale('C4 minor')
|
||||
* // See add for more information.
|
||||
*/
|
||||
sub: [(a, b) => a - b, num],
|
||||
/**
|
||||
*
|
||||
* Multiplies each number by the given factor.
|
||||
* @name mul
|
||||
* @memberof Pattern
|
||||
* @example
|
||||
* "1 1.5 [1.66, <2 2.33>]".mul(150).freq().out()
|
||||
*/
|
||||
mul: [(a, b) => a * b, num],
|
||||
/**
|
||||
*
|
||||
* Divides each number by the given factor.
|
||||
* @name div
|
||||
* @memberof Pattern
|
||||
*/
|
||||
div: [(a, b) => a / b, num],
|
||||
mod: [mod, num],
|
||||
pow: [Math.pow, num],
|
||||
@ -1370,8 +1461,7 @@ function _composeOp(a, b, func) {
|
||||
// avoid union, as we want to throw away the value of 'b' completely
|
||||
result = pat['_op' + how](other, (a) => (b) => op(a, b));
|
||||
result = result._removeUndefineds();
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
result = pat['_op' + how](other, (a) => (b) => _composeOp(a, b, op));
|
||||
}
|
||||
return result;
|
||||
|
||||
@ -18,3 +18,6 @@ if (typeof AudioContext !== 'undefined') {
|
||||
return convolver;
|
||||
};
|
||||
}
|
||||
|
||||
// TODO: make the reverb more exciting
|
||||
// check out https://blog.gskinner.com/archives/2019/02/reverb-web-audio-api.html
|
||||
|
||||
@ -13,9 +13,9 @@ import '@strudel.cycles/react/dist/style.css';
|
||||
|
||||
ReactDOM.render(
|
||||
<React.StrictMode>
|
||||
<div className="min-h-screen">
|
||||
<header className="flex-none flex justify-start sticky top-0 z-[2] w-full h-16 px-2 items-center border-b border-gray-200 bg-white">
|
||||
<div className="p-4 w-full flex justify-between">
|
||||
<div className="min-h-screen bg-slate-900">
|
||||
<header className="flex-none flex justify-start sticky top-0 z-[2] w-full h-16 px-2 items-center border-b border-slate-500 text-white bg-slate-900 z-[100]">
|
||||
<div className="p-4 w-full flex justify-between items-center">
|
||||
<div className="flex items-center space-x-2">
|
||||
<img src={'https://tidalcycles.org/img/logo.svg'} className="Tidal-logo w-10 h-10" alt="logo" />
|
||||
<h1 className="text-xl cursor-pointer" onClick={() => window.scrollTo(0, 0)}>
|
||||
@ -23,15 +23,14 @@ ReactDOM.render(
|
||||
</h1>
|
||||
</div>
|
||||
{!window.location.href.includes('localhost') && (
|
||||
<div className="flex space-x-4">
|
||||
<div className="flex space-x-4 text-slate-200">
|
||||
<a href="../">go to REPL</a>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</header>
|
||||
<main className="p-4 pl-6 max-w-3xl prose">
|
||||
<main className="p-4 pl-6 max-w-3xl prose prose-invert">
|
||||
<Tutorial />
|
||||
{/* <ApiDoc /> */}
|
||||
</main>
|
||||
</div>
|
||||
</React.StrictMode>,
|
||||
|
||||
@ -365,10 +365,24 @@ note("g2!2 <bb2 c3>!2, <c4@3 [<eb4 bb3> g4 f4]>")
|
||||
|
||||
The sampler will always pick the closest matching sample for the current note!
|
||||
|
||||
## Effects
|
||||
## Sampler Effects
|
||||
|
||||
{{ 'Pattern.begin' | jsdoc }}
|
||||
|
||||
{{ 'Pattern.end' | jsdoc }}
|
||||
|
||||
{{ 'Pattern.loopAt' | jsdoc }}
|
||||
|
||||
{{ 'Pattern.chop' | jsdoc }}
|
||||
|
||||
## Audio Effects
|
||||
|
||||
Wether you're using a synth or a sample, you can apply these effects:
|
||||
|
||||
{{ 'gain' | jsdoc }}
|
||||
|
||||
{{ 'velocity' | jsdoc }}
|
||||
|
||||
{{ 'cutoff' | jsdoc }}
|
||||
|
||||
{{ 'resonance' | jsdoc }}
|
||||
@ -496,11 +510,15 @@ The following functions modify a pattern temporal structure in some way.
|
||||
|
||||
{{ 'Pattern.late' | jsdoc }}
|
||||
|
||||
{{ 'Pattern.rev' | jsdoc }}
|
||||
{{ 'Pattern.legato' | jsdoc }}
|
||||
|
||||
{{ 'Pattern.struct' | jsdoc }}
|
||||
|
||||
{{ 'Pattern.legato' | jsdoc }}
|
||||
{{ 'Pattern.euclid' | jsdoc }}
|
||||
|
||||
{{ 'Pattern.euclidLegato' | jsdoc }}
|
||||
|
||||
{{ 'Pattern.rev' | jsdoc }}
|
||||
|
||||
{{ 'Pattern.iter' | jsdoc }}
|
||||
|
||||
@ -536,63 +554,17 @@ The following functions modify a pattern temporal structure in some way.
|
||||
|
||||
## Value Modifiers
|
||||
|
||||
### add(n)
|
||||
{{ 'Pattern.add' | jsdoc }}
|
||||
|
||||
Adds the given number to each item in the pattern:
|
||||
{{ 'Pattern.sub' | jsdoc }}
|
||||
|
||||
<MiniRepl tune={`"0 2 4".add("<0 3 4 0>").scale('C major')`} />
|
||||
{{ 'Pattern.mul' | jsdoc }}
|
||||
|
||||
Here, the triad `0, 2, 4` is shifted by different amounts. Without add, the equivalent would be:
|
||||
{{ 'Pattern.div' | jsdoc }}
|
||||
|
||||
<MiniRepl tune={`"<[0 2 4] [3 5 7] [4 6 8] [0 2 4]>".scale('C major')`} />
|
||||
{{ 'Pattern.round' | jsdoc }}
|
||||
|
||||
You can also use add with notes:
|
||||
|
||||
<MiniRepl tune={`"c3 e3 g3".add("<0 5 7 0>")`} />
|
||||
|
||||
Behind the scenes, the notes are converted to midi numbers as soon before add is applied, which is equivalent to:
|
||||
|
||||
<MiniRepl tune={`"48 52 55".add("<0 5 7 0>")`} />
|
||||
|
||||
### sub(n)
|
||||
|
||||
Like add, but the given numbers are subtracted:
|
||||
|
||||
<MiniRepl tune={`"0 2 4".sub("<0 1 2 3>").scale('C4 minor')`} />
|
||||
|
||||
See add for more information.
|
||||
|
||||
### mul(n)
|
||||
|
||||
Multiplies each number by the given factor:
|
||||
|
||||
<MiniRepl tune={`"0,1,2".mul("<2 3 4 3>").scale('C4 minor')`} />
|
||||
|
||||
... is equivalent to:
|
||||
|
||||
<MiniRepl tune={`"<[0,2,4] [0,3,6] [0,4,8] [0,3,6]>".scale('C4 minor')`} />
|
||||
|
||||
This function is really useful in combination with signals:
|
||||
|
||||
<MiniRepl tune={`sine.struct("x*16").mul(7).round().scale('C major')`} />
|
||||
|
||||
Here, we sample a sine wave 16 times, and multiply each sample by 7. This way, we let values oscillate between 0 and 7.
|
||||
|
||||
### div(n)
|
||||
|
||||
Like mul, but dividing by the given number.
|
||||
|
||||
### round()
|
||||
|
||||
Rounds all values to the nearest integer:
|
||||
|
||||
<MiniRepl tune={`"0.5 1.5 2.5".round().scale('C major')`} />
|
||||
|
||||
### apply(func)
|
||||
|
||||
Like layer, but with a single function:
|
||||
|
||||
<MiniRepl tune={`"<c3 eb3 g3>".scale('C minor').apply(scaleTranspose("0,2,4"))`} />
|
||||
{{ 'Pattern.apply' | jsdoc }}
|
||||
|
||||
{{ 'Pattern.range' | jsdoc }}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user