Merge pull request #11 from Bubobubobubobubo/sequences_overhaul
Sequences overhaul
This commit is contained in:
163
src/API.ts
163
src/API.ts
@ -22,21 +22,175 @@ interface ControlChange {
|
|||||||
value: number;
|
value: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
interface Array<T> {
|
||||||
|
palindrome(): T[];
|
||||||
|
random(index: number): T;
|
||||||
|
rand(index: number): T;
|
||||||
|
degrade(amount: number): T;
|
||||||
|
repeatAll(amount: number): T;
|
||||||
|
repeatPair(amount: number): T;
|
||||||
|
repeatOdd(amount: number): T;
|
||||||
|
loop(index: number): T;
|
||||||
|
div(division: number): T;
|
||||||
|
shuffle(): this;
|
||||||
|
rotate(steps: number): this;
|
||||||
|
unique(): this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Array.prototype.shuffle = function () {
|
||||||
|
let currentIndex = this.length,
|
||||||
|
randomIndex;
|
||||||
|
while (currentIndex !== 0) {
|
||||||
|
randomIndex = Math.floor(Math.random() * currentIndex);
|
||||||
|
currentIndex--;
|
||||||
|
[this[currentIndex], this[randomIndex]] = [
|
||||||
|
this[randomIndex],
|
||||||
|
this[currentIndex],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
|
||||||
|
Array.prototype.rotate = function (steps: number) {
|
||||||
|
const length = this.length;
|
||||||
|
if (steps < 0) {
|
||||||
|
steps = length + (steps % length);
|
||||||
|
} else if (steps > 0) {
|
||||||
|
steps = steps % length;
|
||||||
|
} else {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
const rotated = this.splice(-steps, steps);
|
||||||
|
this.unshift(...rotated);
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
|
||||||
|
Array.prototype.unique = function () {
|
||||||
|
const seen = new Set();
|
||||||
|
let writeIndex = 0;
|
||||||
|
for (let readIndex = 0; readIndex < this.length; readIndex++) {
|
||||||
|
const value = this[readIndex];
|
||||||
|
if (!seen.has(value)) {
|
||||||
|
seen.add(value);
|
||||||
|
this[writeIndex++] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.length = writeIndex;
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
|
||||||
|
Array.prototype.degrade = function <T>(this: T[], amount: number) {
|
||||||
|
if (amount < 0 || amount > 100) {
|
||||||
|
throw new Error("Amount should be between 0 and 100");
|
||||||
|
}
|
||||||
|
if (this.length <= 1) {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
for (let i = 0; i < this.length; ) {
|
||||||
|
const rand = Math.random() * 100;
|
||||||
|
if (rand < amount) {
|
||||||
|
if (this.length > 1) {
|
||||||
|
this.splice(i, 1);
|
||||||
|
} else {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
|
||||||
|
Array.prototype.repeatAll = function <T>(this: T[], amount: number) {
|
||||||
|
if (amount < 1) {
|
||||||
|
throw new Error("Amount should be at least 1");
|
||||||
|
}
|
||||||
|
let result = [];
|
||||||
|
for (let i = 0; i < this.length; i++) {
|
||||||
|
for (let j = 0; j < amount; j++) {
|
||||||
|
result.push(this[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.length = 0;
|
||||||
|
this.push(...result);
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
|
||||||
|
Array.prototype.repeatPair = function <T>(this: T[], amount: number) {
|
||||||
|
if (amount < 1) {
|
||||||
|
throw new Error("Amount should be at least 1");
|
||||||
|
}
|
||||||
|
|
||||||
|
let result = [];
|
||||||
|
|
||||||
|
for (let i = 0; i < this.length; i++) {
|
||||||
|
// If the index is even, repeat the element
|
||||||
|
if (i % 2 === 0) {
|
||||||
|
for (let j = 0; j < amount; j++) {
|
||||||
|
result.push(this[i]);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
result.push(this[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update the original array
|
||||||
|
this.length = 0;
|
||||||
|
this.push(...result);
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
|
||||||
|
Array.prototype.repeatOdd = function <T>(this: T[], amount: number) {
|
||||||
|
if (amount < 1) {
|
||||||
|
throw new Error("Amount should be at least 1");
|
||||||
|
}
|
||||||
|
|
||||||
|
let result = [];
|
||||||
|
|
||||||
|
for (let i = 0; i < this.length; i++) {
|
||||||
|
// If the index is odd, repeat the element
|
||||||
|
if (i % 2 !== 0) {
|
||||||
|
for (let j = 0; j < amount; j++) {
|
||||||
|
result.push(this[i]);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
result.push(this[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update the original array
|
||||||
|
this.length = 0;
|
||||||
|
this.push(...result);
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
Array.prototype.palindrome = function (index) {
|
Array.prototype.palindrome = function <T>() {
|
||||||
let left_to_right = Array.from(this);
|
let left_to_right = Array.from(this);
|
||||||
let right_to_left = Array.from(this.reverse());
|
let right_to_left = Array.from(this.reverse());
|
||||||
return left_to_right.concat(right_to_left);
|
return left_to_right.concat(right_to_left);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// @ts-ignore
|
||||||
|
Array.prototype.random = function <T>(this: T[], index: number): T {
|
||||||
|
return this[Math.floor(Math.random() * this.length)];
|
||||||
|
};
|
||||||
|
|
||||||
|
Array.prototype.loop = function <T>(this: T[], index: number): T {
|
||||||
|
return this[index % this.length];
|
||||||
|
};
|
||||||
|
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
Array.prototype.random = function (index) {
|
Array.prototype.random = function (index) {
|
||||||
return this[Math.floor(Math.random() * this.length)];
|
return this[Math.floor(Math.random() * this.length)];
|
||||||
};
|
};
|
||||||
// @ts-ignore
|
|
||||||
Array.prototype.loop = function (index) {
|
Array.prototype.loop = function (index) {
|
||||||
return this[index % this.length];
|
return this[index % this.length];
|
||||||
};
|
};
|
||||||
// @ts-ignore
|
|
||||||
Array.prototype.rand = Array.prototype.random;
|
Array.prototype.rand = Array.prototype.random;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -52,13 +206,12 @@ Array.prototype.in = function <T>(this: T[], value: T): boolean {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export async function loadSamples() {
|
export async function loadSamples() {
|
||||||
// const ds = "https://raw.githubusercontent.com/felixroos/dough-samples/main/";
|
|
||||||
return Promise.all([
|
return Promise.all([
|
||||||
initAudioOnFirstClick(),
|
initAudioOnFirstClick(),
|
||||||
samples("github:Bubobubobubobubo/Topos-Samples/main"),
|
|
||||||
samples("github:tidalcycles/Dirt-Samples/master").then(() =>
|
samples("github:tidalcycles/Dirt-Samples/master").then(() =>
|
||||||
registerSynthSounds()
|
registerSynthSounds()
|
||||||
),
|
),
|
||||||
|
samples("github:Bubobubobubobubo/Topos-Samples/main"),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -523,7 +523,7 @@ There are three basic filters: a _lowpass_, _highpass_ and _bandpass_ filters wi
|
|||||||
|
|
||||||
\`\`\`javascript
|
\`\`\`javascript
|
||||||
mod(.5) && snd('sawtooth')
|
mod(.5) && snd('sawtooth')
|
||||||
.cutoff(pick(2000,500)) + usine(.5) * 4000)
|
.cutoff(pick(2000,500) + usine(.5) * 4000)
|
||||||
.resonance(0.9).freq(pick(100,150))
|
.resonance(0.9).freq(pick(100,150))
|
||||||
.out()
|
.out()
|
||||||
\`\`\`
|
\`\`\`
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import { type Editor } from '../main';
|
import { type Editor } from "../main";
|
||||||
import { AudibleEvent } from './AbstractEvents';
|
import { AudibleEvent } from "./AbstractEvents";
|
||||||
import { midiToFreq, noteFromPc } from 'zifferjs';
|
import { midiToFreq, noteFromPc } from "zifferjs";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
superdough,
|
superdough,
|
||||||
@ -8,7 +8,6 @@ import {
|
|||||||
} from "superdough";
|
} from "superdough";
|
||||||
|
|
||||||
export class SoundEvent extends AudibleEvent {
|
export class SoundEvent extends AudibleEvent {
|
||||||
|
|
||||||
constructor(sound: string | object, public app: Editor) {
|
constructor(sound: string | object, public app: Editor) {
|
||||||
super(app);
|
super(app);
|
||||||
if (typeof sound === "string") this.values = { s: sound, dur: 0.5 };
|
if (typeof sound === "string") this.values = { s: sound, dur: 0.5 };
|
||||||
|
|||||||
34
src/main.ts
34
src/main.ts
@ -559,23 +559,6 @@ export class Editor {
|
|||||||
(globalThis as Record<string, any>)[name] = value;
|
(globalThis as Record<string, any>)[name] = value;
|
||||||
});
|
});
|
||||||
|
|
||||||
// Loading from URL bar
|
|
||||||
let url = new URLSearchParams(window.location.search);
|
|
||||||
if (url !== undefined) {
|
|
||||||
let new_universe;
|
|
||||||
if (url !== null) {
|
|
||||||
const universeParam = url.get("universe");
|
|
||||||
if (universeParam !== null) {
|
|
||||||
new_universe = JSON.parse(atob(universeParam));
|
|
||||||
const randomName: string = uniqueNamesGenerator({
|
|
||||||
dictionaries: [adjectives, colors, animals],
|
|
||||||
});
|
|
||||||
this.loadUniverse(randomName, new_universe["universe"]);
|
|
||||||
this.emptyUrl();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this.state = EditorState.create({
|
this.state = EditorState.create({
|
||||||
extensions: [
|
extensions: [
|
||||||
...this.editorExtensions,
|
...this.editorExtensions,
|
||||||
@ -602,6 +585,23 @@ export class Editor {
|
|||||||
});
|
});
|
||||||
|
|
||||||
this.changeModeFromInterface("global");
|
this.changeModeFromInterface("global");
|
||||||
|
|
||||||
|
// Loading from URL bar
|
||||||
|
let url = new URLSearchParams(window.location.search);
|
||||||
|
if (url !== undefined) {
|
||||||
|
let new_universe;
|
||||||
|
if (url !== null) {
|
||||||
|
const universeParam = url.get("universe");
|
||||||
|
if (universeParam !== null) {
|
||||||
|
new_universe = JSON.parse(atob(universeParam));
|
||||||
|
const randomName: string = uniqueNamesGenerator({
|
||||||
|
dictionaries: [adjectives, colors, animals],
|
||||||
|
});
|
||||||
|
this.loadUniverse(randomName, new_universe["universe"]);
|
||||||
|
this.emptyUrl();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
get note_buffer() {
|
get note_buffer() {
|
||||||
|
|||||||
Reference in New Issue
Block a user