> For the complete documentation index, see [llms.txt](https://docs.sattern.dev/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.sattern.dev/tutorial/steps.md).

# 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.

```javascript
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](https://jacobsologub.s3.amazonaws.com/sattern/doc/classes/_sattern_.sattern.step.html#constructor). Here's another example showing how we can create a step object that sets each property one-by-one.

```javascript
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.

```javascript
// 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:

```javascript
// 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.

{% hint style="info" %}
`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.
{% endhint %}

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](https://soul.dev/) patches.
