mirror of
https://github.com/eliasstepanik/strudel-docker.git
synced 2026-01-11 13:48:34 +00:00
add note calls everywhere
This commit is contained in:
parent
5d7e46b246
commit
08c4c641ec
@ -32,52 +32,52 @@ const euclid = (pulses, steps, rotation = 0) => {
|
||||
* @returns Pattern
|
||||
* @example
|
||||
* // The Cuban tresillo pattern.
|
||||
* n("c3").euclid(3,8)
|
||||
* note("c3").euclid(3,8)
|
||||
*/
|
||||
|
||||
/**
|
||||
* @example // A thirteenth century Persian rhythm called Khafif-e-ramal.
|
||||
* n("c3").euclid(2,5)
|
||||
* note("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)
|
||||
* note("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.
|
||||
* "c3".euclid(3,5,2)
|
||||
* note("c3").euclid(3,5,2)
|
||||
* @example // A Ruchenitza rhythm used in a Bulgarian folk-dance.
|
||||
* "c3".euclid(3,7)
|
||||
* note("c3").euclid(3,7)
|
||||
* @example // The Cuban tresillo pattern.
|
||||
* "c3".euclid(3,8)
|
||||
* note("c3").euclid(3,8)
|
||||
* @example // Another Ruchenitza Bulgarian folk-dance rhythm.
|
||||
* "c3".euclid(4,7)
|
||||
* note("c3").euclid(4,7)
|
||||
* @example // The Aksak rhythm of Turkey.
|
||||
* "c3".euclid(4,9)
|
||||
* note("c3").euclid(4,9)
|
||||
* @example // The metric pattern used by Frank Zappa in his piece titled Outside Now.
|
||||
* "c3".euclid(4,11)
|
||||
* note("c3").euclid(4,11)
|
||||
* @example // Yields the York-Samai pattern, a popular Arab rhythm.
|
||||
* "c3".euclid(5,6)
|
||||
* note("c3").euclid(5,6)
|
||||
* @example // The Nawakhat pattern, another popular Arab rhythm.
|
||||
* "c3".euclid(5,7)
|
||||
* note("c3").euclid(5,7)
|
||||
* @example // The Cuban cinquillo pattern.
|
||||
* "c3".euclid(5,8)
|
||||
* note("c3").euclid(5,8)
|
||||
* @example // A popular Arab rhythm called Agsag-Samai.
|
||||
* "c3".euclid(5,9)
|
||||
* note("c3").euclid(5,9)
|
||||
* @example // The metric pattern used by Moussorgsky in Pictures at an Exhibition.
|
||||
* "c3".euclid(5,11)
|
||||
* note("c3").euclid(5,11)
|
||||
* @example // The Venda clapping pattern of a South African children’s song.
|
||||
* "c3".euclid(5,12)
|
||||
* note("c3").euclid(5,12)
|
||||
* @example // The Bossa-Nova rhythm necklace of Brazil.
|
||||
* "c3".euclid(5,16)
|
||||
* note("c3").euclid(5,16)
|
||||
* @example // A typical rhythm played on the Bendir (frame drum).
|
||||
* "c3".euclid(7,8)
|
||||
* note("c3").euclid(7,8)
|
||||
* @example // A common West African bell pattern.
|
||||
* "c3".euclid(7,12)
|
||||
* note("c3").euclid(7,12)
|
||||
* @example // A Samba rhythm necklace from Brazil.
|
||||
* "c3".euclid(7,16,14)
|
||||
* note("c3").euclid(7,16,14)
|
||||
* @example // A rhythm necklace used in the Central African Republic.
|
||||
* "c3".euclid(9,16)
|
||||
* note("c3").euclid(9,16)
|
||||
* @example // A rhythm necklace of the Aka Pygmies of Central Africa.
|
||||
* "c3".euclid(11,24,14)
|
||||
* note("c3").euclid(11,24,14)
|
||||
* @example // Another rhythm necklace of the Aka Pygmies of the upper Sangha.
|
||||
* "c3".euclid(13,24,5)
|
||||
* note("c3").euclid(13,24,5)
|
||||
*/
|
||||
Pattern.prototype.euclid = function (pulses, steps, rotation = 0) {
|
||||
return this.struct(euclid(pulses, steps, rotation));
|
||||
|
||||
@ -472,7 +472,7 @@ export class Pattern {
|
||||
* @memberof Pattern
|
||||
* @returns Pattern
|
||||
* @example
|
||||
* "0.5 1.5 2.5".round().scale('C major')
|
||||
* "0.5 1.5 2.5".round().scale('C major').note()
|
||||
*/
|
||||
round() {
|
||||
return this._asNumber().fmap((v) => Math.round(v));
|
||||
@ -704,7 +704,7 @@ export class Pattern {
|
||||
* @name apply
|
||||
* @memberof Pattern
|
||||
* @example
|
||||
* "<c3 eb3 g3>".scale('C minor').apply(scaleTranspose("0,2,4"))
|
||||
* "<c3 eb3 g3>".scale('C minor').apply(scaleTranspose("0,2,4")).note()
|
||||
*/
|
||||
_apply(func) {
|
||||
return func(this);
|
||||
@ -925,9 +925,9 @@ export class Pattern {
|
||||
* @memberof Pattern
|
||||
* @returns Pattern
|
||||
* @example
|
||||
* "c3,eb3,g3"
|
||||
* note("c3,eb3,g3")
|
||||
* .struct("x ~ x ~ ~ x ~ x ~ ~ ~ x ~ x ~ ~")
|
||||
* .slow(4).note()
|
||||
* .slow(4)
|
||||
*/
|
||||
// struct(...binary_pats) {
|
||||
// // Re structure the pattern according to a binary pattern (false values are dropped)
|
||||
@ -984,7 +984,7 @@ export class Pattern {
|
||||
* @param {function} func
|
||||
* @returns Pattern
|
||||
* @example
|
||||
* "c3 eb3 g3".when("<0 1>/2", x=>x.sub(5))
|
||||
* "c3 eb3 g3".when("<0 1>/2", x=>x.sub(5)).note()
|
||||
*/
|
||||
when(binary_pat, func) {
|
||||
//binary_pat = sequence(binary_pat)
|
||||
@ -1003,7 +1003,7 @@ export class Pattern {
|
||||
* @param {function} func function to apply
|
||||
* @returns Pattern
|
||||
* @example
|
||||
* "c3 eb3 g3".off(1/8, x=>x.add(7))
|
||||
* "c3 eb3 g3".off(1/8, x=>x.add(7)).note()
|
||||
*/
|
||||
off(time_pat, func) {
|
||||
return stack(this, func(this.late(time_pat)));
|
||||
@ -1077,7 +1077,7 @@ export class Pattern {
|
||||
* @memberof Pattern
|
||||
* @returns Pattern
|
||||
* @example
|
||||
* "c3 d3 e3 g3".rev()
|
||||
* note("c3 d3 e3 g3").rev()
|
||||
*/
|
||||
rev() {
|
||||
const pat = this;
|
||||
@ -1297,7 +1297,7 @@ export class Pattern {
|
||||
* @name legato
|
||||
* @memberof Pattern
|
||||
* @example
|
||||
* n("c3 eb3 g3 c4").legato("<.25 .5 1 2>")
|
||||
* note("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))));
|
||||
@ -1387,14 +1387,14 @@ function _composeOp(a, b, func) {
|
||||
* @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')
|
||||
* "0 2 4".add("<0 3 4 0>").scale('C major').note()
|
||||
* // Without add, the equivalent would be:
|
||||
* // "<[0 2 4] [3 5 7] [4 6 8] [0 2 4]>".scale('C major')
|
||||
* // "<[0 2 4] [3 5 7] [4 6 8] [0 2 4]>".scale('C major').note()
|
||||
* @example
|
||||
* // You can also use add with notes:
|
||||
* "c3 e3 g3".add("<0 5 7 0>")
|
||||
* "c3 e3 g3".add("<0 5 7 0>").note()
|
||||
* // Behind the scenes, the notes are converted to midi numbers:
|
||||
* // "48 52 55".add("<0 5 7 0>")
|
||||
* // "48 52 55".add("<0 5 7 0>").note()
|
||||
*/
|
||||
add: [(a, b) => a + b, numOrString], // support string concatenation
|
||||
/**
|
||||
@ -1403,7 +1403,7 @@ function _composeOp(a, b, func) {
|
||||
* @name sub
|
||||
* @memberof Pattern
|
||||
* @example
|
||||
* "0 2 4".sub("<0 1 2 3>").scale('C4 minor')
|
||||
* "0 2 4".sub("<0 1 2 3>").scale('C4 minor').note()
|
||||
* // See add for more information.
|
||||
*/
|
||||
sub: [(a, b) => a - b, num],
|
||||
@ -1579,7 +1579,7 @@ export function reify(thing) {
|
||||
*
|
||||
* @return {Pattern}
|
||||
* @example
|
||||
* stack(g3, b3, [e4, d4]) // "g3,b3,[e4,d4]"
|
||||
* stack(g3, b3, [e4, d4]).note() // "g3,b3,[e4,d4]".note()
|
||||
*/
|
||||
export function stack(...pats) {
|
||||
// Array test here is to avoid infinite recursions..
|
||||
@ -1652,7 +1652,7 @@ export function fastcat(...pats) {
|
||||
* @param {...any} items - The items to concatenate
|
||||
* @return {Pattern}
|
||||
* @example
|
||||
* cat(e5, b4, [d5, c5]) // "<e5 b4 [d5 c5]>"
|
||||
* cat(e5, b4, [d5, c5]).note() // "<e5 b4 [d5 c5]>".note()
|
||||
*
|
||||
*/
|
||||
export function cat(...pats) {
|
||||
@ -1662,7 +1662,7 @@ export function cat(...pats) {
|
||||
/** Like {@link seq}, but each step has a length, relative to the whole.
|
||||
* @return {Pattern}
|
||||
* @example
|
||||
* timeCat([3,e3],[1, g3]) // "e3@3 g3"
|
||||
* timeCat([3,e3],[1, g3]).note() // "e3@3 g3".note()
|
||||
*/
|
||||
export function timeCat(...timepats) {
|
||||
const total = timepats.map((a) => a[0]).reduce((a, b) => a.add(b), Fraction(0));
|
||||
@ -1683,7 +1683,7 @@ export function sequence(...pats) {
|
||||
|
||||
/** Like **cat**, but the items are crammed into one cycle. Synonyms: fastcat, sequence
|
||||
* @example
|
||||
* seq(e5, b4, [d5, c5]) // "e5 b4 [d5 c5]"
|
||||
* seq(e5, b4, [d5, c5]).note() // "e5 b4 [d5 c5]".note()
|
||||
*
|
||||
*/
|
||||
export function seq(...pats) {
|
||||
|
||||
@ -27,9 +27,9 @@ export const isaw2 = isaw._toBipolar();
|
||||
*
|
||||
* @return {Pattern}
|
||||
* @example
|
||||
* "c3 [eb3,g3] g2 [g3,bb3]".legato(saw.slow(4))
|
||||
* "c3 [eb3,g3] g2 [g3,bb3]".legato(saw.slow(4)).note()
|
||||
* @example
|
||||
* saw.range(0,8).segment(8).scale('C major').slow(4)
|
||||
* saw.range(0,8).segment(8).scale('C major').slow(4).note()
|
||||
*
|
||||
*/
|
||||
export const saw = signal((t) => t % 1);
|
||||
@ -42,7 +42,7 @@ export const sine2 = signal((t) => Math.sin(Math.PI * 2 * t));
|
||||
*
|
||||
* @return {Pattern}
|
||||
* @example
|
||||
* sine.segment(16).range(0,15).slow(2).scale('C minor')
|
||||
* sine.segment(16).range(0,15).slow(2).scale('C minor').note()
|
||||
*
|
||||
*/
|
||||
export const sine = sine2._fromBipolar();
|
||||
@ -52,7 +52,7 @@ export const sine = sine2._fromBipolar();
|
||||
*
|
||||
* @return {Pattern}
|
||||
* @example
|
||||
* stack(sine,cosine).segment(16).range(0,15).slow(2).scale('C minor')
|
||||
* stack(sine,cosine).segment(16).range(0,15).slow(2).scale('C minor').note()
|
||||
*
|
||||
*/
|
||||
export const cosine = sine._early(Fraction(1).div(4));
|
||||
@ -63,7 +63,7 @@ export const cosine2 = sine2._early(Fraction(1).div(4));
|
||||
*
|
||||
* @return {Pattern}
|
||||
* @example
|
||||
* square.segment(2).range(0,7).scale('C minor')
|
||||
* square.segment(2).range(0,7).scale('C minor').note()
|
||||
*
|
||||
*/
|
||||
export const square = signal((t) => Math.floor((t * 2) % 2));
|
||||
|
||||
@ -69,9 +69,9 @@ function scaleOffset(scale, offset, note) {
|
||||
* @memberof Pattern
|
||||
* @name transpose
|
||||
* @example
|
||||
* "c2 c3".fast(2).transpose("<0 -2 5 3>".slow(2)).transpose(0)
|
||||
* "c2 c3".fast(2).transpose("<0 -2 5 3>".slow(2)).note()
|
||||
* @example
|
||||
* "c2 c3".fast(2).transpose("<1P -2M 4P 3m>".slow(2)).transpose(0)
|
||||
* "c2 c3".fast(2).transpose("<1P -2M 4P 3m>".slow(2)).note()
|
||||
*/
|
||||
|
||||
Pattern.prototype._transpose = function (intervalOrSemitones) {
|
||||
@ -107,6 +107,7 @@ Pattern.prototype._transpose = function (intervalOrSemitones) {
|
||||
* "-8 [2,4,6]"
|
||||
* .scale('C4 bebop major')
|
||||
* .scaleTranspose("<0 -1 -2 -3 -4 -5 -6 -4>")
|
||||
* .note()
|
||||
*/
|
||||
|
||||
Pattern.prototype._scaleTranspose = function (offset /* : number | string */) {
|
||||
@ -134,9 +135,10 @@ Pattern.prototype._scaleTranspose = function (offset /* : number | string */) {
|
||||
* @name scale
|
||||
* @param {string} scale Name of scale
|
||||
* @returns Pattern
|
||||
* @example
|
||||
* @example
|
||||
* "0 2 4 6 4 2"
|
||||
* .scale(seq('C2 major', 'C2 minor').slow(2))
|
||||
* .note()
|
||||
*/
|
||||
|
||||
Pattern.prototype._scale = function (scale /* : string */) {
|
||||
|
||||
@ -40,7 +40,7 @@ Pattern.prototype.fmapNested = function (func) {
|
||||
* @param {range} range note range for possible voicings (optional, defaults to `['F3', 'A4']`)
|
||||
* @returns Pattern
|
||||
* @example
|
||||
* stack("<C^7 A7 Dm7 G7>".voicings(), "<C3 A2 D3 G2>")
|
||||
* stack("<C^7 A7 Dm7 G7>".voicings(), "<C3 A2 D3 G2>").note()
|
||||
*/
|
||||
|
||||
Pattern.prototype.voicings = function (range) {
|
||||
|
||||
@ -260,9 +260,9 @@ resulting in a rhythmical structure of "x ~ ~ x ~ ~ x ~" (3 beats over 8 segment
|
||||
|
||||
<br />
|
||||
|
||||
# Web Audio Output
|
||||
# Synths, Samples & Effects
|
||||
|
||||
The default way to output sound is by using the Web Audio Output.
|
||||
Let's take a closer look at how we can control synths, sounds and effects.
|
||||
|
||||
## Synths
|
||||
|
||||
@ -447,11 +447,38 @@ Wether you're using a synth or a sample, you can apply these effects:
|
||||
|
||||
<br />
|
||||
|
||||
# Core API
|
||||
# JavaScript API
|
||||
|
||||
While the mini notation is powerful on its own, there is much more to discover.
|
||||
Internally, the mini notation will expand to use the actual functional JavaScript API.
|
||||
|
||||
For example, this Pattern in Mini Notation:
|
||||
|
||||
<MiniRepl tune={`note("c3 eb3 g3")`} />
|
||||
|
||||
is equivalent to this Pattern without Mini Notation:
|
||||
|
||||
<MiniRepl tune={`note(seq(c3, eb3, g3))`} />
|
||||
|
||||
Similarly, there is an equivalent function for every aspect of the mini notation.
|
||||
|
||||
Which representation to use is a matter of context. As a rule of thumb, you can think of the JavaScript API
|
||||
to fit better for the larger context, while mini notation is more practical for individiual rhythms.
|
||||
|
||||
## Limits of Mini Notation
|
||||
|
||||
While the Mini Notation is a powerful way to write rhythms shortly, it also has its limits. Take this example:
|
||||
|
||||
<MiniRepl
|
||||
tune={`stack(
|
||||
note("c2 eb2(3,8)").s('sawtooth').cutoff(800),
|
||||
s("bd,~ sd,hh*4")
|
||||
)`}
|
||||
/>
|
||||
|
||||
Here, we are using mini notation for the individual rhythms, while using the function `stack` to mix them.
|
||||
While stack is also available as `,` in mini notation, we cannot use it here, because we have different types of sounds.
|
||||
|
||||
## Notes
|
||||
|
||||
Notes are automatically available as variables:
|
||||
@ -474,15 +501,17 @@ To avoid getting to many nested parens, there is an alternative syntax to add a
|
||||
|
||||
<MiniRepl tune={`seq(d4, fs4, a4).note()`} />
|
||||
|
||||
You can use this with any function that declares a type, just make sure to leave the parens empty!
|
||||
You can use this with any function that declares a type (like `n`, `s`, `note`, `freq` etc), just make sure to leave the parens empty!
|
||||
|
||||
## Pattern Factories
|
||||
|
||||
The following functions will return a pattern.
|
||||
|
||||
<!--
|
||||
{{ 'pure' | jsdoc }}
|
||||
|
||||
Most of the time, you won't need that function as input values of pattern creating functions are purified by default.
|
||||
-->
|
||||
|
||||
{{ 'cat' | jsdoc }}
|
||||
|
||||
@ -526,7 +555,7 @@ You can freely mix JS patterns, mini patterns and values! For example, this patt
|
||||
stack(a3,c3,e4),
|
||||
stack(b3,d3,fs4),
|
||||
stack(b3,e4,g4)
|
||||
)`}
|
||||
).note()`}
|
||||
/>
|
||||
|
||||
...is equivalent to:
|
||||
@ -537,12 +566,12 @@ You can freely mix JS patterns, mini patterns and values! For example, this patt
|
||||
"a3,c3,e4",
|
||||
"b3,d3,f#4",
|
||||
"b3,e4,g4"
|
||||
)`}
|
||||
).note()`}
|
||||
/>
|
||||
|
||||
... as well as:
|
||||
|
||||
<MiniRepl tune={`"<[g3,b3,e4] [a3,c3,e4] [b3,d3,f#4] [b3,e4,g4]>"`} />
|
||||
<MiniRepl tune={`note("<[g3,b3,e4] [a3,c3,e4] [b3,d3,f#4] [b3,e4,g4]>")`} />
|
||||
|
||||
While mini notation is almost always shorter, it only has a handful of modifiers: \* / ! @.
|
||||
When using JS patterns, there is a lot more you can do.
|
||||
@ -689,13 +718,13 @@ The Tonal API, uses [tonaljs](https://github.com/tonaljs/tonal) to provide helpe
|
||||
|
||||
Transposes all notes to the given number of semitones:
|
||||
|
||||
<MiniRepl tune={`"c2 c3".fast(2).transpose("<0 -2 5 3>".slow(2)).transpose(0)`} />
|
||||
<MiniRepl tune={`"c2 c3".fast(2).transpose("<0 -2 5 3>".slow(2)).note()`} />
|
||||
|
||||
This method gets really exciting when we use it with a pattern as above.
|
||||
|
||||
Instead of numbers, scientific interval notation can be used as well:
|
||||
|
||||
<MiniRepl tune={`"c2 c3".fast(2).transpose("<1P -2M 4P 3m>".slow(2)).transpose(1)`} />
|
||||
<MiniRepl tune={`"c2 c3".fast(2).transpose("<1P -2M 4P 3m>".slow(2)).note()`} />
|
||||
|
||||
### scale(name)
|
||||
|
||||
@ -703,7 +732,8 @@ Turns numbers into notes in the scale (zero indexed). Also sets scale for other
|
||||
|
||||
<MiniRepl
|
||||
tune={`"0 2 4 6 4 2"
|
||||
.scale(seq('C2 major', 'C2 minor').slow(2))`}
|
||||
.scale(seq('C2 major', 'C2 minor').slow(2))
|
||||
.note()`}
|
||||
/>
|
||||
|
||||
Note that the scale root is octaved here. You can also omit the octave, then index zero will default to octave 3.
|
||||
@ -717,14 +747,15 @@ Transposes notes inside the scale by the number of steps:
|
||||
<MiniRepl
|
||||
tune={`"-8 [2,4,6]"
|
||||
.scale('C4 bebop major')
|
||||
.scaleTranspose("<0 -1 -2 -3 -4 -5 -6 -4>")`}
|
||||
.scaleTranspose("<0 -1 -2 -3 -4 -5 -6 -4>")
|
||||
.note()`}
|
||||
/>
|
||||
|
||||
### voicings(range?)
|
||||
|
||||
Turns chord symbols into voicings, using the smoothest voice leading possible:
|
||||
|
||||
<MiniRepl tune={`stack("<C^7 A7 Dm7 G7>".voicings(), "<C3 A2 D3 G2>")`} />
|
||||
<MiniRepl tune={`stack("<C^7 A7 Dm7 G7>".voicings(), "<C3 A2 D3 G2>").note()`} />
|
||||
|
||||
<!-- TODO: use voicing collection as first param + patternify. -->
|
||||
|
||||
@ -732,7 +763,7 @@ Turns chord symbols into voicings, using the smoothest voice leading possible:
|
||||
|
||||
Turns chord symbols into root notes of chords in given octave.
|
||||
|
||||
<MiniRepl tune={`"<C^7 A7b13 Dm7 G7>".rootNotes(3)`} />
|
||||
<MiniRepl tune={`"<C^7 A7b13 Dm7 G7>".rootNotes(3).note()`} />
|
||||
|
||||
Together with layer, struct and voicings, this can be used to create a basic backing track:
|
||||
|
||||
@ -740,7 +771,7 @@ Together with layer, struct and voicings, this can be used to create a basic bac
|
||||
tune={`"<C^7 A7b13 Dm7 G7>".layer(
|
||||
x => x.voicings(['d3','g4']).struct("~ x"),
|
||||
x => x.rootNotes(2).tone(synth(osc('sawtooth4')).chain(out()))
|
||||
)`}
|
||||
).note()`}
|
||||
/>
|
||||
|
||||
<!-- TODO: use range instead of octave. -->
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user