MIDI Entrée

Dans cette section, nous allons apprendre comment connecter un contrôleur MIDI pour envoyer des événements dans Sonic Pi pour contrôler nos synthés et nos sons. Allez chercher un contrôleur MIDI comme un clavier ou une surface de contrôle et devenons physique !

Connecter un contrôleur MIDI

Afin d’obtenir de l’information d’un périphérique MIDI externe dans Sonic Pi, nous devons d’abord le connecter à notre ordinateur. Habituellement, ce sera par une connexion USB, quoi que les plus vieux équipements auront des connecteurs 5-pins pour lesquels vous aurez besoin que votre ordinateur le supporte physiquement (par exemple, certaines cartes de sons ont des connecteurs MIDI DIN). Une fois que votre périphérique est connecté, démarrez Sonic Pi et jetez un coup d’oeil à la section IO du panneau Préférences. Vous devriez voir votre périphérique listé là. Si ce n’est pas le cas, essayez de presser le bouton ‘Reset MIDI’ et regarder s’il apparaît. Si vous ne voyez toujours rien, la prochaine chose à essayer est de consulter la configuration MIDI de votre système d’exploitation pour vérifier si votre périphérique y est. Si tout cela ne marche pas, sentez vous à l’aise de poser des questions dans la salle publique de clavardage : http://gitter.im/samaaron/sonic-pi

Recevoir des événements MIDI

Une fois que votre périphérique est connecté, Sonic Pi recevra automatiquement les événements. Vous pouvez le voir par vous-même en manipulation votre périphérique MIDI et en regardant la queue de journalisation dans le secteur inférieur droit de votre fenêtre d’application en-dessous du journal ( si ce n’est pas visible allez dans Préférences->Éditeur->Afficher & Cacher et activer le “Afficher la queue de journalisation”). Vous verrez un flux d’événements comme :

/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]

Once you can see a stream of messages like this, you’ve successfully connected your MIDI device. Congratulations, let’s see what we can do with it!

MIDI Time State

These events are broken into two sections. Firstly there’s the name of the event such as /midi/nanokey2_keyboard/0/1/note_on and secondly there’s the values of the event such as [18, 62]. Interestingly, these are the two things we need to store information in Time State. Sonic Pi automatically inserts incoming MIDI events into Time State. This means you can get the latest MIDI value and also sync waiting for the next MIDI value using everything we learned in section 10 of this tutorial.

Contrôle des effets (FX)

Now we’ve connected a MIDI device, seen its events in the cue log and discovered that our knowledge of Time State is all we need to work with the events, we can now start having fun. Let’s build a simple MIDI piano:

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

There’s a few things going on in the code above including some issues. Firstly, we have a simple live_loop which will repeat forever running the code between the do/end block. This was introduced in Section 9.2. Secondly, we’re calling sync to wait for the next matching Time State event. We use a string representing the MIDI message we’re looking for (which is the same as was displayed in the cue logger). Notice that this long string is provided to you by Sonic Pi’s autocompletion system, so you don’t have to type it all out by hand. In the log we saw that there were two values for each MIDI note on event, so we assign the result to two separate variables note and velocity. Finally we trigger the :piano synth passing our note.

Now, you try it. Type in the code above, replace the sync key with a string matching your specific MIDI device and hit Run. Hey presto, you have a working piano! However, you’ll probably notice a couple of problems: firstly all the notes are the same volume regardless of how hard you hit the keyboard. This can be easily fixed by using the velocity MIDI value and converting it to an amplitude. Given that MIDI has a range of 0->127, to convert this number to a value between 0->1 we just need to divide it by 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

Update the code and hit Run again. Now the velocity of the keyboard is honoured. Next, let’s get rid of that pesky pause.

Removing Latency

Before we can remove the pause, we need to know why it’s there. In order to keep all the synths and FX well-timed across a variety of differently capable CPUs, Sonic Pi schedules the audio in advance by 0.5s by default. (Note that this added latency can be configured via the fns set_sched_ahead_time! and use_sched_ahead_time). This 0.5s latency is being added to our :piano synth triggers as it is added to all synths triggered by Sonic Pi. Typically we really want this added latency as it means all synths will be well timed. However, this only makes sense for synths triggered by code using play and sleep. In this case, we’re actually triggering the :piano synth with our external MIDI device and therefore don’t want Sonic Pi to control the timing for us. We can turn off this latency with the command use_real_time which disables the latency for the current thread. This means you can use real time mode for live loops that have their timing controlled by syncing with external devices, and keep the default latency for all other live loops. Let’s see:

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

Update your code to match the code above and hit Run again. Now we have a low latency piano with variable velocity coded in just 5 lines. Wasn’t that easy!

Commencer

Finally, as our MIDI events are going straight into the Time State, we can also use the get fn to retrieve the last seen value. This doesn’t block the current thread and returns nil if there’s no value to be found (which you can override by passing a default value - see the docs for get). Remember that you can call get in any thread at any time to see the latest matching Time State value. You can even use time_warp to jump back in time and call get to see past events…

Now You are in Control

Choix (“choose”)