开发者

(iphone) Is having many AVAudioPlayer instance fine?

For my small game, I'd like to play effect sound for various scenario.

Mostly it will be user-interaction related.

I may need to play multiple sounds at one time.

I'm planning to allocate AVAudioPlayer for each sound.

I wonder a viewController having about 10-20 AVAudioPlayers is fine.

开发者_开发问答(sound data itself is rather small, less than 100k in aac)

I just feel that declaring 10-20 AVAudioPlayer instance in a class seems weird.

Is there a better way of doing it or am I just over-thinking it?


I think OpenAL is a better option in such situations. Dont worry if you dont know it. There is a great video tutorial here (with source code): http://www.71squared.com/2009/05/iphone-game-programming-tutorial-9-sound-manager/

To find more you can visit: http://benbritten.com/2008/11/06/openal-sound-on-the-iphone/comment-page-1/


Yes, it's fine to have many AVAudioPlayer instances. I don't know how many the limit is but it's definitely more than a dozen.

Here are some gotchas:

AVAudioPlayer doesn't do level mixing, so if your sounds are high volume, they may end up constructively interfering with each other and causing waveform distortion. I set a maximum volume of 0.8 to try to work around this, but it's not reliable.

If you try to start them all at the same time, using the play method may end up starting them out of sync. Instead, figure out a time soon enough that the user won't notice, but far enough away that it gives your code time to exit and AVFoundation time to get ready. Then use [player playAtTime:soon].

Here's some code that's working for me now. YMMV:

-(void)play
{
    BOOL success;

    AVAudioPlayer *player = self.player;

    player.numberOfLoops = -1;
    player.currentTime = 0;
    player.volume = _volume;

    // NSLog(@"deviceCurrentTime=%f", player.deviceCurrentTime);

    static double soon = 0;
    if (soon < player.deviceCurrentTime) {
        soon = player.deviceCurrentTime + 0.5; // why so flakey???
    }
    success = [player playAtTime:soon]; // too flakey for now

    if (!success) {
        NSLog(@"player %@ FAILED", player);
    } else {
        NSLog(@"player %@ %@ playing at: %f", player, [[player.url relativePath] lastPathComponent], soon);
    }
}

(I'm not sure if my "soon" var is thread-safe, and you should adjust the slop until it works for you... 0.1 was too fast for me at some point or other so I bumped it up to 0.5.)

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜