Desenhar música: dança de caixão no Pure Data

Programação e Memes


A programação é um processo à beira da ciência e da criatividade. Sem um programa bem projetado, um computador é uma unidade desamparada que gasta eletricidade. A maioria dos especialistas modernos trabalha com linguagens simbólicas declarativas - eles criam programas a partir de comandos de texto: simples - atribuição, multiplicação; e condições de verificação complexa, executando rotinas em um loop.

Mas nem todas as linguagens de programação são projetadas para resolver problemas do sistema. Alguns são criados para treinamento, apresentações e shows digitais. Quando o desempenho e a funcionalidade aparecem em segundo plano, surgem soluções originais, como o ambiente de programação visual Pure Data.

Em 2020, a dança do vídeo arquivado da cerimônia fúnebre da agência Dada awu do Gana se tornou o meme mais popular da Rússia. Hoje, temos que recriar passo a passo o lendário tema musical Coffin Dance, usando o ambiente da descrição sonora algorítmica Pure Data.

Sobre programação visual


Por programação visual, é habitual entender o processo de descrição de um programa para um dispositivo de computação usando elementos gráficos funcionais. Portanto, o uso do designer de formulário WPF no ambiente de desenvolvimento do Visual Studio pode ser chamado de programação visual da interface. Os designers gráficos apareceram junto com os primeiros computadores pessoais. Agora, nas aulas de ciência da computação, o Visual Pascal está sendo estudado em algumas escolas. e metade das melhorias padrão em 1C pode ser feita sem escrever uma linha de código.

Porém, os ambientes de programação visual completos apareceram mais tarde. Quando se trata de criar uma linguagem de programação que consiste apenas em comandos gráficos, surgem várias dificuldades, por causa das quais a funcionalidade da própria linguagem deve ser reduzida.
Portanto, várias chamadas do mesmo subprograma em diferentes partes do código C ++ são naturais para o programador. Em um ambiente gráfico, uma chamada de sub-rotina pode ser representada, por exemplo, por uma seta de um objeto no texto do programa principal para uma sub-rotina de objeto e, quando houver muitas dessas setas, o código gráfico se torna ilegível. Os desenvolvedores de ambientes de desenvolvimento educacional geralmente impõem um limite (no número de chamadas, objetos no programa, variáveis ​​usadas) para proteger o usuário e tornar o processo de programação visual mais visual.
Um exemplo de um programa Sanscript simples:

imagem

Mas se você se distrair da programação em sentido amplo, poderá encontrar importantes problemas aplicados que são resolvidos graficamente de maneira mais conveniente e eficiente do que em simbólicos. Uma dessas tarefas: uma descrição dos instrumentos virtuais. Nos anos 80 do século passado, a maioria das gravações musicais foi feita ao vivo. Os sintetizadores digitais eram inferiores em qualidade sonora aos instrumentos acústicos, e os sistemas digitais verdadeiramente "musicais" eram caros.

Tudo mudou com a introdução da tecnologia VST, introduzida em 1996 como uma biblioteca volumosa para trabalhar com som. Funcionalidade O VST nos permitiu descrever a arquitetura de sintetizadores digitais reais, processadores de efeitos e emular com muito precisão seu trabalho em um computador. No entanto, apenas uma equipe de programadores qualificados e engenheiros de som poderia criar essa descrição. A questão de criar instrumentos virtuais personalizados permaneceu em aberto.

Naqueles mesmos anos, na tentativa de popularizar a síntese sonora entre amadores, apareceu o projeto experimental Pure Data - um ambiente de desenvolvimento visual focado na descrição de sintetizadores simples. Around Pure Data, um pequeno grupo de "fãs" formados que promoveram a programação visual no FB, Youtube: eles escreveram e traduziram materiais de treinamento, publicaram exemplos de sintetizadores e mixagens de músicas inteiras em um patch (este é o nome do programa Pure Data por analogia com os patches em sintetizadores de hardware modulares ) Mas o meio ambiente não recebeu ampla distribuição no mundo.

Fundamentos de dados puros


O ambiente de desenvolvimento Pure Data pode ser baixado gratuitamente no site oficial. O programa distribui código-fonte aberto e está disponível para usuários do Windows, Linux e MacOS X. Instale e execute o Pure Data. No menu Arquivo, crie um novo patch. A seguinte janela de edição será exibida:

imagem

O menu Put contém uma lista de objetos gráficos a partir dos quais faremos nosso primeiro sintetizador. Após selecionar o item apropriado, o elemento é adicionado ao campo gráfico (Tela) do patch atual. Os elementos podem ser editados (altere a assinatura, que afeta seu comportamento, bem como movidos) e conectados por linhas (mantendo o botão esquerdo do mouse em uma das saídas do objeto de origem, movendo o cursor para a entrada do objeto de destino e liberando-o). Por exemplo, criaremos um elemento do tipo "Objeto" com a chave de nome e um elemento do tipo "Número". As entradas do elemento são destacadas em preto e localizadas acima do quadro do próprio elemento, e as saídas estão abaixo dele. Conecte a saída do objeto-chave à entrada do elemento Number.
Nós temos:

imagem

Todo esse tempo estávamos no modo de edição de patches. Para entrar no modo de execução, vá para o menu Editar e desmarque o item Modo de edição. O ponteiro do mouse no contorno deve mudar da mão para a seta. Agora pressione qualquer tecla no teclado principal. Veremos como o valor de Number muda quando pressionado:

imagem

Vamos analisar o resultado do patch. Depois de atribuir a chave de nome ao objeto, ele possui uma saída, mas nenhuma entrada. Um objeto com esse nome ouve o teclado e envia um código de tecla cada vez que é pressionado em tempo de execução. O elemento Number tem uma entrada e uma saída. Tomando um número como entrada, Number o exibe na tela e envia o mesmo valor para a saída. Observe que, após soltar a tecla, o número continua sendo exibido. Isso mostra que as entradas mantêm o último valor que aceitam.

Volte ao modo de edição e adicione outro objeto chamado sel 49. Ele terá duas entradas e duas saídas. Este objeto envia um sinal para a primeira saída cada vez que um valor chega a uma das entradas e corresponde ao valor armazenado na outra entrada. Se a entrada receber um valor diferente do acumulado, o sinal será enviado para a segunda saída. A primeira parte do nome sel especifica o tipo de objeto, o segundo 49 - grava o valor padrão para a segunda entrada. 49 é o código da chave "1".

Um sinal é um tipo de dados especial que não pode ser simplesmente emitido, por exemplo, enviando Number para a entrada. Mas com a ajuda de sinais, você pode "iniciar" o trabalho de alguns elementos.

Volte ao menu Put e adicione o elemento Bang ao nosso patch. Conecte a saída Number à primeira entrada do sel 49 e a primeira saída do sel 49 à entrada Bang. Receberemos o seguinte patch:

imagem

Passaremos para um modo de execução. Pressionando várias teclas, seus códigos aparecerão. Quando você pressiona a “tecla especial” com o código 49, o objeto sel gera um

imagem

único sinal que, ao pressionar o botão estrondo, o pressiona automaticamente: O objeto estrondo gera um sinal em sua única saída quando é pressionado no modo de execução, o sinal ou valor chega à entrada. Adicione um pouco de som ao nosso projeto. Para que o patch funcione corretamente com dados de áudio, o menu Mídia deve ter uma marca de seleção oposta ao item DSP On. Você também precisará entrar no menu Midi Settings e instalar o dispositivo de saída. No Windows:

imagem

Clique em OK e retorne ao modo de edição. Para trabalhar com sinais Midi, dois elementos são usados ​​com mais frequência: objetos makenote e noteout. Adicione um desses objetos e também crie várias mensagens de mensagem com os seguintes valores:

imagem

Mensagem é um elemento da programação visual com comportamento complexo. Se a mensagem for chamada de um determinado número, clicando na mensagem ou após o recebimento de um sinal em sua entrada, em ambos os casos, esse número e sinal serão emitidos simultaneamente.

O objeto de anotação, quando recebe o valor na primeira entrada, gera som em um dos canais MIDI. O número do canal pode ser indicado explicitamente no nome do objeto (no nosso caso 1 - piano) ou transferido para a terceira anotação de entrada. A primeira entrada faz o tom em termos de midi: (60 - é a primeira oitava e, em seguida, +1 - um aumento por meio-tom, -1 - uma diminuição por meio-tom) e a segunda - uma descrição da nota: volume, duração, natureza da produção sonora.
O objeto makenote recebe o tom na primeira entrada e no segundo volume (0 - silêncio, 127 - volume máximo) converte o tom na primeira saída e gera uma descrição da nota para a segunda anotação na segunda saída. Os valores padrão para as primeira e segunda entradas makenote são especificados imediatamente após o nome do objeto. Conecte os elementos como mostrado na figura e vá para o modo de execução:

imagem

Quando você clica em uma mensagem, uma nota deve soar correspondente à afinação no nome da mensagem. 60 - nota para, 62 - re, 67 - la. Agora, no modo de edição, conecte a primeira saída do seletor (objeto sel) com a mensagem 60. Adicione mais 2 seletores com códigos para as teclas 2 e 3 no teclado e obtenha o sintetizador mais simples:

imagem

Pressionar as teclas 1-3 no makenote enviará uma mensagem com o tom apropriado e uma nota será tocada. Na próxima seção, tentaremos descrever uma melodia complexa que será tocada seqüencialmente nota a nota ao enviar apenas um sinal.

Recriando a dança do caixão


Música


Para descrever uma melodia complexa, precisamos estudar 2 objetos importantes - metro ef, bem como vários objetos auxiliares. Considere um exemplo simples:

imagem

O objeto metro possui duas entradas. O primeiro sinal é recebido. Qualquer sinal diferente de parar inclui um metrônomo. Para desativar, use o sinal de saída da mensagem com a parada de texto. A segunda entrada, metro, recebe um intervalo em milissegundos. Quando o metrônomo é ativado, ele envia imediatamente um sinal para sua única saída e reenvia o sinal a cada n milissegundos. O intervalo n pode ser especificado pelo valor padrão no nome do objeto ou transferido para a segunda entrada. Depois de entrar no modo de execução, podemos iniciar o metrônomo com o botão acima e ver como o botão abaixo é pressionado a cada 0,4 segundos. Ao enviar uma mensagem com um novo intervalo, aceleraremos ou desaceleraremos a frequência de envio de sinais. Depois que a mensagem de parada é enviada, a sinalização para.

Lembre-se da música de Coffin Dance:


A melodia principal pode ser descrita por uma sequência de 64 notas e pausas da 8ª duração, ou seja, às 8 medidas em 4/4. Portanto, precisamos organizar o envio cíclico dos 64º sinais para as mensagens de notas correspondentes. Para fazer isso, use o objeto f.

F - de flutuação - representa uma variável real. O objeto f tem duas entradas. Na segunda entrada, você pode enviar um valor numérico (por exemplo, da saída da mensagem ou da saída de Number), que é escrito como o valor da variável. O valor padrão é 0. Com a primeira entrada e saída, as coisas são um pouco mais complicadas. Considere um exemplo:

imagem

Então, encontramos uma conexão mágica entre os memes "Pressione F para prestar respeito" e "dança do caixão". Vamos mudar para o modo de execução. Quando você clica na mensagem 3, o valor será gravado na variável de objeto f, mas em número não veremos isso. Se você enviar o sinal para a primeira entrada f com o botão bang, o que acontece em termos de Pure Data é uma iteração, a saber:

  • A saída f enviará o valor atual da variável (3)
  • O objeto + 5 receberá o número 3 na primeira entrada e retornará a soma de duas entradas 8 (aqui o valor na segunda entrada é definido por padrão após o nome + objeto de adição)
  • O objeto% 40 receberá o número 8 na primeira entrada e retornará o restante da divisão da 8ª por 40 (o valor da segunda entrada é definido por padrão)
  • A variável f receberá o valor (3 + 5)% 40 = 8 na segunda entrada.A iteração está concluída

Assim, após a primeira iteração, vemos o valor 3 no número de entrada e tem um valor real de 8 para a variável f. Na próxima iteração, o número receberá os oito salvos anteriormente, e f aumentará em mais 5 e assumirá o valor 13. Quando se trata de iteração com a saída 38, obtemos o valor (38 + 5)% 40 = 3 para a variável f. Assim, os valores f e os valores de saída serão repetidos ciclicamente. O uso de módulos de adição e divisão permite que você obtenha um ciclo com qualquer período e quaisquer valores para iterações.

Conecte a saída do metrônomo à primeira entrada f e defina vários seletores e botões na saída f. Inicie o metrônomo e veja como os botões acendem alternadamente e depois de pressionar automaticamente o último botão, o ciclo se repete. Fragmento:

imagem

Para que o loop seja executado sempre do valor 3, conectei a saída da mensagem de parada à entrada da mensagem 3 enviando o valor inicial para f.

Vamos descrever a melodia. Para fazer isso, crie um patch limpo e descreva o metrônomo com um intervalo de 230 (exatamente 230 milissegundos dura uma colcheia na melodia) e um ciclo de 64 notas. Para selecionar os valores, usamos a variável f e o novo elemento moses para nós, cuja funcionalidade será descrita abaixo. Também adicionamos vários objetos makenote, mensagens com notas, anotações nos canais 1 (piano) e 10 (bateria) e combinamos os seletores de moses de cada iteração com as notas correspondentes. Obtenha o patch:

imagem

Como você pode ver, com a programação visual, o uso de um grande número de objetos reduz a legibilidade do programa. De fato, um patch é uma combinação de elementos simples. Considere a seguinte "rotina":

imagem

O objeto moses armazena um número na segunda entrada, que pode ser definida por padrão. Se a primeira entrada receber um número menor que o valor armazenado da segunda entrada, um sinal será enviado da primeira saída do Moisés, caso contrário, o sinal será enviado da segunda saída. Portanto, a primeira saída de moses 1 se comporta de maneira semelhante à primeira saída de sel 0. Vamos ver um monte de + 63% 64. Permite reduzir os valores no loop em um. Se uma foi inserida, a saída será 0; para a entrada 0, a saída será 63 - obteremos um ciclo de 64 elementos na ordem inversa. Se conectarmos a saída deste pacote à entrada da próxima construção + 63% 64 e conectar moses 1 à saída de cada pacote, mas para cada um dos 64 valores possíveis de f, exatamente um moses enviará um sinal para a primeira saída. Portanto, o número 7 precisa ser reduzido 7 vezes em 1,para obter 0, o 7º moses 1 na iteração 7 receberá 0 na primeira entrada e enviará um sinal para a nota correspondente. Se para 64 seletores você precisar editar manualmente os valores padrão dos parâmetros, as rotinas + 63% 64 meses 1 poderão ser copiadas e a conexão das saídas do% 64 anterior às entradas + 63 obterá um seletor cíclico complexo de 64 posições.

O patch da melodia usa duplicação de objetos de anotações. Esta técnica permite aumentar o volume ignorando a marca limite. Portanto, se você conectar o mesmo makenote 67 127 a 2 nota 1, mas ao enviar um sinal da primeira entrada do makenote, a nota la (código 67, primeira oitava) será reproduzida com um volume de 127 * 2 = 254. Instrumentos MIDI no Pure Data muito silencioso, então essa técnica é útil na criação de melodias de conjunto (no nosso caso, 2 pianos são tocados nos canais 1 e 5 e kit de bateria 10 com volume triplo).

Para decorar a simulação (o processo de mover dados entre objetos do código de correção em tempo de execução), é conveniente usar botões duplicados. No exemplo acima, seus 6 objetos de estrondo têm uma silhueta de botão Reproduzir, que é destacada automaticamente quando o botão estrondo extremo é pressionado à direita. O processamento do sinal de estrondo é um processo que consome muitos recursos, mas na próxima seção colocaremos toda uma variedade de botões e tentaremos retratar uma dança do vídeo com a ajuda deles.

Animação


Para animação, precisamos das mesmas variáveis ​​f, objects - operadores aritméticos e um metrônomo, além de seletores. Desta vez, precisamos de apenas 8 quadros, então usaremos objetos sel. Crie um campo 20x10 a partir dos botões de estrondo (usaremos a operação de cópia). Depois de colocar o patch com a melodia no centro, obtemos a seguinte figura:

imagem

Você pode simplesmente conectar as saídas esquerdas de cada seletor aos botões que devem ser pressionados nesse quadro e enviar o sinal do metrônomo para a entrada de uma nova variável do ciclo f. Mas essa abordagem tem duas falhas:

  • 0,23 s por quadro - rápido demais para nossa dança. E o uso do segundo metrônomo nos surpreenderá: o noteout e o bang têm um atraso diferente em resposta ao sinal;
  • o botão permanece pressionado por 0,05 segundos a partir do momento em que o sinal foi recebido, o que significa que, pelos 0,18 segundos restantes, a “tela” da animação ficará em branco e a imagem no loop piscará.

Para resolver esses problemas, usamos a divisão. A seguinte construção:

imagem

pega o valor de entrada f da ciclo-melodia principal. Depois de dividir por 2, obtemos uma redução na mudança de quadro: para 0 e 1, o quadro 1 será mostrado, para 2 e 3, quadro 2 e assim por diante. Para cada quadro, um sinal ainda é enviado a cada 0,23 segundos. Agora vamos usar outro loop:

imagem

Para sincronizar com a melodia principal, um atraso foi adicionado a ela: o sinal de inclusão passa do seletor primeiro pelo botão e somente então para a primeira entrada do metrônomo. Agora, se você criar um estrondo e conectar sua saída a todos os botões de pixel de um determinado quadro, o quadro acima poderá realçar o quadro a cada 0,046 segundos, o que é mais rápido que a frequência de atualização dos botões, ou seja, o quadro acenderá continuamente até que o próximo quadro seja alterado. Um ciclo de 5 iterações garante que os quadros não sejam estratificados, pois 0,046 * 5 = 0,23 s - o período dos seletores de quadros.

Ao criar uma animação, o computador travava regularmente, mas era possível desenhar 5 figuras diferentes e criar um ciclo de 8 quadros a partir da seguinte ordem:

1 2 3 2 1 4 5 2

O patch final com Coffin Dance (muitos elementos decorativos - botões e comentários adicionados) no modo de edição:

imagem

dificilmente é possível analisar o código fonte da simulação nesta imagem infernal, mas o patch funciona corretamente:

imagem

no canto inferior direito, um contador é usado para parar automaticamente o player após o 121º dia. notas. Inicialmente, supunha-se uma animação de 48x24 pixels, mas o computador a recusou categoricamente com um rugido triste do cooler e uma reinicialização inesperada do Windows no modo de segurança. A arte original em pixel 48x24 do artista LikaLou anexada no final do vídeo. Então, após 3 dias de "desenho musical", temos o Coffin Dance no Pure Data:


Conclusão


A programação visual de memes é uma atividade divertida, embora demore muito tempo e às vezes destrua seu hardware. Mesmo uma tarefa aparentemente simples de dança fúnebre exige uma abordagem modular para a criação de um programa, conhecimento dos recursos não apenas da linguagem de implementação, mas também do ambiente de desenvolvimento.

Usando o exemplo de patch para Coffin Dance, você pode julgar o nível de desenvolvimento da programação visual. Existem linguagens gráficas que lidam bem com algumas tarefas do aplicativo, se forem ambientes de desenvolvimento convenientes. Mas a indústria de programação visual como um todo está em sua infância.

Referências


Site oficial Pure Data
Noções básicas de programação visual em Pure Data
Sobre o
artigo padrão do VST Coffin Dance na Wikipedia
Coffin Dance in Pure Data: vídeo original

All Articles