# Algorithmic Manipulation

One of the nice things about live coding is that you can schedule events to happen, or repeat, in the future. This allows you to continue coding while repeated functions are called and adding variety to your music. This section is an in-depth look at how the Player `every` method is implemented and how you can combine multiple instances of it to create complex music from simple patterns.

### Basics

First let’s look at a simple example which reverses a sequence every 8 beats:

```p1 >> pluck([0, 1, 2, 3, 4, 5, 6, 7]).every(8, "reverse")
```

The first argument is the number of beats between each call of a method and the second argument is the name of the method itself as a string. The reason for using the string name of the method instead of a function is so that Python can check if the method is valid using the `getattr` function and raise an error if it isn’t. Running the code `print(getattr(p1, "reverse"))` will give you something similar to `<bound method="" player.reverse="" of="" >`. What then happens, in essence, is that the scheduling clock runs `getattr(p1, "reverse").__call__()` every 8 beats.

You can use a list of durations to schedule method calls at irregular intervals like so:

```p1 >> pluck([0, 1, 2, 3, 4, 5, 6, 7]).every([6, 2], "reverse")
```

The code above will call the `reverse` method after 6 beats, then 2 beats after that, then again 6 beats after that call, repeating this until stopped. You can also use a `Pattern` or `PatternGenerator` object such as `PRand` to call methods at times not pre-determined:

```p1 >> pluck([0, 1, 2, 3, 4, 5, 6, 7]).every(PRand([2, 4, 8]), "reverse")
```

If you try and specify multiple calls of the same method you’ll find that only the last one updated gets scheduled. If you want to use more than one repeated call to the same method you can use the `ident` keyword and give it a name or number to differentiate it:

```# Call "reverse" every 8 beats *and* every 5 beats
d1 >> pluck([0, 1, 2, 3, 4, 5, 6, 7]).every(8, "reverse").every(5, "reverse", ident=1)
```

Player methods that can be used with `every` effectively are `reverse`, `rotate`, `shuffle`, `jump`, and `stutter`.

### The `cycle` keyword

Sometimes it might be useful to schedule a method for the same point in an N-beat cycle e.g. stutter the sound on the 6th beat of every 8 beat cycle. You can do this by simply specifying the length of the cycle as a keyword argument:

```d1 >> play("x-o-").every(6, "stutter", cycle=8)
```

Rather than calling `stutter` every 6 beats, it is called every 8 beats (the cycle size) but offset by 6 beats.

### The `stutter` method in depth

One of the most useful methods that can be called using `every` is the `stutter` method. This plays the last event sent to SuperCollider multiple times across a specified duration. You can also specify attributes/effects to attach to the events such as `pan` or `shape` using keyword arguments.

You can specify the number of times an event is stuttered simply by supplying an integer to the `every` call following the name of the method as a string. The default for this is 2 which means you will hear 1 extra event – 2 minus the event already being played. Using a value of 4 will play 3 extra events (you get the idea). By default the events will be stuttered across the duration of the event you are stuttering but you can also stutter the events across a given timeframe by supplying a `dur` keyword:

```# Play the event 4 times every 6 beats across 1/2 a beat
d1 >> play("x-o-", dur=1/2).every(6, "stutter", 4)

# Play the event 4 times every 6 beats across 3 beats
d1 >> play("x-o-", dur=1/2).every(6, "stutter", 4, dur=3)

# You can also specify the number of events to stutter using the 'n' keyword
d1 >> play("x-o-", dur=1/2).every(6, "stutter", dur=3, n=4)
```

Just as you supply keyword arguments to control the sound of your synths, you can do the same with `stutter` to control the sound being played. These can be a list or pattern of values which are given to each event stuttered in turn i.e. not played all at once:

```# Stutter 8 times with increasing playback speed
d1 >> play("x-o-").every(4, "stutter", 8, rate=[1,2,3,4,5,6,7,8])

# Stutter 4 times with alternating panning and higher rate
d1 >> play("x-o-").every(4, "stutter", 4, dur=3, pan=[-1, 1], rate=2)

# You can still use tuples / PGroups to add simultaneous effects
d1 >> play("x-o-").every(4, "stutter", 4, dur=1, pan=(-1,1), rate=(4, 1/2))
```

Note that when using a list of values, only the first `n` values will be used (where `n` is the number of times being stuttered).

### Using Pattern methods

On top of `reverse`, `rotate`, `shuffle`, `jump`, and `stutter`, you can also schedule any method that belongs to the `Pattern` class to be called on any attribute of a player. The behaviour is slightly different to when scheduling player methods in that instead of being called every n beats, it is called and then un-called so-to-speak. It’s probably best to demonstrate with an example:

```# Calls the "trim" method on the degree attribute
d1 >> play("x-o-").every(4, "trim", 3)
```

The “x-o-” pattern is trimmed to just “x-o” after 4 beats then reverts back to “x-o-” again after the next 4 beats. By default the method is called on `degree` attribute (which is pitch for most synths and the string of characters for the `play` synth) – you can specify a different attribute by prefixing the method name with the name of the attribute then a “.” like so:

```# Trim the octave pattern to 3 every 4 beats
p1 >> pluck([0,1,2,3], oct=[4,5,6,7]).every(4, "oct.trim", 3)
```

Arguments that would be supplied to the pattern method are given following the name of the method. For example the pattern method `offadd`, which layers a pattern with itself but with a value added and delayed by a duration, takes 2 arguments; the value to add and the delay time (default is 0.5). Here are some examples on how to use it with `every`:

```# Play a note 2 steps higher delayed 1/2 a beat
p1 >> pasha([0, 4], dur=[3/4, 3/4, 1/2]).every(3, "offadd", 2)

# Play a note 4 steps higher delayed 3/4 of a beat
p1 >> pasha([0,1,3,4], dur=1/2).every(5, "offadd", 4, 3/4)
```

You can use any method of the `Pattern` class, which you can see by running `help(Pattern)` or looking at the in depth descriptions.