Compare commits
17 Commits
superdough
...
dependabot
| Author | SHA1 | Date | |
|---|---|---|---|
| dea8808721 | |||
| aa2eb0651d | |||
| ec68419775 | |||
| cf702fd9f1 | |||
| 5e565e3a11 | |||
| d9906857d3 | |||
| e592499711 | |||
| c13d1bb072 | |||
| d2f9376197 | |||
| 8940bf3505 | |||
| 9d7fe9e815 | |||
| 59dc42b103 | |||
| 47534a0724 | |||
| a36aa53e04 | |||
| 4db41275b4 | |||
| 8b10af555c | |||
| 2ee66cd9fb |
12
ToposServer/package-lock.json
generated
12
ToposServer/package-lock.json
generated
@ -1,16 +1,16 @@
|
|||||||
{
|
{
|
||||||
"name": "topos-server",
|
"name": "topos-server",
|
||||||
"version": "1.0.0",
|
"version": "0.0.1",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "topos-server",
|
"name": "topos-server",
|
||||||
"version": "1.0.0",
|
"version": "0.0.1",
|
||||||
"license": "GPL-3.0-or-later",
|
"license": "GPL-3.0-or-later",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"osc": "^2.4.4",
|
"osc": "^2.4.4",
|
||||||
"ws": "^8.14.2"
|
"ws": "^8.17.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@serialport/binding-mock": {
|
"node_modules/@serialport/binding-mock": {
|
||||||
@ -309,9 +309,9 @@
|
|||||||
"integrity": "sha512-P+6vtWyuDw+MB01X7UeF8TaHBvbCovf4HPEMF/SV7BdDc1SMTiBy13SRD71lQh4ExFTG1d/WNzDGDCyOKSMblw=="
|
"integrity": "sha512-P+6vtWyuDw+MB01X7UeF8TaHBvbCovf4HPEMF/SV7BdDc1SMTiBy13SRD71lQh4ExFTG1d/WNzDGDCyOKSMblw=="
|
||||||
},
|
},
|
||||||
"node_modules/ws": {
|
"node_modules/ws": {
|
||||||
"version": "8.14.2",
|
"version": "8.17.1",
|
||||||
"resolved": "https://registry.npmjs.org/ws/-/ws-8.14.2.tgz",
|
"resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz",
|
||||||
"integrity": "sha512-wEBG1ftX4jcglPxgFCMJmZ2PLtSbJ2Peg6TmpJFTbe9GZYOQCDPdMYu/Tm0/bGZkw8paZnJY45J4K2PZrLYq8g==",
|
"integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=10.0.0"
|
"node": ">=10.0.0"
|
||||||
},
|
},
|
||||||
|
|||||||
@ -10,6 +10,6 @@
|
|||||||
"license": "GPL-3.0-or-later",
|
"license": "GPL-3.0-or-later",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"osc": "^2.4.4",
|
"osc": "^2.4.4",
|
||||||
"ws": "^8.14.2"
|
"ws": "^8.17.1"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -174,6 +174,7 @@
|
|||||||
<summary class="font-semibold lg:text-xl text-orange-300">Basics</summary>
|
<summary class="font-semibold lg:text-xl text-orange-300">Basics</summary>
|
||||||
<div class="flex flex-col">
|
<div class="flex flex-col">
|
||||||
<p rel="noopener noreferrer" id="docs_introduction" class="doc_header">Welcome </p>
|
<p rel="noopener noreferrer" id="docs_introduction" class="doc_header">Welcome </p>
|
||||||
|
<p rel="noopener noreferrer" id="docs_atelier" class="doc_header">Atelier (FR)</p>
|
||||||
<p rel="noopener noreferrer" id="docs_interface" class="doc_header">Interface</p>
|
<p rel="noopener noreferrer" id="docs_interface" class="doc_header">Interface</p>
|
||||||
<p rel="noopener noreferrer" id="docs_interaction" class="doc_header">Interaction</p>
|
<p rel="noopener noreferrer" id="docs_interaction" class="doc_header">Interaction</p>
|
||||||
<p rel="noopener noreferrer" id="docs_shortcuts" class="doc_header">Keyboard</p>
|
<p rel="noopener noreferrer" id="docs_shortcuts" class="doc_header">Keyboard</p>
|
||||||
@ -367,10 +368,12 @@
|
|||||||
<input id="show-completions" type="checkbox" value="" class="w-4 h-4 text-blue-600 rounded focus:ring-blue-600 focus:ring-2">
|
<input id="show-completions" type="checkbox" value="" class="w-4 h-4 text-blue-600 rounded focus:ring-blue-600 focus:ring-2">
|
||||||
<label for="default-checkbox" class="ml-2 text-sm font-medium text-foreground">Show Completions</label>
|
<label for="default-checkbox" class="ml-2 text-sm font-medium text-foreground">Show Completions</label>
|
||||||
</div>
|
</div>
|
||||||
|
<!--
|
||||||
<div class="flex items-center mb-4 ml-5">
|
<div class="flex items-center mb-4 ml-5">
|
||||||
<input id="load-demo-songs" type="checkbox" value="" class="w-4 h-4 text-blue-600 rounded focus:ring-blue-600">
|
<input id="load-demo-songs" type="checkbox" value="" class="w-4 h-4 text-blue-600 rounded focus:ring-blue-600">
|
||||||
<label for="default-checkbox" class="ml-2 text-sm font-medium text-foreground">Load Demo Song</label>
|
<label for="default-checkbox" class="ml-2 text-sm font-medium text-foreground">Load Demo Song</label>
|
||||||
</div>
|
</div>
|
||||||
|
-->
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
14
src/API.ts
14
src/API.ts
@ -1602,6 +1602,20 @@ export class UserAPI {
|
|||||||
};
|
};
|
||||||
ry = this.rhythm;
|
ry = this.rhythm;
|
||||||
|
|
||||||
|
|
||||||
|
public nrhythm = (
|
||||||
|
div: number,
|
||||||
|
pulses: number,
|
||||||
|
length: number,
|
||||||
|
rotate: number = 0,
|
||||||
|
): boolean => {
|
||||||
|
let rhythm = this._euclidean_cycle(pulses, length, rotate).map(n => !n)
|
||||||
|
return (
|
||||||
|
this.beat(div) && rhythm.beat(div)
|
||||||
|
);
|
||||||
|
};
|
||||||
|
nry = this.nrhythm;
|
||||||
|
|
||||||
_euclidean_cycle(
|
_euclidean_cycle(
|
||||||
pulses: number,
|
pulses: number,
|
||||||
length: number,
|
length: number,
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
import { type Editor } from "./main";
|
import { type Editor } from "./main";
|
||||||
// Basics
|
// Basics
|
||||||
import { introduction } from "./documentation/basics/welcome";
|
import { introduction } from "./documentation/basics/welcome";
|
||||||
|
import { atelier } from "./documentation/basics/atelier";
|
||||||
import { loading_samples } from "./documentation/learning/samples/loading_samples";
|
import { loading_samples } from "./documentation/learning/samples/loading_samples";
|
||||||
import { amplitude } from "./documentation/learning/audio_engine/amplitude";
|
import { amplitude } from "./documentation/learning/audio_engine/amplitude";
|
||||||
import { effects } from "./documentation/learning/audio_engine/effects";
|
import { effects } from "./documentation/learning/audio_engine/effects";
|
||||||
@ -77,6 +78,7 @@ export const makeExampleFactory = (application: Editor): Function => {
|
|||||||
|
|
||||||
export const documentation_pages = [
|
export const documentation_pages = [
|
||||||
"introduction",
|
"introduction",
|
||||||
|
"atelier",
|
||||||
"sampler",
|
"sampler",
|
||||||
"amplitude",
|
"amplitude",
|
||||||
"audio_basics",
|
"audio_basics",
|
||||||
@ -126,6 +128,7 @@ export const documentation_factory = (application: Editor) => {
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
introduction: introduction(application),
|
introduction: introduction(application),
|
||||||
|
atelier: atelier(application),
|
||||||
interface: software_interface(application),
|
interface: software_interface(application),
|
||||||
interaction: interaction(application),
|
interaction: interaction(application),
|
||||||
code: code(application),
|
code: code(application),
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
// import { tutorial_universe } from "./universes/tutorial";
|
// import { tutorial_universe } from "./universes/tutorial";
|
||||||
import { gzipSync, decompressSync, strFromU8 } from "fflate";
|
import { gzipSync, decompressSync, strFromU8 } from "fflate";
|
||||||
import { examples } from "./examples/excerpts";
|
// import { examples } from "./examples/excerpts";
|
||||||
import { type Editor } from "./main";
|
import { type Editor } from "./main";
|
||||||
import { uniqueNamesGenerator, colors, animals } from "unique-names-generator";
|
import { uniqueNamesGenerator, colors, animals } from "unique-names-generator";
|
||||||
import { tryEvaluate } from "./Evaluator";
|
import { tryEvaluate } from "./Evaluator";
|
||||||
@ -63,7 +63,7 @@ export interface Settings {
|
|||||||
selected_universe: string;
|
selected_universe: string;
|
||||||
line_numbers: boolean;
|
line_numbers: boolean;
|
||||||
time_position: boolean;
|
time_position: boolean;
|
||||||
load_demo_songs: boolean;
|
// load_demo_songs: boolean;
|
||||||
tips: boolean;
|
tips: boolean;
|
||||||
completions: boolean;
|
completions: boolean;
|
||||||
send_clock: boolean;
|
send_clock: boolean;
|
||||||
@ -150,7 +150,7 @@ export class AppSettings {
|
|||||||
public midi_clock_input: string | undefined = undefined;
|
public midi_clock_input: string | undefined = undefined;
|
||||||
public default_midi_input: string | undefined = undefined;
|
public default_midi_input: string | undefined = undefined;
|
||||||
public midi_clock_ppqn: number = 24;
|
public midi_clock_ppqn: number = 24;
|
||||||
public load_demo_songs: boolean = true;
|
// public load_demo_songs: boolean = true;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
const settingsFromStorage = JSON.parse(
|
const settingsFromStorage = JSON.parse(
|
||||||
@ -174,7 +174,7 @@ export class AppSettings {
|
|||||||
this.midi_clock_input = settingsFromStorage.midi_clock_input;
|
this.midi_clock_input = settingsFromStorage.midi_clock_input;
|
||||||
this.midi_clock_ppqn = settingsFromStorage.midi_clock_ppqn || 24;
|
this.midi_clock_ppqn = settingsFromStorage.midi_clock_ppqn || 24;
|
||||||
this.default_midi_input = settingsFromStorage.default_midi_input;
|
this.default_midi_input = settingsFromStorage.default_midi_input;
|
||||||
this.load_demo_songs = settingsFromStorage.load_demo_songs;
|
// this.load_demo_songs = settingsFromStorage.load_demo_songs;
|
||||||
} else {
|
} else {
|
||||||
this.universes = template_universes;
|
this.universes = template_universes;
|
||||||
}
|
}
|
||||||
@ -204,7 +204,7 @@ export class AppSettings {
|
|||||||
midi_clock_input: this.midi_clock_input,
|
midi_clock_input: this.midi_clock_input,
|
||||||
midi_clock_ppqn: this.midi_clock_ppqn,
|
midi_clock_ppqn: this.midi_clock_ppqn,
|
||||||
default_midi_input: this.default_midi_input,
|
default_midi_input: this.default_midi_input,
|
||||||
load_demo_songs: this.load_demo_songs,
|
// load_demo_songs: this.load_demo_songs,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -232,7 +232,7 @@ export class AppSettings {
|
|||||||
this.midi_clock_input = settings.midi_clock_input;
|
this.midi_clock_input = settings.midi_clock_input;
|
||||||
this.midi_clock_ppqn = settings.midi_clock_ppqn;
|
this.midi_clock_ppqn = settings.midi_clock_ppqn;
|
||||||
this.default_midi_input = settings.default_midi_input;
|
this.default_midi_input = settings.default_midi_input;
|
||||||
this.load_demo_songs = settings.load_demo_songs;
|
// this.load_demo_songs = settings.load_demo_songs;
|
||||||
localStorage.setItem("topos", JSON.stringify(this.data));
|
localStorage.setItem("topos", JSON.stringify(this.data));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -245,13 +245,13 @@ export const initializeSelectedUniverse = (app: Editor): void => {
|
|||||||
* @param app - The main application
|
* @param app - The main application
|
||||||
* @returns void
|
* @returns void
|
||||||
*/
|
*/
|
||||||
if (app.settings.load_demo_songs) {
|
// if (app.settings.load_demo_songs) {
|
||||||
let random_example = examples[Math.floor(Math.random() * examples.length)];
|
// let random_example = examples[Math.floor(Math.random() * examples.length)];
|
||||||
app.selected_universe = "Demo";
|
// app.selected_universe = "Demo";
|
||||||
app.universes[app.selected_universe] = structuredClone(template_universe);
|
// app.universes[app.selected_universe] = structuredClone(template_universe);
|
||||||
app.universes[app.selected_universe].global.committed = random_example;
|
// app.universes[app.selected_universe].global.committed = random_example;
|
||||||
app.universes[app.selected_universe].global.candidate = random_example;
|
// app.universes[app.selected_universe].global.candidate = random_example;
|
||||||
} else {
|
// } else {
|
||||||
try {
|
try {
|
||||||
app.selected_universe = app.settings.selected_universe;
|
app.selected_universe = app.settings.selected_universe;
|
||||||
if (app.universes[app.selected_universe] === undefined)
|
if (app.universes[app.selected_universe] === undefined)
|
||||||
@ -262,7 +262,6 @@ export const initializeSelectedUniverse = (app: Editor): void => {
|
|||||||
app.selected_universe = app.settings.selected_universe;
|
app.selected_universe = app.settings.selected_universe;
|
||||||
app.universes[app.selected_universe] = structuredClone(template_universe);
|
app.universes[app.selected_universe] = structuredClone(template_universe);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
(
|
(
|
||||||
app.interface.universe_viewer as HTMLInputElement
|
app.interface.universe_viewer as HTMLInputElement
|
||||||
).placeholder! = `${app.selected_universe}`;
|
).placeholder! = `${app.selected_universe}`;
|
||||||
|
|||||||
@ -44,8 +44,8 @@ export const installInterfaceLogic = (app: Editor) => {
|
|||||||
app.settings.midi_channels_scripts;
|
app.settings.midi_channels_scripts;
|
||||||
(app.interface.midi_clock_ppqn as HTMLInputElement).value =
|
(app.interface.midi_clock_ppqn as HTMLInputElement).value =
|
||||||
app.settings.midi_clock_ppqn.toString();
|
app.settings.midi_clock_ppqn.toString();
|
||||||
(app.interface.load_demo_songs as HTMLInputElement).checked =
|
// (app.interface.load_demo_songs as HTMLInputElement).checked =
|
||||||
app.settings.load_demo_songs;
|
// app.settings.load_demo_songs;
|
||||||
|
|
||||||
const tabs = document.querySelectorAll('[id^="tab-"]');
|
const tabs = document.querySelectorAll('[id^="tab-"]');
|
||||||
// Iterate over the tabs with an index
|
// Iterate over the tabs with an index
|
||||||
@ -373,8 +373,8 @@ export const installInterfaceLogic = (app: Editor) => {
|
|||||||
midiChannelsScripts.checked = app.settings.midi_channels_scripts;
|
midiChannelsScripts.checked = app.settings.midi_channels_scripts;
|
||||||
const midiClockPpqn = app.interface.midi_clock_ppqn as HTMLInputElement;
|
const midiClockPpqn = app.interface.midi_clock_ppqn as HTMLInputElement;
|
||||||
midiClockPpqn.value = app.settings.midi_clock_ppqn.toString();
|
midiClockPpqn.value = app.settings.midi_clock_ppqn.toString();
|
||||||
const loadDemoSongs = app.interface.load_demo_songs as HTMLInputElement;
|
// const loadDemoSongs = app.interface.load_demo_songs as HTMLInputElement;
|
||||||
loadDemoSongs.checked = app.settings.load_demo_songs;
|
// loadDemoSongs.checked = app.settings.load_demo_songs;
|
||||||
const vimModeCheckbox = app.interface.vim_mode_checkbox as HTMLInputElement;
|
const vimModeCheckbox = app.interface.vim_mode_checkbox as HTMLInputElement;
|
||||||
vimModeCheckbox.checked = app.settings.vimMode;
|
vimModeCheckbox.checked = app.settings.vimMode;
|
||||||
|
|
||||||
@ -502,12 +502,12 @@ export const installInterfaceLogic = (app: Editor) => {
|
|||||||
app.settings.midi_clock_ppqn = value;
|
app.settings.midi_clock_ppqn = value;
|
||||||
});
|
});
|
||||||
|
|
||||||
app.interface.load_demo_songs.addEventListener("change", () => {
|
// app.interface.load_demo_songs.addEventListener("change", () => {
|
||||||
let checked = (app.interface.load_demo_songs as HTMLInputElement).checked
|
// let checked = (app.interface.load_demo_songs as HTMLInputElement).checked
|
||||||
? true
|
// ? true
|
||||||
: false;
|
// : false;
|
||||||
app.settings.load_demo_songs = checked;
|
// app.settings.load_demo_songs = checked;
|
||||||
});
|
// });
|
||||||
|
|
||||||
app.interface.universe_creator.addEventListener("submit", (event) => {
|
app.interface.universe_creator.addEventListener("submit", (event) => {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
|
|||||||
@ -1,4 +1,50 @@
|
|||||||
{
|
{
|
||||||
|
"theotteryears": {
|
||||||
|
"black": "#000000",
|
||||||
|
"color1": "#e52222",
|
||||||
|
"green": "#5ef763",
|
||||||
|
"yellow": "#fc951e",
|
||||||
|
"blue": "#c48dff",
|
||||||
|
"magenta": "#fa2573",
|
||||||
|
"cyan": "#67d9f0",
|
||||||
|
"white": "#f2f2f2",
|
||||||
|
"brightblack": "#555555",
|
||||||
|
"brightred": "#ff5555",
|
||||||
|
"brightgreen": "#55ff55",
|
||||||
|
"brightyellow": "#ffff55",
|
||||||
|
"brightblue": "#5555ff",
|
||||||
|
"brightmagenta": "#ff55ff",
|
||||||
|
"brightcyan": "#55ffff",
|
||||||
|
"brightwhite": "#ffffff",
|
||||||
|
"background": "#000000",
|
||||||
|
"selection_foreground": "#000000",
|
||||||
|
"cursor": "#bbbbbb",
|
||||||
|
"foreground": "#bbbbbb",
|
||||||
|
"selection_background": "#bbbbbb"
|
||||||
|
},
|
||||||
|
"theotteryears 2": {
|
||||||
|
"black": "#000000",
|
||||||
|
"color1": "#8AA2A9",
|
||||||
|
"green": "#7FDEFF",
|
||||||
|
"yellow": "#F3DFBF",
|
||||||
|
"blue": "#EB8A90",
|
||||||
|
"magenta": "#E8871E",
|
||||||
|
"cyan": "#E8871E",
|
||||||
|
"white": "#E8871E",
|
||||||
|
"brightblack": "#FF3864",
|
||||||
|
"brightred": "#FF3864",
|
||||||
|
"brightgreen": "#FF3864",
|
||||||
|
"brightyellow": "#FF3864",
|
||||||
|
"brightblue": "#71baf2",
|
||||||
|
"brightmagenta": "#FF3864",
|
||||||
|
"brightcyan": "#FF3864",
|
||||||
|
"brightwhite": "#ffffff",
|
||||||
|
"background": "#000000",
|
||||||
|
"selection_foreground": "#000000",
|
||||||
|
"cursor": "#bdc3c2",
|
||||||
|
"foreground": "#bdc3c2",
|
||||||
|
"selection_background": "#FF3864"
|
||||||
|
},
|
||||||
"Tomorrow Night Burns": {
|
"Tomorrow Night Burns": {
|
||||||
"black": "#252525",
|
"black": "#252525",
|
||||||
"color1": "#832e31",
|
"color1": "#832e31",
|
||||||
|
|||||||
BIN
src/documentation/basics/TOPOS_COMMANDS.pdf
Normal file
BIN
src/documentation/basics/TOPOS_COMMANDS.pdf
Normal file
Binary file not shown.
193
src/documentation/basics/atelier.ts
Normal file
193
src/documentation/basics/atelier.ts
Normal file
@ -0,0 +1,193 @@
|
|||||||
|
import { type Editor } from "../../main";
|
||||||
|
import { makeExampleFactory } from "../../Documentation";
|
||||||
|
|
||||||
|
export const atelier = (application: Editor): string => {
|
||||||
|
const makeExample = makeExampleFactory(application);
|
||||||
|
return `
|
||||||
|
# Atelier (06 mars 2024)
|
||||||
|
|
||||||
|
Bonjour tout le monde ! Nous sommes :
|
||||||
|
|
||||||
|
- [Rémi Georges](https://remigeorges.fr) : musicien, réalisateur en informatique musicale.
|
||||||
|
- [Agathe Herrou](https://www.youtube.com/@th4music) : musicienne, chercheuse.
|
||||||
|
- [Raphaël Forment](https://raphaelforment.fr) : musicien, doctorant.
|
||||||
|
|
||||||
|
Nous pratiquons le [live coding](https://livecoding.fr). Nous utilisons notre ordinateur comme un instrument de musique, nous programmons de la musique devant notre public. Nous pouvons faire plein de choses comme :
|
||||||
|
|
||||||
|
- créer des instruments de musique, des synthétiseurs, des boîtes à rythme.
|
||||||
|
- jouer des échantillons, charger des images, des vidéos, créer des animations.
|
||||||
|
- contrôler d'autres instruments, jouer avec d'autres musiciens.
|
||||||
|
|
||||||
|
Topos est un instrument de musique. On peut l'utiliser depuis n'importe quel ordinateur, sans avoir à installer quoi que ce soit. Nous l'avons fabriqué pour que tout le monde puisse jouer facilement de la musique.
|
||||||
|
|
||||||
|
|
||||||
|
## Découverte
|
||||||
|
|
||||||
|
<br>
|
||||||
|
|
||||||
|
${makeExample(
|
||||||
|
"Percussions", `
|
||||||
|
tempo(120) // Changer le tempo
|
||||||
|
beat(1)::sound('kick').out()
|
||||||
|
beat(2)::sound('snare').out()
|
||||||
|
beat(.5)::sound('hh').out()
|
||||||
|
`, true,)}
|
||||||
|
|
||||||
|
<br>
|
||||||
|
|
||||||
|
- Qu'est-ce qu'il se passe si je change un nombre ?
|
||||||
|
- Qu'est-ce qu'il se passe si je change un nom ?
|
||||||
|
- Essayez par exemple <ic>"sid"</ic> ou <ic>"trump"</ic>.
|
||||||
|
- Qu'est-ce qu'il se passe si j'enlève <ic>.out()</ic> ?
|
||||||
|
- Est-il possible de jouer un rythme très rapide ou très lent ?
|
||||||
|
|
||||||
|
|
||||||
|
### Ajout d'une basse
|
||||||
|
|
||||||
|
<br>
|
||||||
|
|
||||||
|
${makeExample(
|
||||||
|
"Une basse", `
|
||||||
|
// Aucun changement dans le code
|
||||||
|
beat(1)::sound('kick').out()
|
||||||
|
beat(2)::sound('snare').out()
|
||||||
|
beat(.5)::sound('hh').out()
|
||||||
|
|
||||||
|
// Une nouvelle partie
|
||||||
|
beat([0.25,0.5].beat(1))::sound("pluck")
|
||||||
|
.note([40,45].beat(2)).out()
|
||||||
|
`, true,)}
|
||||||
|
|
||||||
|
<br>
|
||||||
|
|
||||||
|
- Qu'est-ce que le son <ic>"pluck"</ic> ?
|
||||||
|
|
||||||
|
- Que signifie <ic>.note([40,45].beat(2))</ic> ?
|
||||||
|
|
||||||
|
- Que se passe-t-il si je change la valeur dans <ic>.beat(2)</ic> ?
|
||||||
|
|
||||||
|
- Que se passe-t-il lorsque j'ajoute de nouveaux nombres dans <ic>[40, 45]</ic> ?
|
||||||
|
|
||||||
|
### Ajout d'une mélodie
|
||||||
|
|
||||||
|
<br>
|
||||||
|
|
||||||
|
${makeExample(
|
||||||
|
"Le morceau complet", `
|
||||||
|
// Aucun changement dans le code
|
||||||
|
beat(1)::sound('kick').out()
|
||||||
|
beat(2)::sound('snare').out()
|
||||||
|
beat(.5)::sound('hh').out()
|
||||||
|
beat([0.25,0.5].beat(1))::sound("pluck")
|
||||||
|
.note([40,45].beat(2)).out()
|
||||||
|
|
||||||
|
// Nouvelle partie mélodique
|
||||||
|
beat([0.25,0.5].beat())::sound("pluck")
|
||||||
|
.note([0,7,5,8,2,9,0].scale("Major",60).beat(1))
|
||||||
|
.vib(8).vibmod(1/4)
|
||||||
|
.delay(0.5).room(1.5).size(0.5)
|
||||||
|
.out()
|
||||||
|
`, true,)}
|
||||||
|
|
||||||
|
<br>
|
||||||
|
|
||||||
|
Ici, on ajoute une nouvelle mélodie mais il s'agit aussi d'un nouvel instrument. C'est pour cela que le code est plus long. Quand on fait du <em>live coding</em>, on code tout en même temps : notes, rythmes, mélodies, sons. C'est beaucoup de choses ! C'est pour cela que le code est court, on essaie de tout taper très vite en jouant !
|
||||||
|
|
||||||
|
- Que signifie selon vous <ic>vib</ic>, <ic>delay</ic>, <ic>room</ic> ou <ic>size</ic> ?
|
||||||
|
|
||||||
|
- Que se passe-t-il si je change les valeurs dans <ic>vib</ic>, <ic>delay</ic>, <ic>room</ic> ou <ic>size</ic> ?
|
||||||
|
|
||||||
|
<br>
|
||||||
|
|
||||||
|
**Exercices :**
|
||||||
|
|
||||||
|
- Transformer <ic>vib(8)</ic> en <ic>vib([2,4,8].beat(1))</ic>.
|
||||||
|
- Transformer <ic>"pluck"</ic> en <ic>["pluck", "clap"].beat(1)</ic>.
|
||||||
|
|
||||||
|
Vous pouvez aussi utiliser la fonction <ic>rhythm</ic> pour jouer rapidement des rythmes.
|
||||||
|
|
||||||
|
${makeExample(
|
||||||
|
"Rythmes rythmes rythmes", `
|
||||||
|
rhythm(0.5, 3, 8)::sound('bd').out()
|
||||||
|
rhythm(0.5, 3, 8)::sound('clap').out()
|
||||||
|
rhythm(0.5, 6, 8)::sound('hat').out()
|
||||||
|
rhythm(0.25, 6, 8)::sound('hat')
|
||||||
|
.vel(0.3).speed(2).out()
|
||||||
|
rhythm(0.5, 2, 8)::sound('sd').out()
|
||||||
|
`, true)};
|
||||||
|
|
||||||
|
## Créer un instrument
|
||||||
|
|
||||||
|
<br>
|
||||||
|
|
||||||
|
Nous allons créer un nouvel instrument à partir d'un son de base. Voici un premier son :
|
||||||
|
|
||||||
|
${makeExample("Notre son de base", `beat(2)::sound('sine').note(50).ad(0, .5).out()`, true)}
|
||||||
|
|
||||||
|
<br>
|
||||||
|
|
||||||
|
Ce son est assez ennuyeux. Nous allons ajouter quelques paramètres :
|
||||||
|
|
||||||
|
${makeExample("Beaucoup mieux !", `beat(2)::sound('sine').note(50).fmi(2).fmh(2).ad(0, .5).out()`, true)}
|
||||||
|
|
||||||
|
<br>
|
||||||
|
|
||||||
|
Nous allons aussi ajouter quelques effets intéressants :
|
||||||
|
|
||||||
|
${makeExample("Ajout d'un écho", `beat(2)::sound('sine').note(50)
|
||||||
|
.fmi(2).fmh(2).ad(1/16, 1.5)
|
||||||
|
.delay(0.5).delayt(0.75).out()`,
|
||||||
|
true)}
|
||||||
|
|
||||||
|
<br>
|
||||||
|
|
||||||
|
Nous pouvons utiliser plusieurs techniques pour rendre le son plus dynamique :
|
||||||
|
- générer des valeurs aléatoires pour les paramètres
|
||||||
|
- utiliser des générateurs de valeurs (comme <ic>usine</ic>)
|
||||||
|
- utiliser la souris ou un autre contrôleur pour changer les valeurs en temps réel
|
||||||
|
|
||||||
|
${makeExample("Plus dynamique encore", `
|
||||||
|
beat(2)::sound('sine').note([50,55,57,62,66, 69, 74].mouseX())
|
||||||
|
.fmi(usine(1/4)).fmh([1,2,0.5].beat())
|
||||||
|
.ad(1/16, 1.5).delay(0.5).delayt(0.75)
|
||||||
|
.out()`, true)}
|
||||||
|
|
||||||
|
<br>
|
||||||
|
|
||||||
|
Un exemple final, le plus complexe jusqu'à présent :
|
||||||
|
|
||||||
|
${makeExample("Un instrument de musique complet", `
|
||||||
|
beat(2)::sound('triangle')
|
||||||
|
.note([50,55,57,62,66, 69, 74].mouseX())
|
||||||
|
.fmi(usine(1/4)).fmh([1,2,0.5].beat())
|
||||||
|
.ad(1/16, 1.5).delay(0.5).delayt(0.75)
|
||||||
|
.room(0.5).size(8).lpf(usine(1/3)*4000).out()`, true)}
|
||||||
|
|
||||||
|
## Compléments
|
||||||
|
|
||||||
|
${makeExample("Quelques échantillons", `
|
||||||
|
ab ade ades2 ades3 ades4 alex alphabet amencutup armora arp arpy auto
|
||||||
|
baa baa2 bass bass0 bass1 bass2 bass3 bassdm bassfoo battles bd bend
|
||||||
|
bev bin birds birds3 bleep blip blue bottle breaks125 breaks152
|
||||||
|
breaks157 breaks165 breath bubble can casio cb cc chin circus clak
|
||||||
|
click clubkick co coins control cosmicg cp cr crow d db diphone
|
||||||
|
diphone2 dist dork2 dorkbot dr dr2 dr55 dr_few drum drumtraks e east
|
||||||
|
electro1 em2 erk f feel feelfx fest fire flick fm foo future gab
|
||||||
|
gabba gabbaloud gabbalouder glasstap glitch glitch2 gretsch gtr h
|
||||||
|
hand hardcore hardkick haw hc hh hh27 hit hmm ho hoover house ht if
|
||||||
|
ifdrums incoming industrial insect invaders jazz jungbass jungle juno
|
||||||
|
jvbass kicklinn koy kurt latibro led less lighter linnhats lt made
|
||||||
|
made2 mash mash2 metal miniyeah monsterb moog mouth mp3 msg mt mute
|
||||||
|
newnotes noise noise2 notes numbers oc off outdoor pad padlong pebbles
|
||||||
|
perc peri pluck popkick print proc procshort psr rave rave2 ravemono
|
||||||
|
realclaps reverbkick rm rs sax sd seawolf sequential sf sheffield
|
||||||
|
short sid sine sitar sn space speakspell speech speechless speedupdown
|
||||||
|
stab stomp subroc3d sugar sundance tabla tabla2 tablex tacscan tech
|
||||||
|
techno tink tok toys trump ul ulgab uxay v voodoo wind wobble world
|
||||||
|
xmas yeah`, true)}
|
||||||
|
|
||||||
|
|
||||||
|
`
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -63,11 +63,9 @@ beat(.25) :: sound('sid').note(
|
|||||||
|
|
||||||
Topos is deeply inspired by the [Monome Teletype](https://monome.org/). The Teletype is/was an open source hardware module for Eurorack synthesizers. While the Teletype was initially born as an hardware module, Topos aims to be a web-browser based cousin of it! It is a sequencer, a scriptable interface, a companion for algorithmic music-making. Topos wishes to fullfill the same goal as the Teletype, keeping the same spirit alive on the web. It is free, open-source, and made to be shared and used by everyone. Learn more about live coding on [livecoding.fr](https://livecoding.fr).
|
Topos is deeply inspired by the [Monome Teletype](https://monome.org/). The Teletype is/was an open source hardware module for Eurorack synthesizers. While the Teletype was initially born as an hardware module, Topos aims to be a web-browser based cousin of it! It is a sequencer, a scriptable interface, a companion for algorithmic music-making. Topos wishes to fullfill the same goal as the Teletype, keeping the same spirit alive on the web. It is free, open-source, and made to be shared and used by everyone. Learn more about live coding on [livecoding.fr](https://livecoding.fr).
|
||||||
|
|
||||||
## Demo Songs
|
## Alternative documentation source (.pdf)
|
||||||
|
|
||||||
Reloading the application will get you one random song example to study every time. Press ${key_shortcut(
|
You can also find a .pdf version listing the principal commands and functions [here](https://github.com/Bubobubobubobubo/topos/blob/main/src/documentation/basics/TOPOS_COMMANDS.pdf). This document has been generated by Chris Collis. It recaps the main sections of this documentation and can be a good companion while learning Topos.
|
||||||
"F5",
|
|
||||||
)} and listen to them all! The demo songs are also used a bit everywhere in the documentation to illustrate some of the working principles :).
|
|
||||||
|
|
||||||
## Support
|
## Support
|
||||||
|
|
||||||
|
|||||||
@ -442,7 +442,7 @@ Array.prototype.scale = function (
|
|||||||
return this.map((value) => {
|
return this.map((value) => {
|
||||||
const octaveShift = Math.floor(value / selected_scale.length) * 12;
|
const octaveShift = Math.floor(value / selected_scale.length) * 12;
|
||||||
return (
|
return (
|
||||||
selected_scale[mod(value, selected_scale.length)] +
|
selected_scale[mod(Math.floor(value), selected_scale.length)] +
|
||||||
base_note +
|
base_note +
|
||||||
octaveShift
|
octaveShift
|
||||||
);
|
);
|
||||||
|
|||||||
@ -213,13 +213,7 @@ export class Editor {
|
|||||||
loadUniverserFromUrl(this);
|
loadUniverserFromUrl(this);
|
||||||
|
|
||||||
// Set the color scheme for the application
|
// Set the color scheme for the application
|
||||||
let available_themes = Object.keys(colors);
|
|
||||||
if (this.settings.theme in available_themes) {
|
|
||||||
this.readTheme(this.settings.theme);
|
this.readTheme(this.settings.theme);
|
||||||
} else {
|
|
||||||
this.settings.theme = "Everblush";
|
|
||||||
this.readTheme(this.settings.theme);
|
|
||||||
}
|
|
||||||
|
|
||||||
this.documentationStyle = createDocumentationStyle(this);
|
this.documentationStyle = createDocumentationStyle(this);
|
||||||
this.bindings = Object.keys(this.documentationStyle).map((key) => ({
|
this.bindings = Object.keys(this.documentationStyle).map((key) => ({
|
||||||
|
|||||||
Reference in New Issue
Block a user