diff --git a/source/sound/sound.cpp b/source/sound/sound.cpp index bd10bf05c..e0e3792b5 100644 --- a/source/sound/sound.cpp +++ b/source/sound/sound.cpp @@ -43,8 +43,8 @@ typedef struct XMFILEDATA typedef struct SFXDETAILS { - int m_channels; - int m_pattern; + int m_channelMask; + int m_pattern; // ..or instrument for loopers int m_looping; }; @@ -71,10 +71,10 @@ static XMFILEDATA s_xmSfxData[CSoundMediator::NUM_SFXBANKIDS]= static SFXDETAILS s_sfxDetails[]= { - { 1, 0, 0 }, + { 1, 6, 1 }, { 1, 1, 0 }, { 1, 2, 0 }, - { 1, 3, 0 }, + { 1, 0, 1 }, }; @@ -90,22 +90,21 @@ static SFXDETAILS s_sfxDetails[]= -int CSoundMediator::s_initialised=false; -int /*CSoundMediator::*/s_currentVolume[CSoundMediator::NUM_VOLUMETYPES]; -int /*CSoundMediator::*/s_targetVolume[CSoundMediator::NUM_VOLUMETYPES]; -int /*CSoundMediator::*/s_volumeDirty[CSoundMediator::NUM_VOLUMETYPES]; +int CSoundMediator::s_initialised=false; +int CSoundMediator::s_currentVolume[CSoundMediator::NUM_VOLUMETYPES]; +int CSoundMediator::s_targetVolume[CSoundMediator::NUM_VOLUMETYPES]; +int CSoundMediator::s_volumeDirty[CSoundMediator::NUM_VOLUMETYPES]; + +xmSampleId CSoundMediator::s_songSampleId=NO_SAMPLE; +xmModId CSoundMediator::s_songModId=NO_SONG; +xmPlayingId CSoundMediator::s_songPlayingId=NOT_PLAYING; +xmSampleId CSoundMediator::s_sfxSampleId=NO_SAMPLE; +xmModId CSoundMediator::s_sfxModId=NO_SONG; static CSpuSound *s_spuSound; - static CXMPlaySound *s_xmplaySound; -static xmSampleId s_songSampleId=NO_SAMPLE; -static xmSongId s_songDataId=NO_SONG; -static xmPlayingSongId s_songPlayingId=NOT_PLAYING; - -static xmSampleId s_sfxSampleId=NO_SAMPLE; -static xmSongId s_sfxDataId=NO_SONG; @@ -123,7 +122,7 @@ void CSoundMediator::initialise() ASSERT(!s_initialised); s_spuSound=new ("SPUSound") CSpuSound(); s_spuSound->initialise(); - s_xmplaySound=new ("XMPlaySound") CXMPlaySound(); s_xmplaySound->initialise(); + s_xmplaySound=new ("XMPlaySound") CXMPlaySound(); s_xmplaySound->initialise(); CXAStream::Init(); @@ -138,9 +137,6 @@ void CSoundMediator::initialise() // ASSERT(CXAStream::MAX_VOLUME==32767); -PAUL_DBGMSG("song: %d-%d (%d)",SONG_BASE_CHANNEL,SONG_MAX_CHANNEL,SONG_CHANNELS); -PAUL_DBGMSG("sfx: %d-%d (%d)",SFX_BASE_CHANNEL,SFX_MAX_CHANNEL,SFX_CHANNELS); - SOUND_DBGMSG("Sound mediator initialised"); s_initialised=true; } @@ -172,13 +168,6 @@ ASSERT(0); Params: Returns: ---------------------------------------------------------------------- */ -int tgt=255; -int val; -static int s_spuChannelUse[24]={-1,-1,-1,-1,-1,-1, - -1,-1,-1,-1,-1,-1, - -1,-1,-1,-1,-1,-1, - -1,-1,-1,-1,-1,-1}; - void CSoundMediator::think(int _frames) { int i; @@ -188,61 +177,6 @@ void CSoundMediator::think(int _frames) ASSERT(s_initialised); -{ -int id; - -id=-1; -for(i=SONG_CHANNELS;i<24;i++) -{ - if(id!=s_spuChannelUse[i]) - { - id=s_spuChannelUse[i]; - if(id!=-1) - { -/* - if(id>=5000) - { -PAUL_DBGMSG("%d is now free.. ( was on chnl %d )",id-5000,i); - while(s_spuChannelUse[i]==id&&i<24) - { - s_spuChannelUse[i++]=-1; - } - i--; - } - else if(id>=100) - { - while(s_spuChannelUse[i]==id&&i<24) - { - s_spuChannelUse[i++]+=100; - } - i--; - } - else -*/ - if(!s_xmplaySound->isSfxActive((xmPlayingSongId)id)) - { -PAUL_DBGMSG("%d end.. ( was on chnl %d )",id,i); - while(s_spuChannelUse[i]==id&&i<24) - { - s_spuChannelUse[i++]=-1; - } - i--; - } -//else -//{ -// PAUL_DBGMSG("channel %d playing",i); -//} - } - } - -} -} - - - - - - // Fade to target volume speed=(_frames*VOLUME_CHANGE_SPEED)>>10; current=s_currentVolume; @@ -270,6 +204,8 @@ PAUL_DBGMSG("%d end.. ( was on chnl %d )",id,i); // Manual update of anything that needs it // CXAStream::ControlXA(); + s_xmplaySound->think(); + // Push through any changes in volume if(s_volumeDirty[SONG]||s_volumeDirty[SONGFADE]) @@ -305,11 +241,11 @@ void CSoundMediator::setSong(SONGID _songId) XMFILEDATA *song; ASSERT(s_songSampleId==NO_SAMPLE); - ASSERT(s_songDataId==NO_SONG); + ASSERT(s_songModId==NO_SONG); song=&s_xmSongData[_songId]; - s_songDataId=s_xmplaySound->loadSongData(song->m_pxm); - s_songSampleId=s_xmplaySound->loadSamples(song->m_vh,song->m_vb); + s_songModId=s_xmplaySound->loadModData(song->m_pxm); + s_songSampleId=s_xmplaySound->loadSampleData(song->m_vh,song->m_vb); } @@ -322,10 +258,10 @@ void CSoundMediator::setSong(SONGID _songId) void CSoundMediator::playSong() { ASSERT(s_songSampleId!=NO_SAMPLE); - ASSERT(s_songDataId!=NO_SONG); + ASSERT(s_songModId!=NO_SONG); ASSERT(s_songPlayingId==NOT_PLAYING); - s_songPlayingId=s_xmplaySound->playSong(s_songSampleId,s_songDataId,SONG_BASE_CHANNEL); + s_songPlayingId=s_xmplaySound->playSong(s_songSampleId,s_songModId,10); // pkg !? s_volumeDirty[SONG]=true; // Force a volume update } @@ -339,14 +275,18 @@ void CSoundMediator::playSong() void CSoundMediator::dumpSong() { ASSERT(s_songSampleId!=NO_SAMPLE); - ASSERT(s_songDataId!=NO_SONG); + ASSERT(s_songModId!=NO_SONG); - if(s_songPlayingId!=NOT_PLAYING)s_xmplaySound->stopSong(s_songPlayingId); - s_xmplaySound->dumpSamples(s_songSampleId); - s_xmplaySound->dumpSongData(s_songDataId); + if(s_songPlayingId!=NOT_PLAYING) + { + s_xmplaySound->stopPlayingId(s_songPlayingId); + s_xmplaySound->unlockPlayingId(s_songPlayingId); + } + s_xmplaySound->dumpSampleData(s_songSampleId); + s_xmplaySound->dumpModData(s_songModId); s_songSampleId=NO_SAMPLE; - s_songDataId=NO_SONG; + s_songModId=NO_SONG; s_songPlayingId=NOT_PLAYING; } @@ -362,11 +302,11 @@ void CSoundMediator::setSfxBank(SFXBANKID _bankId) XMFILEDATA *song; ASSERT(s_sfxSampleId==NO_SAMPLE); - ASSERT(s_sfxDataId==NO_SONG); + ASSERT(s_sfxModId==NO_SONG); song=&s_xmSfxData[_bankId]; - s_sfxDataId=s_xmplaySound->loadSongData(song->m_pxm); - s_sfxSampleId=s_xmplaySound->loadSamples(song->m_vh,song->m_vb); + s_sfxModId=s_xmplaySound->loadModData(song->m_pxm); + s_sfxSampleId=s_xmplaySound->loadSampleData(song->m_vh,song->m_vb); } @@ -376,60 +316,42 @@ void CSoundMediator::setSfxBank(SFXBANKID _bankId) Params: Returns: ---------------------------------------------------------------------- */ - - -int CSoundMediator::playSfx(int _sfxId) +xmPlayingId CSoundMediator::playSfx(int _sfxId) { + int sfxChannelMask; + xmPlayingId playId; + SFXDETAILS *sfx; + ASSERT(s_sfxSampleId!=NO_SAMPLE); - ASSERT(s_sfxDataId!=NO_SONG); - - int baseChannel; - int channelCount=0; - int sfxChannelMask,maskCopy; - int i,j; - int valid; - int maskCheck=1; - int playId; - -sfxChannelMask=3; - - // Count channels - maskCopy=sfxChannelMask; - for(i=0;i<24&&maskCopy;i++) - { - if(maskCopy&1) - channelCount++; - maskCopy>>=1; - } - - // Find some spare channels to play on - valid=false; - for(i=SFX_BASE_CHANNEL;iplaySfx(s_sfxSampleId,s_sfxDataId,baseChannel,_sfxId,sfxChannelMask); + sfx=&s_sfxDetails[_sfxId]; + if(sfx->m_looping) + { + playId=s_xmplaySound->playLoopingSfx(s_sfxSampleId,s_sfxModId,sfx->m_pattern,10); + } + else + { + playId=s_xmplaySound->playSfx(s_sfxSampleId,s_sfxModId,sfx->m_pattern,sfx->m_channelMask,20); + if(playId!=NOT_PLAYING)s_xmplaySound->unlockPlayingId(playId); // We really don't care about one-shot sfx.. + } s_volumeDirty[SFX]=true; // Force a volume update -// Clear any dead channels -//for(i=SFX_BASE_CHANNEL;istopPlayingId(_id); + s_xmplaySound->unlockPlayingId(_id); } diff --git a/source/sound/sound.h b/source/sound/sound.h index f843a8f31..e83c8beb4 100644 --- a/source/sound/sound.h +++ b/source/sound/sound.h @@ -79,55 +79,53 @@ public: // General - static void initialise(); - static void shutdown(); - static void think(int _frames); + static void initialise(); + static void shutdown(); + static void think(int _frames); // Song interface - static void setSong(SONGID _songId); - static void playSong(); - static void dumpSong(); - static void setSongToFadedOut() {setVolume(SONGFADE,0);} - static void setSongToFadedIn() {setVolume(SONGFADE,255);} + static void setSong(SONGID _songId); + static void playSong(); + static void dumpSong(); + static void setSongToFadedOut() {setVolume(SONGFADE,0);} + static void setSongToFadedIn() {setVolume(SONGFADE,255);} // SFX interface - static void setSfxBank(SFXBANKID _bankId); - static int playSfx(int _sfxId); -// static void stopSfx(int _id); + static void setSfxBank(SFXBANKID _bankId); + static xmPlayingId playSfx(int _sfxId); +// static void setposition(int _playId,vector pos ); + static void stopSfx(xmPlayingId _id); // Speech interface - static void playSpeech(SpeechEquate _speech); + static void playSpeech(SpeechEquate _speech); // Control - static void setVolume(VOLUMETYPE _type,int _val); - static int getVolume(VOLUMETYPE _type); -// static void stopAllSound(); + static void setVolume(VOLUMETYPE _type,int _val); + static int getVolume(VOLUMETYPE _type); +// static void stopAllSound(); private: enum { - NUM_SPU_CHANNELS=24, - - SONG_BASE_CHANNEL =0, - SONG_CHANNELS =10, - SONG_MAX_CHANNEL =SONG_BASE_CHANNEL+SONG_CHANNELS-1, - - SFX_BASE_CHANNEL =SONG_MAX_CHANNEL+1, - SFX_CHANNELS =NUM_SPU_CHANNELS-SFX_BASE_CHANNEL, - SFX_MAX_CHANNEL =SFX_BASE_CHANNEL+SFX_CHANNELS-1, - VOLUME_CHANGE_SPEED=2, INITIAL_VOLUME=192, }; - + CSoundMediator() {;} - static int s_initialised; + static int s_initialised; -// static int s_currentVolume[NUM_VOLUMETYPES]; -// static int s_targetVolume[NUM_VOLUMETYPES]; + static int s_currentVolume[NUM_VOLUMETYPES]; + static int s_targetVolume[NUM_VOLUMETYPES]; + static int s_volumeDirty[NUM_VOLUMETYPES]; + + static xmSampleId s_songSampleId; + static xmModId s_songModId; + static xmPlayingId s_songPlayingId; + static xmSampleId s_sfxSampleId; + static xmModId s_sfxModId; }; diff --git a/source/sound/xmplay.cpp b/source/sound/xmplay.cpp index c46dec94d..d51c02efb 100644 --- a/source/sound/xmplay.cpp +++ b/source/sound/xmplay.cpp @@ -1,4 +1,3 @@ -unsigned char *xmPtr; /*========================================================================= spu.cpp @@ -96,14 +95,14 @@ void CXMPlaySound::initialise() size=XM_GetSongSize(); for(i=0;im_refCount=0; } + for(i=0;im_locked==false&&ch->m_useType==SFX) + { + id=ch->m_playingId; + if(id!=-1) + { + if(XM_GetFeedback(ch->m_internalId,&fb)) + { +PAUL_DBGMSG("%d finished.. ( was on chnl %d )",id,i); + while(ch->m_playingId==id&&im_useType=SILENT; + ch++; + i++; + } + ch--; + } + } + } + ch++; + } + +for(i=0;i<24;i++) + spuflags[i]=m_spuChannelUse[i].m_useType; +} + + /*---------------------------------------------------------------------- Function: Purpose: Params: Returns: ---------------------------------------------------------------------- */ -xmSampleId CXMPlaySound::loadSamples(FileEquate _vhFe,FileEquate _vbFe) +xmSampleId CXMPlaySound::loadSampleData(FileEquate _vhFe,FileEquate _vbFe) { int vabId; XMVab *vab; @@ -195,7 +248,7 @@ xmSampleId CXMPlaySound::loadSamples(FileEquate _vhFe,FileEquate _vbFe) Params: Returns: ---------------------------------------------------------------------- */ -xmSongId CXMPlaySound::loadSongData(FileEquate _songFe) +xmModId CXMPlaySound::loadModData(FileEquate _songFe) { int songId; XMSong *song; @@ -208,7 +261,7 @@ xmSongId CXMPlaySound::loadSongData(FileEquate _songFe) { // Yup.. song->m_refCount++; - return(xmSongId)songId; + return(xmModId)songId; } } @@ -231,7 +284,7 @@ xmSongId CXMPlaySound::loadSongData(FileEquate _songFe) songId++;song++; } - return (xmSongId)songId; + return (xmModId)songId; } @@ -241,7 +294,7 @@ xmSongId CXMPlaySound::loadSongData(FileEquate _songFe) Params: Returns: ---------------------------------------------------------------------- */ -void CXMPlaySound::dumpSamples(xmSampleId _sampleId) +void CXMPlaySound::dumpSampleData(xmSampleId _sampleId) { XMVab *vab; @@ -260,7 +313,7 @@ void CXMPlaySound::dumpSamples(xmSampleId _sampleId) Params: Returns: ---------------------------------------------------------------------- */ -void CXMPlaySound::dumpSongData(xmSongId _songId) +void CXMPlaySound::dumpModData(xmModId _songId) { XMSong *song; @@ -294,7 +347,7 @@ void CXMPlaySound::setStereo(int _stereo) Params: Returns: ---------------------------------------------------------------------- */ -void CXMPlaySound::setVolume(xmPlayingSongId _songId,unsigned char _volume) +void CXMPlaySound::setVolume(xmPlayingId _songId,unsigned char _volume) { XM_SetMasterVol(_songId,_volume>>1); } @@ -306,7 +359,7 @@ void CXMPlaySound::setVolume(xmPlayingSongId _songId,unsigned char _volume) Params: Returns: ---------------------------------------------------------------------- */ -void CXMPlaySound::setPanning(xmPlayingSongId _songId,char _pan) +void CXMPlaySound::setPanning(xmPlayingId _songId,char _pan) { XM_SetMasterPan(_songId,_pan); } @@ -318,38 +371,38 @@ void CXMPlaySound::setPanning(xmPlayingSongId _songId,char _pan) Params: Returns: ---------------------------------------------------------------------- */ -//int sid=0; -//int chan=0; -xmPlayingSongId CXMPlaySound::playSong(xmSampleId _sampleId,xmSongId _songId,int _baseChannel) +xmPlayingId CXMPlaySound::playSong(xmSampleId _sampleId,xmModId _songId,int _channelCount) { - XMVab *vab; - int id; + int baseChannel; + XMVab *vab; + int id; + xmPlayingId retId; ASSERT(s_xmVabs[_sampleId].m_refCount!=0); ASSERT(s_xmSongs[_songId].m_refCount!=0); - - vab=&s_xmVabs[_sampleId]; - id=XM_Init(vab->m_vabId, // id from XM_VABInit - _songId, // XM id ( as passed to InitXMData ) - 0, // Song id - _baseChannel, // First channel - XM_Loop, // Loop - -1, // Play mask - XM_Music, // Music - 0); // Pattern to start at - return (xmPlayingSongId)id; -} + baseChannel=findSpareChannels(_channelCount,255); + if(baseChannel!=-1) + { + retId=getNextSparePlayingId(); + vab=&s_xmVabs[_sampleId]; + id=XM_Init(vab->m_vabId, // id from XM_VABInit + _songId, // XM id ( as passed to InitXMData ) + -1,//baseChannel,//0, // Song id + baseChannel, // First channel + XM_Loop, // Loop + -1, // Play mask + XM_Music, // Music + 0); // Pattern to start at + markChannelsAsActive(baseChannel,_channelCount,SONG,retId,id,255); +PAUL_DBGMSG("playSong %d/%d ( on %d-%d )",retId,id,baseChannel,baseChannel+_channelCount-1); + } + else + { + retId=NOT_PLAYING; + } -/*---------------------------------------------------------------------- - Function: - Purpose: - Params: - Returns: - ---------------------------------------------------------------------- */ -void CXMPlaySound::stopSong(xmPlayingSongId _songId) -{ - XM_PlayStop(_songId); + return retId; } @@ -359,45 +412,138 @@ void CXMPlaySound::stopSong(xmPlayingSongId _songId) Params: Returns: ---------------------------------------------------------------------- */ -//int sid=0; -//int chan=0; -int SONGNUM=1; -xmPlayingSongId CXMPlaySound::playSfx(xmSampleId _sampleId,xmSongId _songId,int _baseChannel,int _sfxPattern,int _playMask=-1) +void CXMPlaySound::unlockPlayingId(xmPlayingId _playingId) { -// XM_PlaySample(XM_GetSampleAddress(_sampleId,_sfxPattern),23,0x3fff,0x3fff,0x800); -// return (xmPlayingSongId)0; + int i; + spuChannelUse *ch; + + ch=m_spuChannelUse; + for(i=0;im_playingId==_playingId) + { +PAUL_DBGMSG("unlocking %d",_playingId); + ASSERT(ch->m_locked!=false); + while(ch->m_playingId==_playingId) + { + ch->m_locked=false; + ch++; + } + return; + } + } + ASSERT(0); // Couldn't find the sound to unlock it! +} + + +/*---------------------------------------------------------------------- + Function: + Purpose: + Params: + Returns: + ---------------------------------------------------------------------- */ +void CXMPlaySound::stopPlayingId(xmPlayingId _playingId) +{ +// ASSERT(m_spuChannelUse[_playingId].m_locked!=true); // Unlock channel first! + + + int i; + spuChannelUse *ch; - int i, maskCopy,channelCount=0; - XMVab *vab; - int id; + ch=m_spuChannelUse; + for(i=0;im_playingId==_playingId) + { + switch(ch->m_useType) + { + case SILENT: + PAUL_DBGMSG("stopping.. woah! %d is already stopped",_playingId); + break; + + case SONG: + PAUL_DBGMSG("stopping song on %d",_playingId); + XM_PlayStop(ch->m_internalId); + break; + + case SFX: + PAUL_DBGMSG("stopping sfx on %d",_playingId); + XM_PlayStop(ch->m_internalId); + break; + + case LOOPINGSFX: + PAUL_DBGMSG("stopping loopingsfx on %d",_playingId); + XM_StopSample(ch->m_internalId); + break; + } + + while(ch->m_playingId==_playingId) + { + ch->m_useType=SILENT; + ch++; + } + return; + } + } + ASSERT(0); // Couldn't find the sound to stop it! +} + + +/*---------------------------------------------------------------------- + Function: + Purpose: + Params: + Returns: + ---------------------------------------------------------------------- */ +xmPlayingId CXMPlaySound::playSfx(xmSampleId _sampleId,xmModId _songId,int _sfxPattern,int _playMask,u8 _priority) +{ + int i,j; + int maskCopy,channelCount; + int valid; + int baseChannel; + XMVab *vab; + int songId; + int id; + xmPlayingId retId; ASSERT(s_xmVabs[_sampleId].m_refCount!=0); ASSERT(s_xmSongs[_songId].m_refCount!=0); - + // Count channels maskCopy=_playMask; - for(i=0;i<24&&maskCopy;i++) + channelCount=0; + for(i=0;i>=1; } - vab=&s_xmVabs[_sampleId]; - XM_SetSFXRange(_baseChannel,channelCount); - id=XM_Init(vab->m_vabId, // id from XM_VABInit - _songId, // XM id ( as passed to InitXMData ) - SONGNUM, // Song id - -1, // First channel - XM_NoLoop, // Loop - _playMask, // Play mask - XM_SFX, // Music - _sfxPattern); // Pattern to start at - -SONGNUM++; -if(SONGNUM>=24)SONGNUM=1; -//PAUL_DBGMSG("sfx - ret:%d",id); - return (xmPlayingSongId)id; + // Play the sound + baseChannel=findSpareChannels(channelCount,_priority); + if(baseChannel!=-1) + { + retId=getNextSparePlayingId(); + vab=&s_xmVabs[_sampleId]; + XM_SetSFXRange(baseChannel,channelCount); + id=XM_Init(vab->m_vabId, // id from XM_VABInit + _songId, // XM id ( as passed to InitXMData ) + -1,//baseChannel,//SONGNUM, // Song id + -1, // First channel + XM_NoLoop, // Loop + _playMask, // Play mask + XM_SFX, // Music + _sfxPattern); // Pattern to start at + XM_ClearSFXRange(); +PAUL_DBGMSG("playSfx %d/%d ( on %d-%d )",retId,id,baseChannel,baseChannel+channelCount-1); + markChannelsAsActive(baseChannel,channelCount,SFX,retId,id,_priority); + } + else + { + retId=NOT_PLAYING; + } + + return retId; } @@ -407,11 +553,139 @@ if(SONGNUM>=24)SONGNUM=1; Params: Returns: ---------------------------------------------------------------------- */ -int CXMPlaySound::isSfxActive(xmPlayingSongId _id) +xmPlayingId CXMPlaySound::playLoopingSfx(xmSampleId _sampleId,xmModId _songId,int _soundId,u8 _priority,int _pitch) { - XM_Feedback fb; + int baseChannel; + xmPlayingId retId; - return XM_GetFeedback(_id,&fb)==0; + baseChannel=findSpareChannels(1,_priority); + if(baseChannel!=-1) + { + retId=getNextSparePlayingId(); +PAUL_DBGMSG("playLoopingSfx %d/- ( on %d-%d )",retId,baseChannel,baseChannel); + XM_PlaySample(XM_GetSampleAddress(_sampleId,_soundId),baseChannel,0x3fff,0x3fff,_pitch); + markChannelsAsActive(baseChannel,1,LOOPINGSFX,retId,baseChannel,_priority); + } + else + { + retId=NOT_PLAYING; + } + + return retId; +} + + +/*---------------------------------------------------------------------- + Function: + Purpose: + Params: + Returns: + ---------------------------------------------------------------------- */ +xmPlayingId CXMPlaySound::getNextSparePlayingId() +{ + xmPlayingId validId; + int i; + spuChannelUse *ch; + static xmPlayingId nextId=(xmPlayingId)(0-1); // fudge to make first id=0 + + + validId=NOT_PLAYING; + while(validId==NOT_PLAYING) + { + nextId=(xmPlayingId)((nextId+1)&0xff); // gives 256 unique id numbers + + // Is this id still in use? + validId=nextId; + ch=m_spuChannelUse; + for(i=0;im_playingId==validId&&!(ch->m_locked==false&&ch->m_useType==SILENT)) + validId=NOT_PLAYING; + ch++; + } + } + + return validId; +} + + +/*---------------------------------------------------------------------- + Function: + Purpose: Returns the base channel of a slot big enuf for the + requested number of channels + Params: + Returns: baseChannel or -1 if no space + ---------------------------------------------------------------------- */ +int CXMPlaySound::findSpareChannels(int _channelCount,int _priority) +{ + int i,j; + int valid; + + // First we search for channels that are marked as unused + valid=false; + for(i=0;i