AudioToolbox: A framework to record and play audio
MIDI (Music Instrument Digital Interface): A standard for musical instruments, and can be used to play MIDI instruments on Apple Devices
MusicSequence: The music sequence previously attached to the audio engine
MusicTrack: Several music events, each timestamped using a series of beats
I’ve created several Apps that require a small piece of audio to play (a *bing* or *chime*. I’ve experimented with
AVAudioPlayer, and looking around on the web for public domain chimes.
It wasn’t that fun I’ll admit that. The performance wasn’t where I wanted it to be, and the quality of the samples I used.
I’m a better developer now (probably). I can find a better solution (probably).
Why didn’t I think of MIDI before?
MIDI Audio — In a Playground
Look, Swift has you well covered in terms of providing
AudioToolbox , and of course this Framework is avaliable in Playgrounds. This is excellent news!
The Playground setup
Now since audio playback is asynchronous we will have to pull out one of our best tricks, that is the playground
needsIndefiniteExecution . This means that our playground needs two lines of code:
PlaygroundPage.current.needsIndefiniteExecution = true
It is with this in place, we can approach the challenge with a light heart and a full brain (or something).
The MIDI steps
Now don’t panic, there is a full playground at the end of this section of the article to help you out, and right here is a step-by-step explanation of how each section of code works.
With that clear, let us press on.
Create a new music sequence and a track
var sequence : MusicSequence? = nilvar musicSequenceStatus: OSStatus = NewMusicSequence(&sequence)var track : MusicTrack? = nilvar musicTrack = MusicSequenceNewTrack(sequence!, &track)var time = MusicTimeStamp(1.0)
musicSequenceStatus is simply an OSStatus making sure that
NewMusicSequence has created the 120 beats-per-minute tempo track on the
track is where will will lay down our mean beats (play the MIDI instruments).
So then we add an (empty) track to the sequence, again returning an OSStatus.
time as a
MusicTimeStamp refers to time values in the sequence, and is measured in beats.
But we haven’t even got started yet. But we have all of the elements needed to make a note.
var note = MIDINoteMessage(channel: 0,
This note is all very nice, let us explain each part in turn:
- channel: The midi channel to be used
- note: The midi note (This is A5, musician friends)
- velocity: The force with which the note is played
- releaseVelocity: The speed with which that the key is released
- duration: The length of the note
We then create a rather attractively named MIDINoteEvent (which again returns an OSStatus), made up of the track (where the notes are played), time (time values in a sequence) and passing the note (that is the note to be played) by reference.
musicTrack = MusicTrackNewMIDINoteEvent(track, time, ¬e)
Now we have a MusicTrackNewMIDINoteEvent added, which is a music track containing a sequence and music track.
We can then create a MusicPlayer to, you know, play the track.
var musicPlayer : MusicPlayer? = nilvar player = NewMusicPlayer(&musicPlayer)player = MusicPlayerSetSequence(musicPlayer!, sequence)player = MusicPlayerStart(musicPlayer!)
NewMusicPlayer takes the
MusicPlayer passed by reference, which is then Set a sequence then actually started.
The MIDI steps: multiple notes
Each note in turn will have a timestamp (obviously the next beat) and I can write each particular note as a
var notes: [UInt8] = [71,69,62,72,71,69,67]
To create multiple notes you can use
MusicTrackNewMIDINoteEvent multiple times. An example? Go on then:
I’ve put a guard statement in to prevent force unwrapping the track unnecessarily.
Have you guessed what the basic melody of the song is?
For that you might need the whole code. Go on, here it is:
The Singleton Story
You might want to play a sound effect just as you move between views. Or have some music playing as you move around your App.
Good luck with creating and destroying instances as such a proposal seems like a whole mess.
The best approach to take would be a MusicPlayerManager to manage the playing of music. No problem, master!
MIDI allows us to have some fun with music, and this is even possible when using a Playground to make our creative musings real by using MIDI. If you want the MIDI notes for use in your own projects, you can use this rather splendid website. Now get going, you maestro, you.
Any questions? You can get in touch with me in a Twitter rant. HERE