在iOS上播放和停止声音样本(Novocaine)
我正在尝试制作一个简单的Drumpad应用程序。 该应用程序需要超快速并尽可能以低延迟播放声音。 前提是将音频样本存储在一个阵列中,并且每击中一个打击垫时都会播放。
有一点需要注意的是,某些打击垫是和弦(而不是鼓),因此他们需要立即停止触摸起来。
以下是我尝试的方法:
系统声音 - 实现起来非常简单,超级响应,没有办法停止声音而不破坏声音,听起来不会超过30秒。
AV框架 - 减速的方法。
惊人的音频引擎 - 看起来不错,但不知道CoreAudio的优势是什么,因为安装过程非常复杂,我无法播放声音。 也不确定延迟。
诺沃卡因 - 我现在就定下来了,看起来非常快,我可以播放声音,但是一旦他们开始,我就没有办法阻止他们。 我不知道如何停止一个声音而不停止整个audioManager?
- (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];
}
看起来像一个简单的任务,启动和停止超低延迟的声音。
我是否应该使用上述方法之一,或者只是咬紧牙关,深入核心音频单元。
有人有主意吗?
我刚刚制作了一个应用程序,它具有与您正在尝试完成的功能类似的功能。 我的推荐:
prepareToPlay方法预加载声音并减少延迟。   您可以阅读更多关于AVFoundation文档中的类的信息:https://developer.apple.com/library/ios/DOCUMENTATION/AVFoundation/Reference/AVFoundationFramework/_index.html 
令人惊讶的是,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
        });
    }
Novocaine不能告诉文件的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。
链接地址: http://www.djcxy.com/p/67937.html