2011-07-06 8 views
3

私はそれぞれが.cafファイルからオーディオサンプルを再生する6つのボタンを持っています。私がボタンを押すと、音がうまく再生されます。それが終わるのを待ってからもう一度押すと、それはうまくいきますが、ボタンを早く押すと、再生前に音がポップしてクリックされます。ボタンを押すと音が鳴ります。ヒットボタンは速く、サウンドの再生はポップとクリックします

ボタンをクリックするたびにAVAudioPlayerを割り当てるだけでは、このポップアップの問題はありませんでしたが、複数の割り当てでメモリリークが発生しました。だから、各ボタンに6つのAVAudioPlayersを作成して再利用しました。これはメモリリークを解消しましたが、上書きするとサンプルがクリック/ポップします。

私は、ボリュームを0に設定し、次のサンプルを再生する前にAVAudioPlayerインスタンスを停止するのをやめさせるためにさまざまな方法を試しましたが、高速のボタンを押して同じサンプルサウンドを繰り返し再生する正しい方法を見つけることができません。ポップを止める。

私はAVAudioPlayerプロパティを.hに保持し、allocステートメントでautoreleaseを使用しています。

お願いします。

**編集:解決策を見つけました。

基本的に私は10個のAVAudioPlayersを自動リリースし、1つが[myPlayer1 isPlaying]の場合は次のものを使用します。

BOOL done = NO; 

if(![self.audioPlayer0 isPlaying] && done == NO) { 
    self.audioPlayer0 = [ [[AVAudioPlayer alloc] initWithContentsOfURL:url error:nil] autorelease ]; 
    [audioPlayer0 play]; 
    done = YES; 
} 

if(![self.audioPlayer1 isPlaying] && done == NO) { 
    self.audioPlayer1 = [ [[AVAudioPlayer alloc] initWithContentsOfURL:url error:nil] autorelease ]; 
    [audioPlayer1 play]; 
    done = YES; 
} 

if(![self.audioPlayer2 isPlaying] && done == NO) { 
    self.audioPlayer2 = [ [[AVAudioPlayer alloc] initWithContentsOfURL:url error:nil] autorelease ]; 
    [audioPlayer2 play]; 
    done = YES; 
} 

if(![self.audioPlayer3 isPlaying] && done == NO) { 
    self.audioPlayer3 = [ [[AVAudioPlayer alloc] initWithContentsOfURL:url error:nil] autorelease ]; 
    [audioPlayer3 play]; 
    done = YES; 
} 

if(![self.audioPlayer4 isPlaying] && done == NO) { 
    self.audioPlayer4 = [ [[AVAudioPlayer alloc] initWithContentsOfURL:url error:nil] autorelease ]; 
    [audioPlayer4 play]; 
    done = YES; 
} 

if(![self.audioPlayer5 isPlaying] && done == NO) { 
    self.audioPlayer5 = [ [[AVAudioPlayer alloc] initWithContentsOfURL:url error:nil] autorelease ]; 
    [audioPlayer5 play]; 
    done = YES; 
} 

if(![self.audioPlayer6 isPlaying] && done == NO) { 
    self.audioPlayer6 = [ [[AVAudioPlayer alloc] initWithContentsOfURL:url error:nil] autorelease ]; 
    [audioPlayer6 play]; 
    done = YES; 
} 

if(![self.audioPlayer7 isPlaying] && done == NO) { 
    self.audioPlayer7 = [ [[AVAudioPlayer alloc] initWithContentsOfURL:url error:nil] autorelease ]; 
    [audioPlayer7 play]; 
    done = YES; 
} 

if(![self.audioPlayer8 isPlaying] && done == NO) { 
    self.audioPlayer8 = [ [[AVAudioPlayer alloc] initWithContentsOfURL:url error:nil] autorelease ]; 
    [audioPlayer8 play]; 
    done = YES; 
} 

if(![self.audioPlayer9 isPlaying] && done == NO) { 
    self.audioPlayer9 = [ [[AVAudioPlayer alloc] initWithContentsOfURL:url error:nil] autorelease ]; 
    [audioPlayer9 play]; 
} 

答えて

0

私は確認することはできませんが、あなたは波形の垂直部分(厄介なハーモニクス、クリック/ポップ)を引き起こす非ゼロクロス、で波を切り捨てているため、問題はおそらく発生します。波形をカットするのではなくフェードする必要があります。引き上げたコサインスムージング/シェイプを調べます。

+0

これもうまくいくかもしれませんが、それを設定することを検討した後、既存のAVAudioPlayerがまだ再生されている場合は、新しいAVAudioPlayerを生成しようと決めました。これにより、1つのAVAudioPlayerオブジェクトを使用して、複数のサンプルを1つずつオーバーレイするのではなく、互いにオーバーレイすることができます。とにかくありがとう。 – GeoffCoope

1

10人のオーディオプレーヤーをすべて動的に作成する代わりに覚えているのはなぜですか?

あなたの効果的なやり方は、すべてのオーディオプレーヤーをループして再生していないものを見つけることです。アレイ内で同じことをやってみませんか?理論的には

for (int i=0; i<playerHolder.count; i++) 
{ 
    if (![[playerHolder objectAtIndex:i] isPlaying]) 
    { 
     AVAudioPlayer *freePlayer = [playerHolder objectAtIndex:i]; 
     freePlayer = [ [[AVAudioPlayer alloc] initWithContentsOfURL:url error:nil] autorelease ]; 
     [freePlayer play]; 
    } 
} 

、混乱することなく、あなたのソリューションと同じことを達成する必要があります何かを再生しようとしたとき

NSMutableArray *playerHolder = [[NSMutableArray alloc] init]; 
int maxNumberOfBuffers = 10; 

for (int i=0; i<maxNumberOfBuffers; i++) 
{ 
    AVAudioPlayer *audioPlayer; 
    [playerHolder addObject:audioPlayer]; 
} 

はその後、単純に配列に目を通します。

+0

両方のソリューションでは、すべてのプレーヤーが使用されている状況を処理するものはありません。もしそれが起こるならば、音は単に演奏されないだろう。どちらのソリューションでも、プレイヤー数を約16に増やすことができ、問題はありません。それはあなたの音の長さによって異なります。 –

+0

それははるかにクリーンな方法、コードサンプルありがとう – GeoffCoope

+0

配列はうまくいきました。サンプルコードを少し変更して私の最後で動作させる必要がありましたが、コンセプトは健全でした。再度、感謝します。 – GeoffCoope

関連する問題