build tutorial

This commit is contained in:
Felix Roos 2022-02-19 21:20:36 +01:00
parent f0a96ba75d
commit 8339d18e0a
5 changed files with 81 additions and 37 deletions

14
docs/dist/tonal.js vendored
View File

@ -18,7 +18,8 @@ export function intervalDirection(from, to, direction = 1) {
}
function scaleTranspose(scale, offset, note) {
let [tonic, scaleName] = Scale.tokenize(scale);
const {notes} = Scale.get(`${tonic} ${scaleName}`);
let {notes} = Scale.get(`${tonic} ${scaleName}`);
notes = notes.map((note2) => Note.get(note2).pc);
offset = Number(offset);
if (isNaN(offset)) {
throw new Error(`scale offset "${offset}" not a number`);
@ -64,7 +65,16 @@ Pattern.prototype._scaleTranspose = function(offset) {
});
};
Pattern.prototype._scale = function(scale) {
return this._mapNotes((value) => ({...value, scale}));
return this._mapNotes((value) => {
let note = value.value;
const asNumber = Number(note);
if (!isNaN(asNumber)) {
let [tonic, scaleName] = Scale.tokenize(scale);
const {pc, oct = 3} = Note.get(tonic);
note = scaleTranspose(pc + " " + scaleName, asNumber, pc + oct);
}
return {...value, value: note, scale};
});
};
Pattern.prototype.define("transpose", (a, pat) => pat.transpose(a), {composable: true, patternified: true});
Pattern.prototype.define("scale", (a, pat) => pat.scale(a), {composable: true, patternified: true});

12
docs/dist/voicings.js vendored
View File

@ -22,16 +22,14 @@ Pattern.prototype.voicings = function(range) {
return stack(...lastVoicing);
});
};
Pattern.prototype.chordBass = function() {
Pattern.prototype.rootNotes = function(octave = 2) {
return this._mapNotes((value) => {
console.log("value", value);
const [_, root] = value.value.match(/^([a-gC-G])[b#]?.*$/);
const bassNote = root + "2";
const [_, root] = value.value.match(/^([a-gA-G])[b#]?.*$/);
const bassNote = root + octave;
return {...value, value: bassNote};
});
};
Pattern.prototype.define("voicings", (range, pat) => pat.voicings(range), {composable: true});
Pattern.prototype.define("chordBass", (pat) => {
console.log("call chordBass ...", pat);
return pat.chordBass();
Pattern.prototype.define("rootNotes", (pat) => {
return pat.rootNotes();
}, {composable: true});

View File

@ -7676,17 +7676,42 @@ synth('sawtooth16').gain('[.2 .8]*8'.m).slow(4)`,
tune: `"c2 c3".m.
synth('sawtooth16').autofilter('<1 4 8>'.m)`,
mdxType: "MiniRepl"
}), /*#__PURE__*/ _react1.mdx("h2", null, `Tonal API`), /*#__PURE__*/ _react1.mdx("p", null, `TODO, see`), /*#__PURE__*/ _react1.mdx("ul", null, /*#__PURE__*/ _react1.mdx("li", {
parentName: "ul"
}, /*#__PURE__*/ _react1.mdx("a", {
parentName: "li",
"href": "https://github.com/tidalcycles/strudel/blob/main/repl/src/tonal.ts"
}, `https://github.com/tidalcycles/strudel/blob/main/repl/src/tonal.ts`)), /*#__PURE__*/ _react1.mdx("li", {
parentName: "ul"
}, /*#__PURE__*/ _react1.mdx("a", {
parentName: "li",
"href": "https://github.com/tidalcycles/strudel/blob/main/repl/src/voicings.ts"
}, `https://github.com/tidalcycles/strudel/blob/main/repl/src/voicings.ts`))), /*#__PURE__*/ _react1.mdx("h2", null, `MIDI API`), /*#__PURE__*/ _react1.mdx("p", null, `TODO, see `, /*#__PURE__*/ _react1.mdx("a", {
}), /*#__PURE__*/ _react1.mdx("h2", null, `Tonal API`), /*#__PURE__*/ _react1.mdx("p", null, `The Tonal API, uses `, /*#__PURE__*/ _react1.mdx("a", {
parentName: "p",
"href": "https://github.com/tonaljs/tonal"
}, `tonaljs`), ` to provide helpers for musical operations.`), /*#__PURE__*/ _react1.mdx("h3", null, `transpose(semitones)`), /*#__PURE__*/ _react1.mdx("p", null, `Transposes all notes to the given number of semitones:`), /*#__PURE__*/ _react1.mdx(_miniReplDefault.default, {
tune: `"c2 c3".m.fast(2).transpose('<0 -2 5 3>'.m.slow(2)).transpose(0)`,
mdxType: "MiniRepl"
}), /*#__PURE__*/ _react1.mdx("p", null, `This method gets really exciting when we use it with a pattern as above.`), /*#__PURE__*/ _react1.mdx("p", null, `Instead of numbers, scientific interval notation can be used as well:`), /*#__PURE__*/ _react1.mdx(_miniReplDefault.default, {
tune: `"c2 c3".m.fast(2).transpose('<1P -2M 4P 3m>'.m.slow(2)).transpose(1)`,
mdxType: "MiniRepl"
}), /*#__PURE__*/ _react1.mdx("h3", null, `scale(name)`), /*#__PURE__*/ _react1.mdx("p", null, `Turns numbers into notes in the scale (zero indexed). Also sets scale for other scale operations, like scaleTranpose.`), /*#__PURE__*/ _react1.mdx(_miniReplDefault.default, {
tune: `"0 2 4 6 4 2".m
.scale(slowcat('C2 major', 'C2 minor').slow(2))`,
mdxType: "MiniRepl"
}), /*#__PURE__*/ _react1.mdx("p", null, `Note that the scale root is octaved here. You can also omit the octave, then index zero will default to octave 3.`), /*#__PURE__*/ _react1.mdx("p", null, `All the available scale names can be found `, /*#__PURE__*/ _react1.mdx("a", {
parentName: "p",
"href": "https://github.com/tonaljs/tonal/blob/main/packages/scale-type/data.ts"
}, `here`), `.`), /*#__PURE__*/ _react1.mdx("h3", null, `scaleTranspose(steps)`), /*#__PURE__*/ _react1.mdx("p", null, `Transposes notes inside the scale by the number of steps:`), /*#__PURE__*/ _react1.mdx(_miniReplDefault.default, {
tune: `"-8 [2,4,6]".m
.scale('C4 bebop major')
.scaleTranspose('<0 -1 -2 -3 -4 -5 -6 -4>'.m)`,
mdxType: "MiniRepl"
}), /*#__PURE__*/ _react1.mdx("h3", null, `voicings(range?)`), /*#__PURE__*/ _react1.mdx("p", null, `Turns chord symbols into voicings, using the smoothest voice leading possible:`), /*#__PURE__*/ _react1.mdx(_miniReplDefault.default, {
tune: `stack("<C^7 A7 Dm7 G7>".m.voicings(), '<C3 A2 D3 G2>'.m)`,
mdxType: "MiniRepl"
}), /*#__PURE__*/ _react1.mdx("p", null, `TODO: use voicing collection as first param + patternify.`), /*#__PURE__*/ _react1.mdx("h3", null, `rootNotes(octave = 2)`), /*#__PURE__*/ _react1.mdx("p", null, `Turns chord symbols into root notes of chords in given octave.`), /*#__PURE__*/ _react1.mdx(_miniReplDefault.default, {
tune: `"<C^7 A7b13 Dm7 G7>".m.rootNotes(3)`,
mdxType: "MiniRepl"
}), /*#__PURE__*/ _react1.mdx("p", null, `Together with edit, groove and voicings, this can be used to create a basic backing track:`), /*#__PURE__*/ _react1.mdx(_miniReplDefault.default, {
tune: `"<C^7 A7b13 Dm7 G7>".m.edit(
x => x.voicings(['d3','g4']).groove('~ x'.m),
x => x.rootNotes(2).tone(synth(osc('sawtooth4')).chain(out))
)`,
height: 150,
mdxType: "MiniRepl"
}), /*#__PURE__*/ _react1.mdx("p", null, `TODO: use range instead of octave.
TODO: find out why composition does not work`), /*#__PURE__*/ _react1.mdx("h2", null, `MIDI API`), /*#__PURE__*/ _react1.mdx("p", null, `TODO, see `, /*#__PURE__*/ _react1.mdx("a", {
parentName: "p",
"href": "https://github.com/tidalcycles/strudel/blob/main/repl/src/midi.ts"
}, `https://github.com/tidalcycles/strudel/blob/main/repl/src/midi.ts`)), /*#__PURE__*/ _react1.mdx("h1", null, `Contributing`), /*#__PURE__*/ _react1.mdx("p", null, `Contributions of any sort are very welcome! You can contribute by editing `, /*#__PURE__*/ _react1.mdx("a", {
@ -57710,11 +57735,11 @@ Pattern.prototype.voicings = function(range) {
return _strudelMjs.stack(...lastVoicing);
});
};
Pattern.prototype.chordBass = function() {
Pattern.prototype.rootNotes = function(octave = 2) {
// range = ['G1', 'C3']
return this._mapNotes((value)=>{
console.log('value', value);
const [_, root] = value.value.match(/^([a-gC-G])[b#]?.*$/);
const bassNote = root + '2';
const [_, root] = value.value.match(/^([a-gA-G])[b#]?.*$/);
const bassNote = root + octave;
return {
...value,
value: bassNote
@ -57725,9 +57750,9 @@ Pattern.prototype.define('voicings', (range, pat)=>pat.voicings(range)
, {
composable: true
});
Pattern.prototype.define('chordBass', (pat)=>{
console.log('call chordBass ...', pat);
return pat.chordBass();
Pattern.prototype.define('rootNotes', (pat)=>{
// console.log('call rootNotes ...', pat);
return pat.rootNotes();
}, {
composable: true
});
@ -62353,14 +62378,16 @@ function intervalDirection(from, to, direction = 1) {
return (sign < 0 ? '-' : '') + interval;
}
// transpose note inside scale by offset steps
function scaleTranspose(scale, offset, note) {
function scaleTranspose(scale, offset, note1) {
let [tonic, scaleName] = _tonal.Scale.tokenize(scale);
const { notes } = _tonal.Scale.get(`${tonic} ${scaleName}`);
let { notes } = _tonal.Scale.get(`${tonic} ${scaleName}`);
notes = notes.map((note)=>_tonal.Note.get(note).pc
); // use only pc!
offset = Number(offset);
if (isNaN(offset)) throw new Error(`scale offset "${offset}" not a number`);
const { pc: fromPc , oct =3 } = _tonal.Note.get(note);
const { pc: fromPc , oct =3 } = _tonal.Note.get(note1);
const noteIndex = notes.indexOf(fromPc);
if (noteIndex === -1) throw new Error(`note "${note}" is not in scale "${scale}"`);
if (noteIndex === -1) throw new Error(`note "${note1}" is not in scale "${scale}"`);
let i = noteIndex, o = oct, n = fromPc;
const direction = Math.sign(offset);
// TODO: find way to do this smarter
@ -62407,11 +62434,20 @@ Pattern.prototype._scaleTranspose = function(offset) {
});
};
Pattern.prototype._scale = function(scale) {
return this._mapNotes((value)=>({
return this._mapNotes((value)=>{
let note = value.value;
const asNumber = Number(note);
if (!isNaN(asNumber)) {
let [tonic, scaleName] = _tonal.Scale.tokenize(scale);
const { pc , oct =3 } = _tonal.Note.get(tonic);
note = scaleTranspose(pc + ' ' + scaleName, asNumber, pc + oct);
}
return {
...value,
value: note,
scale
})
);
};
});
};
Pattern.prototype.define('transpose', (a, pat)=>pat.transpose(a)
, {
@ -108871,4 +108907,4 @@ exports.default = cx;
},{"@parcel/transformer-js/src/esmodule-helpers.js":"gkKU3"}]},["3uVTb"], "3uVTb", "parcelRequire94c2")
//# sourceMappingURL=index.6618aa59.js.map
//# sourceMappingURL=index.8b62917f.js.map

File diff suppressed because one or more lines are too long

View File

@ -11,6 +11,6 @@
<body>
<div id="root"></div>
<noscript>You need to enable JavaScript to run this app.</noscript>
<script src="/tutorial/index.6618aa59.js" defer=""></script>
<script src="/tutorial/index.8b62917f.js" defer=""></script>
</body>
</html>