ClaudiusMaximus' Journal

20 (-20) -

Journal

2007-12-03 00:09 pdlua-0.3 released

pdlua is a Lua embedding for Pd, allowing you to write Pd classes/objects using the Lua scripting language.

New features in pdlua-0.3:

  • send support - send messages to receivers.
  • receive support - bind your object to receive names.
  • clock support - schedule callbacks for the future.
  • static build support - link the Lua interpreter into the pdlua external, for systems that don't provide Lua 5.1.

You can download the stable release tarball: pdlua-0.3

Or, check out the development version from SVN:

svn checkout https://devel.goto10.org/svn/maximus/pdlua pdlua

2007-11-13 21:08 OpenLab4 Event

OpenLab4 will be a whole day event around Free Software as creative means in music, digital arts and performance. The event will provide the general public an opportunity to learn about the potentials and culture of Free Software as well as enabling Openlab activists to showcase their work. The event will start with presentations in the early afternoon and finish with a series of live demonstrations and perfomances in the evening.

I'll be giving a presentation on GraphGrow.

2007-11-13 21:03 Piksel Festival

Piksel Banner

I'm playing at 9pm on Friday, but I'm mainly looking forward to all the cool stuff that'll be going on.

2007-10-09 20:22 The mathematics of GraphGrow

GraphGrow in SVN now has code to calculate the Hausdorff dimension of the generated fractal. However, this calculation is only guaranteed to be valid if an open set condition holds. Moreover, there is no algorithm to check if the condition holds (because there is no algorithm to construct the feasible open sets required).

I guess I'll have to add a big fat warning sticker on the info pane of GraphGrow saying that the calculated dimension isn't necessarily valid, but it's frustrating that it seems impossible to check algorithmically if it's valid or not.

References

  • A Fractal Dimension Estimate For A Graph-Directed IFS Of Non-Similarities -- G A Edgar, Jeffrey Golds
  • Multifractal Decompositions Of Digraph Recursive Fractals -- G A Edgar, R Daniel Mauldin
  • On The Open Set Condition For Self-Similar Fractals -- Christoph Bandt, Nguyen Viet Hung, Hui Rao

Footnote: I'm not a professional mathematician, so my ramblings above might be completely wrong..

2007-10-03 12:37 GraphGrow -- SVG plus Javascript equals Thing

I've been interested in doing something interactive with SVG plus Javascript (or ECMAScript) for a while, since I saw Andre Schmidt's SVG GUI widget ideas with JavaScript. I was inspired by remembering parts of Benoit Mandelbrot's The Fractal Geometry Of Nature in which a "seed graph" was recursively expanded into a fractal form by replacing each edge with a "rule graph". The process can lead to images like this:

Sierpinski Carpet made with GraphGrow

GraphGrow

Tested with Firefox 1.5, it might not work properly in other browsers. No instructions yet, just click around and see what happens. There are some glitches in the event handling, will fix them soon hopefully.

UPDATE: I recorded a short video showing how it works: GraphGrow video (Ogg Theora format, no sound). The only further thing to note is that shift-click in GraphGrow is delete, apart from that it should be possible to work out how to use it I hope.

2007-09-25 17:11 pdlua-0.2 released

pdlua is a library for extending Pd with Lua.

Features:

  • Loader functionality gives Lua objects full Pd class status.
  • [luax] class to create Lua objects without full class status (useful for rapid development and testing).
  • [lua] class to run Lua scripts.
  • Example files ranging from trivial (helloworld) to powerful (lexpr).
  • Incomplete documentation.

Note: several things changed to make pdlua-0.2 incompatible with pdlua-0.1, however upgrading is highly recommended.

You can download a source tarball here: pdlua-0.2. Or check out the development sources from the Subversion repository:

svn co https://devel.goto10.org/svn/maximus/pdlua pdlua

2007-09-19 16:24 buildtorrent-0.5 released

New features in buildtorrent:

  • Large file support (can now create torrents for files/directories larger than 2GB).
  • Hashing progress bar (neat display instead of reams of dots).

You can download a source tarball here: buildtorrent-0.5. Or check out the development sources from the Subversion repository:

svn co https://devel.goto10.org/svn/maximus/buildtorrent buildtorrent

2007-09-09 16:08 unmed -- recovering useable data from obsolete tracker files

Another week, another new project. Actually an old project reviced, or more rewritten from scratch because I couldn't find the old source, and the old source was written in Java which I'm no longer keen on...

So far unmed can show the block data from OctaMED MMD0 format files, which is not all that useful as the majority of my old files are MMD1 or above. But it's a start at least. Here's some sample output:

...
==== Block 0007 ====
00:   --- 00 C00   --- 00 C00   A-2 03 000   F#1 03 000
01:   --- 00 000   --- 00 000   --- 00 000   --- 00 000
02:   --- 00 000   --- 00 000   --- 00 000   --- 00 C00
03:   --- 00 000   --- 00 000   --- 00 000   --- 00 000
04:   A-2 01 000   C#2 01 000   --- 00 000   F#2 01 000
05:   --- 00 C00   --- 00 C00   --- 00 000   --- 00 C00
06:   --- 00 000   --- 00 000   B-2 03 000   --- 00 000
07:   --- 00 000   --- 00 000   A-2 03 000   --- 00 000
08:   --- 00 000   --- 00 000   G#2 03 000   --- 00 000
09:   --- 00 000   --- 00 000   --- 00 000   --- 00 000
0A:   --- 00 000   --- 00 000   --- 00 000   --- 00 000
0B:   --- 00 000   --- 00 000   --- 00 000   --- 00 000
0C:   B-2 01 000   D-2 01 000   --- 00 000   F-2 01 000
0D:   --- 00 C00   --- 00 C00   --- 00 000   --- 00 C00
0E:   --- 00 000   --- 00 000   --- 00 000   --- 00 000
0F:   --- 00 000   --- 00 000   --- 00 000   --- 00 000
10:   --- 00 000   --- 00 000   A-2 03 000   F#1 03 000
11:   --- 00 000   --- 00 000   --- 00 000   --- 00 000
12:   --- 00 000   --- 00 000   --- 00 000   --- 00 C00
13:   --- 00 000   --- 00 000   --- 00 000   --- 00 000
14:   A-2 01 000   C#2 01 000   --- 00 000   F#2 01 000
15:   --- 00 C00   --- 00 C00   --- 00 000   --- 00 C00
16:   --- 00 000   --- 00 000   B-2 03 000   --- 00 000
17:   --- 00 000   --- 00 000   --- 00 000   --- 00 000
18:   --- 00 000   --- 00 000   A-2 03 000   --- 00 000
19:   --- 00 000   --- 00 000   --- 00 C00   --- 00 000
1A:   --- 00 000   --- 00 000   G#2 03 000   --- 00 000
1B:   --- 00 000   --- 00 000   --- 00 000   --- 00 000
1C:   B-2 01 000   D-2 01 000   --- 00 000   F-2 01 000
1D:   --- 00 C00   --- 00 C00   --- 00 000   --- 00 C00
1E:   --- 00 000   --- 00 000   A-2 03 000   --- 00 000
1F:   --- 00 000   --- 00 000   --- 00 000   --- 00 000
...

2007-09-03 16:05 buildtorrent-0.4 released

Previously buildtorrent would only work on files and directories in the current directory, and moreover would generate bad .torrent files if you gave a directory name with a trailing '/'. These bugs have now been fixed. Some tests (all should work and generate good .torrent files):

buildtorrent -a http://www.example.com/announce directory output.torrent
buildtorrent -a http://www.example.com/announce directory/ output.torrent
buildtorrent -a http://www.example.com/announce /path/to/directory output.torrent
buildtorrent -a http://www.example.com/announce /path/to/directory/ output.torrent
buildtorrent -a http://www.example.com/announce file output.torrent
buildtorrent -a http://www.example.com/announce /path/to/file output.torrent

You can download a source tarball here: buildtorrent-0.4. Or check out the current development sources from the Subversion repository:

svn co https://devel.goto10.org/svn/maximus/buildtorrent buildtorrent

2007-08-18 18:49 Arrow Transformers for sample rate conversion

In my previous post you may have noticed this:

phasor rate phase0 = ...

where 'rate' is the sample rate. It's rather annoying having to pass the sample rate to every ugen that might need it, increasingly so if we imagine that there might be more things in the environment that various ugens might need. Control.Arrow.Transformer.Reader provides such an environment.

Say we want to be able to change the sampling rate of a subgraph of our DSP algorithm, either upsampling to allow higher precision or downsampling to reduce the amount of calculation required. We can define a class or resamplable graphs like this: *

> class ArrowCircuit a => ReSample a where
>   expand   :: Num b => Int -> a b b   -- zero interleaving
>   decimate :: Int -> a b b            -- decimation
>   zoh      :: Int -> a b b            -- low quality reconstruction filter (zero order hold)
>   --       :: Num b => Int -> a b b   -- high quality reconstruction filter(s)

But this doesn't help much, because we'd need some way of keeping track of the sample rate changes. The solution is to store the sample rate in an environment, which our upSample and downSample graph manipulators can use:

> data AudioState = AudioState

> runSample sr graph = proc p -> (|runReader (graph -< p)|) sr

> upSample n graph = proc p -> do
>   sr <- readState -< AudioState
>   (|runReader (decimate n <<< graph <<< expand n -< p)|) (sr * fromIntegral n)

> downSample n graph = proc p -> do
>   sr <- readState -< AudioState
>   (|runReader (expand n <<< graph <<< decimate n -< p)|) (sr / fromIntegral n)

Then our ugens that need the current sample rate can get it:

> phasor phase0 = proc hz -> do
>   sr <- readState -< AudioState
>   rec accum <- delay (wrap phase0) -< wrap (accum + hz / sr)
>   returnA -< accum

while ugens that don't need the sample rate don't need to worry about it at all, even if they use ugens that do need the sample rate:

> osc phase0 = proc hz -> do
>   phase <- phasor phase0 -< hz
>   returnA -< cos (2 * pi * phase)

* Note: the above ReSample class is somewhat ill, as the (Num b) constraint in expand means that only graphs with a single numeric input and output can be resampled. I'm not sure how to fix this yet, perhaps something like (expand :: Int -> a b (Maybe b)) would be useful, as that would make explicit the padding, and force resampled graphs to use a suitable reconstruction filter.

2007-08-17 20:51 Zirkit : Multimedia dataflow in Haskell using Arrows

Arrows are fun for images:

image = proc p -> do
  d1 <- disc <<< arr (translate (-0.75) 0.5) <<< arr (uscale 0.5) -< p
  d2 <- disc <<< arr (translate 1.15 (-0.5)) <<< arr (uscale 0.25) -< p
  s <- square <<< arr (translate 0.25 0) <<< arr (uscale 0.5) <<< arr (rotate (2 * pi * (-72) / 360)) -< p
  c <- arr greyToRGB <<< checkers (0.25, 0.25) <<< arr (rotate (2 * pi * 45 / 360)) -< p
  r <- solid red -< p
  u <- union -< (d1, s)
  d <- diff -< (u, d2)
  o <- choose -< (d, c, r)
  returnA -< o

See the above composition of shapes.

Arrows are fun for animation too:

Arrows are also fun for audio:

wrap x = x - fromIntegral (floor x)

phasor rate phase0 = proc hz -> do
  increment <- arr (/rate) -< hz
  rec accum <- delay (wrap phase0) -< wrap (accum + increment)
  returnA -< accum

osc rate phase0 = proc hz -> do
  phase <- phasor rate phase0 -< hz
  returnA -< cos (2 * pi * phase)

fm rate = proc _ -> do
  modA <- osc rate 0 -< 110/8
  modB <- osc rate 0 -< (modA * 110) + 220
  carrier <- osc rate 0 -< (modB * 220) + 440
  returnA -< carrier

Listen to the above three-oscillator frequency modulation.

Full (but work-in-progress, rather disorganized, etc) source code is in the Zirkit SVN repository.

2007-08-14 08:07 Arrows in Haskell : bumpy first steps

I was reading up on arrows, specifically A New Notation For Arrows, but ran into some trouble. Here's what I discovered.

Firstly, I started out with:

newtype SF b c = SF { runSF :: [b] -> [c] }

That is, I wanted to process lists. I implemented the Arrow instance as found in the above paper without too much difficulty:

instance Arrow SF where
  arr f = SF (map f)
  SF f >>> SF g = SF (g . f)
  first  (SF f) = SF (uncurry zip . (f *** id) . unzip)
  second (SF f) = SF (uncurry zip . (id *** f) . unzip)

But then the trouble arrived - I suddenly noticed that the paper was using infinite sequences, not the finite sequences I was using myself. Trying to implement an ArrowLoop as per the paper led to horrible grief:

-- instance ArrowLoop SF where
--  loop (SF f) = SF (loop (unzip . f . uncurry zip))

The problem is that this is far too strict - on non-empty input it caused stack overflow crashes, which isn't exactly what I wanted. I found the solution in Programming With Arrows (page 17), which involves some subtlety with lazy patterns:

instance ArrowLoop SF where
  loop (SF f) = SF $ \as ->
      let (bs,cs) = unzip (f (zip as (stream cs))) in bs
    where stream ~(x:xs) = x:stream xs

Then a length-preserving delay function for ArrowCircuit (not sure yet why this might be necessary or otherwise desireable, but it seems sensible) completes the base code to build funky circuits with:

class ArrowLoop a => ArrowCircuit a where
  delay :: b -> a b b

instance ArrowCircuit SF where
  delay x = SF (init . (x:))

The counter is implemented exactly as in the Notation paper, and now it works!

counter :: ArrowCircuit a => a Bool Int
counter = proc reset -> do
  rec next <- delay 0 -< out + 1
      out <- returnA -< if reset then 0 else next
  returnA -< out

And if you need proof:

main :: IO ()
main = do
  let x = runSF counter
  print (x (map b "tfftfffftfftffttfttfff"))
  where
    b 't' = True
    b 'f' = False

-- outputs [0,1,2,0,1,2,3,4,0,1,2,0,1,2,0,0,1,0,0,1,2,3]

Should be fun to play around with this some more, now I've got the big headaches out of the way (I hope).

2007-08-09 07:05 Extending PureData with Haskell : AngloHaskell, Cambridge, UK : Friday 2007-0810

I'm giving a talk at AngloHaskell entitled Extending PureData with Haskell.

EDIT: the slides are now online: Extending PureData with Haskell slides (the page-flipping requires Javascript, without this you'll see the whole thing on one page), plus some introductory Pd patches in the same directory.

2007-07-22 15:40 Website updates

Summer's here, so I thought it was time for a spring clean. Mostly removing old cruft and reorganizing the remaining material (notably the gallery) to be more usefully structured, plus a couple of little stylesheet tweaks.

2007-07-22 07:10 Feed your head

I was toying with horrendous bash scripts and XSLT stylesheets to manipulate XML from the Internet Archive, and thought an obvious application would be to make podcast feeds so stuff could be downloaded semi-automatically by people without bash/xsltproc/etc know-how. Looking around the web, I found that OPML seems to be the standard for collections of RSS feeds, so I made an OPML feed of the RSS feeds I created for the audio stuff of mine on the Internet Archive:

ClaudiusMaximus media meta-feed

Any/all feedback appreciated, as ever.

2007-07-21 21:51 Semi-automatic downloading from the Internet Archive

I've uploaded a lot of stuff to the Internet Archive (over 50 items at last count). Most of the audio I've uploaded is in FLAC format, and is currently sitting on a computer that no longer works (I turned it off, went away, came back, and it wouldn't turn on again). So while I figure out what to do (probably involving getting an external hard drive enclosure to rescue the data), I wanted to download the VBR MP3 versions so I can listen to them again. I didn't fancy manually downloading the files one by one with a web browser, so I ventured into the icky world of XML and XSLT, using bash to glue it all together.

Here's the script that glues it all together. Note that the Internet Archive kindly makes meta-data files available with predictable names, so it's easy to grab given an Internet Archive identifier. unarchive.sh expects a list of such identifiers, one per line, on its standard input:

#!/bin/bash
while read ident
do
  mkdir -p "${ident}" &&
  wget -nv -O - "http://www.archive.org/download/${ident}/${ident}_files.xml" |
  xsltproc unarchive.xsl - |
  while read file
  do
    wget -nv -c -P "${ident}" "http://www.archive.org/download/${ident}/${file}"
  done
done

xsltproc is a tool that munges an XML file according to a stylesheet written in the XSLT language. unarchive.xsl generates a list of the filenames of all the files that are of format VBR MP3:

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" />
<xsl:template match="/">
 <xsl:for-each select="files/file">
  <xsl:choose>
    <xsl:when test="format='VBR MP3'">
     <xsl:value-of select="@name" /><xsl:text>
</xsl:text>
    </xsl:when>
  </xsl:choose>
 </xsl:for-each>
</xsl:template>
</xsl:stylesheet>

If I'm bored one day I'll adapt it to download only "original" files (ignoring all the "derivative" files).

UPDATE the adaptation is just changing "format='VBR MP3'" to "@source='original'"

identifiers for my stuff on archive.org )

2007-07-18 14:30 Recursion in Gem for Pd -- a tutorial

Download the Pd Gem recursion tutorial. Update: you no longer need any special externals (other than Gem and Zexy), pure-Pd implementations of the required objects are included.

Repetition Is Futile

Repetition Is Futile (Pd patch)

Repetition Is Futile (Gem output)

Iteration Is Insufficient

Iteration Is Insufficient (Pd patch)

Iteration Is Insufficient (Gem output)

Recursive Spiral

Recursive Spiral (Pd patch)

Recursive Spiral (Gem output)

Binary Tree

Binary Tree (Pd patch)

Binary Tree (Gem output)

N-ary Tree

N-ary Tree (Pd patch)

N-ary Tree (Gem output)

Breaking Symmetry

Breaking Symmetry (Pd patch)

Breaking Symmetry (Gem output)

2007-07-09 10:28 Balanced audio cables for the win

Faced with this grimy electrical interference noise there was no other option. A trip to my local music shop yielded nothing, so I went up to the hub of all music technology in central london and snaffled the last two cables they had. Being stereo 6.35mm jack to stereo 6.35mm jack. And the grime is gone. Wahey for balanced audio and its magic of noise cancellation.

(S,-S) => (S+N,-S+N) => (S+N)-(-S+N) => (S+S)+(N-N) => S

2007-07-07 16:39 From 97% to 66% CPU usage with very little effort

Here are the flags that make GHC generate Really Fast Code (TM):

-fexcess-precision -fvia-C -optc-O2 -optc-mfpmath=sse -optc-msse2 -optc-march=pentium-m

Now I can add some more/better audio stuff to d01234...

2007-07-07 16:35 Output Update

Some more new stuff for you to listen and watch and (maybe) enjoy:

Clouds Are Made Of Water :: bleepy electronica

Twins :: generative baroque ambient

Live At Shunt :: improv techno

Live At The Dukes :: improv techno

Stinky Old Poo :: the first computer music I ever recorded

20 (-20) -