Someone ask me to share the code I hacked in for a delay between sounds. Here it is:
typedef struct _channelGroup {
int startIndex;
int endIndex;
int currentIndex;
bool mute;
////// added
uint64_t minimalPause;
uint64_t lastTimeStamp;
//////
} channelGroup;
////// added
- (void) setPauseTime:(int64_t)pause forChannelGroup:(int)channel
{
_channelGroups[channel].minimalPause = pause;
}
//////
- (ALuint)playSound:(int) soundId channelGroupId:(int)channelGroupId pitch:(float) pitch pan:(float) pan gain:(float) gain loop:(BOOL) loop {
#ifdef DEBUG
//Sanity check parameters - only in DEBUG
NSAssert(soundId >= 0, @"soundId can not be negative");
NSAssert(soundId < CD_MAX_BUFFERS, @"soundId exceeds limit");
NSAssert(channelGroupId >= 0, @"channelGroupId can not be negative");
NSAssert(channelGroupId < _channelGroupTotal, @"channelGroupId exceeds limit");
NSAssert(pitch > 0, @"pitch must be greater than zero");
NSAssert(pan >= -1 && pan <= 1, @"pan must be between -1 and 1");
NSAssert(gain >= 0, @"gain can not be negative");
#endif
uint64_t timeStamp;
channelGroup *cGroup = &_channelGroups[channelGroupId];
//If mute or initialisation has failed or buffer is not loaded then do nothing
if (_mute || !functioning || _bufferStates[soundId] != CD_BS_LOADED || cGroup->mute) {
#ifdef DEBUG
if (!functioning) {
CCLOG(@"Denshion: sound playback aborted because sound engine is not functioning");
} else if (_bufferStates[soundId] != CD_BS_LOADED) {
CCLOG(@"Denshion: sound playback aborted because buffer %i is not loaded", soundId);
}
#endif
return CD_MUTE;
}
//Work out which channel we can use
int channel = cGroup->currentIndex;
if (channel != CD_CHANNEL_GROUP_NON_INTERRUPTIBLE) {
if (cGroup->startIndex != cGroup->endIndex) {
cGroup->currentIndex++;
if(cGroup->currentIndex > cGroup->endIndex) {
cGroup->currentIndex = cGroup->startIndex;
}
}
////// added
if(cGroup->minimalPause > 0)
{
timeStamp = getTimeStampInMiliseconds();
if((timeStamp - cGroup->lastTimeStamp) < cGroup->minimalPause)
return CD_NO_SOURCE;
cGroup->lastTimeStamp = timeStamp;
}
//////
return [self _startSound:soundId channelId:channel pitchVal:pitch*scheduler.timeScale panVal:pan gainVal:gain looping:loop checkState:TRUE];
} else {
//Channel group is non interruptible therefore we must search for the first non playing channel/source if there are any
int checkingIndex = cGroup->startIndex;
ALint state = 0;
while ((checkingIndex <= cGroup->endIndex) && (channel == CD_CHANNEL_GROUP_NON_INTERRUPTIBLE)) {
//Check if source is playing
alGetSourcei(_sources[checkingIndex], AL_SOURCE_STATE, &state);
if (state != AL_PLAYING) {
channel = checkingIndex;
}
checkingIndex++;
}
if (channel != CD_CHANNEL_GROUP_NON_INTERRUPTIBLE) {
//Found a free channel
////// added
if(cGroup->minimalPause > 0)
{
timeStamp = getTimeStampInMiliseconds();
if((timeStamp - cGroup->lastTimeStamp) < cGroup->minimalPause)
return CD_NO_SOURCE;
cGroup->lastTimeStamp = timeStamp;
}
//////
return [self _startSound:soundId channelId:channel pitchVal:pitch*scheduler.timeScale panVal:pan gainVal:gain looping:loop checkState:FALSE];
} else {
//Didn't find a free channel
return CD_NO_SOURCE;
}
}
}