# Different types of TimeVar

This section introduces the various incarnations of TimeVars that are available to use in FoxDot. So far we have seen the basic, vanilla TimeVar that holds a value for a certain number of beats and then changes to the next value. There also exists a number of TimeVars that gradually change between these values as well as TimeVars for representing whole `Pattern` objects. Let’s delve into these now:

There are three types of gradual-change TimeVars that (unsurprisingly) gradually change between values over time instead of instantly changing once the assigned duration has elapsed. These are `linvar`, `sinvar`, and `expvar` and their names relate to the way in which the values change over time, as described below:

#### linvar

This TimeVar changes between values on a linear scale, hence the name `linvar`. As with all TimeVars, it takes a series of values and durations as its input:

```>>> my_linvar = linvar([0, 1], 4)
>>> print(Clock.now(), my_linvar)
0, 0
>>> print(Clock.now(), my_linvar)
1, 0.25
>>> print(Clock.now(), my_linvar)
2, 0.5
>>> print(Clock.now(), my_linvar)
3, 0.75```

As time progresses, the value changes such that after the given duration (4 beats in this example) it will be exactly 1. Once that duration has elapsed, the `linvar` will start to linearly change its value in the direction of the next input value, which is 0. Over the next 4 beats, the value will decrease at a linear rate towards 0.

```>>> print(Clock.now(), my_linvar)
4, 1
>>> print(Clock.now(), my_linvar)
5, 0.75
>>> print(Clock.now(), my_linvar)
6, 0.5
>>> print(Clock.now(), my_linvar)
7, 0.25```

#### sinvar

Instead of changing between values at a linear rate, a `sinvar` changes at a rate derived from a sinusoidal wave. You can see below that the rate is seemingly much faster but will still reach the final value of 1 at the same time as the `linvar`.

```>>> my_sinvar = sinvar([0, 1], 4)
>>> print(Clock.now(), my_linvar, my_sinvar)
1, 0.25, 0.38
>>> print(Clock.now(), my_linvar, my_sinvar)
2, 0.50, 0.71
>>> print(Clock.now(), my_linvar, my_sinvar)
3, 0.75, 0.92
>>> print(Clock.now(), my_linvar, my_sinvar)
4, 1, 1```

#### Expvar

The rate of change in the `expvar` is exponential, so starts small but finishes in large steps. You can see this is also the case when decreasing values:

```>>> my_expvar([0, 1], 4)
>>> print(Clock.now(), my_linvar, my_sinvar, my_expvar)
1, 0.25, 0.38, 0.06
>>> print(Clock.now(), my_linvar, my_sinvar, my_expvar)
2, 0.50, 0.71, 0.25
>>> print(Clock.now(), my_linvar, my_sinvar, my_expvar)
3, 0.76, 0.93, 0.57
>>> print(Clock.now(), my_linvar, my_sinvar, my_expvar)
4, 1, 1, 1
>>> print(Clock.now(), my_linvar, my_sinvar, my_expvar)
5, 0.74, 0.92, 0.93
>>> print(Clock.now(), my_linvar, my_sinvar, my_expvar)
6, 0.50, 0.71, 0.75
>>> print(Clock.now(), my_linvar, my_sinvar, my_expvar)
7, 0.25, 0.38, 0.43```

#### Notes and examples

It should be noted when a player is using a gradual change TimeVar it will use the value stored in it at the time the note is triggered. That means, once a note is played, you will not hear a change in value over time in the note itself. Try these lines of code out yourself:

```# No gradual change in the high pass frequency
p1 >> dirt(dur=4, hpf=linvar([0, 4000], 4))

# Apparent gradual change in the high-pass frequency
p2 >> dirt(dur=1/4, hpf=linvar([0, 4000], 4)) ```

You can also use a duration of 0 to immediately skip the gradual change and move on to the next value; this is useful for ‘resetting’ values and creating drops:

```# Ramp up to 4000Hz then reset to 0
p1 >> dirt(dur=1/4, hpf=expvar([0, 4000], [8, 0]))```

Just as you can with regular TimeVars, gradual-change TimeVars can be nested within other TimeVars to better manage how the values are applied. For example, we can ramp the high-pass filter frequency only on the last 4 beats of a 32 beat cycle like so:

```# Use a regular TimeVar to set the value to 0 for 28 beats
p1 >> dirt(dur=1/4, hpf=var([0, expvar([0, 4000], [4, 0])], [28, 4]))```

## Pattern TimeVars (Pvar)

So far we have only stored single values in a TimeVar but sometimes it is useful to store a whole Pattern object. You can’t do this using a regular TimeVar as any Pattern in the input list of values is treated as a nested list of single values. To avoid this behaviour, you need to use a `Pvar`, short for Pattern-TimeVar. It is created exactly like any other TimeVar but values can be whole lists/Patterns:

```>>> a = Pvar([[0, 1, 2, 3], [4, 5, 6]], 4)
>>> print(Clock.now(), a)
0, P[0, 1, 2, 3]
>>> print(Clock.now(), a)
4, P[4, 5, 6]```

Mathematical operations and transformations also work identically to the regular TimeVars:

```>>> a = Pvar([[0, 1, 2, 3], [4, 5, 6]], 4)
>>> b = (a * 2) + 1
>>> print(Clock.now(), a, b)
0, P[0, 1, 2, 3], P[1, 3, 5, 7]
>>> print(Clock.now(), a, b)
4, P[4, 5, 6], P[9, 11, 13]```
```>>> def odd_test(num):
...     """ Convert an even number to 3 and an odd to 5 """
...     return 5 if num % 2 == 1 else 3
>>>
>>> c = c.transform(odd_test)
>>> print(a, b, c)
P[0, 1, 2, 3], P[1, 3, 5, 7], P[3, 5, 3, 5]
>>> print(a, b, c)
P[4, 5, 6], P[9, 11, 13], P[3, 5, 3]```

You can even nest a `Pvar` within a Pattern as you would a normal Pattern to alternate values being played… and then change this based on time!

```# Alternate the alternating notes every 8 beats
p1 >> pluck([0, 1, 2, Pvar([[4, 5, 6, 7], [11, 9]], 8)], dur=1/4, sus=1)```