Capítulo 4
Modelagem Física
Neste capítulo veremos como o Csound emula instrumentos acústicos
através da síntese por modelagem física. É importante notar que o Csound não foi
desenvolvido com o propósito de emular sons reais, mas sim para criar novos sons
sintetizados, portanto os opcodes a seguir são uma exceção à regra, e tem características
próprias, diversas de um instrumento replicado por samples. Veremos primeiro o opcode
mais usado dentre eles, pluck, e em seguida passaremos por repluck, wgpluck,
wgpluck2, wgbow, wgbowedbar, wgbrass, wgclar e wgflute.
Primeiro vejamos como é a sintaxe dos opcodes de cordas vibrantes e o que eles
tëm em comum. A sintaxe de pluck que usaremos é:
ares pluck kamp, kcps, icps, ifn, imeth
Em imeth temos o método de decaimento usado na corda, e usaremos apenas o
método 1 que é de média simples entre os harmônicos iniciais e finais. 
Ifn nos diz qual tabela deverá ser usada como onda inicial antes do decaimento, se
ifn = 0 uma onda inicial de ruído aleatório é utilizada. Para simular uma corda real é
melhor usar ifn = 0, pois o ruído inicial é rico em harmônicos o que acentua o processo
de decaimento para uma onda apenas com harmônicos inteiros, como acontece quando
uma corda real é tocada.
Kcps determina a frequência fundamental, a partir da qual é determinada quais
parcias são harmônicas e devem ser mantidas, e quais parciais são inarmônicas e devem
ser atenuadas. A única exigência é que kcps atinja no mínimo o valor de icps, pois para
valores menores que icps, o período da onda não caberá no buffer.
Icps não afeta a frequência, apenas é usada para determinar de antemão o
tamanho do buffer para armazenar um ciclo de onda da frequência fundamental, e atenuar
subsequentemente as parciais inarmônicas dentro desse buffer. Se quisermos que o buffer
tenha, ao invés de apenas um ciclo de onda, vários ciclos de onda da fundamental, basta
usarmos uma frequência em icps abaixo da fundamental real determinada por kcps.
Um trecho de código que usa pluck vem a seguir:
instr 1
  kamp = 20000
  icps = cpspch(p4)
  kcps linseg icps, p3, icps*2
  ifn = 0
  imeth = 1
  a1 pluck kamp, kcps, icps, ifn, imeth
  out a1
endin
Podemos comparar pluck com seu parente mais complexo, repluck, criado por
John ffitch, cuja sintaxe é:
ares repluck iplk, kamp, icps, kpick, krefl, axcite
Se em pluck podemos variar a frequência, em repluck não haverá essa
possibilidade, mas em compensação podemos definir em que ponto tocaremos a corda e
em que local estará colocado o captador. Isso é feito respectivamente através de iplk para
o ponto em que a corda será tocada e kpick para o local do captador, que podem conter
valores entre 0 e 1.
Em krefl definimos o tempo que a corda se manterá vibrando (i.e., a velocidade
do decaimento), e deve conter um valor estritamente entre 0 e 1, mas diferente de 0 e de
1. Quanto maior krefl, maior a perda de amplitude e a velocidade do decaimento.
Finalmente em axcite temos a onda que excitará a corda, e preferencialmente
deve ser uma onda de baixíssima frequência, algo entre 1Hz e 10Hz, para a corda ser
excitada poucas vezes ao longo da duração da nota.
Um trecho de código típico de repluck está abaixo, onde usamos axcite oscilando
apenas uma vez ao longo de toda a duração da nota:
instr 2
  iplk = 0.75
  kamp = 30000
  icps = cpspch(p4)
  kpick = 0.75
  krefl = 0.5
  axcite oscil 1, 1/p3, 1
  a1 repluck iplk, kamp, icps, kpick, krefl, axcite
  out a1
endin
Vamos ver agora o restante da família de opcodes que utiliza modelagem física
por wave guide, desenvolvidos primeiro por Perry Cook e depois codificados para o
Csound por John ffitch. O primeiro grupo para cordas vibrantes são wgpluck e
wgpluck2. Abaixo temos a sintaxe de wgpluck2, que é uma versão simplificada de
repluck:
ares wgpluck2 iplk, kamp, icps, kpick, krefl
Temos em wgpluck2 os mesmos parâmetros de repluck, utilizando a mesma
faixa de valor, mas desta vez sem a onda de excitação axcite. Abaixo temos um trecho de
código de wgpluck2:
instr 3
  iplk = 0.25
  kamp = 30000
  icps = cpspch(p4)
  kpick = 0.25
  krefl = 0.7
  a1 wgpluck2 iplk, kamp, icps, kpick, krefl
  out a1
endin
Chegamos agora a wgpluck, que é uma versão mais complexa de repluck e
wgpluck2. A sintaxe de wgpluck é:
ares wgpluck icps, iamp, kpick, iplk, idamp, ifilt, axcite
Esse opcode é semelhante a repluck e wgpluck2, pois além dos parâmetros de
utilização idêntica, temos idamp que é uma nova versão de krefl, que para valores
maiores o decaimento é mais rápido, mas com a novidade que para valores negativos de
idamp há um acréscimo do sinal com o tempo. Vale lembrar que ao contrário de krefl,
idamp não é normalizado, podendo assumir qualquer valor positivo ou negativo.
Em ifilt temos um filtro na ponte (ponto onde as cordas são presas ao corpo do
instrumento) em que definimos a partir de quais harmônicos a onda será atenuada,
valores altos para uma atenuação primeiro de frequências altas e valores baixos para que
haja no início uma atenuação das baixas frequências. 
Um trecho de código utilizando as particularidades de wgpluck vem abaixo:
instr 4
  icps = cpspch(p4)
  iamp = 10000
  kpick = 0.5
  iplk = 0
  idamp = -10
  ifilt = 1000
  axcite oscil 1, 1/p3, 1
  
  a1 wgpluck icps, iamp, kpick, iplk, idamp, ifilt, axcite
  out a1
endin
A seguir temos o código completo com os quatro instrumentos e o score dando
as frequências a serem tocadas.
<CsoundSynthesizer>
<CsOptions>
-o string.wav
</CsOptions>
<CsInstruments>
instr 1
  kamp = 20000
  icps = cpspch(p4)
  kcps linseg icps, p3, icps*2
  ifn = 0
  imeth = 1
  a1 pluck kamp, kcps, icps, ifn, imeth
  out a1
endin
instr 2
  iplk = 0.75
  kamp = 30000
  icps = cpspch(p4)
  kpick = 0.75
  krefl = 0.5
  axcite oscil 1, 1/p3, 1
  a1 repluck iplk, kamp, icps, kpick, krefl, axcite
  out a1
endin
instr 3
  iplk = 0.25
  kamp = 30000
  icps = cpspch(p4)
  kpick = 0.25
  krefl = 0.7
  a1 wgpluck2 iplk, kamp, icps, kpick, krefl
  out a1
endin
instr 4
  icps = cpspch(p4)
  iamp = 10000
  kpick = 0.5
  iplk = 0
  idamp = -10
  ifilt = 1000
  axcite oscil 1, 1/p3, 1
  
  a1 wgpluck icps, iamp, kpick, iplk, idamp, ifilt, axcite
  out a1
endin
</CsInstruments>
<CsScore>
f1 0 16384 10 1 
     
i1 0 5 7.09  
i2 5 5 7.09  
i3 10 5 7.09  
i4 15 5 7.09  
e
 
</CsScore>
</CsoundSynthesizer>
Fig.1: string.csd
No Csound temos a modelagem de instrumentos de arco através do  opcode
wgbow. A sintaxe de wgbow a ser usada é:
ares wgbow kamp, kfreq, kpres, krat, kvibf, kvamp, ifn
Em kamp e kfreq temos a amplitude e a frequência de nota. Em kpres a
pressão do arco sobre a corda, e deve variar entre 1 e 5, e em krat o ponto em que o arco
está sobre a corda, que deve variar entre 0.025 e 0.23.
Embutido no opcode temos um vibrato, controlado pelos parâmetros kvibf,
kvamp e ifn. Em kvibf temos a frequência do vibrato, que deve ser um valor baixo,
usualmente entre 1 e 12Hz, em kvamp temos a amplitude do vibrato, ou seja, em que
porcentagem o vibrato alterará a frequência original, e deve ser um valor baixíssimo, em
torno de um centésimo. Finalmente em ifn temos a forma de onda do vibrato, usualmente
uma f-table com uma senóide. A seguir o código usando wgbow:
 
<CsoundSynthesizer>
<CsOptions>
-o wgbow.wav
</CsOptions>
<CsInstruments>
sr = 44100
kr = 4410
ksmps = 10
nchnls = 1
instr 1
  kamp = 30000
  kfreq = cpspch(p4)
  kpres = 3
  krat = 0.13
  kvibf = 4
  kvamp = 0.01
  ifn = 1
  a1 wgbow kamp, kfreq, kpres, krat, kvibf, kvamp, ifn
  out a1
endin
</CsInstruments>
<CsScore>
f 1 0 128 10 1
i 1 0 5 8.09
 
e
</CsScore>
</CsoundSynthesizer>
Fig.2: wgbow.csd
O opcode seguinte, para uma barra percutida, é wgbowedbar, e a sintaxe que
usaremos é:
ares wgbowedbar kamp, kfreq, kpos, kbowpres, kgain \
[, iconst] [, itvel] [, ibowpos]
Como em wgbow, kpos determina a posição do arco, mas agora pode variar
entre 0 e 1, e kbowpress determina a pressão do arco, com valores entre 0.6 e 0.7. Em
kgain há o ganho de saída do opcode, que deve variar em torno de 0.9 e 1.
De fato, wgbowedbar é um opcode muito sensível, e é preciso fazer um ajuste
fino entre kbowpres e kgain para se obter uma saída satisfatória. Poucos décimos de
mudança nesses parâmetros é a diferença entre uma microfonia completamente
descontrolada e o silêncio absoluto. Abaixo temos o código usando wgbowedbar, com os
parâmetros devidamente ajustados:
<CsoundSynthesizer>
<CsOptions>
-o wgbowedbar.wav
</CsOptions>
<CsInstruments>
sr = 44100
kr = 4410
ksmps = 10
nchnls = 1
instr 1
  kamp = 30000
  kfreq = cpspch(p4)
  kpos = 0.5
  kbowpres = 0.7
  kgain = 0.995
  a1 wgbowedbar kamp, kfreq, kpos, kbowpres, kgain
  out a1
endin
</CsInstruments>
<CsScore>
f 1 0 128 10 1
i 1 0 5 8.09
e
</CsScore>
</CsoundSynthesizer>
Fig.3: wgbowedbar.csd
Vejamos agora os opcodes de modelagem física para os instrumentos de sopro,
que tem semelhanças de parâmetro com wgbow. Mais especificamente veremos
wgbrass, wgclar e wgflute. A sintaxe que usaremos de wgbrass é:
ares wgbrass kamp, kfreq, ktens, iatt, kvibf, kvamp, ifn
 
Kamp e kfreq são a amplitude e a frequência, ktens é semelhante a kbowpres,
nos diz a pressão que o instrumentista faria ao soprar, e deve conter valores em torno de
0.4. Em seguida vem iatt, o único parâmetro realmente novo, que nos diz o tempo de
ataque da nota até atingir pressão total. Kvibf, kvamp e ifn fazem parte do vibrato
embutido, como em wgbow
Todos os opcodes da seção de sopros estão em nível experimental, e tem-se que
ter uma atenção especial com o vibrato. É recomendável que se use um valor baixíssimo
para frequência e amplitude do vibrato, ou o som sofrerá cortes. Um trecho de código
para wgbrass vem abaixo:
instr 1
  kamp = 30000
  kfreq = cpspch(p4)
  ktens = 0.4
  iatt = 0.1
  kvibf = 1/(2*p3)
  kvamp = 0.2
  ifn = 1
  a1 wgbrass kamp, kfreq, ktens, iatt, kvibf, kvamp, ifn
  out a1
endin
A seguir temos wgclar, a variação para clarineta de wgbrass, e a sintaxe que
usaremos é:
ares wgclar kamp, kfreq, kstiff, iatt, idetk, kngain, kvibf, kvamp, \
    ifn
A maioria dos parâmetros aqui são herdados de wgbrass. Os parâmetros que já
tínhamos visto antes são kamp e kfreq para amplitude e frequência, iatt para tempo de
ataque, e kvibf, kvamp e ifn para a frequência, amplitude e forma de onda do vibrato.
Vejamos a seguir  os parâmetros novos. Kstiff é a força que o ar sai da clarineta, e
deve conter valores negativos entre -0.1 e -0.5, sendo maior e mais ruidoso conforme
valores mais negativos são definidos. Idetk é o intervalo de tempo entre parar de soprar o
instrumento e parar de ser emitido som, através de um rápido decaimento, e valores em
torno de 0.1 segundos são geralmente usados. Kngain é o ganho que deve sofrer o ruído
que acompanha o som da clarineta, normalmente com valores de no máximo 0.5.
A seguir temos um trecho de código com wgclar:
instr 2
  kamp = 30000
  kfreq = cpspch(p4)
  kstiff = -0.4
  iatt = 0.1
  idetk = 0.1
  kngain = 0.4
  kvibf = 1/(2*p3)
  kvamp = 0.2
  ifn = 1
  a1 wgclar kamp, kfreq, kstiff, iatt, idetk, kngain, kvibf, kvamp,\
ifn
  out a1
endin
E como último instrumento da seção de sopros, temos wgflute, que emula uma
flauta, e sua sintaxe reduzida é:
ares wgflute kamp, kfreq, kjet, iatt, idetk, kngain, kvibf, kvamp, ifn
Aqui o único novo parâmetro é kjet, que é similar a ktens, kbowpres e kstiff, e
controla a força do jato de ar, e deve conter valores entre 0.1 e 0.5. Os parâmetros
restantes são como vistos acima em wgclar. 
Um trecho de código para wgflute é:
instr 3
  kamp = 30000
  kfreq = cpspch(p4)
  kjet = 0.3
  iatt = 0.1
  idetk = 0.1
  kngain = 0.05
  kvibf = 1/(2*p3)
  kvamp = 0.05
  ifn = 1
  a1 wgflute kamp, kfreq, kjet, iatt, idetk, kngain, kvibf, kvamp, ifn
  out a1
endin
A seguir temos o código completo dos três instumentos de sopro, tocados pelo
score:
<CsoundSynthesizer>
<CsOptions>
-o wind.wav
</CsOptions>
<CsInstruments>
sr = 44100
kr = 4410
ksmps = 10
nchnls = 1
instr 1
  kamp = 30000
  kfreq = cpspch(p4)
  ktens = 0.4
  iatt = 0.1
  kvibf = 1/(2*p3)
  kvamp = 0.2
  ifn = 1
  a1 wgbrass kamp, kfreq, ktens, iatt, kvibf, kvamp, ifn
  out a1
endin
instr 2
  kamp = 30000
  kfreq = cpspch(p4)
  kstiff = -0.4
  iatt = 0.1
  idetk = 0.1
  kngain = 0.4
  kvibf = 1/(2*p3)
  kvamp = 0.2
  ifn = 1
  a1 wgclar kamp, kfreq, kstiff, iatt, idetk, kngain, kvibf, kvamp, ifn
  out a1
endin
instr 3
  kamp = 30000
  kfreq = cpspch(p4)
  kjet = 0.3
  iatt = 0.1
  idetk = 0.1
  kngain = 0.05
  kvibf = 1/(2*p3)
  kvamp = 0.05
  ifn = 1
  a1 wgflute kamp, kfreq, kjet, iatt, idetk, kngain, kvibf, kvamp, ifn
  out a1
endin
</CsInstruments>
<CsScore>
f1 0 16384 10 1 
     
i1 0 5 8.09  
i2 5 5 8.09  
i3 10 5 8.09
</CsScore>
</CsoundSynthesizer>
Fig. 4: wind.csd