documenting seq functions

This commit is contained in:
2023-11-14 14:50:07 +01:00
parent 2631ab5e5d
commit a4a29af0e6
8 changed files with 52 additions and 8064 deletions

View File

@ -1 +0,0 @@
if('serviceWorker' in navigator) navigator.serviceWorker.register('/dev-sw.js?dev-sw', { scope: '/', type: 'classic' })

View File

@ -1,104 +0,0 @@
/**
* Copyright 2018 Google Inc. All Rights Reserved.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// If the loader is already loaded, just stop.
if (!self.define) {
let registry = {};
// Used for `eval` and `importScripts` where we can't get script URL by other means.
// In both cases, it's safe to use a global var because those functions are synchronous.
let nextDefineUri;
const singleRequire = (uri, parentUri) => {
uri = new URL(uri + ".js", parentUri).href;
return registry[uri] || (
new Promise(resolve => {
if ("document" in self) {
const script = document.createElement("script");
script.src = uri;
script.onload = resolve;
document.head.appendChild(script);
} else {
nextDefineUri = uri;
importScripts(uri);
resolve();
}
})
.then(() => {
let promise = registry[uri];
if (!promise) {
throw new Error(`Module ${uri} didnt register its module`);
}
return promise;
})
);
};
self.define = (depsNames, factory) => {
const uri = nextDefineUri || ("document" in self ? document.currentScript.src : "") || location.href;
if (registry[uri]) {
// Module is already loading or loaded.
return;
}
let exports = {};
const require = depUri => singleRequire(depUri, uri);
const specialDeps = {
module: { uri },
exports,
require
};
registry[uri] = Promise.all(depsNames.map(
depName => specialDeps[depName] || require(depName)
)).then(deps => {
factory(...deps);
return exports;
});
};
}
define(['./workbox-b7fccfec'], (function (workbox) { 'use strict';
self.skipWaiting();
workbox.clientsClaim();
/**
* The precacheAndRoute() method efficiently caches and responds to
* requests for URLs in the manifest.
* See https://goo.gl/S9QRab
*/
workbox.precacheAndRoute([{
"url": "registerSW.js",
"revision": "3ca0b8505b4bec776b69afdba2768812"
}, {
"url": "index.html",
"revision": "0.fnf2e5c80tg"
}], {});
workbox.cleanupOutdatedCaches();
workbox.registerRoute(new workbox.NavigationRoute(workbox.createHandlerBoundToURL("index.html"), {
allowlist: [/^\/$/]
}));
workbox.registerRoute(({
url
}) => [/^https:\/\/raw\.githubusercontent\.com\/.*/i, /^https:\/\/shabda\.ndre\.gr\/.*/i].some(regex => regex.test(url)), new workbox.CacheFirst({
"cacheName": "external-samples",
plugins: [new workbox.ExpirationPlugin({
maxEntries: 5000,
maxAgeSeconds: 2592000
}), new workbox.CacheableResponsePlugin({
statuses: [0, 200]
})]
}), 'GET');
}));
//# sourceMappingURL=sw.js.map

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@ -112,6 +112,58 @@ onbeat(1.5,2.5,3.5, 3.75)::snd('hat').gain(r(0.9,1.1)).out() // Cool high-hats
true
)}
## XOX Style sequencers
- <ic>seq(expr: string, duration: number = 0.5): boolean</ic> : this function takes a string composed of <ic>x</ic> and <ic>o</ic> symbols like so: <ic>"xoxxoo"</ic>. It will return <ic>true</ic> (<ic>x</ic>) or <ic>false</ic> (<ic>o</ic>) after a <ic>duration</ic> amount.
- <ic>expr: string</ic>: any string composed of <ic>x</ic> or <ic>o</ic> like so: <ic>"xooxoxxoxoo"</ic>.
- <ic>duration: number</ic>: an optional duration (in beats) like <ic>1</ic> or </ic>4</ic>. It can be patterned.
${makeExample(
"Sequence built using a classic XOX sequencer style",
`
seq('xoxo')::sound('fhardkick').out()
seq('ooxo')::sound('fsoftsnare').out()
seq('xoxo', 0.25)::sound('fhh').out()
`,
true
)}
${makeExample(
"Another sequence using more complex parameters",
`
seq('xoxooxxoo', [0.5, 0.25].dur(2, 1))::sound('fhardkick').out()
seq('ooxo', [1, 2].bar())::sound('fsoftsnare').speed(0.5).out()
seq(['xoxoxoxx', 'xxoo'].bar())::sound('fhh').out()
`,
true
)}
- <ic>fullseq(expr: string, duration: number = 0.5): boolean</ic> : a variant. Will return <ic>true</ic> or <ic>false</ic> for a whole period, depending on the symbol. Useful for long structure patterns.
- <ic>expr: string</ic>: any string composed of <ic>x</ic> or <ic>o</ic> like so: <ic>"xooxoxxoxoo"</ic>.
- <ic>duration: number</ic>: an optional duration (in beats) like <ic>1</ic> or </ic>4</ic>. It can be patterned.
${makeExample(
"Long structured patterns",
`
function simplePat() {
log('Simple pattern playing!')
seq('xoxooxxoo', [0.5, 0.25].dur(2, 1))::sound('fhardkick').out()
seq('ooxo', [1, 2].bar())::sound('fsoftsnare').speed(0.5).out()
seq(['xoxoxoxx', 'xxoo'].bar())::sound('fhh').out()
}
function complexPat() {
log('Complex pattern playing!')
seq('xoxooxxoo', [0.5, 0.25].dur(2, 1))::sound('fhardkick').out()
seq('ooxo', [1, 2].bar())::sound('fsoftsnare').speed(0.5).out()
seq(['xoxoxoxx', 'xxoo'].bar())::sound('fhh').out()
}
fullseq('xooxooxx', 4) ? simplePat() : complexPat()
`,
true
)}
## Cyclical rhythm generators
We included a bunch of popular rhythm generators in Topos such as the euclidian rhythms algorithms or the one to generate rhythms based on a binary sequence. They all work using _iterators_ that you will gradually learn to use for iterating over lists. Note that they are levaraging <ic>mod(...n:number[])</ic> that you just learned about!