OpenAL vs AVAudioPlayer and other ways to play sounds

I know that OpenAL is a fast library, but it does not support compressed audio format and is not so easy to use ...

AVAudioPlayer is not so fast, but it supports wide format file formats, as well as compressed formats such as mp3.

There is also a SKAction class that can play sound, as well as SystemSoundID ...

I have a few questions:

  • What would be the preferred way / player / technique for playing:

    • sound effects (several at a time)?
    • sound effects that can sometimes be repeated after a short delay
    • background music which loop
  • Also, is it a smart switch to using uncompressed sound for sound effects? I suppose this is normal because these files are small?

+4
source share
3 answers

I personally use ObjectAL . This is good because it uses OpenAL and AVAudioPlayer, but abstracts many of the complex parts from you. My game has background music, tons of sounds played simultaneously, and sounds encoded in the form of loops that increase volume, pitch, etc. Based on the speed of sprites. ObjectAL can do all this.

ObjectAL can be used to play simple sounds and music loops using the OALSimpleAudio class. Or you can delve deeper into it and do more complex things.

ObjectAL , .

, , . , , , .

+4

, . , 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

SKAudio.m

#import "SKAudio.h"

@implementation SKAudio

#pragma mark -
#pragma mark setup sound

// get a repeating sound
+(AVAudioPlayer*)setupRepeatingSound:(NSString*)file volume:(float)volume {
    AVAudioPlayer *s = [self setupSound:file volume:volume];
    s.numberOfLoops = -1;
    return s;
}

// setup a sound
+(AVAudioPlayer*)setupSound:(NSString*)file volume:(float)volume{
    NSError *error;
    NSURL *url = [[NSBundle mainBundle] URLForResource:file withExtension:nil];
    AVAudioPlayer *s = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:&error];
    s.numberOfLoops = 0;
    s.volume = volume;
    [s prepareToPlay];
    return s;
}

#pragma mark sound controls

// play a sound now through GCD
+(void)playSound:(AVAudioPlayer*)player {
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        [player play];
    });
}

// play a sound later through GCD
+(void)playSound:(AVAudioPlayer*)player afterDelay:(float)delaySeconds {

    dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delaySeconds * NSEC_PER_SEC);
    dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
        [player play];
    });
}

// pause a currently running sound (mostly for background music)
+(void)pauseSound:(AVAudioPlayer*)player {
    [player pause];
}

@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];
+3

Here is the @patrick solution port for 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()
}
+2
source

All Articles