Capítulo 10
MIDI e Execução em Tempo Real
Existe uma gama de opcodes que lida com eventos MIDI no Csound, entretanto
existe alguns que são usados na maioria das vezes. Tipicamente, queremos que uma nota
tocada pelo controlador MIDI externo seja enviada para um instrumento do Csound, para
que seja processada e emitida em tempo real.
O método do Csound para lidar com eventos MIDI é simples e eficiente. Cada
canal MIDI é associado a um instrumento da seção orchestra, e sempre que um evento
ocorre neste canal, o instrumento é executado pelo tempo que a nota MIDI durar, com
acesso a todas as informações dessa nota. Quando a nota pára de ser tocada pelo
instrumento real, o instrumento do Csound deixa de ser executado.
Faremos um programa que a partir de um teclado, toque uma senóide na
frequência da tecla pressionada. A primeira coisa a fazer é associar um canal MIDI usado
pelo teclado a um instrumento da seção orchestra do CSound. 
Isso pode ser feito através do opcode massign, ou MIDI assign, e a sintaxe que
usaremos é:
massign ichnl, insnum
que
associa um canal ichnl ao instrumento número isnum. A declaração de massign
deve estar sempre no cabeçalho, antes da declaração do primeiro instrumento. Para
associar o canal 1 ao instrumento número 1, teremos no programa:
massign 1, 1
Sempre que uma nota fôr tocada no canal 1 pelo controlador MIDI, nosso
instrumento 1 será executado pelo tempo que essa nota durar.
Dentro do instrumento 1, precisamos obter qual nota está sendo tocada, e em
que velocidade ela foi tocada. Para obter a frequência da nota tocada, usaremos o opcode
cpsmidi, cuja sintaxe é:
icps cpsmidi
onde a nota que está sendo tocada pelo controlador externo, será armazenada em Hertz
em icps. Em alguns casos, poderíamos não querer essa informação direto em valores de
frequência, mas apenas o número MIDI da nota, e para isso usaríamos:
ival notnum
em que o número da nota MIDI, que vai de 0 a 127, seria armazenado em ival.
Poderíamos usar esse número para dizer qual a f-table usaríamos naquela nota:
a1 oscil kamp, icps, ival
e cada nota teria um timbre diferente.
E para obter com que velocidade, ou força, a nota está sendo tocada pelo
controlador externo, podemos usar o opcode iveloc, e sua sintaxe é:
ival veloc [ilow] [, ihigh]
Se omitirmos ilow e ihigh, iveloc armazenará em ival o valor MIDI da
dinâmica, que varia de 0 a 127. 
Se escrevermos os valores para ilow e ihigh, eles determinarão a faixa em que
veloc escalonará a dinâmica. Se quisermos obter um valor pra amplitude entre 0 e 30000,
escreveríamos:
iamp veloc 0, 30000
Existe ainda um último opcode que será útil em nosso instrumento. Quando o
controlador pára de tocar a nota, o instrumento é bruscamente interrompido. Às vezes
queremos que o instrumento tenha um tempo de release, tal que depois que a nota não
está sendo mais tocada pelo controlador, ela sofra um decaimento suave durante um
tempo extra.
Esse tempo extra de release é dado ao instrumento através do opcode de
envelope linsegr:
kres linsegr ia, idur1, ib [, idur2] [, ic] [...], irel, iz
Com exceção dos dois últimos parâmetros irel e iz, o restante é idêntico a linseg. O
opcode traçará um segmento de reta entre os valores ia e ib com duração de idur1
segundos, e assim sucessivamente para os segmentos seguintes. 
O parâmetro imediatamente anterior a irel, que será o último valor que kres
assumirá, será mantido durante todo o restante da nota, até que o controlador MIDI pare
de tocá-la. Quando o controlador pára, então o instrumento recebe mais irel segundos,
para decair até o valor de iz.
Vamos adaptar o primeiro exemplo desse livro, seno.csd, para ser tocado por
um controlador MIDI em tempo real. 
Uma complicação que surgiria nesse momento seria conectar fisicamente o
controlador MIDI ao computador, isso se você possuir o equipamente necessário. Para
que esse exemplo seja geral no sentido de funcionar em qualquer máquina, usaremos um
controlador MIDI virtual, que é o Virtual MIDI Keyboard, criado por Steven Yi. 
Ele exibe uma interface gráfica com um teclado de piano na tela, onde
selecionamos canais MIDI e bancos, que pode ser tocada com o mouse, ou até
diretamente pelo teclado do PC, utilizando no teclado qwerty as fileiras de teclas Z-M, S-
J, Q-P e 2-0, seguindo o desenho de teclas brancas e pretas do piano.
O Virtual MIDI Keyboard é ativado na linha de comando acrescentando-se o
flag:
-+rtmidi=virtual
 
Nosso código então ficaria:
 
<CsoundSynthesizer>
<CsOptions>
-M0 -+rtmidi=virtual
</CsOptions>
<CsInstruments>
; Inicializa as variáveis globais.
sr = 44100
kr = 4410
ksmps = 10
nchnls = 1
; associa o canal midi 1 ao instrumento 1
massign 1,1
; o instrumento 1 será executado enquanto o evento midi durar no canal 1
instr 1
  ; Velocidade da nota midi
  iamp veloc 0, 30000
  ; Frequência da nota midi
  icps cpsmidi
  ; Número da f-table com a senóide
  ifn = 1
  ; envelope com ataque de 0.5 segundos, 
  ; e que sustentará a amplitude até que a nota midi termine,
  ; havendo então um tempo extra de 1 segundo para que o instrumento
  ; silencie suavemente.
  kamp linsegr 0, 0.5, iamp, 1, 0
  ; Toca a nota midi com uma senóide
  a1 oscil kamp, icps, ifn
  out a1
endin
</CsInstruments>
<CsScore>
; Tabela #1: uma simples onda de seno usando GEN10.
f 1 0 16384 10 1
; Toca o instrumento #1 por 2 segundos, começando em 0 segundos
f 0 120
e
</CsScore>
</CsoundSynthesizer>
Fig.3: midi.csd, a versão MIDI de seno.csd.
Na seção score usamos uma f-table vazia, com índice 0, para ser carregada após
120 segundos. Ela é necessária apenas para fazer com que possamos tocar por 120
segundos, enviando eventos MIDI para o instrumento, e então o programa termine.
Como no restante desse livro, tocamos apenas na superfície do suporte MIDI,
esperando que sirva para que o usuário aprofunde-se nos meandros da programação nas
áreas descritas neste livro, e em outras que estarão por vir.