では実際に楽器アプリを作り始めてみる。楽器アプリ作成で大事なのは、オーディオフレームワークの選定だ。前回解説したように、iPhoneは様々な種類のオーディオ技術を提供している。そこで、いくつかの技術を取り上げて、個別の楽器アプリを作ってみよう。

まず使ってみるのは、System Sound Serviceだ。おそらく、これが最も簡単な楽器アプリになるだろう。実現する楽器は、ベルにしてみる。つまり、鐘の音だ。この楽器を選んだ理由は、後で説明しよう。

System Sound Serviceの使い方

はじめに、System Sound Serviceについて説明しよう。これは、Audio Toolboxフレームワークが提供するサービスだ。警告音のような、短いサウンドを鳴らすために使われるものだ。目安としては、30秒以下のサウンドだ。iPhoneのバイブレーション機能も、このサービスからアクセスする。

System Sound Serviceの使い方は、非常に簡単だ。まず、システムサウンドIDを作成する。これには、AudioServicesCreateSystemSoundIDという関数を使う。引数として、.aifや.wavといったオーディオファイルを渡してやればいい。取得したシステムサウンドIDを鳴らすには、AudioServicesPlaySystemSoundという関数を使う。

たとえば、次のようなソースコードで音を鳴らす事ができるだろう。

List 1.

// オーディオファイルのパスを取得する
NSURL*  url;
url = [NSURL fileURLWithPath:
        [[NSBundle mainBundle] pathForResource:@"C4" ofType:@"aif"]];

// システムサウンドを作成する
AudioServicesCreateSystemSoundID((CFURLRef)url, &_soundC4);

// サウンドを鳴らす
AudioServicesPlayAlertSound(sound);

これだけだ。これで、プロジェクトに追加されているC4.aifというオーディオファイルを鳴らす事ができる。

このサービスを使って、楽器アプリを作る事を考えてみよう。まず、必要なオーディオファイル(おそらく12音以上)を読み込み、システムサウンドIDを取得する。そして、画面上のボタンなどが押されたら、それを鳴らす。これだけで楽器アプリとして動作するはずだ。

鍵盤のレイアウトと横回転

早速、アプリを作ってみよう。Xcodeを立ち上げて、新規プロジェクトを作成する。そして、ユーザインタフェースのレイアウトを行おう。

今回は、ピアノの鍵盤のようにボタンを配置しておこう。iPhoneを横に持って使うと想定しておく。

それぞれのボタンには、インスペクタウインドウを使って、tagの値を設定しておく。この値を使って、どのボタンが押されたか判別する事にしよう。この値は、UIViewクラスのtagプロパティから取得できる。

ボタンからは、アクションを接続しておこう。今回は、playSound:という、送り手を引き数に取るアクションを用意した。すべてのボタンからこのアクションを呼び出す事にする。レイアウトとアクションの接続が終わったら、Xcodeに戻ろう。

今回は横画面専用のインタフェースにしたので、アプリケーションの起動時に強制的に横画面にしておくことにする。applicationDidFinishLaunching:メソッドの中で、この処理を行おう。

List 2.

- (void)applicationDidFinishLaunching:(UIApplication *)application
{
    // ステータスバーを上にする
    [UIApplication sharedApplication].statusBarOrientation =
            UIInterfaceOrientationLandscapeRight;

    // アプリケーションの表示フレームを取得する
    CGRect  frame;
    frame = [UIScreen mainScreen].applicationFrame;

    // 中心位置を作成
    CGPoint center;
    center.x = CGRectGetWidth(frame) * 0.5f;
    center.y = CGRectGetHeight(frame) * 0.5f;

    // バウンズを作成
    CGRect  bounds;
    bounds.origin = CGPointZero;
    bounds.size.width = CGRectGetHeight(frame);
    bounds.size.height = CGRectGetWidth(frame);

    // アフィン変換を作成
    CGAffineTransform   transform;
    transform = CGAffineTransformMakeRotation(M_PI_2);

    // ビューを回転させる
    viewController.view.center = center;
    viewController.view.bounds = bounds;
    viewController.view.transform = transform;

    // ウィンドウを表示する
    [window addSubview:viewController.view];
    [window makeKeyAndVisible];
}

まず、ステータスバーの位置を変更しておく。そして回転を行うのだが、これはビューコントローラのビューに対して、transformプロパティを設定してやる事で実現できる。このプロパティはアフィン変換を表すものなので、90度回転する変換を指定してやればいい。

ただし、このとき注意しておきたい事がある。UIViewの大きさや位置を表すプロパティにframeがあるが、transformのプロパティとして単位行列以外を設定すると、この値は不定となる。代わりに、ビューの中心位置を表すcenterと、ビューの大きさを表すboundsといったプロパティを使用する必要が出てくるのだ。それらもあわせて設定行っている。

音を鳴らす

続いて、音を鳴らすための設定だ。まず、システムサウンドIDを作成する。これは、ビューコントローラクラスの、viewDidLoadで行っている。

List 3.

- (void)viewDidLoad
{
    // サウンドを読み込む
    NSURL*  url;

    url = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"C4" ofType:@"aif"]];
    AudioServicesCreateSystemSoundID((CFURLRef)url, &_soundC4);
    url = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"C#" ofType:@"aif"]];
    AudioServicesCreateSystemSoundID((CFURLRef)url, &_soundCS);
    ......

このようにして13個のオーディオファイルを読み込んでいる。

音を鳴らすのは、playSound:アクションメソッドだ。

List 4.

- (IBAction)playSound:(id)sender
{
    // タグを取得して、サウンドを決定する
    SystemSoundID   sound = (SystemSoundID)NULL;
    switch ([sender tag]) {
    case 100: sound = _soundC4;  break;
    case 101: sound = _soundCS; break;
    case 102: sound = _soundD;  break;
    case 103: sound = _soundDS; break;
    case 104: sound = _soundE;  break;
    case 105: sound = _soundF;  break;
    case 106: sound = _soundFS; break;
    case 107: sound = _soundG;  break;
    case 108: sound = _soundGS; break;
    case 109: sound = _soundA;  break;
    case 110: sound = _soundAS; break;
    case 111: sound = _soundB;  break;
    case 112: sound = _soundC5; break;
    }

    // サウンドを鳴らす
    if (sound) {
        AudioServicesPlayAlertSound(sound);
    }
}

このメソッドの引き数であるsenderとしてボタンが送られてくるので、そのタグの値からサウンドを決定している。そして、AudioServicesPlayAlertSoundで音を鳴らせばいい。

これで、十分な機能を持つ楽器アプリの完成だ。だが実際に使ってみると、いくつか不満を感じるだろう。まず、音量の調整ができていない。また、鳴らした音を途中で止める事ができない。System Sound Serviceは、これらの機能は提供していないのだ。

今回の説明で楽器としてベルを取り上げたのは、このようなAPIの制約があるためだ。ベルならば、音量や持続時間を変化できなくとも、それらしく聞こえると考えたのだ。

次回は、別のフレームワークを使って楽器アプリを作成して見よう。

ここまでのソースコード: ChurchBell-1.zip