Capítulo 1
Primeiros Instrumentos
Csound tem uma capacidade de criação de sons apenas limitada pelo
programador, e dada a abrangência do programa iremos nesse capítulo aprender sua
estrutura e sintaxe, usando exemplos simples a partir de senóides.
Explicaremos nessa seção como configurar o Csound para ser executado no
Windows e no Unix. 
Antes de executar o Csound no Windows, as variáveis de ambiente
OPCODEDIR e OPCODEDIR64 devem estar definidas com o caminho das bibliotecas
do Csound. Se  o Csound está instalado por exemplo em c:\csound, tipicamente devem
ser definidas as variáveis de ambiente como:
OPCODEDIR=c:\csound\plugins
OPCODEDIR64=c:\csound\plugins64
Além disso, o diretório bin de Csound, no nosso exemplo c:\csound\bin, deve
estar na variável de ambiente PATH. Por exemplo, no Windows poderíamos ter:
PATH=%PATH%;C:\csound5\bin
Para realizarmos essa configuração no Unix, devemos copiar o executável csound
para /usr/local/bin e as bibliotecas do Csound devem ser copiadas para /usr/local/lib.
Csound tem uma estrutura em relação aos arquivos bastante versátil. Existem dois
métodos para se executar Csound, podemos usar o modelo de dois arquivos-fonte ou o
modelo de um único arquivo-fonte. 
Nesse primeiro contato com o programa, para entendermos melhor como ele
funciona, iremos usar o modelo de dois arquivos-fonte separados. Nesse modelo são
usados dois arquivos para que o Csound renderize um arquivo de saída de áudio, esses
dois arquivos são o arquivo de orchestra, que contém as definições dos instrumentos, e o
arquivo de score, que contém a “partitura” da música, com suas notas, durações,
intensidades, etc. O arquivo de saída é do tipo .wav ou  .aiff, para execuções que não são
em tempo real, ou a saída é diretamente nos alto-falantes, quando não especificarmos um
arquivo de saída.
Convencionalmente quando vai-se executar o Csound com esses dois arquivos-
fonte, é usado o mesmo nome para ambos, diferenciando-os pelas extensões  .orc para o
arquivo orchestra e .sco para o arquivo score. Por exemplo, se quisermos o arquivo de
saída  seno.wav a partir dos arquivos seno.orc e seno.sco, digitaremos algo como:
csound –o seno.wav seno.orc seno.sco
 
Com a opção –o dizemos qual arquivo de saída desejamos, nesse caso o arquivo
de saída será seno.wav, e em seguida dizemos qual o arquivo-fonte da orchestra,
seno.orc, e o arquivo-fonte do score, seno.sco..
Nesse primeiro exemplo queremos apenas produzir uma onda de seno na
frequência do Lá do diapasão, 440Hz, e através do exemplo poderemos ver como os
arquivos de orchestra e score conversam entre si, para produzir o arquivo de saída. Aqui
o arquivo score dirá:
1.
A forma de onda inicial a ser usada, nesse caso uma senóide.
2.
O instrumento a ser usado em cada nota
3.
O tempo de início de cada nota
4.
A duração de cada nota
Como você pode ver, o arquivo de score fornece os parâmetros que o arquivo de
orchestra usará, e o arquivo de orchestra define como esses parâmetros serão usados para
efetivamente gerar o som de saída. Aqui está o arquivo de score com sua sintaxe:
/* seno.sco */
; 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
i 1 0 2
e
/* seno.sco */
Fig. 1: seno.sco, o arquivo score para uma senóide
A sintaxe do arquivo score
Na fig.1 temos os comentários entre “/*” e “*/”, ou após “;”. Na terceira linha
temos o que é chamado de f-table, ou function table,  que é uma tabela indicando a forma
de onda que os instrumentos poderão usar mais tarde. Nesse caso essa tabela conterá os
valores para a onda de seno. A sintaxe de uma f-table é:
f índice  tempo de início  tamanho  GEN#  parâmtro1 parâmetro2 ...
     Na Fig.1 temos essa sintaxe na linha:
f 1 0 16384 10 1
Então olhando para a linha acima podemos ver que a f-table tem índice 1, é
carregada após 0 segundos, tem o tamanho de 16384 amostras (ou pontos), usa a rotina
GEN10 para gerar a onda que será armazenada na tabela, e tem o número 1 como
primeiro parâmetro para a GEN10.
Todas as f-table como a acima são preenchidas com formas de onda gerada pelas
rotinas GEN do Csound, que neste presente momento vão de GEN1 até GEN52, e para
usá-las basta especificar o seu número no quarto parâmetro da declaração da f-table. Cada
rotina GEN gera uma forma de onda diferente. As mais importantes, GEN1 e GEN10,
respectivamente carregam um arquivo de áudio ou senóides em uma tabela. Estamos
portanto usando a GEN10 no exemplo acima para preencher os 16384 pontos da f-table
com os valores do seno. O parâmetro 1 que vem após o 10 diz que deve ser usada apenas
uma onda de seno na tabela, e não vários harmônicos sobrepostos.
Vale ressaltar que o tamanho das f-tables são sempre em potências de 2, i.e.,
1024, 2048, 4096, 8192, 16384 pontos, etc.
Após as declarações das f-tables temos a sintaxe da declaração de nota, que é:
; p1
  p2      p3       p4
p5
i número do instrumento  início  duração  parâmetro1  parâmetro2  ...
Novamente na Fig.1 temos essa declaração na linha:
i 1 0 2
Portanto na sexta linha da Fig.1 temos que o instrumento 1 será tocado por 2
segundos, começando em 0 segundos, imediatamente no início da música.
Finalmente a letra “e” indica que chegamos ao final do arquivo score. Vejamos
agora como essas declarações serão usadas no arquivo de orchestra, onde o som é
produzido.
A sintaxe do arquivo orchestra
Na fig. 2 temos a listagem do arquivo orchestra, que será usado em conjunto
com o arquivo score visto acima,  para nosso primeiro instrumento:
/* seno.orc */
; Inicializa as variáveis globais.
sr = 44100
kr = 4410
ksmps = 10
nchnls = 1
; Instrumento #1.
instr 1
  ; Amplitude do sinal
  kamp = 30000
  ; Frequência
  kcps = 440
  ; Número da f-table.
  ifn = 1
  ; Toca com amplitude 30000 e frequência de 440 Hz a onda do seno
  ; armazenada na tabela 1.
  a1 oscil kamp, kcps, ifn
  
  ; Manda o som armazenado em a1 para o arquivo de saída, seno.wav 
  out a1
endin
/* seno.orc */
Fig. 2 : seno.orc o arquivo orchestra para uma senóide
A listagem começa com o cabeçalho, presente em todo aquivo orchestra. Aqui
declaramos as variáveis globais sample rate (taxa de amostragem) como sr = 44100
amostras por segundo, kontrol rate (taxa de controle) como kr = 4410 amostras por
segundo, e a razão sample rate dividido por control rate como ksmps = 10, e finalmente
declaramos o número de canais como nchnls = 1, ou seja, o som será mono.
O Csound faz uma diferença entre taxa de amostragem sr e taxa de controle kr.
A taxa de amostragem sr é a quantidade de vezes por segundo que pontos de uma tabela
são gerados para produzir o áudio da onda contida nessa tabela. A taxa de controle kr é a
quantidade de vezes por segundo que uma onda é modificada em um instrumento,
tipicamente bem menor que a taxa de amostragem. Finalmente em ksmps temos a razão
entre sr e kr
Então não precisamos que a cada ponto lido da tabela essa onda seja alterada,
mas como no exemplo acima, essa onda pode ser modificada a cada 10 pontos lidos, já
que a taxa de modificação kr é a taxa de controle que é 10 vezes menor que a taxa de
amostragem, o que economiza em muito o processamento da onda e não afeta a
percepção de quem ouve.
As variáveis usadas na orchestra podem ser estáticas ou dinâmicas, locais ou
globais,  dependendo do prefixo que possuem. Veremos em mais detalhes a seguir o que
isso significa. No nosso aquivo orchestra temos o opcode oscil usado como:
a1 oscil kamp, kcps, ifn
No Csound as variáveis podem ter qualquer nome, mas devem sempre começar
com os prefixos “k”,” a”, i”, ou “g”, e isto tem significado para o interpretador.
As variáveis com o prefixo “i”, como em ifn, tem espaço para apenas um valor,
isto é, não são tabelas. É uma variável tradicional, como em outras linguagens de
programação.
Variáveis com o prefixo “k”, como em kamp, são variáveis dinâmicas que são
atualizadas automaticamente com a frequência da taxa de controle, em nosso exemplo ela
é lida 4410 vezes por segundo, avançando um ponto na variável a cada leitura. Essas
variáveis são ditas k-rate, pois seguem a taxa de controle, como no exemplo de kr =
4410. Tecnicamente essas variáveis são simples tabelas, e Csound avança lendo kr
pontos dessa tabela por segundo, e elas são criadas com tamanho suficiente para durar
durante toda a nota, fornecendo novos pontos. São normalmente usadas para controlar e
modificar parâmetros de uma onda, como por exemplo alterando a amplitude dessa onda
ao longo da duração da nota. Aqui kamp não tem um valor fixo, mas pode ser uma tabela
com valores entre 0 e 30000. Então o oscilador irá reproduzir uma onda que começa com
amplitude 0 e cresce até a amplitude final 30000.
Variáveis com o prefixo “a”,  como em a1, são variáveis dinâmicas do tipo a-
rate, e são similares às variáveis k-rate, mas são atualizadas segundo a taxa de
amostragem, em nosso exemplo, na taxa de sr = 44100 vezes por segundo. Pela sua
elevada fidelidade de som e alto custo computacional, são usadas apenas para sinais de
áudio, ou o sinal final que viremos a ouvir. 
Podemos ainda multiplicar, por exemplo, uma váriável k-rate de 100 pontos
por uma variável a-rate de 1000 pontos, e elas gerarão uma variável a-rate como uma
tabela de 1000 pontos modificada a cada 10 pontos. 
Todas essas váriáveis são locais e existem apenas dentro do instrumento. Se
quisermos que uma variável seja global e vista por todos os instrumentos, devemos
declará-la no cabeçalho da seção orchestra, e usar o prefixo “g” antes de qualquer outro
prefixo. Nossas variáveis usadas acima ficariam então gifn, gkamp e ga1, e deveriam
estar definidas no cabeçalho da orchestra.
Logo depois do cabeçalho vem a declaração de início do nosso primeiro
instrumento com a palavra-chave instr seguida do número do instrumento, nesse caso 1.
Por questão de legibilidade usamos aqui uma boa prática: definimos os
parâmetros kamp, kcps e ifn como variáveis antes de usá-los no opcode oscil. O
opcode oscil tem como parâmetros respectivamente a amplitude, a frequência e a forma
de onda a ser usada. Como vimos antes em oscil os parâmetros kamp e kcps são
variáveis de controle, e ifn é um parâmetro de inicialização.  
No arquivo orchestra vemos que a amplitude foi definida como 30000, a
frequência como 440 Hz e a forma de onda é indicada através do índice 1 da f-table.
Como já armazenamos no arquivo score uma senóide na f-table 1, o opcode oscil aqui
apenas processará essa forma de onda para ter amplitude 30000 e frequência 440 Hz, uma
nota de Lá no diapasão. No lado esquerdo a onda de saída é armazenada na variável  a1.
Na linha seguinte o opcode out grava a onda armazenada em a1 no arquivo de
saída especificado na linha de comando, seno.wav, ou manda o sinal diretamente para as
caixas de som, se nenhum arquivo de saída fôr especificado na linha de comando.
Finalmente no arquivo orchestra temos a declaração de fim de instrumento, endin.
Então ao executarmos esses dois arquivos obteremos um arquivo seno.wav que
contém o som de uma senóide a 440 Hz tocada por 2 segundos. Apesar da simplicidade
desse primeiro exemplo, ele teve o propósito de esclarecer várias questões em relação ao
que é feito no arquivo score e no arquivo orchestra. Note que o mesmo arquivo orchestra
pode ser usado para vários arquivos scores diferentes, um mesmo instrumento tocando
várias partituras diferentes.
Como dito acima em oscil os parâmetros kamp e kcps são dinâmicos, isso quer
dizer na terminologia do Csound que eles são parâmetros de performance, ou seja, podem
ser mudados em tempo de execução. O outro tipo possível de parâmetros são os
parâmetros de inicialização, que podem ter apenas um valor e são definidos assim que a
nota é iniciada. No caso de oscil, o parâmetro ifn é de inicialização.
Integrando os arquivos orchestra e score: o arquivo unificado .CSD
Falamos no início do capítulo que havia duas maneiras de executar o Csound:
com dois arquivos-fonte orchestra e score separados, ou com um único arquivo-fonte.
Vamos ver agora a segunda maneira.
À primeira vista o uso de arquivos orchestra e score é bastante intuitivo, pois
são isolados as duas principais etapas de renderização do Csound. Entretanto o uso
constante do programa, fez com que fôsse desenvolvido o formato de um único arquivo,
com seções para a orchestra e para o score, tornando-se assim um formato mais compacto
e fácil de se organizar quando se tem muitos arquivos.
Trata-se do formato .CSD, que contém em um só arquivo três seções:
CsOptions para opções de linha de comando, CsInstruments, para os instrumentos que
eram armazenados no arquivo orchestra, e CsScore, a seção que conterá o que era
armazenado no arquivo score. Assim, nosso exemplo anterior seno.orc e seno.sco se
tornariam um só arquivo CSD, como vemos na figura 3:
<CsoundSynthesizer>
<CsOptions>
-o seno.wav
</CsOptions>
<CsInstruments>
; Inicializa as variáveis globais.
sr = 44100
kr = 4410
ksmps = 10
nchnls = 1
; Instrumento #1.
instr 1
  ; Amplitude do sinal
  kamp = 30000
  ; Frequência
  kcps = 440
  ; Número da f-table.
  ifn = 1
  ; Toca com amplitude 30000 e frequência de 440 Hz a onda do seno
  ; armazenada na tabela 1.
  a1 oscil kamp, kcps, ifn
  
  ; Manda o som armazenado em a1 para o arquivo de saída, seno.wav 
  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
i 1 0 2
e
</CsScore>
</CsoundSynthesizer>
Fig.3: seno.csd, nosso primeiro arquivo csd, nesse caso a versão exata em seno.csd dos
arquivos anteriores seno.orc e seno.sco.
Note que além da orchestra e do score ficarem encapsulados nas seções
CsInstruments e CsScore, agora a nossa antiga opção de linha de comando “-o
seno.wav” fica dentro da seção CsOptions, e nossa linha de comando para executar o
arquivo se reduz para:
csound seno.csd
Daqui para frente usaremos apenas arquivos CSD, mas tenham em mente que
muitos usuários ainda usam os formatos orchestra e score, e esse formato é compatível
com qualquer versão de Csound.
No arquivo anterior seno.csd as únicas informações que passamos do score para
a orchestra são o número do instrumento, o tempo de início da nota e sua duração. Esses
três parâmetros são obrigatórios em qualquer score, e são referenciados na seção
orchestra respectivamente por p1, p2 e p3. Assim se quisermos que uma variável idur
contenha a duração da nota que está sendo executada, basta declarar dentro da seção
orchestra a linha:
idur = p3
Esses três primeiros parâmetros são reservados pelo Csound, assim p1 sempre é
o número do intrumento, p2 o tempo de início da nota em segundos e p3 a duração em
segundos. Mas podemos definir qualquer número de parâmetros adicionais, começando
por p4.
Em seno.csd definimos a frequência do oscilador dentro da seção orchestra
através da declaração kcps = 440. Seria melhor se nosso instrumento pudesse tocar
qualquer frequência, e pudéssemos especificar essa frequência na seção score, dando uma
frequência diferente a cada nota do instrumento. 
Até aqui temos usado sempre a frequência fixa de Lá 4, isto é, 440 Hz, mas
usaremos agora a frequência como um parâmetro dado pelo score. Se tornaria muito
trabalhoso definir as notas musicais pela frequência em Hertz, então usaremos o
conversor de valores cpspch, que tem como parâmetro a nota em octave-point-pitch-
class, que é um formato intuitivo para definir notas.
Nesse formato valores inteiros como 7.00, 8.00, 9.00 definem a oitava em que
se está, e as duas casas decimais definem a nota dentro da oitava. Temos por exemplo que
7.00 é o Dó central (C3), e que 7.01 é o Dó sustenido nessa oitava (C3#), e 7.02 é o Ré
(D3), e etc. Assim cada centésimo a mais corresponde a um semitom acima, e portanto
nesse exemplo para cobrir as doze notas dessa oitava haverá a variação entre 7.00 e 7.11.
Pode-se especificar também milésimos como 7.015 para a nota um quarto de tom entre
C#3 e D3, em composições microtonais. 
Veja como ficará nosso arquivo cpspch.csd, usando essa notação para diferentes
notas renderizadas pelo instrumento. Usando a notação octave-point-pitch-class
tocaremos a escala de Dó Maior em nosso oscilador, e dentro da orchestra faremos a
conversão dessa notação em Hertz usando cpspch.
<CsoundSynthesizer>
<CsOptions>
-o cpspch.wav
</CsOptions>
<CsInstruments>
; Inicializa as variáveis globais.
sr = 44100
kr = 4410
ksmps = 10
nchnls = 1
; Instrumento #1.
instr 1
  ; Amplitude do sinal
  kamp = 30000
  ; Frequência especificada pelo score
  kcps = cpspch(p4)
  ; Número da f-table.
  ifn = 1
  ; Toca com amplitude 30000 e frequência dada pelo score a onda do seno
  ; armazenada na tabela 1.
  a1 oscil kamp, kcps, ifn
  
  ; Manda o som armazenado em a1 para os alto-falantes 
  out a1
endin
</CsInstruments>
<CsScore>
; Tabela #1: uma simples onda de seno usando GEN10.
f 1 0 16384 10 1
; Toca o instrumento #1 com cada nota durando um décimo de segundo e 
; percorrendo toda a escala de Dó maior.
i 1 0 0.1 8.00
i 1 0.1 0.1 8.02
i 1 0.2 0.1 8.04
i 1 0.3 0.1 8.05
i 1 0.4 0.1 8.07
i 1 0.5 0.1 8.09
i 1 0.6 0.1 8.11
i 1 0.7 0.1 9.00
e
</CsScore>
</CsoundSynthesizer>
Fig. 4: cpspch.csd