2009-03-03 16 views
4

私は、AVAudioPlayerを使用してサウンドFXをアプリケーションの別のスレッドで再生しています。今、私のアプリはかなりシンプルですが、私はスクロールバックグラウンドのためのUIScrollViewを持っています。単純なサイドスクロールタイプのゲーム(マリオやカンフーなど)でプレイヤーと敵を表すCALayersをいくつか持っています...ビューを適切にスクロールして、問題なくプレーヤを左右に動かすことができます。私はサウンドエフェクトを演奏している "攻撃"ボタンを持っています...そして、サウンドエフェクトを演奏すると何度も、グラフィックスでちょっとしたヒッチがあります。これはQuartzを使ったiPhoneのコースのパーですか? OpenGLを調べ始めることなく、これを少しでもスムーズに実行できる方法はありますか?iPhoneゲームでサウンドを再生する - スローダウン

答えて

2

どのようにサウンドを再生していますか?私が推測するならば、サウンドが再生されるたびに、OSは実際にそれをディスクから読み込んで再生することになります。

更新:

[OK]を、あなたが本当に音を再生するために新しいスレッドを作成する必要はありません。これだけでゲームに吃音を引き起こす可能性があり、冗長性もあります。AVAudioPlayerの再生方法は非同期です。サウンドが終了したときではなく、すぐに戻ります。

1

(答えではなく、長さのためにコメントを使用するので、私はコードを表示することができます):

- (void)playSoundThreaded:(id)soundPlayer 
{ 
    if(soundPlayer == nil) 
    return; 

    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; 
    [(AVAudioPlayer*)soundPlayer play]; 
    [pool release]; 
} 

- (void)playSound:(AVAudioPlayer*)player 
{ 
    if(player == nil) 
    return; 

    [NSThread detachNewThreadSelector:@selector(playSoundThreaded:) 
    toTarget:self withObject:(id)player]; 
} 

そして、次のように音がアップロードされている:メソッドをプレイ

私の音は、次のとおりです。

fxPlayer = [[AVAudioPlayer alloc] initWithData: 
    [NSData dataWithContentsOfFile: 
    [[NSBundle mainBundle] pathForResource:@"voicehiya" ofType:@"caf"]] error:NULL]; 

私たちは、音がディスクから毎回再ロードされていることをいくつかの暗示があった...しかし、それはあるか、それを防ぐ方法を理由として見当がつかないました。

4

dataWithContentsOfFileの代わりにNSData dataWithContentsOfMappedFileを使用します。

また、AVAudioPlayerは独自のスレッドを処理します。作成する必要はありません。 [AVAudioPlayer play]は再生を開始した後に戻ります。再生終了後ではありません。

AVAudioPlayerを不要にしたときには、忘れずにそれを忘れないでください。たとえば、音だけを再生したい場合は、audioPlayerDidFinishPlayingを実装します:正常にデリゲートしてリリースします。

1

スレッドがあなたのプレーヤーを複雑にすると思う。

/* setup the sound player */ 
AVAudioPlayer *player1=[[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL  fileURLWithPath:audioFilePath] error:NULL]; 
player1.numberOfLoops = 0; 
player1.volume=1.0f; 
[player1 prepareToPlay]; 

をして、playSoundは

[player play]; 

になり、AudioSessionカテゴリがあまりにも正しく設定されていることを忘れないでください:行くためにこれを試してみてください。

2

私は同じような問題を抱えていました。ときに最初にロード、それを解決するために、私は最初のボリューム0でサウンドを再生し、一時停止 - これはまだ減速をもたらすと思われるprepareToPlayより良い作品:

player.volume = 0.0; 
[player play]; 
[player pause]; 
player.volume = 1.0; 

私がちょうど[サウンドを再生するには時間が来るとプレイヤープレイ];その後、更新サイクルごとに、アクティブなすべてのサウンドをループして、終了しようとしているサウンドをキャッチし、期限切れにするのではなく巻き戻します。これによりオーバーヘッドがなくなり、サウンドを最初から起動するのが遅くなります。ここでの例では、音の終わりから2番目の音1/15を停止します。

for ({each player in active sounds}) 
{ 
    if ((player.duration - player.currentTime) <= (1.0/15.0)) 
    { 
    [player pause]; 
    player.currentTime = 0.0; 
    } 
} 

は、今では次のプレイのために行く準備ができます。うまく動作するようです!

更新:私はまだサウンドが再生されたときに少し休止していました。私はゼロボリュームで演奏することは実際に何もしていないと思いますが、それを0.0001音量で再生してから一時停止するように変更しました。聞こえませんが、サウンドを準備する作業をしているようです。

1

なぜAudioServicesPlaySystemSoundを使用しないのですか?これは効果音に適しています。

私のゲーム(vConqr)ではUIScrollViewも使用されています。これは他にもたくさんのビューがあります(すべて自分自身のCALayerを持つため)。パフォーマンスにはあまり影響しません。

+0

AudioServicesPlaySystemSoundには個別の音量コントロールがありません。私は元々このようにしていましたが、それには吃音はありませんでした。 – GoatRider

+0

には、fxにとって本当に価値のあるボリュームコントロールがあります。ほとんどの人は、それらをオンまたはオフにしたいだけです – philsquared

+0

それはもちろん、アプリケーションに依存します。私はお互いにバウンドしているボールを使ってシミュレーションを進めていました。各ヒットの音量がヒットのベロシティに比例するようにしたいと思っていました。 – GoatRider

2

最初は同じ問題がありました。ドキュメントごとに、サウンドの再生が終了するたびに「prepareToPlay」を呼び出す必要があります。 AVAudioPlayerDelegateプロトコルを採用し、次のメソッドを追加するとこれが実行されます。

-(void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag{ 
    [player prepareToPlay]; 
} 
0

私は仕事中のプロジェクトのおかげで数日間これを調査してきました。自分のコードに自家用のプロファイリングを追加し、サウンドを再生する呼び出しがOpenGLゲームでフレームレートの問題を引き起こしていることがわかりました。私は私が見つけたものに基づいてあなたのためのいくつかの提案を持っている:

  1. は、あなたのバックグラウンドミュージックのためのmp3を再生するAVAudioPlayerを使用してください。

  2. 効果音としては、OpenALを使用してください。

  3. サウンドエフェクトの場合は、appleのオーディオコンバータコマンドラインツールを使用して、サウンドを.caf形式にします。これは、非圧縮形式で、サウンドカードに送信する前にCPUがサウンドをメモリに展開する必要はありません。直接行くことができ、時間を節約できます。ツールの使用方法については、HEREを参照してください。 (ページの一番下までスクロールしてください)

  4. よく聞こえる最も低いビット深度を使用してください。あなたは本当に128 kbpsを必要としません - あなたはおそらく多くのもののために20で離れて得ることができます。低いビットレート=少ない処理=より速いサウンド。

他にも役立つ情報があればお知らせします。がんばろう!

関連する問題