blauha.us Labs Blog


Table Of Contents

Composition for Genetic Algorithm and Guitar

Soundcloud

This was an AI experiment in using a Genetic Algorithm for computational musical creativity.

Implementing part of an algorithm specified in a paper by Liu et. al. [1] and building on a Java sound demo from javakode.com[2], I created this short duet between tones created by a genetic algorithm and a classical guitar.

Here is the fitness function that I used for the GA, based on [1]. A general overview of GA's follows.

public class RuleEngine {
    // a = score note
    // b = ga note
    // prev = previous ga note
    public static int points(Note a, Note b, Note prev) {
        return  unison(a, b) +
            minorSecond(a, b) +
            majorSecond(a, b) +
            minorThird(a, b) +
            majorThird(a, b) +
            perfectFourth(a, b) +
            diminishedFifth(a, b) +
            perfectFifth(a, b) +
            minorSixth(a, b) +
            majorSixth(a, b) +
            minorSeventh(a, b) +
            majorSeventh(a, b) +
            octave(a, b) +
            diversity(b, prev);
        }
    public static int diversity(Note gaNote, Note prev) {
        if (prev == null) {
            return 0;
        } else if (gaNote.val() == prev.val()) {
            return -2;
        } else {
            return 0;
        }    
    }
    public static int unison(Note a, Note b) {
        int points = a.val() == b.val() ? 8 : 0;
        return points;
    }
    public static int minorSecond(Note a, Note b) {
        int points = Math.abs(a.val() - b.val()) == 1 ? -20 : 0;
        return points;
    }
    public static int majorSecond(Note a, Note b) {
        int points = Math.abs(a.val() - b.val()) == 2 ? -20 : 0;
        return points;
    }
    public static int minorThird(Note a, Note b) {
        int points = Math.abs(a.val() - b.val()) == 3 ? -20 : 0;
        return points;
    }

    public static int majorThird(Note a, Note b) {
        int points = Math.abs(a.val() - b.val()) == 4 ? 8 : 0;
        return points;
    }
    public static int perfectFourth(Note a, Note b) {
        int points = Math.abs(a.val() - b.val()) == 5 ? 15 : 0;
        return points;
    }
    public static int diminishedFifth(Note a, Note b) {
        int points = Math.abs(a.val() - b.val()) ==6  ? -30 : 0;
        return points;
    }
    public static int perfectFifth(Note a, Note b) {
        int points = Math.abs(a.val() - b.val()) == 7 ? 15 : 0;
        return points;
    }
    public static int minorSixth(Note a, Note b) {
        int points = Math.abs(a.val() - b.val()) == 8 ? 8 : 0;
        return points;
    }
    public static int majorSixth(Note a, Note b) {
        int points = Math.abs(a.val() - b.val()) == 9 ? 8 : 0;
        return points;
    }
    public static int minorSeventh(Note a, Note b) {
        int points = Math.abs(a.val() - b.val()) == 10 ? -20 : 0;
        return points;
    }
    public static int majorSeventh(Note a, Note b) {
        int points = Math.abs(a.val() - b.val()) == 11 ? -20 : 0;
        return points;
    }
    public static int octave(Note a, Note b) {
        int points = a.val() % b.val() == 0 ? 8 :0;
        return points;
    }
}

A genetic algorithm based solution is useful where you have a problem space where it is not possible to combinatorially try every possible solution, so you use a stochastic process to generate approximate solutions. For the composition above, it was also useful for generating different creative solutions based on a set of rules. (Rules like, prefer a perfect 4th over a minor 2nd interval.)

The basic process for an Evolutionary solution is:

NOTES

[1] Liu, C. H., & Ting, C. K. (2012, June). Polyphonic accompaniment using genetic algorithm with music theory In Evolutionary Computation (CEC), 2012 IEEE Congress on (pp. 1-7). IEEE.

[2] Playing MIDI Music with the Java API: Some Simple Examples (N.D.) retrieved 10/9/2013 from http://www.javakode.com/apps/music1/