iOS在播放前播放相同的音效

时间:2014-05-05 07:57:43

标签: ios audio

我正在为iOS 7创建一款iPhone游戏。我有一个名为sharedResources的类,其中包含在游戏中反复使用的某些数据的副本,包括4秒长的声音效果。

所以我正在创建这样的声音效果:

    filePathTD = [[NSBundle mainBundle]
                 pathForResource:@"towerDamage" ofType:@"aiff"];
    fileURLTD = [NSURL fileURLWithPath:filePathTD];

    towerDamge = [[AVAudioPlayer alloc] initWithContentsOfURL:fileURLTD
                                                    error:&error];
    if (error)
        NSLog(@"Error: %@", [error localizedDescription]);

然后在其他地方调用它:

[towerDamage play];

我的问题是,与我想要调用它的速度相比,声音效果很长。因此,当我在播放它的同时调用它时它不会同时播放,因为它已经在使用,而且我只有一个副本。

所以我问:在不使用太多内存的情况下,同时播放多次声音效果的最佳方法是什么?

我知道我可以制作多份副本,但是如果我为每个需要它的角色制作副本,那么当我可能只需要5份时,我可能会有30份副本。我想的是只制作5份副本,只使用目前没有使用的副本。但由于我是iOS开发的新手,我不确定除了这个黑客之外是否有更好的方法来完成这项任务?

1 个答案:

答案 0 :(得分:1)

在AVAudioPlayer实例上使用prepareToPlay将预加载声音文件。也许你可以将一些合理数量的它们加载到一个数组中,然后根据需要循环它们。如果您需要的数量超过分配的数量,那么您在此时选择将新的数据加载到内存中,或者再次启动列表中的第一个。一个更复杂的系统可以根据因素或应用程序中发生的事情在阵列中存储更多或更少的声音。

也许是这样的? (我已经遗漏了错误检查,而不是为了简洁起见)

  //setup the managing class to be
//<AVAudioPlayerDelegate>

///--- instance variables or properties
int nextIndexToPlayInArrayOfSounds = 0;
NSMutableArray *arrayOfSounds = [NSMutableArray array];
int numberOfSoundsNeeded = 10;


//make a method to setup the sounds
for (int i = 0; i < numberOfSoundsNeeded; i++) {

    AVAudioPlayer *mySound = [[AVAudioPlayer alloc] initWithContentsOfURL:[[NSBundle mainBundle] URLForResource:[NSString stringWithFormat:@"soundNameOnDisk"] withExtension:@"aiff"] error:NULL];
    mySound.delegate = self;
    [arrayOfSounds addObject:mySound];
    [mySound prepareToPlay];


}

//make a method to play a sound
//and then play the next sound in the list, or if past the end of the array, or play the first one
AVAudioPlayer *nextSoundToPlay;

if (numberOfSoundsNeeded > nextIndexToPlayInArrayOfSounds) {
    nextIndexToPlayInArrayOfSounds++;
}else{
    nextIndexToPlayInArrayOfSounds = 0;
}

//obviously I'm skipping error checking and nil pointers, etc
nextSoundToPlay = [arrayOfSounds objectAtIndex:nextIndexToPlayInArrayOfSounds ];
[nextSoundToPlay playAtTime:0];