AVAudioPlayerを使った短いサウンドの鳴らし方(のポカとその直し方)
昨日の続きです。
ボタンを押したら音が出ると言う仕様はクリアされました。
しかし、最初のボタンの音が鳴っている間に次のボタンを押すと、音が重なってしまうと言う問題が浮上。
さてどうやったら解けるのかとウェブ上を彷徨う事約一分。
[iPhone 開発メモ] AVAudioPlayer を使用して音楽を再生する | Sun Limited Mt.
昨日と同じサイト上にて解を発見。
早速実装です。
取り合えず、
AVAudioPlayer **curSound; AVAudioPlayer *sound1; AVAudioPlayer *sound2; NSString *path; NSURL *url; path = [[NSBundle mainBundle] pathForResource:@"Sound_1" ofType:@"wav"]; url = [NSURL fileURLWithPath:path]; sound1 = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:nil]; path = [[NSBundle mainBundle] pathForResource:@"Sound_2" ofType:@"wav"]; url = [NSURL fileURLWithPath:path]; sound2 = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:nil]; curSound = &sound1;
と初期化&ロード(別関数にあるのを色々纏めてあります)
そして音を止めて新しい音を始める関数として
- (void) playSoundStoppingCur:(AVAudioPlayer *)newSound { [*curSound stop]; curSound = &newSound; [*curSound play]; }
を作成。
わくわくしながら実行を押してみたのですが・・・
コレが見事にクラッシュ・・・
何故だ・・・
追記
VSとは違うデバッグに悪戦苦闘しながらポインタが示している場所を見たり見直したりして答えが分かりました。
その解答は↓
- (void) playSoundStoppingCur:(AVAudioPlayer **)newSound { [*curSound stop]; curSound = newSound; [*curSound play]; }
そう。Parameterとしてポインタのポインタが必要だったのです。
(そして当然newSoundはAVAudioPlayer**になったのでcurSound = &newSound;)
最初の関数でも文法的にも目的的にも問題は無いのですが、所詮newSoundは一時的な変数。
この関数が終わったときにはポイ捨てされる運命です。
最初の関数ではcurSoundはもう存在しない番地を指し示している訳ですね。
うーーーーむ。ポインタについてはこう言うのをちょっと忘れてますね。
まぁ解けて良かったです。
所でこのAVAudioPlayer。何故か一番最初に音を出す時、ちょっと一瞬止まるんですよね。
何故だろう?
追記2:
AVAudioPlayerにはprepareToPlayと言う関数があり、先のそれを使っておけば最初の音は止まらないらしいです。
「らしい」なのは、なんとなく未だに停まっている気がするからです・・・
気の所為では無いと思うんですが・・・