Pular para conteúdo

4.2 Tipos de TimeVar🔗

Introdução🔗

Esta seção apresenta as várias encarnações de TimeVars que estão disponíveis para uso no FoxDot. Até agora, vimos o TimeVar básico, que mantém um valor por um certo número de batidas e depois muda para o próximo valor. Também existe uma série de TimeVars que mudam gradualmente entre esses valores, bem como TimeVars para representar objetos Pattern inteiros. Vamos nos aprofundar neles agora:

TimeVars de Mudança Gradual🔗

Existem três tipos de TimeVars de mudança gradual que (sem surpresa) mudam gradualmente entre valores ao longo do tempo, em vez de mudarem instantaneamente após o término da duração atribuída. São elas: linvar, sinvar e expvar, e seus nomes estão relacionados à maneira como os valores mudam ao longo do tempo, conforme descrito abaixo:

linvar(values, dur)🔗

Este TimeVar alterna entre valores em uma escala linear, daí o nome linvar. Assim como todos os TimeVars, ele recebe uma série de valores e durações como entrada. Se dur for omitido, ele utilizará o valor do medidor atual.

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

Conforme o tempo passa, o valor muda de forma que, após o tempo determinado (4 batidas neste exemplo), ele será exatamente 1. Quando esse tempo tiver passado, o linvar começará a mudar linearmente seu valor na direção do próximo valor de entrada, que é 0. Nas próximas 4 batidas, o valor diminuirá a uma taxa linear em direção a 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(values, dur)🔗

Em vez de alternar entre valores a uma taxa linear, uma sinvar altera-se a uma taxa derivada de uma onda sinusoidal. Você pode ver abaixo que a taxa é aparentemente muito mais rápida, mas ainda assim atingirá o valor final de 1 ao mesmo tempo que a 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(values, dur)🔗

A taxa de variação do expvar é exponencial, então, começa pequena, mas termina em grandes etapas. Você pode ver que isso também ocorre quando os valores diminuem:

>>> 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🔗

É importante observar que, quando um player está usando uma variável TimeVar de mudança gradual, ela usará o valor armazenado nela no momento em que a nota for acionada. Isso significa que, uma vez que a nota for tocada, você não ouvirá uma mudança no valor ao longo do tempo na própria nota. Experimente estas linhas de código:

# Sem alteração gradual na frequência de passagem alta
p1 >> dirt(dur=4, hpf=linvar([0, 4000], 4))

# Mudança gradual aparente na frequência de passagem alta
p2 >> dirt(dur=1/4, hpf=linvar([0, 4000], 4))

Você também pode usar uma duração de 0 para pular imediatamente a mudança gradual e passar para o próximo valor; isso é útil para "redefinir" valores e criar quedas:

# Aumente até 4000 Hz e, então, redefina para 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:

Assim como você pode fazer com TimeVars regulares, TimeVars de mudança gradual podem ser aninhadas dentro de outras TimeVars para gerenciar melhor como os valores são aplicados. Por exemplo, podemos aumentar a frequência do filtro passa-alta apenas nas últimas 4 batidas de um ciclo de 32 batidas, assim:

# Use um TimeVar normal para definir o valor como 0 para 28 batidas.
p1 >> dirt(dur=1/4, hpf=var([0, expvar([0, 4000], [4, 0])], [28, 4]))

TimeVars de Padrões🔗

Pvar(patterns, dur)🔗

Até agora, armazenamos apenas valores únicos em uma TimeVar, mas às vezes é útil armazenar um objeto Pattern inteiro. Você não pode fazer isso usando uma TimeVar normal, pois qualquer Pattern na lista de valores de entrada é tratado como uma lista aninhada de valores únicos. Para evitar esse comportamento, você precisa usar uma Pvar, abreviação de Pattern-TimeVar. Ela é criada exatamente como qualquer outra TimeVar, mas os valores podem ser listas/Patterns inteiros:

>>> 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]

Operações matemáticas e transformações também funcionam de maneira idêntica às TimeVars normais:

>>> 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):
...     """ Converta um número par em 3 e um ímpar em 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]

Você pode até mesmo aninhar um Pvar dentro de um padrão, como faria com um padrão normal, para alternar os valores reproduzidos... e depois alterar isso com base no tempo!

# Alterne as notas alternadas a cada 8 batidas
p1 >> pluck([0, 1, 2, Pvar([[4, 5, 6, 7], [11, 9]], 8)], dur=1/4, sus=1)