lint topos

This commit is contained in:
2023-12-04 18:35:36 +01:00
parent 0aa6039f17
commit 98c71953a4
12 changed files with 127 additions and 123 deletions

View File

@ -17,24 +17,24 @@
</p> </p>
</p> </p>
--------------------- ---
Topos is a web based live coding environment. Topos is capable of many things: Topos is a web based live coding environment. Topos is capable of many things:
- it is a music sequencer made for improvisation and composition alike - it is a music sequencer made for improvisation and composition alike
- it is a synthesizer capable of additive, substractive, FM and wavetable - it is a synthesizer capable of additive, substractive, FM and wavetable
synthesis, backed up by a [powerful web based audio engine](https://www.npmjs.com/package/superdough) synthesis, backed up by a [powerful web based audio engine](https://www.npmjs.com/package/superdough)
- it can also generate video thanks to [Hydra](https://hydra.ojack.xyz/) and - it can also generate video thanks to [Hydra](https://hydra.ojack.xyz/) and
custom oscilloscopes, frequency visualizers and image sequencing capabilities custom oscilloscopes, frequency visualizers and image sequencing capabilities
- it can be used to sequence other MIDI devices (and soon.. OSC!) - it can be used to sequence other MIDI devices (and soon.. OSC!)
- it is made to be used without the need of installing anything, always ready at - it is made to be used without the need of installing anything, always ready at
[https://topos.live](https://topos.live) [https://topos.live](https://topos.live)
- Topos is also an emulation and personal extension of the [Monome Teletype](https://monome.org/docs/teletype/) - Topos is also an emulation and personal extension of the [Monome Teletype](https://monome.org/docs/teletype/)
--------------------- ---
![Screenshot](https://github.com/Bubobubobubobubo/Topos/blob/main/img/topos_gif.gif) ![Screenshot](https://github.com/Bubobubobubobubo/Topos/blob/main/img/topos_gif.gif)
## Disclaimer ## Disclaimer
**Topos** is still a young project developed by two hobbyists :) Contributions are welcome! We wish to be as inclusive and welcoming as possible to your ideas and suggestions! The software is working quite well and we are continuously striving to improve it. **Topos** is still a young project developed by two hobbyists :) Contributions are welcome! We wish to be as inclusive and welcoming as possible to your ideas and suggestions! The software is working quite well and we are continuously striving to improve it.

View File

@ -2,13 +2,13 @@ const WebSocket = require("ws");
const osc = require("osc"); const osc = require("osc");
const cleanIncomingOSC = (oscMsg) => { const cleanIncomingOSC = (oscMsg) => {
let data = oscMsg.args; let data = oscMsg.args;
// Remove information about type of data // Remove information about type of data
data = data.map((item) => { data = data.map((item) => {
return item.value; return item.value;
}) });
return {data: data, address: oscMsg.address}; return { data: data, address: oscMsg.address };
} };
// ============================================== // ==============================================
// Receiving and forwarding OSC UDP messages // Receiving and forwarding OSC UDP messages
@ -16,18 +16,21 @@ const cleanIncomingOSC = (oscMsg) => {
console.log("> OSC Input: 127.0.0.1:30000"); console.log("> OSC Input: 127.0.0.1:30000");
const wss = new WebSocket.Server({ port: 3001 }); const wss = new WebSocket.Server({ port: 3001 });
var udpPort = new osc.UDPPort({ var udpPort = new osc.UDPPort({
localAddress: "0.0.0.0", localAddress: "0.0.0.0",
localPort: 30000, localPort: 30000,
metadata: true metadata: true,
}); });
udpPort.on("message", function (oscMsg, timeTag, info) { udpPort.on("message", function (oscMsg, timeTag, info) {
console.log(`> Incoming OSC to ${oscMsg.address}:`, oscMsg.args.map( console.log(
(item) => {return item.value}) `> Incoming OSC to ${oscMsg.address}:`,
); oscMsg.args.map((item) => {
wss.clients.forEach(client => { return item.value;
if (client.readyState === WebSocket.OPEN) { }),
client.send(JSON.stringify(cleanIncomingOSC(oscMsg))); );
} wss.clients.forEach((client) => {
}); if (client.readyState === WebSocket.OPEN) {
client.send(JSON.stringify(cleanIncomingOSC(oscMsg)));
}
});
}); });
udpPort.open(); udpPort.open();

View File

@ -12,10 +12,14 @@ wss.on("connection", function (ws) {
const message = JSON.parse(data); const message = JSON.parse(data);
sendOscMessage( sendOscMessage(
formatAndTypeMessage(message), formatAndTypeMessage(message),
message.address, message.address,
message.port message.port,
);
console.log(
`> Message sent to ${message.address}:${message.port}: ${JSON.stringify(
message.args,
)}`,
); );
console.log(`> Message sent to ${message.address}:${message.port}: ${JSON.stringify(message.args)}`)
} catch (error) { } catch (error) {
console.error("> Error processing message:", error); console.error("> Error processing message:", error);
} }
@ -24,12 +28,12 @@ wss.on("connection", function (ws) {
wss.on("error", function (error) { wss.on("error", function (error) {
console.error("> Server error:", error); console.error("> Server error:", error);
}) });
wss.on("close", function () { wss.on("close", function () {
// Close the websocket server // Close the websocket server
wss.close(); wss.close();
console.log("> Closing websocket server") console.log("> Closing websocket server");
}); });
let udpPort = new osc.UDPPort({ let udpPort = new osc.UDPPort({
@ -37,7 +41,7 @@ let udpPort = new osc.UDPPort({
localPort: 3000, localPort: 3000,
metadata: true, metadata: true,
remoteAddress: "0.0.0.0", remoteAddress: "0.0.0.0",
remotePort: 57120, remotePort: 57120,
}); });
udpPort.on("error", function (error) { udpPort.on("error", function (error) {
console.error("> UDP Port error:", error); console.error("> UDP Port error:", error);
@ -51,7 +55,7 @@ udpPort.open();
function sendOscMessage(message, address, port) { function sendOscMessage(message, address, port) {
try { try {
udpPort.options.remotePort = port udpPort.options.remotePort = port;
message.address = address; message.address = address;
udpPort.send(message); udpPort.send(message);
} catch (error) { } catch (error) {
@ -61,21 +65,19 @@ function sendOscMessage(message, address, port) {
const formatAndTypeMessage = (message) => { const formatAndTypeMessage = (message) => {
let newMessage = {}; let newMessage = {};
delete message.args['address']; delete message.args["address"];
delete message.args['port']; delete message.args["port"];
newMessage.address = message.address; newMessage.address = message.address;
newMessage.timestamp = osc.timeTag(message.timetag); newMessage.timestamp = osc.timeTag(message.timetag);
args = [...Object.entries(message.args)].flat().map((arg) => { args = [...Object.entries(message.args)].flat().map((arg) => {
if (typeof arg === 'string') if (typeof arg === "string") return { type: "s", value: arg };
return {type: 's', value: arg}; if (typeof arg === "number") return { type: "f", value: arg };
if (typeof arg === 'number') if (typeof arg === "boolean")
return {type: 'f', value: arg}; return value ? { type: "s", value: 1 } : { type: "s", value: 0 };
if (typeof arg === 'boolean') });
return value ? {type: 's', value: 1} : {type: 's', value: 0};
})
newMessage.args = args newMessage.args = args;
return newMessage; return newMessage;
} };

View File

@ -1,14 +1,14 @@
var pjson = require('./package.json'); var pjson = require("./package.json");
let banner = ` let banner = `
┏┳┓ ┏┓┏┓┏┓ ┏┳┓ ┏┓┏┓┏┓
┃ ┏┓┏┓┏┓┏ ┃┃┗┓┃ ┃ ┏┓┏┓┏┓┏ ┃┃┗┓┃
┻ ┗┛┣┛┗┛┛ ┗┛┗┛┗┛ ┻ ┗┛┣┛┗┛┛ ┗┛┗┛┗┛
${pjson.version}\n` ${pjson.version}\n`;
function greet() { function greet() {
console.log(banner) console.log(banner);
} }
module.exports = { module.exports = {
greet: greet greet: greet,
} };

View File

@ -1,9 +1,8 @@
const WebSocket = require("ws"); const WebSocket = require("ws");
const osc = require("osc"); const osc = require("osc");
require('./banner').greet(); require("./banner").greet();
// Topos to OSC // Topos to OSC
require('./ToposToOSC') require("./ToposToOSC");
// OSC to Topos // OSC to Topos
require("./OSCtoTopos") require("./OSCtoTopos");

View File

@ -1299,7 +1299,7 @@ export class UserAPI {
const results: boolean[] = nArray.map( const results: boolean[] = nArray.map(
(value) => (value) =>
(this.app.clock.pulses_since_origin - Math.floor(nudge * this.ppqn())) % (this.app.clock.pulses_since_origin - Math.floor(nudge * this.ppqn())) %
Math.floor(value * this.ppqn()) === Math.floor(value * this.ppqn()) ===
0, 0,
); );
return results.some((value) => value === true); return results.some((value) => value === true);
@ -1319,7 +1319,7 @@ export class UserAPI {
const results: boolean[] = nArray.map( const results: boolean[] = nArray.map(
(value) => (value) =>
(this.app.clock.pulses_since_origin - nudgeInPulses) % (this.app.clock.pulses_since_origin - nudgeInPulses) %
Math.floor(value * barLength) === Math.floor(value * barLength) ===
0, 0,
); );
return results.some((value) => value === true); return results.some((value) => value === true);
@ -1917,7 +1917,7 @@ export class UserAPI {
// ============================================================= // =============================================================
register = (name: string, operation: EventOperation<AbstractEvent>): void => { register = (name: string, operation: EventOperation<AbstractEvent>): void => {
AbstractEvent.prototype[name] = function( AbstractEvent.prototype[name] = function (
this: AbstractEvent, this: AbstractEvent,
...args: any[] ...args: any[]
) { ) {
@ -2101,13 +2101,13 @@ export class UserAPI {
// ============================================================= // =============================================================
public osc = (address: string, port: number, ...args: any[]): void => { public osc = (address: string, port: number, ...args: any[]): void => {
sendToServer({ sendToServer({
address: address, address: address,
port: port, port: port,
args: args, args: args,
timetag: Math.round(Date.now() + this.app.clock.deadline), timetag: Math.round(Date.now() + this.app.clock.deadline),
} as OSCMessage); } as OSCMessage);
} };
public getOSC = (address?: string): any[] => { public getOSC = (address?: string): any[] => {
/** /**
@ -2116,11 +2116,11 @@ export class UserAPI {
if (address) { if (address) {
let messages = oscMessages.filter((msg) => msg.address === address); let messages = oscMessages.filter((msg) => msg.address === address);
messages = messages.map((msg) => msg.data); messages = messages.map((msg) => msg.data);
return messages return messages;
} else { } else {
return oscMessages; return oscMessages;
} }
} };
// ============================================================= // =============================================================
// Transport functions // Transport functions

View File

@ -69,9 +69,9 @@ export class Clock {
// @ts-ignore // @ts-ignore
clockCallback = (time: number, duration: number, tick: number) => { 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. * MIDI clock message if the setting is enabled. Also evaluates the global buffer.
* *
* @param time - precise AudioContext time when the tick should happen * @param time - precise AudioContext time when the tick should happen
* @param duration - seconds between each tick * @param duration - seconds between each tick
* @param tick - count of the current tick * @param tick - count of the current tick
@ -88,8 +88,9 @@ export class Clock {
); );
this.app.clock.time_position = futureTimeStamp; this.app.clock.time_position = futureTimeStamp;
if (futureTimeStamp.pulse % this.app.clock.ppqn == 0) { if (futureTimeStamp.pulse % this.app.clock.ppqn == 0) {
this.timeviewer.innerHTML = `${zeroPad(futureTimeStamp.bar, 2)}:${futureTimeStamp.beat + 1 this.timeviewer.innerHTML = `${zeroPad(futureTimeStamp.bar, 2)}:${
} / ${this.app.clock.bpm}`; futureTimeStamp.beat + 1
} / ${this.app.clock.bpm}`;
} }
if (this.app.exampleIsPlaying) { if (this.app.exampleIsPlaying) {
tryEvaluate(this.app, this.app.example_buffer); tryEvaluate(this.app, this.app.example_buffer);
@ -103,8 +104,8 @@ export class Clock {
convertTicksToTimeposition(ticks: number): TimePosition { convertTicksToTimeposition(ticks: number): TimePosition {
/** /**
* Converts ticks to a time position. * Converts ticks to a time position.
* *
* @param ticks - ticks to convert * @param ticks - ticks to convert
* @returns TimePosition * @returns TimePosition
*/ */
@ -119,7 +120,7 @@ export class Clock {
get ticks_before_new_bar(): number { get ticks_before_new_bar(): number {
/** /**
* Calculates the number of ticks before the next bar. * Calculates the number of ticks before the next bar.
* *
* @returns number - ticks before the next bar * @returns number - ticks before the next bar
*/ */
const ticskMissingFromBeat = this.ppqn - this.time_position.pulse; const ticskMissingFromBeat = this.ppqn - this.time_position.pulse;
@ -130,7 +131,7 @@ export class Clock {
get next_beat_in_ticks(): number { get next_beat_in_ticks(): number {
/** /**
* Calculates the number of ticks before the next beat. * Calculates the number of ticks before the next beat.
* *
* @returns number - ticks before the next beat * @returns number - ticks before the next beat
*/ */
return this.app.clock.pulses_since_origin + this.time_position.pulse; return this.app.clock.pulses_since_origin + this.time_position.pulse;
@ -139,7 +140,7 @@ export class Clock {
get beats_per_bar(): number { get beats_per_bar(): number {
/** /**
* Returns the number of beats per bar. * Returns the number of beats per bar.
* *
* @returns number - beats per bar * @returns number - beats per bar
*/ */
return this.time_signature[0]; return this.time_signature[0];
@ -148,7 +149,7 @@ export class Clock {
get beats_since_origin(): number { get beats_since_origin(): number {
/** /**
* Returns the number of beats since the origin. * Returns the number of beats since the origin.
* *
* @returns number - beats since the origin * @returns number - beats since the origin
*/ */
return Math.floor(this.tick / this.ppqn); return Math.floor(this.tick / this.ppqn);
@ -157,7 +158,7 @@ export class Clock {
get pulses_since_origin(): number { get pulses_since_origin(): number {
/** /**
* Returns the number of pulses since the origin. * Returns the number of pulses since the origin.
* *
* @returns number - pulses since the origin * @returns number - pulses since the origin
*/ */
return this.tick; return this.tick;
@ -174,7 +175,7 @@ export class Clock {
public pulse_duration_at_bpm(bpm: number = this.bpm): number { public pulse_duration_at_bpm(bpm: number = this.bpm): number {
/** /**
* Returns the duration of a pulse in seconds at a given bpm. * Returns the duration of a pulse in seconds at a given bpm.
* *
* @param bpm - bpm to calculate the pulse duration for * @param bpm - bpm to calculate the pulse duration for
* @returns number - duration of a pulse in seconds * @returns number - duration of a pulse in seconds
*/ */
@ -242,7 +243,7 @@ export class Clock {
public start(): void { public start(): void {
/** /**
* Start the clock * Start the clock
* *
* @remark also sends a MIDI message if a port is declared * @remark also sends a MIDI message if a port is declared
*/ */
this.app.audioContext.resume(); this.app.audioContext.resume();
@ -254,7 +255,7 @@ export class Clock {
public pause(): void { public pause(): void {
/** /**
* Pause the clock. * Pause the clock.
* *
* @remark also sends a MIDI message if a port is declared * @remark also sends a MIDI message if a port is declared
*/ */
this.running = false; this.running = false;

View File

@ -9,8 +9,8 @@ export interface OSCMessage {
export let outputSocket = new WebSocket("ws://localhost:3000"); export let outputSocket = new WebSocket("ws://localhost:3000");
export let inputSocket = new WebSocket("ws://localhost:3001"); export let inputSocket = new WebSocket("ws://localhost:3001");
export let oscMessages : any[] = []; export let oscMessages: any[] = [];
inputSocket.addEventListener('message', (event) => { inputSocket.addEventListener("message", (event) => {
let data = JSON.parse(event.data); let data = JSON.parse(event.data);
if (oscMessages.length >= 1000) { if (oscMessages.length >= 1000) {
oscMessages.shift(); oscMessages.shift();
@ -18,7 +18,6 @@ inputSocket.addEventListener('message', (event) => {
oscMessages.push(data); oscMessages.push(data);
}); });
// @ts-ignore // @ts-ignore
outputSocket.onopen = function (event) { outputSocket.onopen = function (event) {
console.log("Connected to WebSocket Server"); console.log("Connected to WebSocket Server");
@ -26,8 +25,9 @@ outputSocket.onopen = function (event) {
outputSocket.send( outputSocket.send(
JSON.stringify({ JSON.stringify({
address: "/successful_connexion", address: "/successful_connexion",
port: 3000, args: {} port: 3000,
}) args: {},
}),
); );
outputSocket.onerror = function (error) { outputSocket.onerror = function (error) {

View File

@ -465,11 +465,7 @@ export class SoundEvent extends AudibleEvent {
if (filteredEvent.freq) { if (filteredEvent.freq) {
delete filteredEvent.note; delete filteredEvent.note;
} }
superdough( superdough(filteredEvent, this.app.clock.deadline, filteredEvent.dur);
filteredEvent,
this.app.clock.deadline,
filteredEvent.dur
);
} }
}; };

View File

@ -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). )}. 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( ${makeExample(
"Welcome! Eval to get started", "Welcome! Eval to get started",
examples[Math.floor(Math.random() * examples.length)], examples[Math.floor(Math.random() * examples.length)],
true, true,
)} )}
# What is Topos? # 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. 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( ${makeExample(
"Small algorithms for direct musical expression", "Small algorithms for direct musical expression",
` `
rhythm(.5, 4, 8) :: sound('drum').out() rhythm(.5, 4, 8) :: sound('drum').out()
rhythm(.25, [5, 7].beat(2), 8) :: sound(['hc', 'fikea', 'hat'].pick(1)) 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]) .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() .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') beat([2,0.5].dur(13.5, 0.5))::snd('fsoftsnare')
.n(0).speed([1, 0.5]).o(4).out()`, .n(0).speed([1, 0.5]).o(4).out()`,
false, false,
)} )}
${makeExample( ${makeExample(
"Computer music should be immediate and intuitive", "Computer music should be immediate and intuitive",
` `
let chord_prog = [0, 0, 5].bar() // Chord progression let chord_prog = [0, 0, 5].bar() // Chord progression
beat(.25)::snd('sine') beat(.25)::snd('sine')
.note(chord_prog + [60, 64, 67, 71].mouseX() .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 .delay(0.5).delayt(0.25).delayfb(0.7) // Delay
.room(0.5).size(8) // Reverb .room(0.5).size(8) // Reverb
.out()`, .out()`,
false, false,
)} )}
${makeExample( ${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)) beat(.5) :: sound('sid').n($(2))
.room(1).speed([1,2].pick()).out() .room(1).speed([1,2].pick()).out()
beat(.25) :: sound('sid').note( beat(.25) :: sound('sid').note(
[34, 36, 41].beat(.25) + [[0,-24].pick(),12].beat()) [34, 36, 41].beat(.25) + [[0,-24].pick(),12].beat())
.room(0.9).size(0.9).n(4).out()`, .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). 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
`; `;
}; };

View File

@ -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: 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( ${makeExample(
"Reading the last OSC messages", "Reading the last OSC messages",
` `
beat(1)::getOsc() beat(1)::getOsc()
// 0 : {data: Array(2), address: '/lala'} // 0 : {data: Array(2), address: '/lala'}
// 1 : {data: Array(2), address: '/lala'} // 1 : {data: Array(2), address: '/lala'}
// 2 : {data: Array(2), address: '/lala'}`, // 2 : {data: Array(2), address: '/lala'}`,
true)} true,
)}
### Filtered messages ### Filtered messages
The <ic>getOsc()</ic> can receive an address filter as an argument. This will return only the messages that match the filter: The <ic>getOsc()</ic> can receive an address filter as an argument. This will return only the messages that match the filter:
${ ${makeExample(
makeExample( "Reading the last OSC messages (filtered)",
"Reading the last OSC messages (filtered)", `
`
beat(1)::getOsc("/lala") beat(1)::getOsc("/lala")
// 0 : (2) [89, 'bob'] // 0 : (2) [89, 'bob']
// 1 : (2) [84, 'bob'] // 1 : (2) [84, 'bob']
// 2 : (2) [82, 'bob'] // 2 : (2) [82, 'bob']
`, true)} `,
true,
)}
## Output ## Output
Once the server is loaded, you are ready to send an **OSC** message: Once the server is loaded, you are ready to send an **OSC** message:
${makeExample( ${makeExample(
"Sending a simple OSC message", "Sending a simple OSC message",
` `
beat(1)::sound('cp').speed(2).vel(0.5).osc() 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: 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( ${makeExample(
"Sending a customized OSC message", "Sending a customized OSC message",
` `
// osc(address, port, ...message) // osc(address, port, ...message)
osc('/my/osc/address', 5000, 1, 2, 3) osc('/my/osc/address', 5000, 1, 2, 3)
`, true)} `,
true,
)}
`}; `;
};

View File

@ -4,7 +4,7 @@ import { scriptBlinkers } from "./Visuals/Blinkers";
import { javascript } from "@codemirror/lang-javascript"; import { javascript } from "@codemirror/lang-javascript";
import { markdown } from "@codemirror/lang-markdown"; import { markdown } from "@codemirror/lang-markdown";
import { Extension } from "@codemirror/state"; import { Extension } from "@codemirror/state";
import { outputSocket, oscMessages } from "./IO/OSC"; import { outputSocket } from "./IO/OSC";
import { import {
initializeSelectedUniverse, initializeSelectedUniverse,
AppSettings, AppSettings,
@ -95,7 +95,7 @@ export class Editor {
isPlaying: boolean = false; isPlaying: boolean = false;
// OSC // OSC
outputSocket: WebSocket = outputSocket outputSocket: WebSocket = outputSocket;
// Hydra // Hydra
public hydra_backend: any; public hydra_backend: any;
@ -205,8 +205,6 @@ export class Editor {
// Loading universe from URL (if needed) // Loading universe from URL (if needed)
loadUniverserFromUrl(this); loadUniverserFromUrl(this);
} }
private getBuffer(type: string): any { private getBuffer(type: string): any {