ClaudiusMaximus' Journal

20 -


2008-09-19 16:08 Website update

I got fed up with my old site engine, for various reasons. So I wrote a new one, which hopefully will make it easier for me to stay motivated to update more often.

You can still visit the old site, which will be gradually dismantled as I port the content to the new system.

2008-07-08 21:47 D012345

A video I made earlier this year:


Download links:

Which reminds me, I need to move this blog to my main website so that I can use <embed> tags...

2008-06-29 16:58 ray42 as a Lua package using tolua

ray42 was nice as it was, but I got fed up with having to recompile each time I wanted to render a new scene, and C++ isn't a particularly friendly scene description language. So I'm now using tolua to make a Lua package from the core of ray42, and it seems to work ok.

This code:


local s = nil
for x = -1, 1 do for y = -1, 1 do for z = -1, 1 do
  local m
  if x*y*z == 0 then m = gold else m = cyan end
  local t = sphere3(m, 0.5):translate(v3(x,y,z)*1.5)
  if s ~= nil then s = s + t else s = t end
end end end
s = s:transform(rotate3(0.3,1,2) * rotate3(0.3,0,2) * rotate3(0.3,0,1))

local l = Lights3:new(rgb(0.25,0.25,0.25))
l:add(v3(-3,0,0), rgb(0.5,0.5,0.5))
l:add(v3( 3,0,0), rgb(0.5,0.5,0.5))
l:add(v3(0,-3,0), rgb(0.5,0.5,0.5))
l:add(v3(0, 3,0), rgb(0.5,0.5,0.5))
l:add(v3(0,0,-3), rgb(0.5,0.5,0.5))
l:add(v3(0,0, 3), rgb(0.5,0.5,0.5))

render3(s, l, 788, 576, 4/3, 2)

generates this image:

cube of spheres 3d

One small tip when using tolua with recent versions of g++: activate the -Wno-write-strings flag to avoid drowning in a flood of:

warning: deprecated conversion from string constant to 'char*'

It is quite boring writing wrappers for ray42's C++ template classes because tolua doesn't seem to understand templates, maybe I should be using tolua++ or some other tool entirely.

2008-06-27 18:13 ray42 : nD raytracing

I've been rewriting ray4 from scratch in C++, extending it to arbitrary dimensions, providing various Constructive Solid Geometry operations, trying out procedural textures, playing around in general. It's way too slow though, the ray tracing algorithm is completely naive and tests every object against every ray, no oct-tree optimisations here. But it seems to generate some pretty pictures, or even animations, if you're prepared to wait a while.

ray42 gallery

So far I've tested with 3D and 4D, and it seems to work to some extent.

Meanwhile, way back in 2006 I was trying to make a compound of five cubes, well it turned out my maths was wrong - instead of (Scheme):

(define A (* 90 (atan (* 2 (- 0.5 (/ (- (sqrt 5) 2) (- 3 (sqrt 5))))))))

I should have been using (C++):

double a(std::atan(2.0l / (1.0l + std::sqrt(5.0l))));

Now the corners line up perfectly:

compound of five cubes


2008-06-19 01:36 pdlua-0.5 released

Pd (aka Pure-data) is a real-time visual programming environment primarily used for multimedia processing. Lua is a powerful, fast, light-weight, embeddable scripting language. pdlua is a Lua embedding for Pd.

This release adds new features to interact with Pd's [value] and [table] and also better support Lua's require() functionality.

pdlua-0.5 (2008-06-18), changes since pdlua-0.4 (2008-03-26):

  • Building: Makefile.static (recommended)
  • Building: autoconfiscated (for advanced users)
  • Feature: interaction with [value], see [revalue] and [lexpr]
  • Feature: interaction with [table], see [ltabdump] and [ltabfill]
  • Feature: require() looks relative to .pd_lua and .pd_luax files
  • Internal: support pd >= 0.41 and pd < 0.41 (pd table API change)

Note: if pdlua is compiled for pd >= 0.41 it won't load in pd < 0.41, and if pdlua is compiled for pd < 0.41 and is loaded in pd >= 0.41 it will exhibit table-related 64bit bugs.

Get a tarball here: pdlua-0.5

Or via SVN:

svn co

Development version (may be broken at times):

svn co

2008-04-13 00:08 buildtorrent-0.7 released

buildtorrent is a simple command-line .torrent file creation tool.

Bug fixes in buildtorrent-0.7:

  • Handle empty files better.
  • No more badly formatted error messages.
  • Don't crash on nonsense piece length.

Download the release tarball: buildtorrent-0.7-1.tar.gz

Or check out the development sources from SVN:

svn checkout buildtorrent

See also: buildtorrent homepage.

2008-03-26 23:02 pdlua-0.4 released

Pd (aka Pure-data) is a real-time visual programming environment primarily used for multimedia processing. Lua is a powerful, fast, light-weight, embeddable scripting language. pdlua is a Lua embedding for Pd.

This is primarily a bug fix release, but also has some incompatible API changes (which should hopefully resolve some Pd vs Lua name clash issues in the long term).

pdlua-0.4 (2008-03-26), changes since pdlua-0.3 (2007-12-02):

  • API change: "load $1"--[lua] users must add the file name extension
  • Bug fix: "load $1"--[lua] works as advertised
  • API change: users must name files "*.pd_lua" instead of "*.lua"
  • API change: users must name files "*.pd_luax" instead of "*.luax"
  • Bug fix: help patches should be found correctly
  • Examples++: [lurn], [luametro], [lpipe]
  • Internal: Doxygenated source comments
  • Internal: fewer leading underscores
  • Internal: renamed all examples for API change and tested them

Thanks to Frank Barknecht for the additional examples.

Get a tarball here: pdlua-0.4

Or via SVN:

svn co

Development version (may be broken at times):

svn co

2008-03-23 00:32 GraphGrow realtime preview with Pd and Gem

You might remember my project GraphGrow which started as a SVG plus ECMAScript system for designing Graph-Directed Iterated Function Systems, then developed into a comand-line video renderer written in C for higher performance.

The project has been dormant for some months, but today I resumed work on a new facet : a realtime preview system using Pd, Gem and Lua. It's currently rather rough/hardcoded - you have to make a new patch for each structure, and there is currently a key piece in the puzzle missing (conversion from [gemlist_info] to a format that the [graphgrow] scene exporter understands).

On the plus side, the realtime rendering (implemented with OpenGL texture feedback) makes it really quick to try out different ways of animating the fractals, and once the exporter is working it should be possible to record animations and later render high quality videos with graphgrow-engine.

Enough talking, some screenshots:

GraphGrow Pd/Gem preview Spiral

GraphGrow Pd/Gem preview Boxy

Patches are in my SVN under "2008/gg/", if you're curious.

UPDATE : I got the Gem->GraphGrow bridge working, apart from a tiny issue (GraphGrow output is upside down compared to Gem output) that should be easy to fix. Screenshot.

2008-02-24 14:04 Linux Audio Conference Club Night 2008-02-29

Linux Audio Conference
Linux Audio Conference

I'll be playing at the Linux Audio Conference Club Night this coming Friday, 8-til-late at Studio 672 in the basement of Stadtgarten.

UPDATE Two videos from my set are now online (download links are in the left sidebar):

External - the visuals I was projecting (nb: I made a typo in the filenames, oops).

Internal - what was on my screen (nb: probably useless to watch anything other than the MPEG2 due to tiny and important details in the image).

If someone knows any way to make multi-angle DVDs using a Free Software tool chain, please let me know!

Many thanks to the organisers of LAC, it was a great experience.

2008-02-17 11:22 Some new (old) videos

I uploaded some old videos I made during the last 3 years or so. Without further ado, here are the links:

DohPaintII Session 2
DohPaintII Session 2

DohPaintII Session 3
DohPaintII Session 3


Scanned 2005-05-01
Scanned 2005-05-01




2008-02-04 18:10 Encoding PPM/WAV to Ogg Theora/Vorbis

The process:

  1. # input files are PPM/*.ppm and audio.wav, with an empty PNG directory for temporary usage
  2. cd PPM && find -name "*.ppm" -exec convert {} ../PNG/{}.png \; && cd ..
  3. mencoder "mf://PNG/*.png" -mf type=png:fps=25 -ovc raw -o video.avi
  4. avidemux video.avi # add audio.wav as audio track, use COPY/COPY as codecs and save as video2.avi
  5. avifix -F "RGB" -i video2.avi
  6. ffmpeg2theora -V 480 -S 1 -A 128 --optimize video2.avi
  7. # output file is video2.ogg

Some notes:

  • mencoder doesn't support PPM, so convert to PNG
  • avidemux is used simply to multiplex the audio and video into one file
  • avifix is needed to set the fourcc so that ffmpeg2theora can understand
  • ffmpeg2theora doesn't support separate audio / video input streams, so we need to have a single already-multiplexed file to feed it with

There must be a better way to do this. Comments appreciated.

2008-01-30 13:39 An obscure colour space for friendly saturation adjustment

I stumbled across Susan Roberta Curtis' 1982 MSc thesis: Saturation and Luminance Control in Color Image Processing. This defines an LC1C2 colour space with some interesting properties that make it more useful than either RGB or YUV.

RGB is a pain at the best of times, but YUV isn't much better. The problem with YUV is that the "constant saturation curve" is not a circle, but a skew ellipse, which makes setting absolute saturation very tricky. This is generally shown best on a vector scope:


The constant saturation curves in the LC1C2 colour space seems to be more circular than in YUV, I haven't measured it yet but the results are pleasing. Here's a fragment of GLSL code that sets the saturation of an RGB colour:

   // inputs
   vec3 in;
   float saturation;
   // outputs
   vec3 out;
   // conversion matrices
   mat3 rgb2lcc = mat3(
      0.299,  0.621,  0.080,
      0.498, -0.442, -0.056,
     -0.162, -0.336,  0.498
  mat3 lcc2rgb = mat3(
      1.0,  1.407,  0.0,
      1.0, -0.677, -0.236,
      1.0,  0.0,    1.848
   // saturation bashing
   vec3 lcc1 = in * rgb2lcc;
   float l  = lcc1.x;
   float c1 = lcc1.y;
   float c2 = lcc1.z;
   float sat = saturation/sqrt(c1*c1+c2*c2);
   vec3 lcc2 = vec3(l, sat*c1, sat*c2);
   vec3 out = lcc2 * lcc2rgb;

Next step is to investigate LC1C2 more scientifically.

2008-01-30 13:24 Hexeract

Following on from hypercube (which renders a 4D cube, aka a tesseract), I've been working on hyperx, a generalisation to arbitrary dimensions and structures. To this end, I switched from (very slow) CPU based rendering to (very fast) GPU based rendering. Not all is accelerated so far, but the polygon rasterization is several orders of magnitude faster. To get the colours looking good, I'm using GLSL, with a fragment shader that manipulates the rendered image.

hexeract is a temporary branch of hyperx to experiment with, currently it renders a 6D cube. It's heavily based on the HelloGPGPU example (GLSL version) from GPGPU. Hopefully Pd's Gem package for OpenGL will be fixed so I can used shaders in it - just seems to be a matter of using GLEW in the right way, or not converting GLint to float and losing precision, or something.

Some example output is here: hexeract undergoing 3 orthogonal rotations (3.3MB)

Source code is in SVN:

svn co hexeract

2008-01-30 13:21 Undecidable


Undecidable :: some old tunes from 2001 that I found on a hard disk image.

2008-01-17 00:47 CycleTile Sonification #1

Periodic two-dimensional image modulation. Scanlines extracted and used as wavetables for oscillators. Audiovisual drone.

CycleTile Sonification #1

CycleTile Sonification #1

Direct download links:

2008-01-09 09:59 Random tiling wallpaper with fbsetbg

fbsetbg (a desktop background/wallpaper setter from the fluxbox project) has options for random wallpaper selection from a directory, and tiling wallpaper. Unfortunately it doesn't seem to support both at the same time.

I found a solution, however:

  1. Install feh (an image viewer and cataloguer).
  2. Create a script ~/bin/wallpaper as follow:
    feh --bg-tile $1
  3. Edit ~/.fluxbox/lastwallpaper as follows (replacing username as appropriate):
    wpsetters /home/claude/bin/wallpaper
  4. Edit ~/.fluxbox/init as follows:
    session.screen0.rootCommand:    fbsetbg -l
    session.screen1.rootCommand:    fbsetbg -l

And then enjoy your random tiled backgrounds. If you don't have a dual head setup, then just remove the stuff relating to the second display, I don't know if its harmless or not to leave it there.

Currently I'm using some created with GridFlow: Cycle Tile. Not quite perfectly seamless, however, need to fix that and rerender them. EDIT: should now be seamless, was a problem with dividing too soon creating rounding errors...

2007-12-29 14:08 /etc/fstab line for less sucky vfat USB pen drive in GNU/Linux with udev

I got sick of having to mount my vfat USB flash drive stick as root, and chmod/chown files after moving them as root. So I investigated udev. Turns out I don't need to write a udev rule, but just add a line in /etc/fstab:

/dev/disk/by-id/usb-USB_DISK_Pro_AA04012700008623-part1 /media/pen/     vfat    user,noauto,uid=claude,gid=claude,dmask=077,fmask=177   0       0
udev creates uniquely named symlinks for each drive out of the box.
allow non-root users to mount
don't mount at boot
uid, gid
the owning user and group of all files
dmask, fmask
permissions to remove from directories and files

2007-12-06 23:22 Drawing polytopes with Haskell and Graphviz

So I was toying with using Graphviz to render polytopes (higher-dimensional generalisations of polygons and polyhedra). I quickly got bored writing .dot files by hand, and switched to the Haskell programming language.

Here's some code that generates a .dot file containing the vertices and edges of a cube of arbitrary dimension:

> module Main where
> import System(getArgs)
> type Node = [Bool]
> edges node = filter (\(u,v) -> u /= v) $ zipWith (\n b -> (n, zipWith (||) n b)) (repeat node) bits
>   where
>     bits = map bit [0..(n-1)]
>     bit b = map (== b) [0..(n-1)]
>     n = length node
> nodes 0 = [[]]
> nodes d = concatMap (\n -> [False:n, True:n]) ns where ns = nodes (d-1)
> main = do
>   args <- getArgs
>   let d = read (head args) :: Int
>       e = concatMap edges (nodes d)
>   putStrLn ("strict graph Cube" ++ (show d) ++ "D {")
>   putStrLn "  node [label=\"\",shape=\"circle\",width=0.1,height=0.1,fixedsize=true,style=\"filled\"];"
>   sequence (map printEdge e)
>   putStrLn "}"
>   where
>     printEdge (u,v) = putStrLn ("  " ++ showNode u ++ " -- " ++ showNode v ++ ";")
>     showNode n = "p" ++ map showCoord n
>     showCoord True = '1'
>     showCoord False = '0'

And here's the output for a cube of 5 dimensions, rendered with neato from Graphviz:

5D cube rendered with neato from Graphviz

I also wrote code for the cross polytope (in 3 dimensions it's an octahedron):

> module Main where
> import System(getArgs)
> type Node = Int
> edges d nodes node = filter (\(u,v) -> u < v && u /= (v + d) `mod` (2 * d)) $ zip (repeat node) nodes
> nodes d = [0..(2*d -1)]
> main = do
>   args <- getArgs
>   let d = read (head args) :: Int
>       n = nodes d
>       e = concatMap (edges d n) n
>   putStrLn ("strict graph Cross" ++ (show d) ++ "D {")
>   putStrLn "  node [label=\"\",shape=\"circle\",width=0.1,height=0.1,fixedsize=true,style=\"filled\"];"
>   sequence (map printEdge e)
>   putStrLn "}"
>   where
>     printEdge (u,v) = putStrLn ("  " ++ showNode u ++ " -- " ++ showNode v ++ ";")
>     showNode n = "p" ++ show n

The output from neato is ugly for this structure, but with circo it looks pretty good:

5D cross polytope rendered with circo

The simplex is left as an exercise for the reader. These 3 (cube, cross, simplex) exist in all dimensions, when I refind my copy of Coxeter's opus I'll attempt code for the others that only exist in certain dimensions.

2007-12-04 17:15 buildtorrent-0.6 released

buildtorrent is a simple command-line .torrent file creation tool.

New features in buildtorrent-0.6:

  • Autoconf build system (the usual ./configure && make && make install).
  • Manual page (so you can get useful information using man buildtorrent).

Download the release tarball: buildtorrent-0.6-1.tar.gz

Or check out the development sources from SVN:

svn checkout buildtorrent

See also: buildtorrent homepage.

2007-12-04 16:20 Jiminy Lemus Cloud - Journey

Jiminy Lemus Cloud - Journey

Jiminy Lemus Cloud - Journey

Once upon a time, in a land far far away, in a house, three intrepid adventurers disembarked from their longboat and set foot on strange territory. Some time later, archaelogists found an ancient platter that seemed to be inscribed using a primitive form of sound recording.

Improv musics.

20 -