Wishful Coding

Didn't you ever wish your
computer understood you?

Theremin Singing Bowl

I built my own electro-mechanical music instrument by combining ideas from some of the coolest instruments I know of:

A theremin is an electronic instrument that you play by moving your hands in the air. It uses an analog circuit with two tuned oscillators, one of which is modulated by the antenna impedance which is perturbed by the presence of your body in the near field. The slight frequency differences are fed into a mixer to produce an audible frequency.

A singing bowl is a very old insturment that is usually played by rotating a suede covered mallet around its outside rim. The stick-slip motion of the mallet excites vibration modes of which the nodes are pushed around by the mallet. Some more experimental musicians also play singing bowls by drawing a violin bow across the rim.

A hurdy-gurdy is a string instrument, which uses a hand-cranked wheel with rosin on it rather than a bow. It also has other unique features like drone strings and a keyboard on the neck.

So here is the idea: what if you used a theremin to drive a hurdy-gurdy wheel and use that to play a singing bowl? Magic theremin singing bowl!

For the theremin I built myself a copy of the Thierrymin (using J113 jfets), which I fed into a comparator, stepper motor driver, and stepper motor. From there the only things I had to tweak were a few resistors to add a little hysteresis, and I played around with the microstepping pins to change the speed of the stepper motor. Here is a rough schematic:

schematic

That was the easy part. Then I did a bunch of experiments with different types of wheels. I tried rosin, suede, wood, plastic. I tried to spin the wheel on a static bowl, or to spin the bowl against a static baton. It kind of worked, but nothing worked quite the way I wanted it. And then life got rather busy and the project sat dormant for a while. So that’s when I decided to just write a blogpost with my progress and shelve the project. Maybe I’ll get back to it one day, or inspire someone else.

Lightweight pure CSS gauge

The other day I was helping my brother with the second version of his performance installation DEMARRAGE, which involves serving a web page from an ESP32 that displays the energy produced by two dynamo bikes.

For this page we wanted a simple gauge, so I figured a solution would be an internet search away. But all the examples I found seemed really complicated, with verbose markup, opaque CSS, and sometimes an entire JS library. So I decidede to make my own.

a dashboard showing a simple CSS gauge

My goals were

  • Very minimal HTML without any extra dummy elements.
  • CSS that is easy to understand and modify.
  • Easy to update the value from JS.
  • A gauge of 270° rather than a semi-circle.
  • (browser compat was not a goal)

The HTML is as simple as it gets, just a div with custom properties and the textual value.

<div class="gauge" style="--value:0.3; font-size:2rem;">30%</div>

Conceptually, the CSS isn’t very complicated either.

  • set the size of the gauge div
  • set a border-radius to make a circle
  • draw a conic-gradiant to make a pie-chart
  • draw a radial-gradient to cut out the center
  • center the text with text-align and line-height

The code CSS makes use of calc and var, primarily to adjust the conic-gradient angle based on a custom property, but also to parameterize the dimensions of the gauge. This means you can override --size and friends to style the gauge without changing hardcoded values.

.gauge {
  --size: 200px;
  --cutout: 50%;
  --color: red;
  --background: white;
  width:var(--size);
  height:var(--size);
  border-radius:calc(var(--size) / 2);
  background:
    radial-gradient(
        var(--background) 0 var(--cutout),
        transparent var(--cutout) 100%),
    conic-gradient(from -135deg, 
        var(--color) calc(270deg*var(--value)),
        grey calc(270deg*var(--value)) 270deg, 
        transparent 270deg);
  text-align: center;
  line-height: var(--size);
}

The JavaScript for changing the gauge value is pretty simple too, given some gauge DOM element el you can change the gauge value and text content by simply doing

el.style.setProperty("--value", 0.8)
el.innerHTML = "80%"

Below is a codepen to play with the code. I hope it’s useful to someone.

See the Pen Pure CSS gauge by Pepijn de Vos (@pepijndevos) on CodePen.

After a bit of chatting on the Recurse Center Zulip, I came up with the following alternative gradients that provide a 3D effect or that goes from red to orange to green. The 3D one works by adding a transparent black gradient to the radial part. The colourful one works by making a fixed backdrop and a transparent-grey gradient on top that reveals the underlying one.

3d red orange green

  background:
    conic-gradient(from -135deg,
      transparent 270deg,
      white 270deg),
    radial-gradient(
      var(--background) 0 var(--cutout),
      #0002 calc(var(--cutout)),
      #0000 calc(var(--cutout) + 15px),
      #0002 calc(var(--cutout) + 30px),
      #0000 calc(var(--cutout) + 30px) 100%),
    conic-gradient(from -135deg,
      var(--color) calc(270deg*var(--value)),
      grey calc(270deg*var(--value)) 270deg,
      transparent 270deg);

  background:
    radial-gradient(
      var(--background) 0 var(--cutout),
      transparent var(--cutout) 100%),
    conic-gradient(from -135deg,
      transparent calc(270deg*var(--value)),
      grey calc(270deg*var(--value)) 270deg,
      transparent 270deg),
    conic-gradient(from -135deg,
      red 0,
      orange 135deg,
      lime 270deg,
      transparent 270deg);
Published on

ChatLZMA

I came across a random tweet, found a Wikipedia page and bumped into some smart people and long story short, apparently compression is equivalent to general intelligence.

So, how do you build ChatGPT with data compression? What if you compress a large corpus of text to build up the encoding table, then you compress your prompt and append some random data and decompress the random data, and hope it decompresses to something sensible.

It feels vaguely similar to diffusion, but what do I know. Look, this is just a dumb idea, let’s just see what happens ok? Well, here is my progress so far. It’s kind of whack but it’s hilarious to me that it produces something resembling words.

import nltk
import lzma
import random

my_filters = [
    {"id": lzma.FILTER_LZMA2, "preset": 9 | lzma.PRESET_EXTREME},
]
lzc = lzma.LZMACompressor(lzma.FORMAT_RAW, filters=my_filters)

corp = nltk.corpus.reuters.raw().encode()
out1 = lzc.compress(corp)

corp = ' '.join(nltk.corpus.brown.words()).encode()
out2 = lzc.compress(corp)

corp = nltk.corpus.gutenberg.raw().encode()
out3 = lzc.compress(corp)

out_end = lzc.flush()

lzd = lzma.LZMADecompressor(lzma.FORMAT_RAW, filters=my_filters)

lzd.decompress(out1)
lzd.decompress(out2)
lzd.decompress(out3)
# mess around to avoid LZMAError: Corrupt input data
lzd.decompress(out_end[:-344])
# insert prompt????
print(lzd.decompress(random.randbytes(50)).decode(errors="ignore"))

Here are a few runs. Note how the start is always , and tri, usually completing it into some word. Are we doing some primitive accidental “prompting” or just flushing the buffer? Either way, not bad for mere seconds of “training”!

$ python train.py 
, and triof billioerse,
But
ht and see th,
Thy smile, in to be happy,
Wmson,
Over tout as aThy smile;t as aThyrged in
 
ent, foldehe snoion since how long,
my roomr? Is ic books 

$ python train.py 
, and triompact, sca,
Take deepcky fouy vitaliz  bodiehow there i,
Nor drummiwisibly wile of the-ations, dutway?
Yet ld woman'okesmanall whoy slow bekesmanalle me 

$ python train.py 
, and tri billions of the boftier, faie no acqutory's dazzd haOr that thpages:
(Sometimeseathe ihern, Sounte, fld Turkey n one,
Worlseathe Border Minstrelsy,ine, New-Ene Queen.

'Thelicate l

$ python train.py 
, and tri, sleepinlke babes  bent,
Abird;
Forhis fair n!
By thea mystic strangehe gifts ofhe body aering
 t: I haue a lugs whipageantuperb-fnz

$ python train.py 
, and triions of b--n the gra, with
e open the countless buAnd bid theng;
Billi  toward you.i ally undya Songs

To f Death, istas of was mar to be UY 9,30