Entrada MIDI

Nesta secção vamos aprender como conectar um controlador MIDI para enviar eventos para o Sonic Pi, para controlar nossos sintetizadores e sons. Vá e pegue um controlador MIDI, como um teclado ou tablet de controle e vamos começar!

Conectando um controlador MIDI

Para receber no Sonic Pi informações de um aparelho MIDI externo, primeiro nós precisamos conectá-lo ao computador. Tipicamente isso é feito através de uma conexão USB, apesar de que aparelhos antigos usam um conector DIN de 5 pinos, para o qual será necessário suporte de hardware em seu computador (por exemplo: algumas placas de áudio possuem conectores DIN). Uma vez que você tenha conectado seu aparelho, abra o Sonic Pi e dê uma olhada na seção IO (Entrada/Saída) do painel de Preferências. Você poderá ver seu aparelho listado lá. Caso não veja, tente o botão ‘Reiniciar MIDI’ e veja se aparece. Se ainda assim você não encontrar nada, a próxima coisa a tentar é consultar as configurações MIDI do seu sistema operacional para ver se ele enxerga seu aparelho. Se tudo isso falhar, sinta-se a vontade para perguntar na sala de chat: http://gitter.im/samaaron/sonic-pi

Recebendo eventos MIDI

Assim que o seu aparelho esteja conectado, o Sonic Pi irá receber eventos automaticamente. Você mesmo pode confirmar a manipular o seu aparelho MIDI e olhando no registro de Deixas (cue logger), na janela da app em baixo à direita, abaixo do registo (se isso não estiver visível, vá em Preferências > Editor > Mostrar & Ocultar e ative a caixa ‘Mostrar o registo de deixas’). Verá um fluxo de eventos como:

/midi/nanokey2_keyboard/0/1/note_off  [55, 64]
/midi/nanokey2_keyboard/0/1/note_on   [53, 102]
/midi/nanokey2_keyboard/0/1/note_off  [57, 64]
/midi/nanokey2_keyboard/0/1/note_off  [53, 64]
/midi/nanokey2_keyboard/0/1/note_on   [57, 87]
/midi/nanokey2_keyboard/0/1/note_on   [55, 81]
/midi/nanokey2_keyboard/0/1/note_on   [53, 96]
/midi/nanokey2_keyboard/0/1/note_off  [55, 64]

Quando você ver um fluxo de mensagens desta forma, você terá conectado com sucesso seu aparelho MIDI. Parabéns, vamos ver o que você consegue fazer com ele!

MIDI Time State

MIDI

Controlando o Código

Agora que você conectou seu aparelho MIDI, viu seus eventos no registro e descobriu que nosso conhecimento do Estado de Tempo (Time State) é tudo o que precisamos para trabalhar com eventos, podemos começar a nos divertir. Vamos construir um piano MIDI simples:

live_loop :midi_piano do 
  note, velocity = sync "/midi/nanokey2_keyboard/0/1/note_on"
  synth :piano, note: note
end

Temos algumas coisas acontecendo no código acima, incluindo alguns problemas. Primeiro, temos um live_loop simples, que irá se repetir para sempre, executando o código entre os blocos do/end. Isto foi apresentado na secção 9.2. Segundo, estamos a chamar o comando sync para esperar pelo próximo evento Time State correspondente. Usamos uma cadeia que representa a mensagem MIDI que estamos a procurar (que é a mesma que foi exibida no registo). Note que esta cadeia longa é fornecida pela função autocompletar do Sonic Pi, desta forma não precisa digitar tudo a mão. No registo nós vemos que haviam dois valores para cada nota MIDI no evento, então nós atribuímos o resultado a duas variáveis note e velocity. Por fim, disparamos o sintetizador :piano passando a nossa nota.

Agora tente você. Digite o código acima, substitua a chave de sincronização com uma cadeia correspondente ao seu aparelho MIDI e clique em Executar. Pronto, tem um piano funcionando! Entretanto, provavelmente notará alguns problemas: primeiro, todas as notas possuem o mesmo volume, independente da força que usa no teclado. Isso pode ser consertado facilmente usando o valor velocity do MIDI e convertendo-o para amplitude. Dado que MIDI possui uma variação entre 0 e 127, para converter este número para um valor entre 0 e 1 nós só precisamos dividi-lo por 127:

live_loop :midi_piano do 
  note, velocity = sync "/midi/nanokey2_keyboard/0/1/note_on"
  synth :piano, note: note, amp: velocity / 127.0
end

Atualize o código e clique em Executar novamente. Agora a força aplicada ao teclado é respeitada. Em seguida, vamos nos livrar desta pausa irritante.

Removendo a Latência

Antes de remover a pausa, nós precisamos entender porque ela acontece. Para manter todos os sintetizadores e Efeitos sincronizados através de uma variedade de CPUs com capacidades diferentes, o Sonic Pi agenda o áudio antecipadamente em 0.5s por padrão. (Note que esta latência adicional pode ser configurada pelas funções set_sched_ahead_time! e use_sched_ahead_time). Estes 0.5s de latência estão sendo adicionados ao disparador do nosso sintetizador :piano assim como está sendo adicionado a todos os sintetizadores disparados pelo Sonic Pi. Tipicamente nós realmente queremos manter esta latência, já que isso significa que todos os sintetizadores estarão sincronizados. Entretanto, isso só faz sentindo para sintetizadores disparados por código, usando play e sleep. No nosso caso, na realidade estamos disparando o sintetizador :piano pelo nosso aparelho MIDI e portanto não queremos que o Sonic Pi controle o tempo por nós. Podemos desligar esta latência com o comando use_real_time, que desabilita a latência para a thread atual. Isto significa que você pode usar o modo Real Time para loops ao vivo controlado por sync com aparelhos externos, e manter a latência padrâo para todos os outros loops. Vejamos:

live_loop :midi_piano do 
  use_real_time
  note, velocity = sync "/midi/nanokey2_keyboard/0/1/note_on"
  synth :piano, note: note, amp: velocity / 127.0
end

Atualize seu código para que ele corresponda ao código acima e clique em ‘Executar’ novamente. Agora nós temos um piano com baixa latência e sensibilidade variável, programado em apenas 5 linhas.

Recuperando valores

Finalmente, como nossos eventos MIDI estão indo diretamente para o Time State, nós também podemos usar a função get para recuperar o último valor recebido. Isso não bloqueia a thread atual e retorna nil se não houver valor para ser recuperado (o que você pode sobrescrever passando um valor padrão - veja a ajuda para get). Lembre-se que você pode chamar get em qualquer thread a qualquer momento para ver o valor mais recente correspondente ao Time State. Você pode até usar time_warp para voltar no tempo e chamar get para ver eventos passados…

Agora Você Está no Controle

O mais importante é que agora você pode usar as mesmas estruturas de código para sincronizar e recuperar (sync e get) informações MIDI de qualquer aparelho MIDI e fazer o que você quiser com os valores. Você pode agora escolher o que seu aparelho MIDI irá fazer!