2012年11月18日

AVAudioPlayerを使ってiPhoneで音楽を演奏する

iOS SDKを使ってBGMや効果音(SE)を鳴らす方法として以下のうちのいずれかを使うのが簡単だ。

AudioToolbox
AVFoundation(AVAudioPlayer)

このうちAudioToolboxは非常に簡単に使用することができるのでちょっとした効果音を鳴らすだけならこちらがよい。システム組込みのベルなどを鳴らしたり、バイブレーションをするのにも使う。

ただしあまり長い音楽を鳴らすのには向かない。アップルの文書ではおおよそ30秒以内の場合にはこちらを使うのに適しているとなっている。つまり、それ以上の長さの場合にはAVFoundationを使うべきだということになる。

今回は後者の使用方法を見て行く。手順としては

(前準備)
・プロジェクトにAVFoundation.frameworkを追加する。
・サウンドデータをプロジェクトに追加する。
(実行手順)
・アプリケーション初期化時にAudioSessionの種別を登録する。
・サウンドリソースを読み込む。
・サウンドを鳴らす

(0)プロジェクトを作成



ここではサンプルなのでなんでもいいのだが、SingleViewApplicationをテンプレートとして選択する。ARCを使う、StroyBoardを使うとしている。プロジェクト名はAVSampleとした。
AVSample1.png

Company Identifierにはテスト中は"edu.self"を使えばいいよってことらしい(ここでは後で実機で動かす必要があるので自社のを使っているけどね)。
AVSample2.png

(1)プロジェクトにAVFoundation.frameworkを追加する。



プロジェクトにAVFoundation.frameworkを追加する。
AVSample3.png

プロジェクトに前回作ったサウンドデータLoop1.cafを追加する。


(2)アプリケーション初期化時にAudioSessionの種別を登録する。



さてここからは、コード。AVAudioSessionの種別を登録するのは使用開始前であればいつでもいいのだが、アプリケーションの初期化時がよいだろう。これはiTunesで音楽を再生しながらアプリを使う場合にはその音楽を停めたくないし、逆にゲームのBGMを鳴らしていて他のバックグラウンドアプリの音楽は停めたいとかの制御をするためのもの。また録音するなど音声入力に関する設定もある。

AVAudioSessionCategoryAmbient; 音楽を鳴らすのが主ではないアプリ用。他のアプリの音は鳴っている。
AVAudioSessionCategorySoloAmbient; デフォルト。他のアプリの音は止まる。
AVAudioSessionCategoryPlayback; 音楽再生が主のアプリ用。
AVAudioSessionCategoryRecord; 録音用
AVAudioSessionCategoryPlayAndRecord; VOIP向け、入出力両方あり。
AVAudioSessionCategoryAudioProcessing; 信号処理。入出力オフ。
AVAudioSessionCategoryMultiRoute; 複数のデバイスへ出力するなど特殊な処理向け。

AVFoundation.png

ただしバックグラウンドでも鳴らし続けるには別途Info.plistの設定などが必要。

このプロジェクトの場合にはそれを書くクラスはXYZAppDelegate。

冒頭でAVFoundation.hを読み込み、- application:didFinishLaunchingWithOptions:に設定を書く。

#import <AVFoundation/AVFoundation.h>


- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
AVAudioSession *session = [AVAudioSession sharedInstance];
[session setCategory:AVAudioSessionCategoryPlayback error:nil];
return YES;
}


今回は、音楽再生メインのアプリということに。

(3)サウンドリソースを準備する。



ビューコントロールがロードされたときに、サウンドの準備をしておく。ヘッダファイルでAVFoundation.hを
#import <AVFoundation/AVFoundation.h>


以下はインプリメンテーションファイル。プレイヤーは自クラスからしかアクセスしないので無名カテゴリに定義する。

@interface XYZViewController ()
@property (strong,nonatomic) AVAudioPlayer *player;
@end


準備は、バンドルリソース内のファイルを読み込んでループ再生を設定。prepareToPlayを呼んでおかないとplayを呼んだ時にすぐに再生してくれない可能性があるので、あらかじめこれを呼んでプレイヤーの実行準備を終えておく。


@implementation XYZViewController

- (void)prepareSound
{
NSURL *soundFile = [NSURL fileURLWithPath:
[[NSBundle mainBundle]pathForResource:@"Loop1" ofType:@"caf"]];
self.player = [[AVAudioPlayer alloc] initWithContentsOfURL:soundFile error:nil];
self.player.delegate = self;

self.player.numberOfLoops = -1;
[self.player prepareToPlay];
}

- (void)viewDidLoad
{
[super viewDidLoad];
[self prepareSound];
}


(4)鳴らす



まずは演奏ボタン/停止ボタンを追加。
AVSample4.png

演奏は-play、停止は-stop。


- (IBAction)startAction:(id)sender {
[self.player play];
}

- (IBAction)stopAction:(id)sender {
[self.player stop];
}


今日は鳴らず所まで。

#なお、今手元にiOS6デバイスがないので、プロジェクトはiOS5.0向けになっています。

Xcode4.5.2
AVSample20121118.zip
posted by 永遠製作所 at 23:30| 東京 ☀| Comment(0) | TrackBack(0) | iPhone/iPod touch | このブログの読者になる | 更新情報をチェックする
この記事へのコメント
コメントを書く
お名前:

メールアドレス:

ホームページアドレス:

コメント: [必須入力]

※ブログオーナーが承認したコメントのみ表示されます。

この記事へのトラックバック