Anda di halaman 1dari 14

Setting Up the Development Environment

Ve will limit oui uiscussion ol iOS uevelopment to the latest veision ol Apple`s inte-
giateu uevelopment enviionment, Xcoue +.2. Even though Xcoue +.2 has Luilt-in sup-
poit loi Git, it will not sullice loi oui puiposes Lecause ol its limiteu suppoit loi suL-
mouules. In oiuei to uownloau a copy ol the iOS Lianch ol liLpu, open a teiminal
(App|ications/Uti|itics/Tcrnina|.app), change into the uiiectoiy wheie you want to keep
youi installation ol liLpu, anu entei the lollowing commanus:
$ git clone git://github.com/libpd/pd-for-ios.git
$ cd pd-for-ios
$ git submodule init
$ git submodule update
This will install liLpu anu its auuio glue loi iOS as well as utilities anu a lew sample
apps. It is goou piactice to keep youi copy ol liLpu up to uate. In oiuei to uo that, you
shoulu iegulaily issue the lollowing commanus in youi pd-jor-ios uiiectoiy:
$ git pull
$ git submodule update
You shoulu tiy the sample apps now in oiuei to make suie that youi installation is
woiking. In oiuei to test a sample pioject, just open its .xcodcproj lile.
Vhen you open a pioject loi the liist time, select the menu item Piouuct Manage
Schemes.. You shoulu see two schemes, one loi the cuiient pioject anu one loi liLpu,
laLeleu libpd-ios (Figuie 6-1). Xcoue sometimes gets conluseu when autocieating
schemes, though, anu il you`ve Leen using liLpu since Leloie the move to GitHuL, then
you may enu up with a spuiious seconu scheme loi liLpu, laLeleu libpd, which you can
salely uelete.
Iigurc -1. Managing schcncs in Xcodc 1.2. WavcTab|cs is onc oj thc sanp|c apps inc|udcd with thc
|ibpd distribution.
86 | Chapter 6:Pd for iOS
This is an excerpt from Chapter 6: Pd for iOS. To order the book visit:
http://shop.oreilly.com/product/0636920022503.do
Il you tiy to iun a sample app anu nothing happens, check the active scheme in the
uppei iighthanu coinei ol Xcoue (Figuie 6-2). It shoulu uisplay the name ol the cuiient
pioject, not libpd-ios. Il it uoesn`t, open the Scheme pop-up menu anu select the main
scheme ol the pioject.
Iigurc -2. Chcc|ing thc activc schcnc
None ol the sample piojects aie teiiiLly exciting, Lut that`s intentional. They aie sup-
poseu to illustiate key points aLout liLpu uevelopment loi iOS; any visual oi musical
uazzle woulu uistiact liom theii main puipose.
Creating a Musical App: Part I
As in Chaptei 5, we`ll cieate a guitai tunei app. Oui liist veision will Le just a uigital
tuning loik, emitting ieleience tones on uemanu. Think ol it as Hc||o Wor|d! loi liLpu.
In oiuei to use liLpu in an app, you neeu to impoit the liLpu Xcoue pioject into youi
pioject anu wiie it up so that the euitoi, compilei, anu linkei can linu the necessaiy
iesouices. Xcoue +.2 makes this initial setup iathei haiu, anu it is lieguently easiei to
copy a sample pioject anu mouily it loi youi puiposes. Neveitheless, we`ll ignoie the
sample piojects loi now anu Luilu oui guitai tunei app liom sciatch.
In Xcoue, select File New New Pioject anu ask the new pioject wizaiu to cieate
the scalloluing ol a Single View Application (Figuie 6-3).
Now Xcoue piesents a numLei ol options loi oui app (Figuie 6-+). Ve neeu to choose
a name loi oui app, e.g., GuitarTuner, a company iuentiliei, anu a pielix, e.g., GT, that
the new pioject wizaiu will piepenu to the classes that it geneiates. In oiuei to stieam-
line the exposition, we`ll limit ouiselves to iPhone apps loi now, Lut eveiything we
uiscuss in this chaptei applies to iPau apps as well. Ve won`t neeu stoiyLoaius in oui
single-view app, Lut we will use automatic ieleience counting (ARC) Lecause that`s
what Apple iecommenus loi new uevelopment.
Importing libpd
Click on the menu item File Auu Files to "GuitaiTunei". anu auu the lile
|ibpd.xcodcproj. Now liLpu shoulu show up as a suLpioject ol youi pioject (Figuie 6-5).
Creating a Musical App: Part I | 87
Iigurc -3. Projcct crcation in Xcodc 1.2
Iigurc -1. Projcct crcation options in Xcodc 1.2
88 | Chapter 6:Pd for iOS
Iigurc -5. |ibpd in Xcodc 1.2
Click on GuitarTuner in the Pioject Navigatoi to get to the main pioject settings anu
check that GuitarTuner is selecteu unuei Taigets. The settings will open on the Sum-
maiy taL (Figuie 6-6). Take this oppoitunity to ueselect all scieen oiientations except
poitiait. Latei, when you have a sense ol how the auuio components inteiact with the
iest ol the app, you may want to ievisit the guestion ol which scieen oiientations to
suppoit. Foi now, oiientation changes aie just one moie potential point ol lailuie anu
so we`ll uisallow them, the lastei to get oui app oll the giounu.
Iigurc -. Projcct scttings
Now select the Builu Settings taL. In the seconu Lai liom the top, select All anu Com-
Lineu, then entei the seaich teim user header. Finu the iow laLeleu Usei Heauei
Seaich Paths anu uouLle-click in the iight column, the one coiiesponuing to youi
cuiient taiget. A little uialog winuow will pop up. Now click on -, then select the Lox
laLeleu recursive, anu linally entei the path to youi liLpu installation (Figuie 6-7). Il
you`ve placeu Loth youi new pioject anu youi copy ol Pu loi iOS in youi Docuncnts
loluei, then the path S(SRCROOT)/../../pd-jor-ios/|ibpd shoulu woik.
Creating a Musical App: Part I | 89
Vhile the entiie setup is teuious, the heauei seaich path is the only pait
that`s eiioi-pione. Il you encountei Luilu pioLlems latei on, you shoulu
liist check whethei youi seaich path is coiiect.
Configuring for Portability
Il you`ie going to shaie youi coue with othei uevelopeis, then you neeu to take special
caie to make youi pioject poitaLle. The Lest solution is pioLaLly the appioach ol Pu
loi iOS, using git suLmouules.
Cieate one loluei that will holu Loth youi pioject loluei anu a copy ol liLpu, packageu
as a git suLmouule (just liLpu, cloneu uiiectly liom git://github.con/|ibpd/|ibpd.git, not
Pu loi iOS). Vith this setup, you can use a simple ielative path, S(SRCROOT)/../../
|ibpd, anu youi heauei seaich path will Le poitaLle.
An auueu Lenelit ol packaging liLpu as a git suLmouule is that it avoius veision conllicts
uown the ioau. The suLmouule ol youi pioject will specily the veision ol liLpu to use,
anu useis ol youi coue will automatically ieceive this veision when they clone youi
pioject. Vhen you choose to upgiaue to a new veision ol liLpu, useis ol youi coue will
ieceive the same upgiaue when they upuate theii local copy.
Select the Builu Phases taL, open the Taiget Depenuencies section anu click on -, then
auu libpd-ios as a uepenuency. Finally, open the Link Binaiies Vith LiLiaiies section
anu auu |ibpd-ios.a, AudioToo|box.jrancwor|, anu A\Ioundation.jrancwor| (Fig-
uie 6-S). Don`t woiiy il Xcoue ienueis the entiy loi |ibpd-ios.a in ieu; it`s a known Lug
ol Xcoue that won`t cause any tiouLle.
Iigurc -7. Hcadcr path scttings
90 | Chapter 6:Pd for iOS
Unloitunately, Xcoue uoes not know that the static liLiaiy |ibpd-ios.a
anu the heauei seaich path aie ielateu. Il you keep moie than one copy
ol liLpu aiounu, then it is easy to get conluseu anu impoit a Linaiy liom
one anu heauei liles liom anothei, potentially leauing to haiu-to-tiack
Luilu lailuies wheie the compilei succeeus Lut the linkei lails.
This completes oui initial setup ol a new pioject with liLpu. Vhew! It was a lot ol woik,
Lut it`s uone now.
Configuring libpd
Let`s auu a Pu patch to oui app. As in Chaptei 5, we use a stiaightloiwaiu mouilication
ol oui synthesizei patch liom Chaptei 2 (Figuie 6-9). Click on the menu item File
Auu File to "GuitaiTunei". anu select the loluei containing youi patch. Xcoue olleis
a numLei ol ways ol impoiting lolueis; make suie to select Cieate gioups loi any
auueu lolueis Leloie clicking on Auu (Figuie 6-10).
Now we set up the components ol liLpu as uiscusseu in Launch Se-
guence on page 57. Fiist, we neeu to conliguie the auuio components ol liLpu, using
an instance ol the PdAudioController class uiscusseu in Chaptei +. The auuio contiollei
is a gloLal oLject, potentially ielevant to all paits ol the app, anu so we have the appli-
cation uelegate manage it anu make it availaLle thiough an accessoi methou.
The appIication deIegate interface GTAppDeIegate.h.
#import <UIKit/UIKit.h>
#import "PdAudioController.h"
@class GTViewController;
@interface GTAppDelegate : UIResponder <UIApplicationDelegate>
Iigurc -8. Conjiguring bui|d phascs
Creating a Musical App: Part I | 91
@property (strong, nonatomic) UIWindow *window;
@property (strong, nonatomic) GTViewController *viewController;
@property (strong, nonatomic, readonly) PdAudioController *audioController;
@end
Iigurc -9. Guitar tuncr patch (jirst vcrsion)
Vhen uesigning a musical app with liLpu, one ol the Lasic uecisions is how to manage
the lile ol the auuio thieau. In this simple example, we`ll take the most stiaightloiwaiu
appioach anu tie the lile ol the auuio thieau to the active lile ol the app. In othei woius,
the auuio thieau will Le active whenevei oui app is active.
Tying the lilecycle ol the auuio thieau to the lilecycle ol the app is a
guick anu convenient way to get a new auuio pioject oll the giounu. I
stait most new piojects that way. Il necessaiy, I ievisit the management
ol the auuio thieau latei, altei I`ve implementeu enough ol the auuio
lunctionality to allow loi meaninglul testing.
The next coue example shows an implementation ol this appioach. Ve cieate anu
conliguie the auuio contiollei on launch, anu we check the ietuin value in case some-
thing goes wiong. In this simple example, we just log a waining anu give up il the
uesiieu conliguiation is not availaLle. In ieal-woilu coue, you will neeu to implement
some giacelul way ol hanuling conliguiation lailuies, anu you may want to tiy a numLei
ol uilleient conliguiations until you linu one that woiks. In any case, the conliguiation
that we aie ieguesting heie, two output channels at CD sample iate with an amLient
auuio session categoiy, is common anu will pioLaLly Le availaLle.
92 | Chapter 6:Pd for iOS
The appIication deIegate impIementation GTAppDeIegate.m.
#import "GTAppDelegate.h"
#import "GTViewController.h"
@implementation GTAppDelegate
@synthesize window = _window;
@synthesize viewController = _viewController;
@synthesize audioController = _audioController;
-(BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
_audioController = [[PdAudioController alloc] init];
if ([self.audioController configureAmbientWithSampleRate:44100
numberChannels:2 mixingEnabled:YES] != PdAudioOK) {
NSLog(@"failed to initialize audio components");
}
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.viewController = [[GTViewController alloc]
initWithNibName:@"GTViewController" bundle:nil];
self.window.rootViewController = self.viewController;
[self.window makeKeyAndVisible];
return YES;
}
Iigurc -10. |nporting thc patch into Xcodc
Creating a Musical App: Part I | 93
// Without ARC, we would need to implement a dealloc method that
// releases _audioController.
-(void)applicationDidBecomeActive:(UIApplication *)application {
self.audioController.active = YES;
}
-(void)applicationWillResignActive:(UIApplication *)application {
self.audioController.active = NO;
}
- (void)applicationDidEnterBackground:(UIApplication *)application { }
- (void)applicationWillEnterForeground:(UIApplication *)application { }
- (void)applicationWillTerminate:(UIApplication *)application { }
@end
The OLjective-C components ol liLpu pioviue line-giaineu suppoit loi
managing auuio conliguiations. You can choose to allow amLient auuio
as well as mixing, anu the contiollei class will automatically choose the
appiopiiate auuio session categoiy. You can also ieconliguie the auuio
components on the lly.
Moieovei, the auuio contiollei class implements the AVAudioSession
Delegate piotocol. An instance ol PdAudiocontroller will iegistei itsell
as the auuio session uelegate, anu it will automatically suspenu playLack
when a phone call comes in. Il this is not the uesiieu Lehavioi, oi il you
want to implement auuitional lunctionality (such as having the auuio
laue in anu out insteau ol just tuining it on anu oll), then you can simply
cieate a suLclass ol PdAudioController anu oveiiiue the methous whose
Lehavioi you`u like to change.
Now we iegistei a uispatchei oLject with liLpu. Vhile we uon`t expect to ieceive any
messages liom Pu loi the time Leing, the uispatchei may still come in hanuy Lecause
it will log status messages that Pu piints to the console.
Ve neeu to ueciue which pait ol oui app shoulu Le iesponsiLle loi managing the uis-
patchei. Since the main puipose ol uispatchei is to ieceive messages liom Pu, anu since
those messages will typically allect the usei inteilace, we`ll put the view contiollei in
chaige ol managing the uispatchei.
Altei iegisteiing the ieceivei, we open oui patch, also in the view contiollei. In oiuei
to open a patch, we neeu to specily the name ol the lile anu the path to the loluei that
contains it. Because ol the way we packageu the patch, we can simply invoke [[NSBundle
mainBundle] resourcePath] in oiuei to get the path.
94 | Chapter 6:Pd for iOS
The view controIIer interface GTViewControIIer.h.
#import <UIKit/UIKit.h>
#import "PdDispatcher.h"
@interface GTViewController : UIViewController {
PdDispatcher *dispatcher;
void *patch;
}
@end
The view controIIer impIementation GTViewControIIer.m.
#import "GTViewController.h"
@implementation GTViewController
#pragma mark - View lifecycle
-(void)viewDidLoad {
[super viewDidLoad];
dispatcher = [[PdDispatcher alloc] init];
[PdBase setDelegate:dispatcher];
patch = [PdBase openFile:@"tuner.pd"
path:[[NSBundle mainBundle] resourcePath]];
if (!patch) {
NSLog(@"Failed to open patch!");
// Gracefully handle failure...
}
}
-(void)viewDidUnload {
[super viewDidUnload];
[PdBase closeFile:patch];
[PdBase setDelegate:nil];
}
// Omitting the remaining view controller methods...
@end
The cleanup in the viewDidUnload methou is not stiictly necessaiy in this simple app,
Lut it is goou piactice to iemain awaie ol the iesouices that we aie consuming anu to
ielease them as soon as possiLle. Even with ARC, theie aie some iesouices that will
not Le automatically ieleaseu, such as Pu patches anu the uelegate ol PdBase.
In piinciple, we alieauy have a musical app. All the ciucial pieces aie piesent anu
woiking; il you launch the app, it will loau a patch, stait an auuio thieau anu ienuei
samples. A uispatchei is installeu anu ieauy to ieceive messages liom Pu. Il you watch
the log messages when launching the app, you`ll see that the auuio components aie
Leing conliguieu anu staiteu. Ve just uon`t heai anything yet Lecause the app uoesn`t
yet tiiggei any sounus. Ve`ll iemeuy that next.
Creating a Musical App: Part I | 95
Connecting the User Interface
In oiuei to have oui patch make sounus, we will auu a lew Luttons to oui usei inteilace.
Each will tiiggei a note coiiesponuing to a stiing on the guitai. The liist step is to auu
the necessaiy callLack lunctions to oui view contiollei (see the next coue example).
The view controIIer interface (GTViewControIIer.h) with caIIback methods.
#import <UIKit/UIKit.h>
#import "PdDispatcher.h"
@interface GTViewController : UIViewController {
PdDispatcher *dispatcher;
void *patch;
}
-(IBAction)playE:(id)sender;
-(IBAction)playA:(id)sender;
-(IBAction)playD:(id)sender;
-(IBAction)playG:(id)sender;
-(IBAction)playB:(id)sender;
-(IBAction)playE2:(id)sender;
@end
This is just the stanuaiu Loileiplate loi connecting UI elements to youi coue. The most
inteiesting pait is oui implementation ol the callLack methous (see the coue example
Lelow). Each callLack senus a MIDI note value to the patch (+0 loi the low E-stiing,
+5 loi the A-stiing, etc.) anu tiiggeis a sounu.
The view controIIer impIementation (GTViewControIIer.m) with caIIback
methods.
#pragma mark - button callbacks
-(void)playNote:(int)n {
[PdBase sendFloat:n toReceiver:@"midinote"];
[PdBase sendBangToReceiver:@"trigger"];
}
-(IBAction)playE:(id)sender {
NSLog(@"Playing E");
[self playNote:40];
}
-(IBAction)playA:(id)sender {
NSLog(@"Playing A");
[self playNote:45];
}
-(IBAction)playD:(id)sender {
NSLog(@"Playing D");
[self playNote:50];
96 | Chapter 6:Pd for iOS
}
-(IBAction)playG:(id)sender {
NSLog(@"Playing G");
[self playNote:55];
}
-(IBAction)playB:(id)sender {
NSLog(@"Playing B");
[self playNote:59];
}
-(IBAction)playE2:(id)sender {
NSLog(@"Playing E2");
[self playNote:64];
}
Finally, we cieate some Luttons in the usei inteilace anu connect them to oui callLack
methous. Open GT\icwContro||cr.xib in the Inteilace Builuei anu auu six Luttons to
the view, one loi each stiing on the guitai. You can assign appiopiiate titles in the
AttiiLute Inspectoi taL on the iight. Il you select Ii|c`s Owncr in the column on the lelt
anu open the connections taL on the iight, you will see oui newly cieateu callLack
methous. Connect each methou to the appiopiiate Lutton event (Figuie 6-11).
In this example, I have chosen to tiiggei sounus when the usei liist
touches a Lutton. This is slightly unusual; the stanuaiu Lehavioi ol Lut-
tons is to tiiggei actions on ielease. Still, I Lelieve that this is the coiiect
choice loi musical apps. Altei all, you will heai a sounu the moment
you piess a key on a piano, not when you ielease it.
Il you launch youi app now, you can push the Luttons anu heai the coiiesponuing
sounus. You may neeu to plug in heauphones il youi Luilt-in speakeis aie unaLle to
ienuei low lieguencies.
This simple example goes a long way towaius Luiluing musical apps. Most ol the majoi
pieces aie alieauy in place. Cleaily, oui app has lots ol ioom loi impiovement, Lut it
seives its puipose: It shows the anatomy ol a simple liLpu-Laseu app with a minimum
ol coue. As an exeicise, you may want to tiy anu impiove this app. Heie aie a lew topics
to think aLout:
Senuing a lloat anu a Lang when playing a sounu is somewhat ieuunuant. How
can you ievise the patch so that a miui note message also acts as a tiiggei? (Hint:
Look up tiiggeis in Pu.)
The sounu is guite Loiing. Can you ieplace the osc~ oLject with anothei sounu
that sounus moie inteiesting? (Hint: Look up the phasor~ oLject loi a guick anu
uiity change, oi ieau up on synthesis technigues anu tiy something moie
sophisticateu.)
Creating a Musical App: Part I | 97
Creating a Musical App: Part II
As in Chaptei 5, we mouily oui patch Ly auuing a fiddle~ oLject that peiloims pitch
analysis on the miciophone input. The patch will senu lloat values to the symLol
pitch when fiddle~ uetects a staLle pitch (Figuie 6-12).
Make suie to upuate the copy ol the patch in youi Xcoue pioject. Also, since the new
veision ol oui patch ieguiies auuio input, we neeu to ieguest input channels when
conliguiing the auuio components:
-(BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
_audioController = [[PdAudioController alloc] init];
if ([self.audioController configurePlaybackWithSampleRate:44100
numberChannels:2 inputEnabled:YES mixingEnabled:NO] != PdAudioOK) {
NSLog(@"failed to initialize audio components");
}
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.viewController = [[GTViewController alloc]
initWithNibName:@"GTViewController" bundle:nil];
Iigurc -11. Connccting buttons in |ntcrjacc Bui|dcr
98 | Chapter 6:Pd for iOS
Want to see more? Get your copy at oreilly.com
http://shop.oreilly.com/product/0636920022503.do

Anda mungkin juga menyukai