适用于iOS应用程序的多轨mp3播放

时间:2012-10-15 19:48:03

标签: objective-c ios core-audio openal audiounit

我正在做一个涉及以多轨道格式播放歌曲的应用程序(鼓,人声,吉他,钢琴等......)。我不需要对每个音轨进行任何精美的音频处理,我需要做的就是播放,暂停和静音/取消静音。

我一直在使用AVAudioPlayer的多个实例,但在进行设备测试时,我注意到首次播放时曲目的播放效果非常不同步。此外,当我暂停并播放曲目时,它们会继续变得更加不同步。经过一番研究后,我意识到AVAudioplayer只有太多的延迟,不能用于我的应用程序。

在我的应用程序中,我基本上有一个AVAudioPlayers的NSArray,我会循环播放每个或暂停/停止每个,我确信这是导致它在设备上失去同步的原因。

似乎苹果的音频混音器对我来说效果很好,但是当我尝试实现它时,我得到一个我无法弄清楚的EXC_BAD_ACCESS错误。

我知道答案是使用OpenAL或音频单元但是当我需要做的就是同时播放5个.mp3音轨时,似乎没有必要花几个星期来学习这些。有没有人对如何做到这一点有任何建议?感谢

3 个答案:

答案 0 :(得分:5)

感谢admsyn的建议,我能够提出解决方案。

AVAudioPlayer有一个currentTime属性,可以返回轨道的当前时间,也可以设置。

所以我按照admsyn的说明实现了startSynchronizedPlayback,然后在我停止跟踪时添加了以下内容:

-(void) stopAll
{
int count = [tracksArr count];
for(int i = 0; i < count; i++)
    {
    trackModel = [tracksArr objectAtIndex:i]
    if(i = 0)
        {
         currentTime = [trackModel currentTime]
        }
    [trackModel stop]
    [trackModel setCurrentTime:currentTime]
    }
{

此代码基本上遍历我的轨道数组,每个轨道都拥有自己的AVAudioPlayer,从第一个轨道获取当前时间,然后将所有以下轨道设置为该时间。现在,当我使用startSynchronizedPlayback方法时,它们都会同步播放,并且暂停未暂停使它们保持同步。希望这对试图保持曲目同步的其他人有所帮助。

答案 1 :(得分:4)

如果您向每个AVAudioPlayer发出单独的play消息,则消息完全可能在不同时间到达,或者AVAudioPlayers完成彼此不同步的预热阶段。您应该使用playAtTime:deviceCurrentTime属性来实现正确的同步。请注意deviceCurrentTime的描述:

  

在调用playAtTime:instance方法时,使用此属性指示“now”。通过将多个音频播放器配置为在deviceCurrentTime的指定偏移处播放,您可以执行精确同步 - 如该方法的讨论中所述。

另请注意playAtTime:讨论中的示例代码:

// Before calling this method, instantiate two AVAudioPlayer objects and
// assign each of them a sound.

- (void) startSynchronizedPlayback {

    NSTimeInterval shortStartDelay = 0.01;            // seconds
    NSTimeInterval now = player.deviceCurrentTime;

    [player       playAtTime: now + shortStartDelay];
    [secondPlayer playAtTime: now + shortStartDelay];

    // Here, update state and user interface for each player, as appropriate
}

答案 2 :(得分:0)

如果您能够将文件解码到磁盘,那么音频单元可能是提供最佳延迟的解决方案。如果您决定使用这样的架构,您还应该查看Novocaine:

https://github.com/alexbw/novocaine

该框架在处理音频单元时遇到了很多麻烦。