MIDI In
In this section we will learn how to connect a MIDI controller to send events into Sonic Pi to control our synths and sounds. Go and grab a MIDI controller such as a keyboard or control surface and let’s get physical! Connecting a MIDI Controller In order to get information from an external MIDI device into Sonic Pi we first need to connect it to our computer. Typically this will be via a USB connection, although older equipment will have a 5-pin DIN connector which you’ll need hardware support for your computer (for example, some sound cards have MIDI DIN connectors). Once you’ve connected your device, launch Sonic Pi and take a look at the IO section of the Preference panel. You should see your device listed there. If not, try hitting the ‘Reset MIDI’ button and see if it appears. If you’re still not seeing anything, the next thing to try is to consult your operating system’s MIDI config to see if it sees your device. Failing all that, feel free to ask questions in the public chat room: http://gitter.im/samaaron/sonic-pi Receiving MIDI Events Once your device is connected, Sonic Pi will automatically receive events. You can see for yourself by manipulating your MIDI device and looking at the cue logger in the bottom right of the application window below the log (if this isn’t visible go to Preferences->Editor->Show & Hide and enable the ‘Show cue log’ tickbox). You’ll see a stream of events such as: /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. ## Controlling Code 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! Getting Values 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 The exciting thing now is that you can now use the same code structures to sync and get MIDI information from any MIDI and do whatever you want with the values. You can now choose what your MIDI device will do!
0 Comments
Lexi - Horror soundtrackKarlTsunemasaAshleyFinal Day
Complete you pieces of music. Publish your music. Sign up and share via soundcloud. You can make it private (only you and who you chose can listen to it) or public (everyone can listen to it) If you want to continue your experiments you can try out live looping using the live loop function. in_thread do
cue :bass sleep 8 cue :bass cue :drums sleep 8 cue :bass sleep 8 end in_thread do loop do sync :drums sample :drum_bass_hard sleep 0.25 sample :drum_cymbal_closed sleep 0.25 sample :drum_snare_hard sleep 0.25 sample :drum_cymbal_closed sleep 0.25 end end in_thread do loop do sync :bass play chord(:A3, :minor) sleep 2 play chord(:C4, :major) sleep 2 play chord(:E3, :minor) sleep 2 play chord(:D4, :major) sleep 2 end end This is code from Otto van Zanten which can help layer the code
in_thread do cue :bass sleep 8 cue :bass cue :piano cue :drums sleep 8 cue :bass sleep 8 (etcetera) end Then underneath that i'll have the drums inside another thread, so something like this in_thread do loop do sync :drums * all the drum related code here* end end in_thread do loop do sync :bass * bass line stuff here* end end Those who want to move on to create a horror movie soundtrack can do so using this video.
There are different ways to edit the sound together. You can code in a linear fashion in Sonic Pi or you can use programs like Garageband or Audacity to splice your audio together.
Day 3 is to create your own song It must have an introduction Verse and Chorus It must have Melody Chords Drum Beat You can use the code to start you off. in_thread do loop do 3.times do sample :drum_heavy_kick sleep 0.5 sample :drum_snare_hard sleep 0.5 sample :drum_heavy_kick sleep 0.5 sample :drum_snare_hard sleep 0.5 end sample :drum_heavy_kick sleep 0.5 sample :drum_snare_hard sleep 0.5 sample :drum_heavy_kick sleep 0.25 sample :drum_snare_hard sleep 0.25 sample :drum_heavy_kick sleep 0.25 sample :drum_snare_hard sleep 0.25 end end or this catchy drum beat in_thread do loop do sample :drum_bass_hard sleep 0.25 sample :drum_cymbal_closed sleep 0.25 sample :drum_snare_hard sleep 0.25 sample :drum_cymbal_closed sleep 0.25 end end For reference:Which terms would I use to write a melody on Sonic Pi?
What is the musical term used for writing ‘loops’? How would you describe the sounds of the synths? What is the musical term for the way an instrument sounds? How would you describe the sounds within the piece of music? How are synths and conventional instruments different?
|