サウンド再生中のタイマーの使用
音声ファイルからサウンドを再生する。かつ再生している間、サウンドの出力レベルを読み取り続ける処理をタイマーで行う。そのために、ソースコードViewController.mの中で以下のように記述した。主要部分のみを示す。
まずは、オブジェクト変数名を定義しておく。
@implementation ViewController
{
AVAudioPlayer *ap;
}
AVAudioPlayerクラスのオブジェクトを生成する。ここでは音声ファイルsample.mp3を用意しておき、それを再生する。meteringEnabledプロパティを設定すると、サウンドの出力レベルを読み取ることが可能になるので、それをYESとしている。
NSBundle *bd = [NSBundlemainBundle]; NSString *path = [bd pathForResource:@"sample.mp3"ofType:@""]; NSURL *url = [NSURLfileURLWithPath:path]; ap = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:nil]; ap.meteringEnabled = YES; ap.delegate = self; channels = ap.numberOfChannels;
画面上には、サウンドの再生ボタンを設置している。このボタンを押すと、NSTimerクラスのオブジェクト(下の例では、playerTimer)を生成し、音声ファイルの再生([ap play])を始める。NSTimerクラスを使うことで、タイマーを管理できる。つまり、一定間隔(ここでは0.1秒間隔)でmonitorAudioPlayerを呼び出す。
- (IBAction)bt_touchdown:(UIButton *)sender { if(sender == bt[0]){ bt[0].enabled = NO; if (!playerTimer) { playerTimer = [NSTimer scheduledTimerWithTimeInterval:0.1 target:selfselector:@selector(monitorAudioPlayer)userInfo:nil repeats:YES]; } [ap play]; }
チャネルごとに最大出力レベルを読み取る。出力はデシベル単位で表示される。
- (void)monitorAudioPlayer { for (int i=0; i<channels; i++) { float db; [ap updateMeters]; db = [ap peakPowerForChannel:i]; NSLog(@"db=%f", db); } }
音声ファイルの再生を止めた後の処理の中で、タイマーを止める(出力レベルの読み取りをやめる)ために以下の処理を行う。
- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)sender successfully:(BOOL)flag { [playerTimer invalidate]; playerTimer = nil; }
参考サイト:iphone - Trying to understand AVAudioPlayer and audio level metering - Stack Overflow