diff --git a/.github/workflows/build_docker.yml b/.github/workflows/build_docker.yml index 80aae64..71a6250 100644 --- a/.github/workflows/build_docker.yml +++ b/.github/workflows/build_docker.yml @@ -3,28 +3,23 @@ name: Build and Push Docker Images on: push: branches: - - 'main' + - "main" jobs: topos: runs-on: ubuntu-latest steps: - - - name: Checkout + - name: Checkout uses: actions/checkout@v2 - - - name: Set up QEMU + - name: Set up QEMU uses: docker/setup-qemu-action@v3 - - - name: Set up Docker Buildx + - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - - - name: Login to Docker Hub + - name: Login to Docker Hub uses: docker/login-action@v3 with: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} - - - name: Build and push + - name: Build and push uses: docker/build-push-action@v5 with: push: true diff --git a/.vscode/settings.json b/.vscode/settings.json index 7a73a41..0967ef4 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,2 +1 @@ -{ -} \ No newline at end of file +{} diff --git a/README.md b/README.md index 2d9ee97..71cca60 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,9 @@ # Topos: A Web-Based Algorithmic Sequencer

 | - Discord | - BuboBubo |  - Amiika | + Discord | + BuboBubo | + Amiika | About Live Coding |

Contributors

@@ -12,15 +12,32 @@

+

+ Buy Me a Coffee at ko-fi.com +

-Topos is a web-based live coding environment. It lives [here](https://topos.live). Documentation is directly embedded in the application itself. Topos is an emulation and extension of the [Monome Teletype](https://monome.org/docs/teletype/) that gradually evolved into something a bit more personal. +--------------------- + +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) +- it can also generate video thanks to [Hydra](https://hydra.ojack.xyz/) and +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 a fairly young project developed by two part time hobbyists :) Do not expect stable features and/or user support in the initial development stage. Contributors and curious people are welcome! 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. ## Installation (for devs and contributors) @@ -46,15 +63,18 @@ The `tauri` version is only here to quickstart future developments but nothing ## Docker ### Run the application + `docker run -p 8001:80 yassinsiouda/topos:latest` ### Build and run the prod image + `docker compose --profile prod up` ### Build and run the dev image **First installation** First you need to map node_modules to your local machine for your ide intellisense to work properly + ```bash docker compose --profile dev up -d docker cp topos-dev:/app/node_modules . @@ -62,7 +82,7 @@ docker compose --profile dev down ``` **Then** + ```bash docker compose --profile dev up ``` - diff --git a/ToposServer/index.js b/ToposServer/index.js deleted file mode 100644 index 01b5bdf..0000000 --- a/ToposServer/index.js +++ /dev/null @@ -1,35 +0,0 @@ -const WebSocket = require("ws"); -const osc = require("osc"); - -const wss = new WebSocket.Server({ port: 3000 }); -console.log("WebSocket server started on ws://localhost:3000"); - -wss.on("connection", function (ws) { - console.log("> Client connected"); - - ws.on("message", function (data) { - try { - const message = JSON.parse(data); - sendOscMessage(message); - } catch (error) { - console.error("> Error processing message:", error); - } - }); -}); - -function sendOscMessage(message) { - const udpPort = new osc.UDPPort({ - localAddress: "127.0.0.1", - localPort: 3000, - remoteAddress: "127.0.0.1", - remotePort: message.port, - }); - - udpPort.on("ready", function () { - console.log("> OSC Message:", message); - udpPort.send(message); - udpPort.close(); - }); - - udpPort.open(); -} diff --git a/ToposServer/package.json b/ToposServer/package.json index 2b71572..fdee0f5 100644 --- a/ToposServer/package.json +++ b/ToposServer/package.json @@ -1,6 +1,6 @@ { "name": "topos-server", - "version": "1.0.0", + "version": "0.0.1", "description": "Topos OSC Server", "main": "index.js", "scripts": { diff --git a/ToposServer/server.js b/ToposServer/server.js new file mode 100644 index 0000000..efa6b21 --- /dev/null +++ b/ToposServer/server.js @@ -0,0 +1,66 @@ +const WebSocket = require("ws"); +const osc = require("osc"); +var pjson = require('./package.json'); + + +// ========================================================== +// SERVER SIDE OSC FORWARDING: WebSocket => OSC +// ========================================================== + +// Listening to WebSocket messages +let banner = ` +┏┳┓ ┏┓┏┓┏┓ + ┃ ┏┓┏┓┏┓┏ ┃┃┗┓┃ + ┻ ┗┛┣┛┗┛┛ ┗┛┗┛┗┛ + ┛ + ${pjson.version}\n` +const wss = new WebSocket.Server({ port: 3000 }); +console.log(banner) +console.log("Listening to: ws://localhost:3000. Open Topos.\n"); + +// Setting up for message broadcasting +wss.on("connection", function (ws) { + console.log("> Client connected"); + ws.on("message", function (data) { + try { + const message = JSON.parse(data); + sendOscMessage(message); + } catch (error) { + console.error("> Error processing message:", error); + } + }); +}); + +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") +}); + +let udpPort; + + +function sendOscMessage(message) { + console.log("sendOscMessage") + try { + if (!message.port === udpPort.remotePort) { + udpPort = new osc.UDPPort({ + localAddress: "127.0.0.1", + localPort: 3000, + remoteAddress: "127.0.0.1", + remotePort: message.port, + }); + udpPort.open(); + } + udpPort.on("ready", function () { + console.log("> OSC Message:", message); + udpPort.send(message); + }); + } catch (error) { + console.log(error) + } +} \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml index 0021919..62f86ee 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,9 +1,9 @@ -version: '3.7' +version: "3.7" services: topos-dev: container_name: topos-dev profiles: ["dev"] - build: + build: context: . target: "dev" volumes: @@ -21,8 +21,8 @@ services: topos-prod: container_name: topos-prod profiles: ["prod"] - build: + build: context: . target: "prod" ports: - - "8001:80" \ No newline at end of file + - "8001:80" diff --git a/favicon/site.webmanifest b/favicon/site.webmanifest index b20abb7..fa99de7 100644 --- a/favicon/site.webmanifest +++ b/favicon/site.webmanifest @@ -1,19 +1,19 @@ { - "name": "", - "short_name": "", - "icons": [ - { - "src": "/android-chrome-192x192.png", - "sizes": "192x192", - "type": "image/png" - }, - { - "src": "/android-chrome-512x512.png", - "sizes": "512x512", - "type": "image/png" - } - ], - "theme_color": "#ffffff", - "background_color": "#ffffff", - "display": "standalone" + "name": "", + "short_name": "", + "icons": [ + { + "src": "/android-chrome-192x192.png", + "sizes": "192x192", + "type": "image/png" + }, + { + "src": "/android-chrome-512x512.png", + "sizes": "512x512", + "type": "image/png" + } + ], + "theme_color": "#ffffff", + "background_color": "#ffffff", + "display": "standalone" } diff --git a/fonts/index.css b/fonts/index.css index 967bf0c..159b271 100644 --- a/fonts/index.css +++ b/fonts/index.css @@ -1,7 +1,8 @@ @font-face { font-family: "IBM Plex Mono"; - src: url("woff2/IBMPlexMono-Regular.woff2") format("woff2"), - url("woff/IBMPlexMono-Regular.woff") format("woff"); + src: + url("woff2/IBMPlexMono-Regular.woff2") format("woff2"), + url("woff/IBMPlexMono-Regular.woff") format("woff"); font-weight: 400; font-style: normal; font-display: swap; @@ -9,8 +10,9 @@ @font-face { font-family: "IBM PLex Mono"; - src: url("woff2/IBMPlexMono-Italic.woff2") format("woff2"), - url("woff/IBMPlexMono-Italic.woff") format("woff"); + src: + url("woff2/IBMPlexMono-Italic.woff2") format("woff2"), + url("woff/IBMPlexMono-Italic.woff") format("woff"); font-weight: 400; font-style: italic; font-display: swap; @@ -18,8 +20,9 @@ @font-face { font-family: "IBM PLex Mono"; - src: url("woff2/IBMPlexMono-Bold.woff2") format("woff2"), - url("woff/IBMPlexMono-Bold.woff") format("woff"); + src: + url("woff2/IBMPlexMono-Bold.woff2") format("woff2"), + url("woff/IBMPlexMono-Bold.woff") format("woff"); font-weight: 700; font-style: normal; font-display: swap; @@ -27,8 +30,9 @@ @font-face { font-family: "IBM Plex Mono"; - src: url("woff2/IBMPlexMono-BoldItalic.woff2") format("woff2"), - url("woff/IBMPlexMono-BoldItalic.woff") format("woff"); + src: + url("woff2/IBMPlexMono-BoldItalic.woff2") format("woff2"), + url("woff/IBMPlexMono-BoldItalic.woff") format("woff"); font-weight: 700; font-style: italic; font-display: swap; @@ -37,84 +41,85 @@ @font-face { font-family: "Comic Mono"; font-weight: normal; - src: url(./woff/ComicMono.woff) format("woff"), - url(./woff2/ComicMono.woff2) format("wooff2"); + src: + url(./woff/ComicMono.woff) format("woff"), + url(./woff2/ComicMono.woff2) format("wooff2"); } @font-face { font-family: "Comic Mono"; font-weight: bold; - src: url(./woff/ComicMono-Bold.woff) format("woff"), - url(./woff/ComicMono-Bold.woff2) format("woff2"), -} - - -@font-face { - font-family: 'jgs7'; - src: url('./woff2/jgs7.woff2') format('woff2'), - url('./woff/jgs7.woff') format('woff'); - font-weight: normal; - font-style: normal; - font-display: swap; + src: + url(./woff/ComicMono-Bold.woff) format("woff"), + url(./woff/ComicMono-Bold.woff2) format("woff2"); } @font-face { - font-family: 'jgs5'; - src: url('./woff2/jgs5.woff2') format('woff2'), - url('./woff/jgs5.woff') format('woff'); - font-weight: normal; - font-style: normal; - font-display: swap; + font-family: "jgs7"; + src: + url("./woff2/jgs7.woff2") format("woff2"), + url("./woff/jgs7.woff") format("woff"); + font-weight: normal; + font-style: normal; + font-display: swap; } @font-face { - font-family: 'jgs9'; - src: url('./woff2/jgs9.woff2') format('woff2'), - url('./woff/jgs9.woff') format('woff'); - font-weight: normal; - font-style: normal; - font-display: swap; -} - - -@font-face { - font-family: 'jgs_vecto'; - src: url('./woff2/jgs_vecto.woff2') format('woff2'); - font-weight: normal; - font-style: normal; - font-display: swap; + font-family: "jgs5"; + src: + url("./woff2/jgs5.woff2") format("woff2"), + url("./woff/jgs5.woff") format("woff"); + font-weight: normal; + font-style: normal; + font-display: swap; } @font-face { - font-family: 'Steps Mono'; - src: url('./woff2/Steps-Mono.woff2') format('woff2'); - font-weight: normal; - font-style: normal; - font-display: swap; + font-family: "jgs9"; + src: + url("./woff2/jgs9.woff2") format("woff2"), + url("./woff/jgs9.woff") format("woff"); + font-weight: normal; + font-style: normal; + font-display: swap; } @font-face { - font-family: 'Steps Mono Thin'; - src: url('./woff2/Steps-Mono-Thin.woff2') format('woff2'); - font-weight: normal; - font-style: normal; - font-display: swap; + font-family: "jgs_vecto"; + src: url("./woff2/jgs_vecto.woff2") format("woff2"); + font-weight: normal; + font-style: normal; + font-display: swap; } - @font-face { - font-family: 'Jet Brains'; - src: url('./woff2/JetBrainsMono-Regular.woff2') format('woff2'); - font-weight: normal; - font-style: normal; - font-display: swap; + font-family: "Steps Mono"; + src: url("./woff2/Steps-Mono.woff2") format("woff2"); + font-weight: normal; + font-style: normal; + font-display: swap; } - @font-face { - font-family: 'Jet Brains'; - src: url('./woff2/JetBrainsMono-Bold.woff2') format('woff2'); - font-weight: 700; - font-style: normal; - font-display: swap; + font-family: "Steps Mono Thin"; + src: url("./woff2/Steps-Mono-Thin.woff2") format("woff2"); + font-weight: normal; + font-style: normal; + font-display: swap; +} + +@font-face { + font-family: "Jet Brains"; + src: url("./woff2/JetBrainsMono-Regular.woff2") format("woff2"); + font-weight: normal; + font-style: normal; + font-display: swap; +} + +@font-face { + font-family: "Jet Brains"; + src: url("./woff2/JetBrainsMono-Bold.woff2") format("woff2"); + font-weight: 700; + font-style: normal; + font-display: swap; } diff --git a/index.html b/index.html index 01c9daf..edde30b 100644 --- a/index.html +++ b/index.html @@ -71,7 +71,7 @@
-
+