iOS目标C低延迟音频播放,如SoundPool

时间:2015-04-05 20:50:23

标签: ios objective-c audio

嘿,在我的Android应用程序上,我可以在SoundPool中预加载我的声音,然后几乎没有延迟播放它们。现在我在iOS / obj-c上寻找相同的东西,但我找不到类似的东西。

我遵循了几个教程,但最终有一个比我预期的更大的延迟,大多数教程建议你将音频转换为未压缩的格式,如wav或caf,但我的MP3已经在14 mb并将它们转换为无损音频导致81 MB的数据对我来说太过分了。

我尝试过的最有希望的事情就是预加载文件(就像我在Android&#'s SoundPool中所做的那样),就像这个OAL示例中所示:

- (bool) preloadUrl:(NSURL*) url seekTime:(NSTimeInterval)seekTime
{
    if(nil == url)
    {
        OAL_LOG_ERROR(@"%@: Cannot open NULL file / url", self);
        return NO;
    }

    OPTIONALLY_SYNCHRONIZED(self)
    {
        // Bug: No longer re-using AVAudioPlayer because of bugs when using multiple players.
        // Playing two tracks, then stopping one and starting it again will cause prepareToPlay to fail.

        bool wasPlaying = playing;

        [self stopActions];

        if(playing || paused)
        {
            [player stop];
        }

        as_release(player);

        if(wasPlaying)
        {
            [[NSNotificationCenter defaultCenter] performSelectorOnMainThread:@selector(postNotification:) withObject:[NSNotification notificationWithName:OALAudioTrackStoppedPlayingNotification object:self] waitUntilDone:NO];
        }

        NSError* error;
        player = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:&error];
        if(nil == player)
        {
            OAL_LOG_ERROR(@"%@: Could not load URL %@: %@", self, url, [error localizedDescription]);
            return NO;
        }

        player.volume = muted ? 0 : gain;
        player.numberOfLoops = numberOfLoops;
        player.meteringEnabled = meteringEnabled;
        player.delegate = self;
        player.pan = pan;

        as_release(currentlyLoadedUrl);
        currentlyLoadedUrl = as_retain(url);

        self.currentTime = seekTime;
        playing = NO;
        paused = NO;

        BOOL allOK = [player prepareToPlay];
        if(!allOK)
        {
            OAL_LOG_ERROR(@"%@: Failed to prepareToPlay: %@", self, url);
        }
        else
        {
            [[NSNotificationCenter defaultCenter] performSelectorOnMainThread:@selector(postNotification:) withObject:[NSNotification notificationWithName:OALAudioTrackSourceChangedNotification object:self] waitUntilDone:NO];
        }
        preloaded = allOK;
        return allOK;
    }
}

但这对于像我这样的音频应用来说仍然会产生大约60毫秒的相当大的延迟。我的音频文件在开头没有任何延迟,因此必须对代码执行某些操作。

我在iPhone 5c上尝试了所有这些东西。

1 个答案:

答案 0 :(得分:1)

能够创建多个AVAudioPlayer并在其上调用prepareToPlay,但我个人喜欢使用AVAssetReader来保留LPCM的缓冲区音频随时可以播放。