Skip to content

Commit

Permalink
lint topos
Browse files Browse the repository at this point in the history
  • Loading branch information
Bubobubobubobubo committed Dec 4, 2023
1 parent 0aa6039 commit 98c7195
Show file tree
Hide file tree
Showing 12 changed files with 127 additions and 123 deletions.
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,24 +17,24 @@
</p>
</p>

---------------------
---

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 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
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 is made to be used without the need of installing anything, always ready at
[https://topos.live](https://topos.live)
- 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)


## 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.
Expand Down
41 changes: 22 additions & 19 deletions ToposServer/OSCtoTopos.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,32 +2,35 @@ const WebSocket = require("ws");
const osc = require("osc");

const cleanIncomingOSC = (oscMsg) => {
let data = oscMsg.args;
// Remove information about type of data
data = data.map((item) => {
return item.value;
})
return {data: data, address: oscMsg.address};
}
let data = oscMsg.args;
// Remove information about type of data
data = data.map((item) => {
return item.value;
});
return { data: data, address: oscMsg.address };
};

// ==============================================
// Receiving and forwarding OSC UDP messages
// Create an osc.js UDP Port listening on port 57121.
console.log("> OSC Input: 127.0.0.1:30000");
const wss = new WebSocket.Server({ port: 3001 });
var udpPort = new osc.UDPPort({
localAddress: "0.0.0.0",
localPort: 30000,
metadata: true
localAddress: "0.0.0.0",
localPort: 30000,
metadata: true,
});
udpPort.on("message", function (oscMsg, timeTag, info) {
console.log(`> Incoming OSC to ${oscMsg.address}:`, oscMsg.args.map(
(item) => {return item.value})
);
wss.clients.forEach(client => {
if (client.readyState === WebSocket.OPEN) {
client.send(JSON.stringify(cleanIncomingOSC(oscMsg)));
}
});
console.log(
`> Incoming OSC to ${oscMsg.address}:`,
oscMsg.args.map((item) => {
return item.value;
}),
);
wss.clients.forEach((client) => {
if (client.readyState === WebSocket.OPEN) {
client.send(JSON.stringify(cleanIncomingOSC(oscMsg)));
}
});
});
udpPort.open();
udpPort.open();
38 changes: 20 additions & 18 deletions ToposServer/ToposToOSC.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,14 @@ wss.on("connection", function (ws) {
const message = JSON.parse(data);
sendOscMessage(
formatAndTypeMessage(message),
message.address,
message.port
message.address,
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) {
console.error("> Error processing message:", error);
}
Expand All @@ -24,20 +28,20 @@ wss.on("connection", function (ws) {

wss.on("error", function (error) {
console.error("> Server error:", error);
})
});

wss.on("close", function () {
// Close the websocket server
wss.close();
console.log("> Closing websocket server")
console.log("> Closing websocket server");
});

let udpPort = new osc.UDPPort({
localAddress: "0.0.0.0",
localPort: 3000,
metadata: true,
remoteAddress: "0.0.0.0",
remotePort: 57120,
remotePort: 57120,
});
udpPort.on("error", function (error) {
console.error("> UDP Port error:", error);
Expand All @@ -51,7 +55,7 @@ udpPort.open();

function sendOscMessage(message, address, port) {
try {
udpPort.options.remotePort = port
udpPort.options.remotePort = port;
message.address = address;
udpPort.send(message);
} catch (error) {
Expand All @@ -61,21 +65,19 @@ function sendOscMessage(message, address, port) {

const formatAndTypeMessage = (message) => {
let newMessage = {};
delete message.args['address'];
delete message.args['port'];
delete message.args["address"];
delete message.args["port"];
newMessage.address = message.address;
newMessage.timestamp = osc.timeTag(message.timetag);

args = [...Object.entries(message.args)].flat().map((arg) => {
if (typeof arg === 'string')
return {type: 's', value: arg};
if (typeof arg === 'number')
return {type: 'f', value: arg};
if (typeof arg === 'boolean')
return value ? {type: 's', value: 1} : {type: 's', value: 0};
})
if (typeof arg === "string") return { type: "s", value: arg };
if (typeof arg === "number") return { type: "f", value: arg };
if (typeof arg === "boolean")
return value ? { type: "s", value: 1 } : { type: "s", value: 0 };
});

newMessage.args = args
newMessage.args = args;

return newMessage;
}
};
10 changes: 5 additions & 5 deletions ToposServer/banner.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
var pjson = require('./package.json');
var pjson = require("./package.json");
let banner = `
┏┳┓ ┏┓┏┓┏┓
┃ ┏┓┏┓┏┓┏ ┃┃┗┓┃
┻ ┗┛┣┛┗┛┛ ┗┛┗┛┗┛
${pjson.version}\n`
${pjson.version}\n`;
function greet() {
console.log(banner)
console.log(banner);
}

module.exports = {
greet: greet
}
greet: greet,
};
7 changes: 3 additions & 4 deletions ToposServer/server.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
const WebSocket = require("ws");
const osc = require("osc");

require('./banner').greet();
require("./banner").greet();
// Topos to OSC
require('./ToposToOSC')
require("./ToposToOSC");
// OSC to Topos
require("./OSCtoTopos")

require("./OSCtoTopos");
24 changes: 12 additions & 12 deletions src/API.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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);
Expand Down Expand Up @@ -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[]
) {
Expand Down Expand Up @@ -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[] => {
/**
Expand All @@ -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
Expand Down
29 changes: 15 additions & 14 deletions src/Clock.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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);
Expand All @@ -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
*/
Expand All @@ -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;
Expand All @@ -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;
Expand All @@ -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];
Expand All @@ -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);
Expand All @@ -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;
Expand All @@ -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
*/
Expand Down Expand Up @@ -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();
Expand All @@ -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;
Expand Down
Loading

0 comments on commit 98c7195

Please sign in to comment.