使用AVAudioEngine构建循环序列器

时间:2015-03-17 13:59:53

标签: ios swift avfoundation core-audio avaudioengine

我正在使用iOS 8中的新AVAudioEngine功能构建一个简单的鼓机,但我无法思考如何构建循环机制。

似乎唯一的方法就是拥有一个AVAudioPlayerNodes的旋转缓冲区,并且有一些工作可以在将来不断调度缓冲区回放。它是否正确?

如果节点(及其缓冲区)只需要安排一次,那就太好了。然后,每当播放头到达序列的末尾时,节点都可以从{1}}开始,然后reset

我通过创建一个空的样本缓冲区,在顺控程序的末尾安排它并附加到play来尝试后者,但它似乎无法正常工作。

completionHandler

1 个答案:

答案 0 :(得分:0)

通过从文件中读取鼓循环/节拍(如上所述)或以编程方式创建可循环缓冲区。

然后使用AVAudioPlayerNodeBufferLoops选项安排该缓冲区,它将自动为您循环。

你可以有多个播放器节点,但我想到这些是轨道(如4轨录音机中的单个音轨),即同时播放声音。

然后在这些播放器节点上安排缓冲区。所以你可以有一个cy钹播放器节点和低音鼓播放器节点等,你的缓冲区就是样本声音。

我写了一个DTMF​​(音调)音调发生器,同时播放两个可循环的正弦波音,为此,我使用两个播放器节点,每个节点都有一个可循环的正弦波缓冲器。

在我的init方法中(createAudioBufferWithLoopableSineWaveFrequency:只填充pcmBuffer):

@property (nonatomic, readonly) AVAudioPlayerNode *playerOneNode;
@property (nonatomic, readonly) AVAudioPlayerNode *playerTwoNode;    
@property (nonatomic, readonly) AVAudioPCMBuffer* pcmBufferOne;
@property (nonatomic, readonly) AVAudioPCMBuffer* pcmBufferTwo;

[...]

    _playerOneNode = [[AVAudioPlayerNode alloc] init];
    [_audioEngine attachNode:_playerOneNode];

    [_audioEngine connect:_playerOneNode to:_mixerNode format:[_playerOneNode outputFormatForBus:0]];

    _pcmBufferOne = [self createAudioBufferWithLoopableSineWaveFrequency:frequency1];

    _playerTwoNode = [[AVAudioPlayerNode alloc] init];
    [_audioEngine attachNode:_playerTwoNode];

    [_audioEngine connect:_playerTwoNode to:_mixerNode format:[_playerTwoNode outputFormatForBus:0]];

    _pcmBufferTwo = [self createAudioBufferWithLoopableSineWaveFrequency:frequency2];

在我的游戏方法中:

if (_playerOneNode && _pcmBufferOne)
{
    [_playerOneNode scheduleBuffer:_pcmBufferOne atTime:nil options:AVAudioPlayerNodeBufferLoops completionHandler:^{

    }];

    [_playerOneNode play];
}

if (_playerTwoNode && _pcmBufferTwo)
{
    [_playerTwoNode scheduleBuffer:_pcmBufferTwo atTime:nil options:AVAudioPlayerNodeBufferLoops completionHandler:^{

    }];

    [_playerTwoNode play];
}

我的停止方法:

[_playerOneNode stop];
[_playerTwoNode stop];

如果它有帮助,我可以指向你的github项目。