Phillip Trelford's Array

POKE 36879,255

Turing drawings

A little while back I stumbled upon a fun generative art project by Maxime Chevalier called Turing drawings that produces 2D procedural art based on randomly generated Turing machines. The project’s code is in JavaScript using a HTML canvas which you can try online, just hit the random button to generate all sorts of weird and wonderful pieces. The project has inspired amongst other things a port to asm.js and a version with genetic recombination of URLs.

For fun I’ve created an F# script that generates Turing drawings that can be run online below via the embedded Cloud Tsunami IDE:


The Tsunami IDE also runs on the desktop and can be embedded into applications like Excel.

If you’re interested in learning more about generative art and trying similar ideas then why not pop down to Skills Matter on Thursday August 15th for a hands on coding session.

Tremolo

This week I added a simple tremolo effect to my mini-keyboard project Monokeys. Tremolo is a trembling effect, and sometimes seen in Low Frequency Oscillators.


I found an example of Coding some Tremolo and wrote the formula as an F# function:

let tremolo freq depth i = (1.0 - depth) + depth * (sineWave freq i) ** 2.0


Then I added sliders for the frequency and depth to compose the shape of a sound:

let tremolo i = tremolo tremoloFreq.Value tremoloDepth.Value i
let shape i = sineWave freq i * fadeOut i * tremolo i

Full source code is available on BitBucket: https://bitbucket.org/ptrelford/monokeys

Monokeys

Press a key to hear a note:


GAFBB should sound familiar to fans of 70s sci-fi.

I wanted to programmatically generate sound effects for a retro game I’m working on. Generating wave files using F# turned out to be less than 30 lines of code:

open System.IO

/// Write WAVE PCM soundfile (8KHz Mono 8-bit)
let write stream (data:byte[]) =
    use writer = new BinaryWriter(stream)
    // RIFF
    writer.Write("RIFF"B)
    let size = 36 + data.Length in writer.Write(size)
    writer.Write("WAVE"B)
    // fmt
    writer.Write("fmt "B)
    let headerSize = 16 in writer.Write(headerSize)
    let pcmFormat = 1s in writer.Write(pcmFormat)
    let mono = 1s in writer.Write(mono)
    let sampleRate = 8000 in writer.Write(sampleRate)
    let byteRate = sampleRate in writer.Write(byteRate)
    let blockAlign = 1s in writer.Write(blockAlign)
    let bitsPerSample = 8s in writer.Write(bitsPerSample)
    // data
    writer.Write("data"B)
    writer.Write(data.Length)
    writer.Write(data)

let sample x = (x + 1.)/2. * 255. |> byte 

let data = Array.init 16000 (fun i -> sin (float i/float 8) |> sample)
let stream = File.Create(@"C:\tone.wav")
write stream data

F#’s ASCII string support and light syntax, combined with .Net’s convenient BinaryWriter class made this ridiculously easy.

Then just for fun I created the simple keyboard in 70 lines of code:

namespace MonoKeys

open System
open System.Windows
open System.Windows.Controls
open Microsoft.Xna.Framework.Audio

type App() as this = 
    inherit Application()

    let sampleRate = 8000

    let sample x = x * 32767. |> int16

    let toBytes (xs:int16[]) =
        let bytes = Array.CreateInstance(typeof<byte>, 2 * xs.Length)
        Buffer.BlockCopy(xs, 0, bytes, 0, 2 * xs.Length)
        bytes :?> byte[]

    let create freq =
        let samples = 12000
        let sine i = sin (Math.PI * 2. * float i / float sampleRate * freq)
        let fadeOut i = float (samples-i) / float samples
        Array.init samples (fun i -> sine i * fadeOut i |> sample)
        |> toBytes

    let play freq =        
        let bytes = create freq
        let effect = new SoundEffect(bytes, sampleRate, AudioChannels.Mono)
        effect.Play() |> ignore
    
    let notes = [
        "A", 220.00
        "A#", 233.08
        "B", 246.94
        "C", 261.63
        "C#", 277.18
        "D", 293.66
        "D#", 311.13
        "E", 329.63
        "F", 349.23
        "F#", 369.99
        "G", 392.00
        "G#", 415.30
        "A", 440.00
        "A#", 466.16
        "B", 493.88
        "C", 523.25
        "C#", 554.37
        "D", 587.33]

    let keys =
        notes |> Seq.map (fun (text,freq) ->
            let key = Button(Content=text)
            key.Click.Add(fun _ -> play freq)
            key
        )

    let grid = Grid()
    do  keys |> Seq.iteri (fun i key ->
            grid.ColumnDefinitions.Add(ColumnDefinition())
            Grid.SetColumn(key,i)
            grid.Children.Add key
        )

    do  this.Startup.AddHandler(fun o e -> this.RootVisual <- grid)


This time Silverlight 5’s SoundEffect class makes generating sounds easy accepting an array of bytes. I simply copied the notes from the web, formatted the text as tuples and mapped them to buttons that showed the text and played a note of the specified frequency. The keys were then laid out on a grid. Look no XAML ;)

Next I’m planning to add some more features to generate sounds like a synthesizer maybe one day like my monotribe

If you’re interested in programming and sound I’d recommend taking a look at Sam Aaron’s Overtone for Clojure and Rob Pickering’s Undertone for F#.

Rob will be running a session on Undertone at this year’s Progressive F# Tutorials in London:

progressivefsharplondon2013