Slipmat Prototype & Processing

I experimenting combining the first Slipmat prototype (built with the Csound API) with Processing. Getting the two systems working together was fairly straight forward. Here’s the code that generated the video.

The following method from class Disc does two things when a disc collides with a border: change direction of the disc and trigger a slipmat event:

public void moveDisc() {
    x += xVelocity * SCALE_VELOCITY;
    y += yVelocity * SCALE_VELOCITY;

    if (x <= DISC_RADIUS || x >= width - 1 - DISC_RADIUS) {
        xVelocity *= -1;
        playNote();
    }

    if (y <= DISC_RADIUS || y >= height - 1 - DISC_RADIUS) {
        yVelocity *= -1;
        playNote();
    }
}

The method playNote() also belongs to class Disc, and is where the actual triggering of the Slipmat event occurs. The instances sp1 and sp2 are part of the Slipmat system. The “sp” is short for “sine percussion.”

public void playNote() {
    sp1.playNote(0.0, 0.35 * (1 - x / width), frequency);
    sp2.playNote(0.0, 0.35 * x / width, frequency);
}

Live Coding and Capturing a Perfomance

It’s the latest fad that’s sweeping computer music. And I would love for Slipmat to have this ability in its arsenal of tools. Without having to sacrifice non-realtime rendering for computationally expensive processes, of course.

The following conceptual live coding prototype shows what a simple session would look like if it was modeled on the Python interpreter:

$ slipmat --capture_performance my_session.txt
>>> from LiveCodeSeq import seq
>>> from MyBassLibrary import rad_rezzy
>>> from random import random
>>> p[0] = [int(random() * 12) for i in range(0, 16)]
>>> p[1] = [int(random() * 12) for i in range(0, 16)]
>>> p[0]
[5, 9, 11, 8, 7, 8, 5, 1, 10, 7, 4, 4, 6, 4, 4, 2]
>>> p[1]
[6, 6, 5, 3, 5, 7, 8, 4, 0, 0, 8, 7, 9, 7, 2, 4]
>>> r = rad_rezzy()
>>> s = seq(instr=r, pattern=p[0], base_pch=6.00, resolution=1/16, tempo=133)
>>> s.start()
>>> s.change_pattern(pattern=p[1], on_beat=0)
>>> @60 s.stop(onbeat=0)

I have a gut feeling that there are some changes that should be made. Though as a starting point, this isn’t a terrible one.

Being able to capture a live coding performance would be fantastic. Not sure how workable it would be, but perhaps such a feature would produce a file that could be played back later:

$ cat my_session.txt
@0             global.seed(7319991298)
@4.04977535403 from LiveCodeSeq import seq
@8.43528123231 from MyBassLibrary import rad_rezzy
@10.9562488312 from random import random
@15.6027957075 p[0] = [int(random() * 12) for i in range(0, 16)]
@20.7757632586 p[1] = [int(random() * 12) for i in range(0, 16)]
@26.2462371683 p[0]
@29.3961696828 p[1]
@34.0424988199 r = rad_rezzy()
@40.3211374075 s = seq(instr=r, pattern=p[0], base_pch=6.00, resolution=1/16, 
                   tempo=133)
@45.5491938514 s.start()
@47.8991166715 s.change_pattern(pattern=p[1], onbeat=0)
@52.6267958091 @60 s.stop(onbeat=0)

The @ schedules are the times in which return was originally pressed for each event. Looks like I’ll be spending some time with ChucK soon.

Early Java Slipmat Prototype

Slipmat has been a pet project of mine for a few years now. The first working prototype was realized in Java. The code for this is up at sourceforge.

Originally, the idea was for slipmat to be a java interface layer that sits on top of Csound. Hence the slipmat metaphor. At one point, it became much too unwieldily and I had abandoned it. Until later when I picked up Python, and decided to give it another go. Python made things much easier all the way around, but I eventually abandoned that too, for reasons I’ll go into later.

Here is an excerpt from one of the original Java prototype examples:

public ControllerExample() {
    /* Create empty SynthRack */
    SynthRack synthRack = new SynthRack(false);
    
    /* Create modules */
    LinearSlide linearSlider = new LinearSlide();
    SynthBass bass = new SynthBass();
    Output output = new Output();

    /* Add modules to the SynthRack */
    synthRack.addModule(linearSlider);
    synthRack.addModule(bass);
    synthRack.addModule(output);

    /* Patch the SynthBass to the Output */
    output.setInput(bass.getOutput());

    /* Create a sequence */
    linearSlider.slide(1.0, 0.05, 2.0, bass.getOscillator1Detune());
    linearSlider.slide(1.125, 0.05, 1.5, bass.getOscillator1Detune());
    bass.playNote(0.0, 8.0, 0.5, 100);
    bass.playNote(2.5, 6.0, 0.25, 200);

    /* Set duration and press play */
    synthRack.setDuration((double) SCORE_DURATION);
    synthRack.startCsound();
}

The full code can be seen here. Once I get things sorted out at sourceforge, I’ll post the Python package there as well.