In 2010 I made an #AudioVisual piece using #Haskell, #OpenGL, and #SC3:

https://mathr.co.uk/blog/2010-03-12_bowntz.html

This weekend I ported it from Haskell to #C, using #SDL2 as framework including #audio in the same program (SC3 was overkill for the simple sounds, and maintaining Haskell code to keep working with changes to the ecosystem is too much busy-work).

I changed the colours (suggested by @netzzz), moved the #physics #simulation from the #video thread to the #audio thread for tighter timing (the SC3 version scheduled events with bundles), and added a #RingBuffer to send the visualisation data back to the video thread (for smoother animation with good a/v sync).

I also did various optimisations, using tables instead of trigonometric functions, using (client-side) vertex arrays instead of glBegin().

License changed from #GPL v3 or later to #AGPL v3 only, in anticipation of compiling it to run in the browser using Emscripten.

Code at:
https://code.mathr.co.uk/bowntz

There's still (at least) one bug: after some time the program freezes and uses 100% CPU, I think it happens when the ball count limit is reached. Takes a long time so will be hard to figure out what is going on...

Bowntz :: mathr

Made the sound spatial using interaural time difference (660us * sin(theta)) and frequency dependent interaural intensity difference (1 + (hz/1000)^0.8 * sin(theta)).

Added keyboard controls (quit, fullscreen toggle). Added command line arguments.

Added video recording (not real-time) by piping PPM image data to ffmpeg, saving WAV with libsndfile, and combining later. Need to investigate how precise a/v sync is in this mode.

Tuned various things so it restarts when the energy drops after ball count limit is reached. Takes about 5m30 for each cycle.

Not sure if I've fixed the freeze bug, it happened after over an hour running. Added random seed control and verified reproducibility, which may help.

Tested on my 1.6GHz dual thread Atom netbook with 1GB RAM, uses about 45% of both cores. AKA not resource hungry.

Video recordings looked very bad because 1px wide lines get desaturated with yuv420p chroma subsampling. Possibly some custom chroma subsampling algorithm could fix it, if brightness Y=0 is black no matter what the chroma UV is (I don't know, would need to check the specs).

Fixed by making lines 3px wide (aesthetically fine for higher resolution displays), and enabling OpenGL line smoothing made them look nicer too (though increased encoded video size by 10%).

Added a proper ending for each section too (disable collisions and apply acceleration until all the balls leave the arena).

Still to do:
- figure out if SDL2 provides video FPS and/or audio latency information, because currently it's hardcoded to 60fps and tuned by eye/ear for my computer, which isn't ideal
- fully debug the 100% CPU freeze, or add a watchdog system to restart if it occurs
- reformat README to Markdown or Djot, for conversion to an HTML web page
- upload some example videos
- web browser version using Emscripten
- later, think about installing on a computer with VGA or TV-out and check how it looks on a 4:3 CRT (I don't have any any more, though)

The disadvantage of OpenGL's wide lines is that curves look slightly weird, because the "width" is not perpendicular to the line, instead either vertical or horizontal, which means the perceptual width is not uniform, and there are little cuts in the 4 diagonal corners of the circle.

I think I fixed the 100% CPU freeze bug. Turns out in certain situations there can be a vast number of collisions in a tiny amount of time.

Now I skip to the end state if there are more than 64 collisions within 1 audio sample (at 44100 Hz).

https://mathr.co.uk/web/bowntz.html

I made a small web page for this project and uploaded some example videos to archive.org, best to download before playing as streaming doesn't seem to work very well.

Bowntz :: mathr

An audio-visual pseudo-physical simulation of colliding circles.

@mathr Something like this would've been fantastic screensaver on Win95.

It's also a great thing to just look at and listen, it's pretty neat.