Нажмите кнопку, чтобы сделать звук. Нажмите кнопку быстрого и воспроизведения звука и щелкает - PullRequest
3 голосов
/ 06 июля 2011

У меня есть 6 кнопок, каждая из которых воспроизводит аудиофрагмент из файла .caf. Если я нажимаю кнопку, звук воспроизводится нормально, если я жду, пока он не закончится, и нажимаю ее снова, он воспроизводится нормально, но если я нажимаю кнопку быстро, то звук воспроизводится и щелкает перед воспроизведением.

У меня изначально не было этой проблемы со щелчком, когда я просто выделял AVAudioPlayer при каждом нажатии кнопки, но это приводило к утечке памяти при многократном выделении. Поэтому я создал 6 AVAudioPlayers для каждой кнопки и повторно использовал ее, это избавило от утечки памяти, но теперь образцы щелкают / всплывают при перезаписи.

Я пробовал множество разных способов, чтобы остановить это, от установки громкости до 0, остановки экземпляра AVAudioPlayer перед воспроизведением следующего семпла и т. Д., Но не могу найти правильный способ многократного воспроизведения одного и того же семпла с быстрым нажатием кнопки и остановки поппинг.

У меня есть свойство AVAudioPlayer, которое сохраняется в .h, и использую autorelease в операторе alloc.

Любая помощь, пожалуйста?

** Редактировать: нашел решение, это не красиво, но работает.

В основном я создал 10 AVAudioPlayers, которые автоматически выпускаются, и если один [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];
}

Ответы [ 2 ]

1 голос
/ 06 июля 2011

Почему вы помните все десять аудиоплееров вместо того, чтобы динамически создавать их?

В вашем новом решении вы эффективно просматриваете все аудиоплееры, чтобы найти тот, который не воспроизводится. Почему бы не сделать то же самое в массиве?

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

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

Затем просто просмотрите массив при попытке воспроизвести что-нибудь:

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];
    }
}

Теоретически, это должно достичь того же, что и ваше решение, без беспорядка.

0 голосов
/ 06 июля 2011

Не могу быть уверен, но проблема, вероятно, возникает из-за того, что вы усекаете волну при пересечении без нуля, что вызывает вертикальную часть в форме волны (неприятные гармоники, щелчок / всплывающее окно). Вам нужно ослабить форму волны, а не вырезать ее. Посмотрите на сглаживание / формирование приподнятого косинуса.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...