Aratu música escrita para tocar e mudar enquanto toca

4. Dando nome às coisas

▶ Abrir no Aratu para ouvir e mudar os exemplos

Esta tabela é o coração desta parte: para cada coisa do Aratu, o nome que ela teria em programação, e com o que se parece.

No Aratu Em termos de programação Parecido com
melodia = | dó4 ré mi fá | uma ligação (binding) de um nome a um valor; o valor é uma sequência de compassos uma constante: não muda enquanto toca; cada edição a define de novo
uma linha uma sequência circular: ao acabar, volta ao começo um clipe em loop numa DAW
drums { hh = …; bd = … } um registro ou namespace: um mapa de nomes para linhas um objeto (drums.hh)
bass.reverb.mix = 0.42 atribuição de propriedade num caminho de um mapa aninhado (parte → efeito → parâmetro) bass.reverb.mix = 0.42 em JavaScript, ou uma regra de CSS
bass: synth.saw -> lowpass -> reverb um pipeline: a saída de cada um é a entrada do próximo composição de funções, reverb(lowpass(saw)), ou o | do terminal
synth.saw, piano.grand uma chave de um catálogo (um enum): um nome que escolhe um som pronto um valor de uma lista fixa; não é um método
motif riff = [mi4 ré dó ré] uma macro: o nome é trocado pelo conteúdo onde aparece uma função sem efeitos colaterais, expandida no lugar (inlining)
riff+2, riff+3st o motivo com um argumento: a transposição riff(2)
riff.inv, riff.retro, serie.P5 uma transformação pura escrita com ponto: devolve um motivo novo e não muda o original um método ou propriedade calculada sem parênteses
row serie = 0 11 3 4 … um vetor (array) de inteiros de 0 a 11 [0, 11, 3, 4, …]
| o o o o | from serie.P0 um zip do ritmo com o vetor, que recomeça quando acaba; cada o é um marcador a preencher zip(ritmo, cycle(serie))
list temas { … } um array de melodias, contado a partir de 1 temas[1] em JavaScript é temas.2 no Aratu
temas.all, temas.random concatenação; escolha aleatória de um item temas.flat(), temas[random()]
{dó|sol} escolha aleatória, sorteada a cada volta random.choice
c?30% um evento com probabilidade de 30% if (random() < 0.3)
seed 7 a semente do gerador pseudoaleatório: a mesma semente dá o mesmo resultado Random(7)
pattern groove { … } um bloco nomeado de linhas um componente, uma cena, um template
play groove x3, fill uma playlist: uma sequência com repetições, em loop uma lista de cenas
|: :|, %, D.S. al coda saltos da partitura, resolvidos antes de tocar um goto que o compilador desenrola
[mi4 ré]x4, riffx4 repetição desenrolada: vira quatro cópias loop unrolling
p:, mf: um estado que vale para as notas seguintes da linha a "cor atual" numa biblioteca de desenho
300 Hz -> 4000 Hz over 4 bars interpolação de um valor no tempo (em escala logarítmica para frequências) tween, automação por keyframes
um knob ligação nos dois sentidos: girar reescreve o número do texto two-way binding; o texto continua sendo a fonte da verdade

at bar é um switch?

Não exatamente. Um switch (ou case) escolhe um caminho entre vários, cada vez que é executado, conforme um valor. Um at bar é uma regra indexada pelo tempo: a partir do compasso 9, aquilo vale, e continua valendo até outra regra mudar a mesma coisa. Se parece mais com um keyframe numa animação, ou com um evento marcado numa linha do tempo.

tempo: 110
bass = | dó2 _ sol1 _ |
at bar 5: bass.reverb.mix = 0.6
at bar 9: bass: out

Para saber o estado no compasso 12, o Aratu junta as regras de todos os compassos até ali: o reverb está em 0.6 (desde o 5) e o baixo está fora (desde o 9). Em programação, isso é uma dobra (fold) das mudanças, em ordem de tempo. from bar 9 to 16: é uma regra com começo e fim: fora do trecho ela não entra na dobra, e volta a valer o que vinha antes.

Já o every é o mais perto de um if com o número do compasso:

tempo: 110
pattern groove { hh = cc cc cc cc; bd = b - b -; sd = - s - s }
pattern fill { sd = ss ss SS SS }
play groove
every 4 bars: play fill

every 4 bars: play fill quer dizer, compasso a compasso, "se este é o último de cada quatro, toque a virada no lugar": if (compasso % 4 == 0). E every 4 bars, first: é if (compasso % 4 == 1).