Sprite kit OpenAL vs AVAudioPlayer vs其他播放声音的技术

Sprite kit OpenAL vs AVAudioPlayer vs其他播放声音的技术,sprite-kit,avaudioplayer,openal,skaction,Sprite Kit,Avaudioplayer,Openal,Skaction,我知道OpenAL是一个快速库,但它不支持任何压缩音频格式,而且使用起来也不那么容易 AVAudioPlayer速度不太快,但支持多种文件格式,以及mp3等压缩格式 还有一个SKAction类可以播放声音,以及SystemSoundID 我有几个问题: 首选的打法/球员/技术是什么: 音效(一次多个) 有时在小时间延迟后可以重复的声音效果 循环播放的背景音乐 另外,使用未压缩音频进行声音效果是明智之举吗?我想这没问题,因为这些文件的大小很小 我个人在用。这很好,因为它利用了OpenAL和AV

我知道OpenAL是一个快速库,但它不支持任何压缩音频格式,而且使用起来也不那么容易

AVAudioPlayer速度不太快,但支持多种文件格式,以及mp3等压缩格式

还有一个SKAction类可以播放声音,以及SystemSoundID

我有几个问题:

  • 首选的打法/球员/技术是什么:

    • 音效(一次多个)
    • 有时在小时间延迟后可以重复的声音效果
    • 循环播放的背景音乐
  • 另外,使用未压缩音频进行声音效果是明智之举吗?我想这没问题,因为这些文件的大小很小

  • 我个人在用。这很好,因为它利用了OpenAL和AVAudioPlayer,但却从您这里抽象出了许多复杂的部分。我的游戏有背景音乐,大量的声音同时播放,以及根据精灵的速度增加音量、音高等的循环声音。ObjectAL可以做到这一切

    ObjectAL可以使用它的OALSimpleAudio类来播放简单的声音和音乐循环。或者你可以更深入,做更复杂的事情

    我专门为我的游戏创建了一个简单的ObjectAL包装器,因此它被进一步抽象了


    据我所知,未压缩音频更好。你只需要确保预先加载声音,这样你的游戏就不会在每次播放声音时都试图拉文件。

    这个非常简单的类为我完美地服务了多个项目,同时运行了很多声音。我发现这比在OpenAL上大惊小怪要简单得多。它有你要求的一切,预先设置的声音,多个并发播放,延迟后,背景循环

    不管您是否使用压缩文件,因为您首先设置了它

    SKAudio.h

    #import <Foundation/Foundation.h>
    @import AVFoundation;
    
    @interface SKAudio : NSObject
    
    +(AVAudioPlayer*)setupRepeatingSound:(NSString*)file volume:(float)volume;
    +(AVAudioPlayer*)setupSound:(NSString*)file volume:(float)volume;
    +(void)playSound:(AVAudioPlayer*)player;
    +(void)playSound:(AVAudioPlayer*)player afterDelay:(float)delaySeconds;
    +(void)pauseSound:(AVAudioPlayer*)player;
    
    @end
    
    要在游戏中使用:

    设置一个类变量并将其与声音一起预加载:

    static AVAudioPlayer *whooshHit;
    static AVAudioPlayer *bgMusic;
    
    +(void)preloadShared {
    
        // cache all the sounds in this class 
        static dispatch_once_t onceToken;
        dispatch_once(&onceToken, ^{
    
           whooshHit = [SKAudio setupSound:@"whoosh-hit-chime-1.mp3" volume:1.0];
    
           // setup background sound with a lower volume
           bgMusic = [SKAudio setupRepeatingSound:@"background.mp3" volume:0.3];
    
        });
    
    }
    
    ...
    
    
    // whoosh with delay
    [SKAudio playSound:whooshHit afterDelay:1.0];
    
    ...
    
    // whoosh and shrink SKAction
    SKAction *whooshAndShrink = [SKAction group:@[
                 [SKAction runBlock:^{ [SKAudio playStarSound:whooshHit afterDelay:1.0]; }],
                 [SKAction scaleTo:0 duration:1.0]]];
    
    ...
    
    [SKAudio playSound:bgMusic];
    
    ... 
    
    [SKAudio pauseSound:bgMusic];
    

    这是@patrick对Swift 3的解决方案的一个端口

    import AVFoundation
    
    // MARK -
    // MARK setup sound
    
    // get a repeating sound
    func setupRepeatingSound(file: String, volume: Float) -> AVAudioPlayer? {
        let sound: AVAudioPlayer? = setupSound(file: file, volume: volume)
        sound?.numberOfLoops = -1
        return sound
    }
    
    // setup a sound
    func setupSound(file: String, volume: Float) -> AVAudioPlayer? {
        var sound: AVAudioPlayer?
        if let path = Bundle.main.path(forResource: file, ofType:nil) {
            let url = NSURL(fileURLWithPath: path)
            do {
                sound = try AVAudioPlayer(contentsOf: url as URL)
            } catch {
                // couldn't load file :(
            }
        }
        sound?.numberOfLoops = 0
        sound?.volume = volume
        sound?.prepareToPlay()
        return sound
    }
    
    // MARK sound controls
    
    // play a sound now through GCD
    func playSound(_ sound: AVAudioPlayer?) {
        if sound != nil {
            DispatchQueue.global(qos: .default).async {
                sound!.play()
            }
        }
    }
    
    // play a sound later through GCD
    func playSound(_ sound: AVAudioPlayer?, afterDelay: Float) {
        if sound != nil {
            DispatchQueue.main.asyncAfter(deadline: .now() + Double(afterDelay)) {
                sound!.play()
            }
        }
    }
    
    // pause a currently running sound (mostly for background music)
    func pauseSound(_ sound: AVAudioPlayer?) {
        sound?.pause()
    }
    

    这看起来很简单,我会试试看。但我不确定我是否理解示例中的dealloc方法……为什么我们手动调用release?我认为您在示例中看到了release,因为它可能是在arc之前创建的。这是一个相当古老的图书馆。您可能不需要使用release或retain。啊,我理解。谢谢我终于尝试了ObjectAL,它看起来非常适合播放多个短声音。但有一个问题。它与电话中断有关。。。你经历过这样的事情吗很抱歉直接与您联系,但我认为您可能知道如何处理此问题,因为您提到您的游戏已使用ObjectAL。非常感谢您的回复,我会尝试一下。我听说过这种方法(通过GCD播放声音),但从未见过它的实际实现。
    import AVFoundation
    
    // MARK -
    // MARK setup sound
    
    // get a repeating sound
    func setupRepeatingSound(file: String, volume: Float) -> AVAudioPlayer? {
        let sound: AVAudioPlayer? = setupSound(file: file, volume: volume)
        sound?.numberOfLoops = -1
        return sound
    }
    
    // setup a sound
    func setupSound(file: String, volume: Float) -> AVAudioPlayer? {
        var sound: AVAudioPlayer?
        if let path = Bundle.main.path(forResource: file, ofType:nil) {
            let url = NSURL(fileURLWithPath: path)
            do {
                sound = try AVAudioPlayer(contentsOf: url as URL)
            } catch {
                // couldn't load file :(
            }
        }
        sound?.numberOfLoops = 0
        sound?.volume = volume
        sound?.prepareToPlay()
        return sound
    }
    
    // MARK sound controls
    
    // play a sound now through GCD
    func playSound(_ sound: AVAudioPlayer?) {
        if sound != nil {
            DispatchQueue.global(qos: .default).async {
                sound!.play()
            }
        }
    }
    
    // play a sound later through GCD
    func playSound(_ sound: AVAudioPlayer?, afterDelay: Float) {
        if sound != nil {
            DispatchQueue.main.asyncAfter(deadline: .now() + Double(afterDelay)) {
                sound!.play()
            }
        }
    }
    
    // pause a currently running sound (mostly for background music)
    func pauseSound(_ sound: AVAudioPlayer?) {
        sound?.pause()
    }