Saturday, April 13, 2013

Tutorial 28 - Codea v1.5.2: Objective C Add On, Audio

Figure 0. Codea Audio Player

28.1 Overview


CodeaAddon is an experimental protocol for adding native extensions to exported Codea projects. You must deal with Lua directly to register your functions and globals. This protocol should be considered alpha in version 1.5.2 and is subject to change in future Codea releases. If the protocol changes we will update the tutorial to reflect this.

As our first example we will demonstrate how to play an mp3 file from within Codea. iOS provides a number of mechanisms for implementing audio playback. The easiest technique from the perspective of the application developer is to use the AVAudioPlayer class which is part of the AV Foundation Framework. Apple recommends that you use this class for audio playback unless you are playing audio captured from a network stream or require very low I/O latency.

Upon instantiating an AVAudioPlayer class, the playback of audio may be controlled and monitored via the methods and properties available. Play, pause and stop methods may be used to control playback and the volume property may be used to adjust the volume level. The playing property may be used to determine whether or not the AVAudioPlayer object is currently playing audio. Using an audio player you can:
  • Play sounds of any duration
  • Play sounds from files or memory buffers
  • Loop sounds
  • Play multiple sounds simultaneously, one sound per audio player, with precise synchronisation
  • Control relative playback level, stereo positioning, and playback rate for each sound you are playing
  • Seek to a particular point in a sound file, which supports such application features as fast forward and rewind
  • Obtain data you can use for playback-level metering

The AV Foundation framework supports the playback of a variety of different audio formats and codecs including both software and hardware based decoding. Codecs and formats currently supported are as follows:
  • AAC (MPEG-4 Advanced Audio Coding)
  • ALAC (Apple Lossless)
  • AMR (Adaptive Multi-rate)
  • HE-AAC (MPEG-4 High Efficiency AAC)
  • iLBC (internet Low Bit Rate Codec)
  • Linear PCM (uncompressed, linear pulse code modulation)
  • MP3 (MPEG-1 audio layer 3)
  • ยต-law and a-law
Figure 1. Adding the AVFoundation Framework

You can optionally implement a delegate to handle interruptions (such as an incoming phone call), or if required update the user interface when a sound has finished playing.

28.2 Add the AVFoundation Framework to your App


Since the AVAudioPlayer class is part of the AV Foundation framework, it will be necessary to add this framework to the project. Fire up Xcode and load the exported version of your Codea application (See Tutorial 27). Click on the imported project file at the top left of the project navigator then in the Build Phases tab, scroll down to the link binary with libraries area and select the drop down arrow. Click on the "+" button below your existing frameworks to add a new framework. Find AVFoundation framework and click on "Add" (Figure 1).


Figure 2. MP3 File added to the Resource Group


28.3 Add the MP3 file to your Project


Any mp3 files that you want to play in your app need to be included in your project bundle. Adding these is simple. For our tutorial we generated a simple loop using Garage Band and then exported it to an mp3 file. Locate your mp3 and drag it from Finder to the Resources Group (folder) in the the Project Navigator of Xcode (Figure 2). We added a sub folder called Music (right click on the Resources Group and add a new Group) to contain the mp3 file but that is optional.


Figure 3. Adding a new Objective-C class.

28.4 Create our Custom Audio Add On Class


To create our new AudioAddOn class, right click on the Addons Group and select New File... from the pop up menu. Click on Cocoa Touch under iOS and make sure that Objective-C class has been selected (Figure 3), then click on Next.

Select Subclass of type NSObject and call the Class AudioAddOn. The two check boxes (Targeted for iPad and With XIB for user interface) should be greyed out. Click on Next, and then click on Create. Two new files will be added to the Addons Group, AudioAddOn.h and AudioAddOn.m.

The header file for our AudioAddOn class is mostly straight forward. We import the AVFoundation framework which we added above and the CodeaAddon class. AudioAddOn conforms to both the CodeaAddon and AVAudioPlayerDelegate protocols. We define a variable called audioAdOnInstance, which allows us to access Objective C methods from within our C functions playMusic() and stopMusic().

In the initialisation of this class we create our audio player object and assign our mp3 file to it. We also pre-buffer the mp3 file and set the number of loops to be infinite (by assigning a negative integer). At the end we assign audioAdOnInstance to self.

Some of the most used AVAudioPlayer delegate methods have been included, but we don't use them in this tutorial. The code is shown at the end of the tutorial.


28.5 Modifications to the Application Delegate


There are only minor changes to the Application Delegate files. We import our add on in the header file and create an instance variable which points to it (called audioAddOn).

In AppDelegate.mm we instantiate our add on class and then register the add on so we can use it in the Lua code.

To play your mp3 file from within your Lua code just call playMusic() and to stop it, call stopMusic(). Too easy!