Saturday, 5 November 2016

Computational Musicology, ????, Profit

This year I had the pleasure of attending FARM at ICFP. As well as demoing Klangmeister, I gave a paper on what computational musicology means for the study of music. The abstract is as follows:

In this paper I examine the relationship that complexity theory and
disjunctive sequences have to music, music-generating programs
and literary works. I then apply these ideas by devising a program
to generate an infinite ‘Copyright Infringement Song’ that contains
all other songs within it. I adopt literary modes of analysis and
presentation, which I motivate by arguing that music is a cultural
and artistic phenomenon rather than a natural one.


The full paper is available online via the ACM.

Most of the FARM papers focused more on general analysis of the structure of music than the interpretation of the meaning of specific pieces. I find the general analytic approach fascinating, but as I argue in my paper, I think computational musicology can be more than that.

I'm grateful to the FARM organisers for accepting a work that is a little loose with the genre conventions of a computer science paper. ICFP is a great conference, but its usual standard of worthwhile research is inherited from mathematics and the sciences. With notable exceptions like James Noble's work on postmodern programming, I don't see many examples of academics employing computational thinking for humanities research.

The paper is based on a talk I gave at Strange Loop last year called Kolmogorov Music.

Monday, 19 September 2016

Music as code talks

I've been giving talks about music theory and code for a few years now, so I thought I'd collect them all together in one place. They are based on Overtone and my Leipzig music composition library.
  1. Functional Composition, about music theory from sine waves through to canons, given at Lambda Jam 2013 (code).
  2. Kolmogorov Music, about music and complexity theory, given at Strange Loop 2015 (code).
  3. Dueling Keyboards, about temperament and tuning systems, given at Clojure eXchange 2015 (code).
  4. Klangmeister, about my online live coding environment, given at FlatMap 2016 (code).
  5. African Polyphony and Polyrhythm, about music from the Central African Republic, given at Strange Loop 2016 (code). Slides are online.
If you're interested in my personal music, check out Whelmed (code).

Sunday, 3 July 2016

Falsehoods programmers believe about music

In the spirit of Patrick McKenzie's great post on falsehoods programmers believe about names, I am trying to write an equivalent one for music. Any false assumption that might be made in codifying music is a candidate for inclusion. Suggestions are very welcome.
  1. Music can be written down.
  2. Okay, maybe not with European notation, but there'll be a specialist notation for that kind of music.
  3. Music is finite in duration.
  4. Music has a composer.
  5. Music is about harmony.
  6. Music uses scales.
  7. Music uses equal temperament.
  8. Music uses tones and semitones.
  9. Music and dance are separate activities.
  10. Playing and listening to music are separate activities.
  11. Musicians can play their part separately from the overall composition.
  12. Music is performed by professional musicians.

Sunday, 26 June 2016

GEB

Douglas Hofstadter's Godel, Escher, Bach is one of my favourite books. Commonly referred to as GEB, this book is a mesmerising meditation on consciousness, mathematics and creativity. The central idea is that of a "strange loop", in which the same message is interpreted on multiple semantic levels.

GEB was the first place I came across the idea of a musical canon. A canon is a beautifully austere form of composition that was popular in the Baroque period. A canon consists of a dux part which sets out the base melody accompanied by a comes part which is some kind of transformation of the dux.

Here is the structure of a canon described using the programming language Clojure. f stands for the transformation selected by the composer.

(defn canon [f notes]
  (->> notes
       (with (f notes))))

For example, the comes might be formed by delaying the dux by a bar and raising every note by a third. In my talk Functional Composition I show how computer code can be used to explain music theory, focussing on JS Bach's Canone alla Quarta from the Goldberg Variations. Canone alla Quarta is an unusually complex and beautiful canon where the transformation is composed of a delay of three beats (a simple canon), a reflection (a mirror canon) and a pitch transposition down a fourth (an interval canon).

Here is the transformation from Canone alla Quarta written in Clojure. comp is a Clojure function for composing multiple transformations together.

(defn canone-alla-quarta [notes]
  (->> notes
       (canon
         (comp (interval -3) mirror (simple 3)))))

I was working on a talk for last year's Strange Loop programming conference (itself a reference to Hofstadter's work) and I decided that I wanted to create my own canon as a tribute to GEB as a finale. Rather than use an ordinary musical transformation for my comes, I wanted to pick something that spoke to the idea of composing music with computer code. I also wanted to incorporate GEB's theme of interpreting messages on multiple levels.

I took the letters G, E and B, and used the ASCII codes that represent these letters as though they were MIDI pitch codes. This gave me my dux. I then took the same three letters and interpreted them as the musical notes G, E and B. This gave me my comes. I had obtained a canon based not on musical concepts like delay or transposition, but on encoding schemes used in computer programming.

(defn canone-alla-geb [notes]
  (->> notes
       (canon
         #(where :pitch ascii->midi %))))

I elaborated the harmonies provided by this canon into a complete track, composed via computer code. The dux and the comes are joined by various other parts, some using polyrhythms to generate apparent complexity from underlying simplicity.

Eventually, the dux and the comes are accompanied by a third canonic voice, in which the names of Godel, Escher and Bach are read out by a text-to-speech program. So the theme of three notes G, E and B becomes a canon of three voices musical, technical and allusive to the three great creative spirits Godel, Escher and Bach.

Listen to the recording.

Read the code.

Watch the talk.

Sunday, 17 May 2015

Lanham on explicit data dependencies

Who's kicking who?

- Richard Lanham, Revising Prose

Tuesday, 20 January 2015

Korzybski on story points

The map is not the territory.

- Alfred Korzybski

Sunday, 19 October 2014

Types don't substitute for tests

When reading discussions about the benefits of types in software construction, I've come across the following claim:
When I use types, I don't need as many unit tests.
This statement is not consistent with my understanding of either types or test-driven design. When I've inquired into reasoning behind the claim, it often boils down to the following:
Types provide assurance over all possible arguments (universal quantification). Unit tests provide assurance only for specific examples (existential quantification). Therefore, when I have a good type system I don't need to rely on unit tests.
This argument does not hold in my experience, because I use types and unit tests to establish different kinds of properties about a program.

Types prove that functions within a program will terminate successfully for all possible inputs (I'm ignoring questions of totality for the sake of simplifying the discussion).

Unit tests demonstrate that functions yield the correct result for a set of curated inputs. The practice of test-driven design aims to provide confidence that the inputs are representative of the function's behaviour through the discipline of expanding a function's definition only in response to an example that doesn't yet hold.

All of the examples that I use in my practice of test-driven design are well-typed, whether or not I use a type system. I do not write unit tests that exercise the behaviour of the system in the presence of badly-typed input, because in an untyped programming language it would be a futile exercise and in a typed programming language such tests would be impossible to write.

If I write a program using a type system, I still require just as many positive examples to drive my design and establish that the generalisations I've created are faithful to the examples that drove them. Simply put, I can't think of a unit test that I would write in the absence of a type system that I would not have to write in the presence of one.

I don't use a type system to prove that my functions return the output I intend for all possible inputs. I use a type system to prove that there does not exist an input, such that my functions will not successfully terminate (again, sidestepping the issue of non-total functions). In other words, a type checker proves the absence of certain undesirable behaviours, but it does not prove the presence of the specific desirable behaviours that I require.

Type systems are becoming more sophisticated and are capable of proving increasingly interesting properties about programs. In particular, dependently typed programming languages like Idris can be used to establish that lists are always non-empty or the parity of addition.

But unless the type system proves that there is exactly one inhabitant of a particular type, I still require a positive example to check that I've implemented the right well-typed solution. And even if the type provably has only one inhabitant, I would still likely write a unit test to help explain to myself how the abstract property enforced by the type system manifests itself.

A type system is complementary to unit tests produced by test-driven design. The presence of a type system provides additional confidence as to the correctness of a program, but as I write software it does not reduce the need for examples in the form of unit tests.