# Entrada MIDI

Nesta seçã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 seu aperelho esteja conectado, o Sonic Pi irá receber eventos automaticamente. Você mesmo pode confirmar manipulando seu aparelho MIDI e olhando no registro de Deixas (cue logger), na janela do app em baixo à direita, abaixo do registro (se isso não estiver visível, vá em Preferências > Editor > Mostrar & Ocultar e habilite a caixa ‘Mostrar o registro de deixas’). Você 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 seção 9.2. Segundo, estamos chamando o comando `sync` para esperar pelo próximo evento Time State correspondente. Usamos uma string representando a mensagem MIDI que estamos procurando (que é a mesma que foi exibida no registro). Note que esta string longa é fornecida pela função autocompletar do Sonic Pi, desta forma você não precisa digitar tudo a mão. No registro nós vemos que haviam dois valorespara cada nota MIDI no evento, então nós atribuímos o resultado a duas variáveis `note` e `velocity`. Por fim, nós disparamos o sintetizador `:piano` passando nossa nota.

Agora tente você. Digite o código acima, substitua a chave de sincronização com uma string correspondente ao seu aparelho MIDI e clique em Executar. Pronto, você tem um piano funcionando! Entretanto, você provavelmente notará alguns problemas: primeiro, todas as notas possuem o mesmo volume, independente da força que você 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!