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

看起来像一个简单的任务,启动和停止超低延迟的声音。

我是否应该使用上述方法之一,或者只是咬紧牙关,深入核心音频单元。

有人有主意吗?


我刚刚制作了一个应用程序,它具有与您正在尝试完成的功能类似的功能。 我的推荐:

  • 使用AVAudioPlayer(和AVAudioRecorder进行录制)。
  • 使用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

    上一篇: Play and stop a sound sample on iOS (Novocaine)

    下一篇: System Sound plays very quietly over speakers