我正在尝试制作一个简单的Drumpad应用。该应用程序需要超快,并尽可能少延迟播放声音。前提是将音频样本存储在一个数组中,当你敲击打击垫时会播放每个音频样本。
问题在于,有些打击垫是和弦(而不是鼓),所以他们需要立即停止On Touch Up。
以下是我尝试的方法:
系统声音 - 实现起来非常简单,反应灵敏,无法在不破坏声音的情况下停止声音,声音不能超过30秒。
AV框架 - 放慢速度的方法。
惊人的音频引擎 - 看起来不错,但不确定CoreAudio的优势是什么,因为设置相当复杂我无法播放声音。也不确定延迟。
Novocaine - 我现在已经解决了这个问题,看起来非常快,而且我可以播放声音,但是一旦他们开始我就看不到阻止它们了。我不知道如何在不停止整个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];
}
看起来像一个简单的任务,启动和停止超低延迟的声音。
我是否应该使用上述方法之一,或者只是咬紧牙关潜入Core Audio Units。
有人有什么想法吗?
答案 0 :(得分:2)
我刚刚开发了一款应用程序,它具有与您要完成的功能类似的功能。我的建议:
prepareToPlay
方法预加载声音并减少延迟。您可以在AVFoundation
文档中阅读有关这些类的更多信息:
https://developer.apple.com/library/ios/DOCUMENTATION/AVFoundation/Reference/AVFoundationFramework/_index.html
答案 1 :(得分: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
});
}
__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。