lint topos
This commit is contained in:
24
src/API.ts
24
src/API.ts
@ -1299,7 +1299,7 @@ export class UserAPI {
|
||||
const results: boolean[] = nArray.map(
|
||||
(value) =>
|
||||
(this.app.clock.pulses_since_origin - Math.floor(nudge * this.ppqn())) %
|
||||
Math.floor(value * this.ppqn()) ===
|
||||
Math.floor(value * this.ppqn()) ===
|
||||
0,
|
||||
);
|
||||
return results.some((value) => value === true);
|
||||
@ -1319,7 +1319,7 @@ export class UserAPI {
|
||||
const results: boolean[] = nArray.map(
|
||||
(value) =>
|
||||
(this.app.clock.pulses_since_origin - nudgeInPulses) %
|
||||
Math.floor(value * barLength) ===
|
||||
Math.floor(value * barLength) ===
|
||||
0,
|
||||
);
|
||||
return results.some((value) => value === true);
|
||||
@ -1917,7 +1917,7 @@ export class UserAPI {
|
||||
// =============================================================
|
||||
|
||||
register = (name: string, operation: EventOperation<AbstractEvent>): void => {
|
||||
AbstractEvent.prototype[name] = function(
|
||||
AbstractEvent.prototype[name] = function (
|
||||
this: AbstractEvent,
|
||||
...args: any[]
|
||||
) {
|
||||
@ -2101,13 +2101,13 @@ export class UserAPI {
|
||||
// =============================================================
|
||||
|
||||
public osc = (address: string, port: number, ...args: any[]): void => {
|
||||
sendToServer({
|
||||
address: address,
|
||||
port: port,
|
||||
args: args,
|
||||
timetag: Math.round(Date.now() + this.app.clock.deadline),
|
||||
} as OSCMessage);
|
||||
}
|
||||
sendToServer({
|
||||
address: address,
|
||||
port: port,
|
||||
args: args,
|
||||
timetag: Math.round(Date.now() + this.app.clock.deadline),
|
||||
} as OSCMessage);
|
||||
};
|
||||
|
||||
public getOSC = (address?: string): any[] => {
|
||||
/**
|
||||
@ -2116,11 +2116,11 @@ export class UserAPI {
|
||||
if (address) {
|
||||
let messages = oscMessages.filter((msg) => msg.address === address);
|
||||
messages = messages.map((msg) => msg.data);
|
||||
return messages
|
||||
return messages;
|
||||
} else {
|
||||
return oscMessages;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// =============================================================
|
||||
// Transport functions
|
||||
|
||||
29
src/Clock.ts
29
src/Clock.ts
@ -69,9 +69,9 @@ export class Clock {
|
||||
// @ts-ignore
|
||||
clockCallback = (time: number, duration: number, tick: number) => {
|
||||
/**
|
||||
* Callback function for the zyklus clock. Updates the clock info and sends a
|
||||
* Callback function for the zyklus clock. Updates the clock info and sends a
|
||||
* MIDI clock message if the setting is enabled. Also evaluates the global buffer.
|
||||
*
|
||||
*
|
||||
* @param time - precise AudioContext time when the tick should happen
|
||||
* @param duration - seconds between each tick
|
||||
* @param tick - count of the current tick
|
||||
@ -88,8 +88,9 @@ export class Clock {
|
||||
);
|
||||
this.app.clock.time_position = futureTimeStamp;
|
||||
if (futureTimeStamp.pulse % this.app.clock.ppqn == 0) {
|
||||
this.timeviewer.innerHTML = `${zeroPad(futureTimeStamp.bar, 2)}:${futureTimeStamp.beat + 1
|
||||
} / ${this.app.clock.bpm}`;
|
||||
this.timeviewer.innerHTML = `${zeroPad(futureTimeStamp.bar, 2)}:${
|
||||
futureTimeStamp.beat + 1
|
||||
} / ${this.app.clock.bpm}`;
|
||||
}
|
||||
if (this.app.exampleIsPlaying) {
|
||||
tryEvaluate(this.app, this.app.example_buffer);
|
||||
@ -103,8 +104,8 @@ export class Clock {
|
||||
|
||||
convertTicksToTimeposition(ticks: number): TimePosition {
|
||||
/**
|
||||
* Converts ticks to a time position.
|
||||
*
|
||||
* Converts ticks to a time position.
|
||||
*
|
||||
* @param ticks - ticks to convert
|
||||
* @returns TimePosition
|
||||
*/
|
||||
@ -119,7 +120,7 @@ export class Clock {
|
||||
get ticks_before_new_bar(): number {
|
||||
/**
|
||||
* Calculates the number of ticks before the next bar.
|
||||
*
|
||||
*
|
||||
* @returns number - ticks before the next bar
|
||||
*/
|
||||
const ticskMissingFromBeat = this.ppqn - this.time_position.pulse;
|
||||
@ -130,7 +131,7 @@ export class Clock {
|
||||
get next_beat_in_ticks(): number {
|
||||
/**
|
||||
* Calculates the number of ticks before the next beat.
|
||||
*
|
||||
*
|
||||
* @returns number - ticks before the next beat
|
||||
*/
|
||||
return this.app.clock.pulses_since_origin + this.time_position.pulse;
|
||||
@ -139,7 +140,7 @@ export class Clock {
|
||||
get beats_per_bar(): number {
|
||||
/**
|
||||
* Returns the number of beats per bar.
|
||||
*
|
||||
*
|
||||
* @returns number - beats per bar
|
||||
*/
|
||||
return this.time_signature[0];
|
||||
@ -148,7 +149,7 @@ export class Clock {
|
||||
get beats_since_origin(): number {
|
||||
/**
|
||||
* Returns the number of beats since the origin.
|
||||
*
|
||||
*
|
||||
* @returns number - beats since the origin
|
||||
*/
|
||||
return Math.floor(this.tick / this.ppqn);
|
||||
@ -157,7 +158,7 @@ export class Clock {
|
||||
get pulses_since_origin(): number {
|
||||
/**
|
||||
* Returns the number of pulses since the origin.
|
||||
*
|
||||
*
|
||||
* @returns number - pulses since the origin
|
||||
*/
|
||||
return this.tick;
|
||||
@ -174,7 +175,7 @@ export class Clock {
|
||||
public pulse_duration_at_bpm(bpm: number = this.bpm): number {
|
||||
/**
|
||||
* Returns the duration of a pulse in seconds at a given bpm.
|
||||
*
|
||||
*
|
||||
* @param bpm - bpm to calculate the pulse duration for
|
||||
* @returns number - duration of a pulse in seconds
|
||||
*/
|
||||
@ -242,7 +243,7 @@ export class Clock {
|
||||
public start(): void {
|
||||
/**
|
||||
* Start the clock
|
||||
*
|
||||
*
|
||||
* @remark also sends a MIDI message if a port is declared
|
||||
*/
|
||||
this.app.audioContext.resume();
|
||||
@ -254,7 +255,7 @@ export class Clock {
|
||||
public pause(): void {
|
||||
/**
|
||||
* Pause the clock.
|
||||
*
|
||||
*
|
||||
* @remark also sends a MIDI message if a port is declared
|
||||
*/
|
||||
this.running = false;
|
||||
|
||||
@ -9,8 +9,8 @@ export interface OSCMessage {
|
||||
export let outputSocket = new WebSocket("ws://localhost:3000");
|
||||
export let inputSocket = new WebSocket("ws://localhost:3001");
|
||||
|
||||
export let oscMessages : any[] = [];
|
||||
inputSocket.addEventListener('message', (event) => {
|
||||
export let oscMessages: any[] = [];
|
||||
inputSocket.addEventListener("message", (event) => {
|
||||
let data = JSON.parse(event.data);
|
||||
if (oscMessages.length >= 1000) {
|
||||
oscMessages.shift();
|
||||
@ -18,7 +18,6 @@ inputSocket.addEventListener('message', (event) => {
|
||||
oscMessages.push(data);
|
||||
});
|
||||
|
||||
|
||||
// @ts-ignore
|
||||
outputSocket.onopen = function (event) {
|
||||
console.log("Connected to WebSocket Server");
|
||||
@ -26,8 +25,9 @@ outputSocket.onopen = function (event) {
|
||||
outputSocket.send(
|
||||
JSON.stringify({
|
||||
address: "/successful_connexion",
|
||||
port: 3000, args: {}
|
||||
})
|
||||
port: 3000,
|
||||
args: {},
|
||||
}),
|
||||
);
|
||||
|
||||
outputSocket.onerror = function (error) {
|
||||
|
||||
@ -465,11 +465,7 @@ export class SoundEvent extends AudibleEvent {
|
||||
if (filteredEvent.freq) {
|
||||
delete filteredEvent.note;
|
||||
}
|
||||
superdough(
|
||||
filteredEvent,
|
||||
this.app.clock.deadline,
|
||||
filteredEvent.dur
|
||||
);
|
||||
superdough(filteredEvent, this.app.clock.deadline, filteredEvent.dur);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@ -12,30 +12,30 @@ Welcome to the **Topos** documentation. You can jump here anytime by pressing ${
|
||||
)}. Press again to make the documentation disappear. Contributions are much appreciated! The documentation [lives here](https://github.com/Bubobubobubobubo/topos/tree/main/src/documentation).
|
||||
|
||||
${makeExample(
|
||||
"Welcome! Eval to get started",
|
||||
examples[Math.floor(Math.random() * examples.length)],
|
||||
true,
|
||||
)}
|
||||
"Welcome! Eval to get started",
|
||||
examples[Math.floor(Math.random() * examples.length)],
|
||||
true,
|
||||
)}
|
||||
|
||||
# What is Topos?
|
||||
|
||||
Topos is an _algorithmic_ sequencer. Topos is also a _live coding_ environment. To sum it up, think: "_making music in real time through code_". Code used as an expressive medium for musical improvisation! Topos uses small algorithms to represent musical sequences and processes.
|
||||
|
||||
${makeExample(
|
||||
"Small algorithms for direct musical expression",
|
||||
`
|
||||
"Small algorithms for direct musical expression",
|
||||
`
|
||||
rhythm(.5, 4, 8) :: sound('drum').out()
|
||||
rhythm(.25, [5, 7].beat(2), 8) :: sound(['hc', 'fikea', 'hat'].pick(1))
|
||||
.lpf([500, 4000+usine(1/2)*2000]).pan(r(0, 1)).ad(0, [1, .5])
|
||||
.db(-ir(1,8)).speed([1,[0.5, 2].pick()]).room(0.5).size(3).o(4).out()
|
||||
beat([2,0.5].dur(13.5, 0.5))::snd('fsoftsnare')
|
||||
.n(0).speed([1, 0.5]).o(4).out()`,
|
||||
false,
|
||||
)}
|
||||
false,
|
||||
)}
|
||||
|
||||
${makeExample(
|
||||
"Computer music should be immediate and intuitive",
|
||||
`
|
||||
"Computer music should be immediate and intuitive",
|
||||
`
|
||||
let chord_prog = [0, 0, 5].bar() // Chord progression
|
||||
beat(.25)::snd('sine')
|
||||
.note(chord_prog + [60, 64, 67, 71].mouseX()
|
||||
@ -47,19 +47,19 @@ beat(.25)::snd('sine')
|
||||
.delay(0.5).delayt(0.25).delayfb(0.7) // Delay
|
||||
.room(0.5).size(8) // Reverb
|
||||
.out()`,
|
||||
false,
|
||||
)}
|
||||
false,
|
||||
)}
|
||||
|
||||
${makeExample(
|
||||
"Making the web less dreadful, one beep at at time",
|
||||
`
|
||||
"Making the web less dreadful, one beep at at time",
|
||||
`
|
||||
beat(.5) :: sound('sid').n($(2))
|
||||
.room(1).speed([1,2].pick()).out()
|
||||
beat(.25) :: sound('sid').note(
|
||||
[34, 36, 41].beat(.25) + [[0,-24].pick(),12].beat())
|
||||
.room(0.9).size(0.9).n(4).out()`,
|
||||
false,
|
||||
)}
|
||||
false,
|
||||
)}
|
||||
|
||||
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).
|
||||
|
||||
@ -75,4 +75,3 @@ Reloading the application will get you one random song example to study every ti
|
||||
|
||||
`;
|
||||
};
|
||||
|
||||
|
||||
@ -24,46 +24,52 @@ Send an **OSC** message to the server from another application or device at the
|
||||
You can access the last 1000 messages using the <ic>getOsc()</ic> function without any argument. This is raw data, you will need to parse it yourself:
|
||||
|
||||
${makeExample(
|
||||
"Reading the last OSC messages",
|
||||
`
|
||||
"Reading the last OSC messages",
|
||||
`
|
||||
beat(1)::getOsc()
|
||||
// 0 : {data: Array(2), address: '/lala'}
|
||||
// 1 : {data: Array(2), address: '/lala'}
|
||||
// 2 : {data: Array(2), address: '/lala'}`,
|
||||
true)}
|
||||
true,
|
||||
)}
|
||||
|
||||
### Filtered messages
|
||||
|
||||
The <ic>getOsc()</ic> can receive an address filter as an argument. This will return only the messages that match the filter:
|
||||
|
||||
${
|
||||
makeExample(
|
||||
"Reading the last OSC messages (filtered)",
|
||||
`
|
||||
${makeExample(
|
||||
"Reading the last OSC messages (filtered)",
|
||||
`
|
||||
beat(1)::getOsc("/lala")
|
||||
// 0 : (2) [89, 'bob']
|
||||
// 1 : (2) [84, 'bob']
|
||||
// 2 : (2) [82, 'bob']
|
||||
`, true)}
|
||||
`,
|
||||
true,
|
||||
)}
|
||||
|
||||
## Output
|
||||
|
||||
Once the server is loaded, you are ready to send an **OSC** message:
|
||||
|
||||
${makeExample(
|
||||
"Sending a simple OSC message",
|
||||
`
|
||||
"Sending a simple OSC message",
|
||||
`
|
||||
beat(1)::sound('cp').speed(2).vel(0.5).osc()
|
||||
`, true
|
||||
`,
|
||||
true,
|
||||
)}
|
||||
|
||||
This is a simple **OSC** message that will inherit all the properties of the sound. You can also send customized OSC messages using the <ic>osc()</ic> function:
|
||||
|
||||
${makeExample(
|
||||
"Sending a customized OSC message",
|
||||
`
|
||||
"Sending a customized OSC message",
|
||||
`
|
||||
// osc(address, port, ...message)
|
||||
osc('/my/osc/address', 5000, 1, 2, 3)
|
||||
`, true)}
|
||||
`,
|
||||
true,
|
||||
)}
|
||||
|
||||
`};
|
||||
`;
|
||||
};
|
||||
|
||||
@ -4,7 +4,7 @@ import { scriptBlinkers } from "./Visuals/Blinkers";
|
||||
import { javascript } from "@codemirror/lang-javascript";
|
||||
import { markdown } from "@codemirror/lang-markdown";
|
||||
import { Extension } from "@codemirror/state";
|
||||
import { outputSocket, oscMessages } from "./IO/OSC";
|
||||
import { outputSocket } from "./IO/OSC";
|
||||
import {
|
||||
initializeSelectedUniverse,
|
||||
AppSettings,
|
||||
@ -95,7 +95,7 @@ export class Editor {
|
||||
isPlaying: boolean = false;
|
||||
|
||||
// OSC
|
||||
outputSocket: WebSocket = outputSocket
|
||||
outputSocket: WebSocket = outputSocket;
|
||||
|
||||
// Hydra
|
||||
public hydra_backend: any;
|
||||
@ -205,8 +205,6 @@ export class Editor {
|
||||
|
||||
// Loading universe from URL (if needed)
|
||||
loadUniverserFromUrl(this);
|
||||
|
||||
|
||||
}
|
||||
|
||||
private getBuffer(type: string): any {
|
||||
|
||||
Reference in New Issue
Block a user