Wednesday, January 14, 2015

Stefaan Himpe - Fairy tale for piano solo

Fairy tale for piano solo

It's been a while but I finally found some time to write, practice and record a new piece. All things music have been on a break for a while now, and I'm glad that I can take a break from taking a break.

You can download the piece from my soundcloud account: https://soundcloud.com/stefaanhimpe/fairy-tale-for-piano-solo



So... what do we have here really? 

The piece started as a sad ending theme for a video game. It was never used for that purpose and so I decided to rework it into something longer. Maybe it's interesting if I tell you how I think about the music, bar by bar. (Then again, maybe it's not ;) Feel free to skip the explanations. Most of all, I'm also curious how much of this I will still recognize in a year or in 5 years. I may even come back to my description and update it as my insights change.)

Bars 1-4: The piece starts off quite melancholic (which was a requirement for the sad ending of the video game). This part is written in C minor key, a key that is traditionally regarded as the key in which to express a declaration of love with lament of unhappy love, sighing of the lovesick soul. Clearly someone is thinking back about something.

Bars 5-8: The beginning is repeated with a slight variation in the accompaniment to avoid making it sound the same twice. It is as if the accompaniment adds more detail to the memories as they are repeated.

Bars 9-12: Suddenly the melancholic fantasy is interrupted with a little waltz. A short distraction? Or perhaps a related memory, a sudden free association. 

Bars 13-20: The distracting thoughts are pushed away and make place again for the fantasy. As the fantasy repeats itself, the melody notes again add more details to the memories. By coloring the melody using notes outside the scale, the color of the memories changes. Little imperfections that keep the story alive as it were.

Bars 21-27: The fantasy continues. The fantasizing person remembers and overthinks some of the consequences that resulted from whatever happened in bars 13-20.

Bars 27-32: Stress level increases a bit. Temper gets a bit heated. 

Bars 33-34: Some soothing thoughts manage to calm down the person.

Bars 35-38: There's our distraction waltz again. It's barely interesting enough to keep our thoughts away from what happened.

Bars 39-48: The fantasy is resumed, but in bar 45 it suddenly takes a different path. The person has second thoughts about how everything really went back then. For a while, things are remembered as perhaps more festive than before (bars 47-48).

Bars 49-52: These finish the first fantasy and prepare the music to change into a different key of f minor. F minor is the key in which one traditionally expresses deep depression, funeral lament, groans of misery and longing for the grave. No doubt the passage that follows will have a sinister side to it.

Bars 52-85: A buildup of emotions, a waterfall of notes follows. In the left hand we have a sad but very static accompaniment with typical f minor notes. In the right hand, in bars 53-64, we also have very dissonant chords which work to create a somewhat uneasy feeling. In bars 65-76, the dissonant chords are now replaced with a locrian motif that further increases the uneasyness in the music. In bar 74, the deepest note of the piece (a very low "d") is reached. Then bars 77-85 repeat the same techniques but a fifth higher and with many more, and much faster notes, which adds even more drama to the already dramatic state of mind of our fantast. The fifth higher brings us in the key of Bb minor, which traditionally is used to express feelings of mocking God and the world, discontented with itself and everything, preparation of suicide. Quite restless and dramatic indeed :)

Bars 86-91: The deepest darkest memories subside and make place again for the sweeter earlier theme.

Bars 92-113: The earlier theme is repeated, but again the colors have changed to something more bitter-sweet. This time the chords in the right hand sound much more yearning than in the beginning of the piece. As if the darkest memories increased the feeling of having lost something valuable and make it more painful to think back about what was lost.

Bars 114-117: Eventually, the person snaps out of his trip through memory lane and we hear the waltz playing again.

Bar 118: The piece ends with some bitter sweet ending chords. A near happy end, and time to get back to work ;)



Saturday, March 8, 2014

Olivier Messiaen - a closer look at his modes of limited transposition

Olivier who?

Olivier Messiaen was a French composer (December 10, 1908 – April 27, 1992), known for inventing a new musical language. He wrote a book about his ideas on rhythm, melody and harmony and is generally regarded as one of the great innovators in music. He drew inspiration mostly from his Christian beliefs and from bird songs. I personally fell in love with this musical language after hearing his work "Vingt Regards sur l'Enfant-Jésus".


One key element of his compositions is a set of scales that he "invented" (or rather, selected from the vast space of possible scales). They consist of symmetrical note groups. While writing music he would often adhere to using only notes from one or more of his scales, leading to special music (with very rewarding harmonies).

I was curious about these special scales and wondered about the mechanisms that cause the scales to "work so well" with a listener, so
I set up my own private investigation and took a close look at his scales.
I discovered quite a number of interesting things (which may be known already in literature, I don't want to claim I found something new, but they were certainly new to me)

I've written up what I came up with so far and put it online on github. The pdf can be seen here: https://github.com/shimpe/mints/blob/master/out/document.pdf?raw=true . All the code required to reconstruct the article is available here https://github.com/shimpe/mints:

Feel free to contact me with questions or remarks about this document.


Saturday, January 4, 2014

Etude for piano solo

Inspired by youtube composer Rolando Gonzalez' recent videos, I set out to write something in classical ("Mozart") style... but as I started working, I felt the piece heading itself in a very different direction. Sorry Mozart, you have been postponed ;)


Sunday, December 29, 2013

Virtual choir: auto harmonize your voice in real time with supercollider



This blog entry is about to describe an experiment I did with the real time audio synthesis and algorithmic composition programming language supercollider. Before you read on, please realize that this stuff is highly addictive.

So you've always wanted to sing in a choir, but didn't have the opportunity or courage to join one near you? Here's an easy way to turn your singing into a choir piece in real time using supercollider.

The system is based on the following example from the supercollider documentation:

s.boot;
 
(
SynthDef("pitchFollow1",{
    var in, amp, freq, hasFreq, out;
    in = Mix.new(SoundIn.ar([0,1]));
    amp = Amplitude.kr(in, 0.05, 0.05);
    # freq, hasFreq = Pitch.kr(in, ampThreshold: 0.02, median: 7);
    //freq = Lag.kr(freq.cpsmidi.round(1).midicps, 0.05);
    out = Mix.new(VarSaw.ar(freq * [0.5,1,2], 0, LFNoise1.kr(0.3,0.1,0.1), amp));
    6.do({
        out = AllpassN.ar(out, 0.040, [0.040.rand,0.040.rand], 2)
    });
    Out.ar(0,out)
}).play(s);
)


This example does something very interesting: it reads sound from your microphone using the SoundIn command, then tracks its frequency using the Pitch command and then synthesizes a new sawtooth wave at different multiples of the detected frequency. The new sawtooth wave is then sent to the speakers, allowing you to hear the sawtooth following your voice's pitch.

Upon hearing this, I immediately thought of harmonizing singing voice in real time, with the possibility to harmonize every note differently, so as to arrive at an (hopefully somewhat interesting) choir piece.

So I sat out to improve the example (combine it with pitch-shifting instead of synthesizing a new sawtooth wave, and add a bit of a GUI to it, to allow reconfiguring the harmonization on the fly), and came up with the following.

Please note that I'm very new to the supercollider programming language, and I'm glad for any suggestions you may have w.r.t. code style! The following code can also be cloned/forked from the github repository.

s.boot;

(
var table;
var gap = 40;
var mapped, mapped2, diffbuf, diffbuf2;
var miditoname;
var nametomidi;
var sound;
var difference, difference2;
var tf, tf2;

// define a function to convert a midi note number to a midi note name
miditoname = ({ arg note = 60, style = \American ;
        var offset = 0 ;
        var midi, notes;
        case { style == \French } { offset = -1}
            { style == \German } { offset = -3} ;
        midi = (note + 0.5).asInteger;
        notes = ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"];

        (notes[midi%12] ++ (midi.div(12)-1+offset))
});

// define a function to convert a midi note name to a midi note number
nametomidi = ({ arg name = "C4", style = \American ;
        var offset = 0 ; // French usage: +1 ; German usage: +3
        var twelves, ones, octaveIndex, midis;

        case { style == \French } { offset = 1}
            { style == \German } { offset = 3} ;

        midis = Dictionary[($c->0),($d->2),($e->4),($f->5),($g->7),($a->9),($b->11)];
        ones = midis.at(name[0].toLower);

        if( (name[1].isDecDigit), {
            octaveIndex = 1;
        },{
            octaveIndex = 2;
            if( (name[1] == $#) || (name[1].toLower == $s) || (name[1] == $+), {
                ones = ones + 1;
            },{
                if( (name[1] == $b) || (name[1].toLower == $f) || (name[1] == $-), {
                    ones = ones - 1;
                });
            });
        });
        twelves = (name.copyRange(octaveIndex, name.size).asInteger) * 12;

        (twelves + 12 + ones + (offset*12))
});

// define a table of reference notes [c c# d ... b]
table = Array.fill(12, {arg i; i + 60}); // [60,61,...,71]
// define a table of mapped notes (Default values)
mapped = [nametomidi.value("g3"),
       nametomidi.value("a3"),
       nametomidi.value("b3"),
       nametomidi.value("bb3"),
       nametomidi.value("c4"),
       nametomidi.value("c4"),
       nametomidi.value("a3"),
       nametomidi.value("d4"),
       nametomidi.value("e4"),
       nametomidi.value("f4"),
       nametomidi.value("f4"),
       nametomidi.value("g4"),
];
mapped2 = [nametomidi.value("e3"),
       nametomidi.value("g3"),
       nametomidi.value("g3"),
       nametomidi.value("g#3"),
       nametomidi.value("a3"),
       nametomidi.value("a4"),
       nametomidi.value("d4"),
       nametomidi.value("b4"),
       nametomidi.value("c4"),
       nametomidi.value("d4"),
       nametomidi.value("d4"),
       nametomidi.value("d4"),
];

// define a table to store the difference between reference and mapped note
difference = Array.fill(table.size, {0});
// define a buffer on the server for consultation from the SynthDef
diffbuf= Buffer.loadCollection(s,table,action:{|msg| msg.postln;});
difference2= Array.fill(table.size, {0});
diffbuf2=Buffer.loadCollection(s,table,action:{|msg| msg.postln;});
tf = List.new(table.size);
tf2 = List.new(table.size);

// define a window called "Setup mapping"
w = Window.new("Setup mapping", Rect(200,200,15*gap,190));
// add the reference notes as labels (fixed), and the mapped notes as text fields (editable)
// whenever a text field is updated, update the list of mapped notes (mapped)
table.do({arg item, i;
    var t, u;
    StaticText(w, Rect(10+gap*i, 10, gap, 30)).string_(miditoname.value(item));

    t = TextField(w, Rect(10+gap*i, 50, gap, 30)).string_(miditoname.value(mapped[i]));
    t.action = { mapped[i] = nametomidi.value(t.value); ("upper map note number " ++ i ++ " from " ++ table[i] ++ " to " ++  mapped[i]).postln;  diffbuf.set(i, (table[i] - mapped[i]).midiratio.reciprocal)};
    tf.add(t);

    u = TextField(w, Rect(10+gap*i, 90, gap, 30)).string_(miditoname.value(mapped2[i]));
    u.action = { mapped2[i] = nametomidi.value(u.value); ("lower map note number " ++ i ++ " from " ++ table[i] ++ " to " ++ mapped2[i]).postln; diffbuf2.set(i, (table[i]-mapped2[i]).midiratio.reciprocal);
    tf2.add(u);
    };
});
// add a button to play a reference note
c = Button(w, Rect(10,130,100,30)).states_([["Play C4",Color.black,Color.gray]]);
c.action_({arg butt;
    if (butt.value == 0,
    {
            var env = Env.perc;
            SinOsc.ar(nametomidi.value("c4").midicps)*EnvGen.kr(env, doneAction:2)!2;
    }.play,
    {})
});

// also add a start/stop button
// when the button is set to start, instantiate a new Synth, otherwise free the Synth
b= Button(w, Rect(110,130,100,30)).states_([
    ["Start",Color.black, Color.red],
    ["Stop",Color.black, Color.green]]);
b.action_({arg butt;
    if (butt.value == 1,
        {
            tf.do({arg item; item.action});
            tf2.do({arg item; item.action});
            table.do({arg item, i;
                difference2[i] = (table[i] - mapped2[i]).midiratio.reciprocal;
                difference[i] = (table[i] - mapped[i]).midiratio.reciprocal;
            });
            diffbuf.setn(0,difference);
            diffbuf2.setn(0,difference2);
            sound = Synth.new("pitchFollow1");
        },
        {   sound.free;}
    )
});

// define the Synth itself:
// - first it determines the pitch of what it hears in the microphone
// - then it harmonizes the pitch with the notes as defined in the ui
SynthDef.new("pitchFollow1",{
    var in, amp, freq, hasFreq, out;
    var t, midinum;
    var harmony, harmony2, partials;
    in = Mix.new(SoundIn.ar([0,1]));
    amp = Amplitude.kr(in, 0.05, 1);
    # freq, hasFreq = Pitch.kr(in);
    midinum = freq.cpsmidi.round(1);
    midinum.postln;
    freq = Lag.kr(midinum.midicps, 0.05);
    //freq = midinum.midicps;
    harmony2= WrapIndex.kr(diffbuf2.bufnum, midinum);
    harmony = WrapIndex.kr(diffbuf.bufnum, midinum);
    partials = [
           0.5,
           1,
           0.5*harmony,
           1*harmony,
         0.5*harmony2,
           1*harmony2,
    ];
    out = Mix.new(PitchShift.ar(in, 0.2, partials, 0, 0.004));

    7.do({
        out = AllpassN.ar(out, 0.040, [0.040.rand,0.040.rand], 2)
    });

    Out.ar(0,out/partials.size)

}).add;

// make the ui visible
w.front;

)



Here's a sound example. It's not perfect, obviously, but to hear the computer create this in real time while you sing into the microphone is quite cool...


And a complete piece:

Sunday, October 20, 2013

Music to die for...

When starting this blog, I announced I would sometimes share things I've come across that really need to heard to be believed.

Here is one such thing...

Árstíðir

I'd happily have missed my train for this...

Thursday, October 3, 2013

Streams and paths

What? 

Piano music, based on a poem by Tricia Adams.

The style uses some harmonic ideas from jazz, and features quickly changing time signatures. Difficulties in performing come from the requirements in precise pedaling, the ever-changing time signatures, and some awkward jumps in the left hand (in combination with the speed).

Where?

The usual places :)

Saturday, August 24, 2013

Algorithmic composition: generating tonal canons with Python and music21

1x spiced up chord progression (intermediate step in canon generation)

 

  What?

According to wikipedia:
Algorithmic composition is the technique of using algorithms to create music.

Some algorithms that have no immediate musical relevance are used by composers as creative inspiration for their music. Algorithms such as fractals, L-systems, statistical models, and even arbitrary data (e.g. census figures, GIS coordinates, or magnetic field measurements) have been used as source materials.
And:
In music, a canon is a contrapuntal compositional technique that employs a melody with one or more imitations of the melody played after a given duration (e.g., quarter rest, one measure, etc.).

How?

Last year I wrote a series of articles on an easy method for writing some types of canons:
In at least one of those articles I claimed that the methods described there should be easy to use as basis for automation. Here I automate the method for writing a simple canon as explained in the first of these articles.

Code?

The code discussed below is available under GPLv3 license on github: https://github.com/shimpe/canon-generator. Similar to the gcc compiler, the music you generate with this program is yours. The GPLv3 license only applies to the code itself.

It depends on free software only: python 2.7, music21 and MuseScore.

Explanation? 

This program generates canons from a given chord progression in a fixed key (no modulations for now, sorry!).

It does NOT generate atonal or experimental music, that is, if you're willing to accept the limitations of the program. It can occasionally generate "grave" errors against common practice rules (e.g. parallel fifths/octaves) -> see further explanation.

It closely follows the method as explained in the  Tutorial on my technique for writing a Canon article referenced above. If you want to understand in detail how it all works, please read that article first, and then come back here. If you just want to experiment with the different program settings, continue :)


One thing is worth explaining in more detail: the article mentions in one of the first steps of the recipe that the composer can start from a chord progression, and "spice it up" to get a choral.  So: how to we get a computer to spice up a chord progression, without building in thousands of composition rules?

I introduced some note transformations that:
  • introduce small steps between notes so as to generate something that could be interpreted as a melody
  • do not fundamentally alter the harmonic function in the musical context
To accomplish this I replace with a sequence of notes without altering the total duration of the fragment, e.g.
  • original note (half note) -> original note (quarter note), neighbouring note (8th note), original note (8th note)
Other transformations  look at the current note and the next note, and interpolate a note in between (again, without changing total duration)
  • original note (half note), next note -> original note (quarter note), note between original note and next note (quarter note), next note
A property of generating melodies by spicing up lists of notes using this method is that after spicing up a list of notes, you can spice the spiced up list again to get an even spicier list (more complex melody, both in pitch and in rhythm).

Finally a warning for the sensitive ears: for a composer to write a choral that obeys all the rules of the "common practice" takes years of study and lots of practice. Given the extreme simplicity of the program, the computer doesn't have any of this knowledge and it will happily generate errors against the common practice rules (e.g. parallel fifths and octaves). Not always, but sometimes, as dicated by randomness. Note that this is an area in which the program could be improved, by checking for errors while spicing up and skipping proposed spicings that introduce errors against the common practice rules.

Yet, despite the extreme simplicity of the method, the results can be surprisingly complex and in some cases sound interesting.

How can I use it?

In its current form, the program is not really easy to install and use, at least if you have no computer experience:
  • You need to install the free python programming language from http://www.python.org/download/releases. I recommend using version 2.7. Version 3 and later of python won't work! 
  • You also need to install the free music21toolkit for computer-aided musicology. Follow the instructions on their website. Music21 provides for vast amounts of music knowledge which would take a long time to write ourselves. I'm using only a fraction of its possibilities in the canon generator.
  • Then you need something to visualize and audition the MusicXml that is generated by the program. For our purposes, the free MuseScore program works perfectly.
  • Finally you need to get the free canon-gen.py program from the github repository https://github.com/shimpe/canon-generator.
The main function defined near the bottom of the canon-gen.py file contains some parameters you can edit to experiment with the generator:
  • chords = "C F Am Dm G C"
    #You can insert a new chord progression here. 
  • scale = music21.scale.MajorScale("C")
    #You can define a new scale in which the notes of the chords should be interpreted here 
  • voices = 5
    #Define the number of voices in your canon here 
  • quarterLength = 2
    #Define the length of the notes used to realize the chord progression
    #(don't choose them too short, since the automatic spicing-up will make them shorter) 
  • spice_depth = 1
    # Define how many times a stream (recursively) should be spiced up
    # e.g. setting 2 will first spice up the chords, then again spice up the already spiced chords.
    # scores very quickly become rhytmically very complex for settings > 2
  • stacking = 1
    # the code can generate multiple versions of the spiced up chord progression, and use those
    # versions to create extra voices
    # e.g. setting stacking = 2 will turn a 3-voice canon into a 3*2 = 6-voice canon 
  • voice_transpositions = { VOICE1 : +12, VOICE2 : 0, VOICE3 : -12, VOICE4: -24, VOICE5: 0 }
    # allow extra octave jumps between voices

What does it sound like?

This is a simple example generated with the program with settings
  • chords = "C F Am Dm G C"
  • scale = music21.scale.MajorScale("C")
  • voices = 5
  • quarterLength = 2 
  • spice_depth = 1
  • stacking = 1 
  • voice_transpositions = { VOICE1 : 0, VOICE2 : 0, VOICE3 : -12, VOICE4: -24, VOICE5: 0 }  

Ideas for future improvements

I see many possible improvements, most of which are low-hanging fruits. Feel free to jump in and improve the code :D
  • fix a known bug related to octaviations in keys other than C
  • support modulations, i.e. keep musical key per measure/beat instead of over the complete chord progression
  • extend the code to cover the things explained in the later articles: crab and table canons
  • see if the method/code can be extended to generate canons at the third, fifth, ...
  • smarter spicing up of chord progressions to avoid parallel fifths/octaves (e.g. rejecting a proposed spice if it introduces an error in the overall stream); or use Dmitry Tymoczko's voice leading spaces to ensure better voice leading by construction.
  • protect the end chord from getting spiced up
  • implement more note transformations, e.g. appogiatura
  • experiment with more rhythms
  • how can we better spice up the chord progressions without messing up too much of the original harmonies?
  • ...