Steps

A Step object represents one single step inside a pattern. Step objects have a 3 basic properties.

  1. duration - The length of the step in clock cycles.

  2. gate - The length of the gate in clock cycles.

  3. map - A "map" describing the target(s) and messages the step should trigger.

Let's go over the code we've written so far and break down the portion of the code that returns the Step objects inside our Pattern.onSequence function.

return [
    new sattern.Step ([sampler, new sattern.Note (64)], 4, 4),
    new sattern.Step ([sampler, new sattern.Note (71)], 4, 4),
    new sattern.Step ([sampler, new sattern.Note (68)], 4, 4),
    new sattern.Step ([sampler, new sattern.Note (76)], 4, 4)
];

The first parameter for our Step object is an Array and is in the form of a key/value pair (one pair in this example). The first element in the Array is the target (sampler) and the second element in the Array is the event or "message" we want to send (note). The second parameter for our Step object is the duration value and the last "third" parameter is the gate value. Step objects can be "constructed" in many ways, as can be seen in the JavaScript API Documentation for the Step object. Here's another example showing how we can create a step object that sets each property one-by-one.

const step = new sattern.Step();
step.duration = 4;
step.gate = 4;
step.map.set (sampler, new sattern.Note (64));

Step objects are not limited to just sending events to one target nor are they limited to sending just one event or one event type. For example let's make all of our Step objects send octaves.

// main.js
// Arpeggiator
//
// Created by Jacob Sologub on 15 Jun 2020.
// Copyright © 2020 Jacob Sologub. All rights reserved.

const sampler = new sattern.Sampler();
sattern.graph.add (sampler);

const sound = new sattern.Sound ("./mcg_mp_064.wav", {
    lowKey: 0, highKey: 127, rootKey: 64
});
sampler.add (sound);

const pattern = new sattern.Pattern();
sattern.add (pattern);
pattern.onSequence = function (context) {
    return [64, 71, 68, 76].map (key => {
        return new sattern.Step ([sampler, [new sattern.Note (key), new sattern.Note (key + 12)]], 4, 4)
    });
};

As you can see on line #19, the second element for our Array becomes an Array that holds two Note objects. To hear this in action, copy the above code snippet and replace the contents of your "main.js" file. Press Command + R or Command + S to save and re-load the current file.

The same idea can be applied to target(s), if we had another sampler we would do something like [sampler, sampler2] or if we wanted to send these notes to the main MIDI output port in addition to our sampler object we'd write something like this:

// main.js
// Arpeggiator
//
// Created by Jacob Sologub on 15 Jun 2020.
// Copyright © 2020 Jacob Sologub. All rights reserved.

const sampler = new sattern.Sampler();
sattern.graph.add (sampler);

const sound = new sattern.Sound ("./mcg_mp_064.wav", {
    lowKey: 0, highKey: 127, rootKey: 64
});
sampler.add (sound);

const pattern = new sattern.Pattern();
sattern.add (pattern);
pattern.onSequence = function (context) {
    return [64, 71, 68, 76].map (key => {
        return new sattern.Step ([[sampler, sattern.graph.midiOut], new sattern.Note (key)], 4, 4)
    });
};

Line #19 sends a Note message to both the sampler object and to the main MIDI output.

sattern.graph.midiOut is the main MIDI output port, and you can set what that device/port is by pressing the (6) "Settings" button on the top left corner of the UI. When Sattern is used as an AU (midi effect)/VST3 plugin the MIDI output will be sent to the host's channel MIDI output.

As mentioned before, Sattern is not limited to just sending Note object messages, you can send Aftertouch, ChannelPressure, Controller, and PitchBend object messages as well as OSCMessage objects and internal "generic" objects like { "gain": 0.75 } to control internal Sattern AudioUnits like the Sampler and SOUL patches.

Last updated