MAC 337/5900 - Computação Musical
Aula 16 - 4/10/7
Capítulo 3 (continuação)
Operações em Fluxos de Controle
- Vimos na aula passada como converter fluxos de áudio em fluxos de controle (p.ex., snapshot) e vice-versa (p.ex., sig~).
- Mas há quatro tipos de operações que podem
ser aplicadas em fluxos de controle que não possuem paralelo em
fluxos de áudio:
- atraso (delay)
- Fig. 3.10: atraso simples (sem buffer) ou composto (com buffer)
- combinação (merging)
- Fig. 3.11b: note que dois eventos podem ocorrer no mesmo instante: são seriados
- poda (pruning)
- remover seletivamente alguns elementos, filtrar
- Fig. 3.11c: só deixa passar os eventos com número associado positivo
- ressincronização (resynchronizing)
- os valores de um fluxo de entrada são joagados para a
saída em instantes determinados por um segundo fluxo de entrada
- Fig. 3.11d
- A Fig. 3.12 mostra exemplos destes 4 tipos de controle no Pd.
- Objetos del ou delay permitem
a definição de um atraso em milissegundos no argumento de
criação ou na entrada direita.
- O atraso é simples, ou seja, se um novo evento entra
no objeto enquanto um atraso está sendo processado, o evento
antigo é descartado e apenas o novo é processado.
- Estes objetos jogam apenas bangs para a saída.
- O objeto pipe implementa um atraso composto, ou seja, novos eventos não descartam os antigos, como num pipe UNIX.
- Além disso, eles também permitem jogar mensagens para a saída e não apenas bangs.
- Filtragem é realizada com vários objetos como, por exemplo,
- moses recebe valores
na entrada esquerda; joga para a saída esquerda os
valores menores do que o determinado na entrada direita e joga
para a saída direita os demais.
- select ou sel jogam para saída um bang apenas se o valor selecionado é enviado em sua entrada.
- ver exemplos na Ajuda do Pd.
- Ressincronia é feito por quase todos objetos Pd que possuem várias entradas.
- A Fig. 3.12d mostra um exemplo disso usando o objeto float que armazena um número em ponto flutuante.
- Usando tudo isso, podemos agora construir um bom sintetizador MIDI monofônico:
- C10.monophonic.synth.pd, também mostrado na Fig. 3.16 é um sintetizador MIDI monofônico que usa os seguintes objetos:
- notein que recebe uma nota MIDI do hardware correspondente e joga para saída seus valores
- stripnote que filtra as mensagens de noteoff deixando passar apenas as demais
- trigger que copia uma mensagem, distribuindo-a para suas várias saídas
- sel para descobrir se é note on ou note off
- select para verificar se o pitch do note off é o mesmo que acabou de chegar do notein
Capítulo 4 - Automação e gerenciamento de vozes
- Até agora, sempre tratamos cada evento isoladamente.
- Mas, muitas vezes, queremos trabalhar com agregados de eventos e não eventos isolados.
- Por exemplo, podemos querer ter várias notas num acorde, ou um timbre composto por vários formantes.
- Este capítulo estuda duas formas de automatizar o
tratamento de agregados: geradores de envoltórias que tratam
agregados ao longo do tempo e bancos de vozes que lidam com os
elementos do agregado simulataneamente.
Geradores de Envoltórias
- Às vezes são também chamados de geradores de transientes, transições.
- O mais famoso deles é o ADSR para controlar a amplitude de uma nota ao longo do tempo.
- A Fig. 4.2 mostra várias possibilidades que surgem quando
usamos geradores de envoltória ADSR associados a apertar (on) ou
soltar (off) a nota de um teclado musical, por exemplo.
- Além de controlar a amplitude, é comum usar
envoltórias para controlar a variação do timbre ao
longo da duração de cada nota.
Variação linear vs. logarítmica vs. de 4a ordem
- Ao implementar a conversão do gráfico ADSR para a amplitude do som em si é preciso notar uma coisa:
- a nossa percepção do som não é linear com a amplitude.
- Portanto, se fizermos um mapeamento linear nossa
percepção não será linear, o som
demorará mais a subir.
- f1(x) = x (linear, ruim)
- f2(x) = 102(x-1) (linear em dB, melhor)
- f3(x) = x4 (melhor de todos segundo Puckette)
- ver diferenças na Fig. 4.3
- A Fig. 4.4 introduz o diagrama para denotar uma
função de transferência, ela pode ser implementada
através de um cálculo aritmético ou através
de uma consulta a uma tabela.
Mudanças de controle Contínuas vs. Descontínuas
- Em alguns momentos, é interessante que as mudanças
de controle sejam contínuas (por exemplo,
variações na amplitude, caso contrário teremos
cliques).
- Em outros momentos, é mais interessante termos
mudanças abruptas (p.ex., a freqüência das notas em
uma melodia).
- Em alguns casos, não é nem possível fazer
uma mudança contínua de um valor para outro (p.ex. ao
trocar o a tabela de forma de onda de um oscilador baseado em tabela).
- Quando ocorrem mudanças repentinas, muitas vezes é necessário mascará-las.
- Há duas técnicas usadas nestes casos muting e switch-and-ramp.
- Uma técnica comumente usada para isso é introduzir uma curva de silenciamento (muting) no ponto da mudança descontínua como mostrado na Fig. 4.5.
- Nesta técnica, normalmente uma curva de silenciamento de cerca de 5ms funciona bem.
- Já a técnica de "troque-e-rampeie" (switch-and-ramp) consiste em tentar sintetizar uma descontinuidade oposta àquela que está ocorrendo.
- A Fig. 4.6 mostra um exemplo desta técnica aplicada a um som percussivo que começa no meio de outro.
- A Fig. 4.7 mostra como a técnica pode ser implementada.
- na figura, "..." é um algoritmo de síntese
qualquer que desejamos interromper repentinamente e fazer
recomeçar do zero. Usamos o ADSR da direita para cancelar a
descontinuidade e a inicializamos com -x onde x é o
último valor da saída.
Polifonia e Bancos de Vozes
- Em música, polifonia significa várias vozes soando
simultaneamente, normalmente em alturas diferentes, às
vezes com timbres diferentes.
- Na música eletrônica, muitas vezes polifonia
significa manter várias cópias de um mesmo processo de
síntese funcionando em paralelo. Chamamos estas cópias de
vozes.
- Usando esta linguagem, o piano é um instrumento polifônico com 88 vozes.
- No piano, cada voz é capaz de tocar apenas uma nota e cada nota é tocada por apenas uma voz.
- Já em instrumentos eletrônica, há mais flexibilidade, a mesma voz pode tocar notas diferentes.
- E surge uma complicação extra pois uma mesma nota
pode ser tocada por mais de uma voz, é necessário
decidir, às vezes dinamicamente, qual será a voz a tocar
cada nota.
- Programas que fazem processamento em lote como CSound, em geral alocam 1 voz para cada nota da peça.
- Em sistemas de tempo real, como MAX e Pd, normalmente se pré-aloca um Banco de vozes.
- O sistema então aloca dinamicamente para as vozes do banco a geração de cada uma das notas da peça.
- Este processo é ilustrado na Fig. 4.8
- Precisamos então de um Algoritmo de alocação e vozes como ilustrado em 4.9.
- Aparecem problemas quando o número de notas que o
"controle" pede para tocar é maior do que o número de
vozes.
- Neste caso o algoritmo precisa tomar uma decisão (chamada de "roubo de voz").
- Na Fig. 4.10, a decisão é interromper a nota mais antiga ainda ativa.
Rótulos nas Vozes
- Vimos que as tarefas de síntese de som são
distribuídas para as vozes por um algoritmo de
alocação (escalonamento).
- Mas e se precisamos cancelar uma tarefa ou alterá-la de alguma forma, como descobrir qual voz está processando-a.
- Isso é resolvido adicionando rótulos às tarefas (notas tocadas pelas vozes).
- Exemplos:
- Uma representação que não usa rótulos:
- start-time end-time pitch ...
1 3 60 ...
2 8 62
4 6 64
5 8 65
- Uma representação que usa rótulos:
- time tag action parameters
1 a start 60 ...
2 b start 62 ...
3 a end
4 c start 64 ...
5 d start 65 ...
6 c end
8 b end
8 d end
Encapsulamento (aninhamento) em Pd
- Os exemplos deste capítulo usam bastante o mecanismo de aninhamento de Pd que permite a criação de subpatches.
- O mecanismo permite não só lidar melhor com a
complexidade, organizando melhor o código mas também a
reutilização de um mesmo subpatch várias vezes no
mesmo patch, como se fossem várias instâncias da mesma
classe.
- Subpatches podem ser de 2 tipos
- one-off que são usados apenas naquele patch e são armazenados no mesmo arquivo.
- são criados digitando-se "pd nome-do-subpatch" dentro de uma caixa de objeto.
- abstractions que são gravadas em outro arquivo .pd no mesmo diretório.
- Chamamos de pai (parent) o patch no qual um subpatch está inserido.
- Eles podem ter
- entradas definidas com as caixas inlet e inlet~ e
- saídas, definidas com as caixas outlet e outlet~
- argumentos de criação que podem ser referenciados como $1, $2, $3, etc.
- note que os argumentos são processados apenas quando a caixa é criada.
- Isso tudo é mostrado no exemplo da Fig. 4.11
- Em um dado subpatch, pode-se definir a propriedade "graph on
parent" que faz com que as suas caixas de controle sejam mostradas no
pai também.
Exemplos
- D02.adsr.pd é um exemplo de envoltória ADSR usando um subpatch do tipo abstração.
- D03.envelope.dB.pd é a mesma coisa mas usando
envoltória mapeado com logarítmico, o que dá
melhor resultado.
- D04.envelope.quartic.pd compara envelopes lineares e de 4a ordem em termos de amplitude e freqüência.
- D05.pitch.envelope.pd mostra como o objeto adsr pode ser usado
com alturas também. Neste caso pode-se pular abruptamente para o
início da envoltória jogando um valor negativo na entrada
do objeto.
- D06.envelope.portamento.pd mostra como implementar portamento, ou
seja, cada nota é ligada na seguinte através de um
glissando. É assim que vários instrumentos
acústicos e a voz humana funcionam.
- D07.additive.pd usa síntese aditiva para simular o som de um sino usando a técnica de Jean-Claude Risset (pesquisador do IRCAM).
- D08.table.spectrum.pd usa um banco de 30 osciladores para gerar um som com um espectro que pode ser desenhado.
Referência
Próxima Aula
Página de MAC
337/5900
Página do Fabio
Página do
DCC