massi-world

this website of mine
Log | Files | Refs

commit e252c3613d39b01395b4543464ef2c36339479a1
parent 27c6370284aa179701cd59dfab1ee204569ef537
Author: massi <mdsiboldi@gmail.com>
Date:   Fri, 19 Jul 2024 05:05:41 -0700

Add rough 1st iteration of color-synth info page

Diffstat:
M.gitignore | 5+++--
MMakefile | 2+-
Asrc/color-synth.md | 41+++++++++++++++++++++++++++++++++++++++++
Msrc/main.lisp | 26+++++++++++++++++++++++---
Astatic/color-synth-sample-1.webp | 0
Astatic/color-synth-sample-2.webp | 0
Astatic/color-synth-sample-3.webp | 0
Astatic/color-synth-sample-4.webp | 0
Mstatic/style.css | 15+++++++++++++++
9 files changed, 83 insertions(+), 6 deletions(-)

diff --git a/.gitignore b/.gitignore @@ -1,3 +1,4 @@ build .env -**/#*# -\ No newline at end of file +**/#*# +**/*.draft +\ No newline at end of file diff --git a/Makefile b/Makefile @@ -8,9 +8,9 @@ build: ./make.lisp serve: http-server build -p 8080 & while true; do \ + inotifywait @./build -qre close_write .; \ make clean; \ make build; \ - inotifywait -qre close_write .; \ done publish: build scp -r build/* "${MASSIWORLD_HOST}:" diff --git a/src/color-synth.md b/src/color-synth.md @@ -0,0 +1,41 @@ +- [git repo here](https://massi.world/git/color-synth) +- [check out color-synth here!](https://massi.world/color-synth) + +## About + +Color-synth is a virtual modular [video synthesizer](https://en.wikipedia.org/wiki/Video_synthesizer). Add and hook up various signal-generating modules, connect them to the video output channels, and watch the colors start dancing in your eyes. + +## Current State + +Color-synth is under __active development__. Everything is subject to change, and any programs you save to url may become invalid in the future. + +## How To Synthesize + +- Add a module using the buttons on the bottom right. +- To connect a module, drag from its purple connector on the top-right of the module, to either a green input port of another module, or the video output channels (lightness, chroma, hue) on the top right of the screen. +- To disconnect a module, do the same thing you did to connect it. +- When you've made something you want to share, click on the `save` button at the bottom right corner. This will save your patch to the url. + +## The Modules + +- The __oscillator__ module generates a waveform signal. In the audio realm, you usually have knobs to control an oscillator's octave, semitone, and cents. Each knob is more precise than the last, and accomplishes different effects - pitching up or down an octave, transposing, and fine-tuning. In the video realm, there are some similarities to this system. Three knobs working at different harmonic levels. `Coarse` controls how the waveform repeats over the entire screen. For example, `coarse` set to `1` means that from the first pixel drawn on the screen to the last, the waveform will go through one cycle. `Fine` works on the row level - each increment of the fine knob will cycle the waveform once per row of pixels. `Superfine` is akin to cents. It enables movement by slightly adjusting the frequency of the wave so that it doesn't perfectly line up with the screen. Finally, you can select between a sine, square, or sawtooth wave with `waveform`. + +- The __signal__ module outputs whatever you put into it. It's useful if you want one control to effect multiple knobs throughout your patch, or if you want to set a knob to a value it isn't normally able to be set to. + +- The __noise__ module outputs random values, scaled by `amount`. + +- The __blur__ module smooths out the signal. Because of the left-to-right order in rendering pixels, this only blurs in the horizontal direction for now. + +- The __math__ module allows signals to be added, subtracted, multiplied, divided, or modulo'd together. Useful for scaling modules that don't have their own scaling knob and making some weird stuff happen. + +- The __image oscillator__ module currently adds a smiley face. In the _future_, you'll be able provide an image of your own! It has one control, `speed`, that is probably confusing right now. Basically, you can think of the color values of an image as a complicated waveform. That waveform has a frequency. In the current state of this module, a speed of `100,000` will display the image at full size. `200,000` will display a 2x2 grid of the image. `300,000`, 3x3. Etc. + +## Roadmap + +- Better inputs. There is much to do here. The current ones are imprecise and unwieldy. +- Image module overhaul. Having inputs for scaleX, scaleY, and image URL would be a good start. +- Workspace improvements. There are a lot of impactful things here. The ability to hide all modules! The ability to move all modules at once and/or pan the workspace. Improvements to the initial positioning of new modules. +- Workflow improvements. Undo/Redo! The ability to delete modules! Adding a module in between two connected modules! Better disconnect ergonomics! +- Module design overhaul. My long-term goal is to style each module in its own unique way, as a nod to all the unique modular synthesis gear out there. +- Mobile support. +- MIDI support, so you can route midi to your browser and sync color-synth with your music! diff --git a/src/main.lisp b/src/main.lisp @@ -1,5 +1,6 @@ (load "~/quicklisp/setup.lisp") (ql:quickload "spinneret") +(ql:quickload "spinneret/cl-markdown") (ql:quickload "local-time") (in-package #:spinneret) @@ -42,11 +43,17 @@ (with-page (:path path :title "Home page" :description "My website.") (header) (:section - (:h2 "web projects") + (:h2 "projects") (:ul - (:li (:a :href "/color-synth" "color-synth")))) + (:li (:a :href "/projects/color-synth.html" "color-synth")))) (:footer ("Last generated: ~A" (local-time:now))))) +(defun file-get-contents (filename) + (with-open-file (stream filename) + (let ((contents (make-string (file-length stream)))) + (read-sequence contents stream) + contents))) + (defun mk-page (&key path maker) (let* ((out-dir "build/") (out-file (format nil "~{~A~}" `(,out-dir ,path)))) @@ -58,8 +65,21 @@ (setf *always-quote* t) (format str (with-output-to-string (*html*) (funcall maker path)))))) +(defun mk-color-synth (path) + (with-page (:path path + :title "color-synth" + :description "color-synth: a synth that outputs colors") + (:div.color-synth + (:h1 "color-synth") + (:div.samples (:img :src "/static/color-synth-sample-1.webp") + (:img :src "/static/color-synth-sample-2.webp") + (:img :src "/static/color-synth-sample-3.webp") + (:img :src "/static/color-synth-sample-4.webp")) + (:div.md (#.(file-get-contents "./src/color-synth.md")))))) + (defparameter sitespec - '(("index.html" mk-home))) + '(("index.html" mk-home) + ("projects/color-synth.html" mk-color-synth))) (defun mk-site () (loop for pagespec in sitespec diff --git a/static/color-synth-sample-1.webp b/static/color-synth-sample-1.webp Binary files differ. diff --git a/static/color-synth-sample-2.webp b/static/color-synth-sample-2.webp Binary files differ. diff --git a/static/color-synth-sample-3.webp b/static/color-synth-sample-3.webp Binary files differ. diff --git a/static/color-synth-sample-4.webp b/static/color-synth-sample-4.webp Binary files differ. diff --git a/static/style.css b/static/style.css @@ -15,3 +15,18 @@ background: var(--light); } } + +.color-synth .samples { + display: flex; + max-width: 100%; +} + +.color-synth .samples > * { + flex: auto; + min-width: 1px; + max-width: 200px; +} + +.color-synth .samples > *:not(:first-child) { + margin-left: 10px; +}