2013-12-10 2 views
1

Я пытаюсь создать простое приложение Drumpad. Приложение должно быть супер быстрым и воспроизводить звук с минимальной задержкой. Предпосылка - это выборки аудио в массиве, и каждый из них воспроизводится, когда вы нажимаете пэд.Воспроизведение и остановка звукового образца на iOS (Novocaine)

Уловка заключается в том, что некоторые колодки являются аккордами (а не барабанами), поэтому им необходимо немедленно остановиться.

Вот подходы я пытался:

System Sound - Очень прост в реализации, супер отзывчивый, никакого способа остановить звуки, не разрушая их, не звучит косяк быть более чем на 30 секунд.

AV Framework - Способ замедления.

Удивительный звуковой движок - Кажется приятным, но не уверен, что преимущество над CoreAudio, поскольку настройка была довольно сложной, я не смог получить звук для воспроизведения. Также не уверен в задержке.

Novocaine - Я остановился на этом сейчас, это кажется очень быстрым, и я могу воспроизводить звуки, но я не видел возможности остановить их, как только они начнутся. Я не знаю, как я могу остановить один звук, не останавливая весь аудиомастер?

- (void) playSoundN:(int)padNum 
{ 
    __weak ViewController * wself = self; 

    NSURL *inputFileURL = [[NSBundle mainBundle] URLForResource:@"Drum - Kick" withExtension:@"wav"]; 

    self.fileReader = [[AudioFileReader alloc] 
        initWithAudioFileURL:inputFileURL 
        samplingRate:self.audioManager.samplingRate 
        numChannels:self.audioManager.numOutputChannels]; 

    [self.fileReader play]; 
    self.fileReader.currentTime = 0.0; 

    [self.audioManager setOutputBlock:^(float *data, UInt32 numFrames, UInt32 numChannels) 
    { 
     [wself.fileReader retrieveFreshAudio:data numFrames:numFrames numChannels:numChannels]; 
     NSLog(@"Time: %f", wself.fileReader.currentTime); 
    }]; 

    [self.audioManager play]; 
} 

Кажется, простая задача, начиная и останавливая звук со сверхнизкой задержкой.

Должен ли я использовать один из вышеуказанных подходов или просто укусить пулю и погрузиться в Core Audio Units.

У кого-нибудь есть идеи?

ответ

2

Я только что сделал приложение, которое имеет сходную функциональность с тем, что вы пытаетесь выполнить. Моя рекомендация:

  1. Используйте AVAudioPlayer (и AVAudioRecorder для записи).
  2. Используйте метод класса prepareToPlay, чтобы предварительно загрузить звук и уменьшить задержку.

Вы можете прочитать больше о классах в документации AVFoundation: https://developer.apple.com/library/ios/DOCUMENTATION/AVFoundation/Reference/AVFoundationFramework/_index.html

+0

Спасибо, я дам ему выстрел снова и посмотрим, приемлемо ли отставание –

1

в изумлении, alexbw принял патч быстро. При обновлении до нового кода, вы можете просто использовать следующие строки в выходном блоке:

[weakSelf.reader retrieveFreshAudio:data numFrames:numFrames numChannels:numChannels]; 
    if (!weakSelf.reader.playing) { 
     weakSelf.audioManager.outputBlock = nil; 
     dispatch_async(dispatch_get_main_queue(), ^{ 
      // UI stuff 
     }); 
    } 

новокаин не может сказать EOF файла, последний используется буфер повтора. Учитывая, что автор считает, что AudioFileReader - это всего лишь кусок сахара и вряд ли его исправит, вот грязное решение.

__block float lastTimeLeft = 0.0f; 
[self.audioManager setOutputBlock:^(float *data, UInt32 numFrames, UInt32 numChannels) { 
    float timeLeft = weakSelf.reader.duration - [weakSelf.reader getCurrentTime]; 
    if (timeLeft > 0.01 && timeLeft != lastTimeLeft) { 
     lastTimeLeft = timeLeft; 
     [weakSelf.reader retrieveFreshAudio:data numFrames:numFrames numChannels:numChannels]; 
    } else { 
     [weakSelf.reader retrieveFreshAudio:data numFrames:numFrames numChannels:numChannels]; //forget this line will cause a buzz at the end. 
     [weakSelf.reader pause]; 
     weakSelf.audioManager.outputBlock = nil; 
    } 
}]; 

Лучшим решением было бы залатать AudioFileReader.

+0

Спасибо, что я скоро закрою этот снимок! –