Skip to content

Commit 28767c0

Browse files
authored
Merge pull request #37 from Andreas-W/SoundLoopEarlyStop
Sound loop early stop
2 parents 9bfde5c + b35414d commit 28767c0

File tree

5 files changed

+84
-12
lines changed

5 files changed

+84
-12
lines changed

Core/GameEngine/Include/Common/AudioEventInfo.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ enum AudioControl CPP_11(: Int)
8080
AC_ALL = 0x0004,
8181
AC_POSTDELAY = 0x0008,
8282
AC_INTERRUPT = 0x0010,
83+
AC_STOPEARLY = 0x0020,
8384
};
8485

8586
class DynamicAudioEventInfo;

Core/GameEngine/Include/Common/GameAudio.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,7 @@ class AudioManager : public SubsystemInterface
194194
virtual void *getDevice( void ) = 0;
195195

196196
// Debice Dependent notification functions
197-
virtual void notifyOfAudioCompletion( UnsignedInt audioCompleted, UnsignedInt flags ) = 0;
197+
virtual void notifyOfAudioCompletion( UnsignedInt audioCompleted, UnsignedInt flags, bool isEarlyStop = false) = 0;
198198

199199
// Device Dependent enumerate providers functions. It is okay for there to be only 1 provider (Miles provides a maximum of 64.
200200
virtual UnsignedInt getProviderCount( void ) const = 0;
@@ -399,7 +399,7 @@ class AudioManagerDummy : public AudioManager
399399
virtual void openDevice() {}
400400
virtual void closeDevice() {}
401401
virtual void* getDevice() { return NULL; }
402-
virtual void notifyOfAudioCompletion(UnsignedInt audioCompleted, UnsignedInt flags) {}
402+
virtual void notifyOfAudioCompletion(UnsignedInt audioCompleted, UnsignedInt flags, bool isEarlyStop=false) {}
403403
virtual UnsignedInt getProviderCount(void) const { return 0; };
404404
virtual AsciiString getProviderName(UnsignedInt providerNum) const { return ""; }
405405
virtual UnsignedInt getProviderIndex(AsciiString providerName) const { return 0; }

Core/GameEngine/Source/Common/INI/INIAudioEventInfo.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,7 @@ const char *theAudioControlNames[] =
210210
"ALL",
211211
"POSTDELAY",
212212
"INTERRUPT",
213+
"STOPEARLY",
213214
NULL
214215
};
215216

Core/GameEngineDevice/Include/MilesAudioDevice/MilesAudioManager.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,7 @@ class MilesAudioManager : public AudioManager
172172
///< NOTE NOTE NOTE !!DO NOT USE THIS IN FOR GAMELOGIC PURPOSES!! NOTE NOTE NOTE
173173
virtual Bool isCurrentlyPlaying( AudioHandle handle );
174174

175-
virtual void notifyOfAudioCompletion( UnsignedInt audioCompleted, UnsignedInt flags );
175+
virtual void notifyOfAudioCompletion( UnsignedInt audioCompleted, UnsignedInt flags, bool isEarlyStop=false );
176176
virtual PlayingAudio *findPlayingAudioFrom( UnsignedInt audioCompleted, UnsignedInt flags );
177177

178178
virtual UnsignedInt getProviderCount( void ) const;
@@ -276,6 +276,8 @@ class MilesAudioManager : public AudioManager
276276
void initFilters( HSAMPLE sample, const AudioEventRTS *eventInfo );
277277
void initFilters3D( H3DSAMPLE sample, const AudioEventRTS *eventInfo, const Coord3D *pos );
278278

279+
// void handleLoopStopEarly(PlayingAudio* audio);
280+
279281
protected:
280282
ProviderInfo m_provider3D[MAXPROVIDERS];
281283
UnsignedInt m_providerCount;

Core/GameEngineDevice/Source/MilesAudioDevice/MilesAudioManager.cpp

Lines changed: 77 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -894,6 +894,25 @@ void MilesAudioManager::playAudioEvent( AudioEventRTS *event )
894894
}
895895
}
896896

897+
//-------------------------------------------
898+
//void MilesAudioManager::handleLoopStopEarly(PlayingAudio* audio) {
899+
// if (!(audio->m_audioEventRTS->getAudioEventInfo()->m_control & AC_STOPEARLY)) {
900+
// // We shouldn't be here.
901+
// DEBUG_LOG((">>> handleLoopStopEarly - invalid audio: %s\n", audio->m_audioEventRTS->getEventName().str()));
902+
// return;
903+
// }
904+
//
905+
// // We assume we have a looping sound and jump right to Decay portion
906+
// // -> create new event, and set old one as kill handle
907+
//
908+
// //That's probably a bad idea actually, since it changes the handle. :(
909+
//
910+
// if (audio->m_type == PAT_3DSample) {
911+
//
912+
// // event->setHandleToKill((*it)->m_audioEventRTS->getPlayingHandle());
913+
// }
914+
//}
915+
897916
//-------------------------------------------------------------------------------------------------
898917
void MilesAudioManager::stopAudioEvent( AudioHandle handle )
899918
{
@@ -936,6 +955,7 @@ void MilesAudioManager::stopAudioEvent( AudioHandle handle )
936955
if (audio->m_audioEventRTS->getPlayingHandle() == handle) {
937956
// found it
938957
audio->m_requestStop = true;
958+
939959
notifyOfAudioCompletion((UnsignedInt)(audio->m_stream), PAT_Stream);
940960
break;
941961
}
@@ -948,7 +968,13 @@ void MilesAudioManager::stopAudioEvent( AudioHandle handle )
948968
}
949969

950970
if (audio->m_audioEventRTS->getPlayingHandle() == handle) {
971+
951972
audio->m_requestStop = true;
973+
if (audio->m_audioEventRTS->getAudioEventInfo()->m_control & AC_STOPEARLY) {
974+
// DEBUG_LOG((">>> stopAudioEvent (sounds): %s\n", audio->m_audioEventRTS->getEventName().str()));
975+
notifyOfAudioCompletion((UnsignedInt)(audio->m_sample), PAT_Sample, true);
976+
}
977+
952978
break;
953979
}
954980
}
@@ -963,7 +989,15 @@ void MilesAudioManager::stopAudioEvent( AudioHandle handle )
963989
#ifdef INTENSIVE_AUDIO_DEBUG
964990
DEBUG_LOG((" (%s)", audio->m_audioEventRTS->getEventName()));
965991
#endif
992+
966993
audio->m_requestStop = true;
994+
995+
if (audio->m_audioEventRTS->getAudioEventInfo()->m_control & AC_STOPEARLY) {
996+
// DEBUG_LOG((">>> stopAudioEvent (3DSounds): %s\n", audio->m_audioEventRTS->getEventName().str()));
997+
998+
notifyOfAudioCompletion((UnsignedInt)(audio->m_3DSample), PAT_3DSample, true);
999+
}
1000+
9671001
break;
9681002
}
9691003
}
@@ -1524,7 +1558,7 @@ Bool MilesAudioManager::isCurrentlyPlaying( AudioHandle handle )
15241558
}
15251559

15261560
//-------------------------------------------------------------------------------------------------
1527-
void MilesAudioManager::notifyOfAudioCompletion( UnsignedInt audioCompleted, UnsignedInt flags )
1561+
void MilesAudioManager::notifyOfAudioCompletion( UnsignedInt audioCompleted, UnsignedInt flags, bool isEarlyStop/*= false*/)
15281562
{
15291563
PlayingAudio *playing = findPlayingAudioFrom(audioCompleted, flags);
15301564
if (!playing) {
@@ -1537,21 +1571,55 @@ void MilesAudioManager::notifyOfAudioCompletion( UnsignedInt audioCompleted, Uns
15371571
}
15381572

15391573
if (playing->m_audioEventRTS->getAudioEventInfo()->m_control & AC_LOOP) {
1540-
if (playing->m_audioEventRTS->getNextPlayPortion() == PP_Attack) {
1541-
playing->m_audioEventRTS->setNextPlayPortion(PP_Sound);
1542-
}
1543-
if (playing->m_audioEventRTS->getNextPlayPortion() == PP_Sound) {
1544-
// First, decrease the loop count.
1545-
playing->m_audioEventRTS->decreaseLoopCount();
15461574

1547-
// Now, try to start the next loop
1548-
if (startNextLoop(playing)) {
1575+
// Early stop
1576+
if (playing->m_audioEventRTS->getAudioEventInfo()->m_control & AC_STOPEARLY && playing->m_requestStop) {
1577+
1578+
if (!isEarlyStop) {
1579+
// We came here from the audio being stopped by other means.
1580+
// To avoid doing things twice, we just return here. I hope this doesn't break things.
1581+
//DEBUG_LOG((">>> notifyOfAudioCompletion EARLYSTOP 1: %s (%s) - nextPP = %d - isEarlyStop = FALSE\n",
1582+
// playing->m_audioEventRTS->getEventName().str(),
1583+
// playing->m_audioEventRTS->getFilename().str(),
1584+
// playing->m_audioEventRTS->getNextPlayPortion()));
15491585
return;
15501586
}
1587+
1588+
//DEBUG_LOG((">>> notifyOfAudioCompletion EARLYSTOP 1: %s (%s) - nextPP = %d\n",
1589+
// playing->m_audioEventRTS->getEventName().str(),
1590+
// playing->m_audioEventRTS->getFilename().str(),
1591+
// playing->m_audioEventRTS->getNextPlayPortion()));
1592+
1593+
// How to advance?
1594+
// - Attack -> Decay
1595+
// - Sound -> Decay
1596+
// - Decay -> this shouldn't really happen.
1597+
// We jump from Attack to Sound, so we then advance to Decay
1598+
if (playing->m_audioEventRTS->getNextPlayPortion() == PP_Attack) {
1599+
playing->m_audioEventRTS->setNextPlayPortion(PP_Sound);
1600+
}
1601+
}
1602+
// Normal loop behavior
1603+
else {
1604+
1605+
if (playing->m_audioEventRTS->getNextPlayPortion() == PP_Attack) {
1606+
playing->m_audioEventRTS->setNextPlayPortion(PP_Sound);
1607+
}
1608+
if (playing->m_audioEventRTS->getNextPlayPortion() == PP_Sound) {
1609+
1610+
// First, decrease the loop count.
1611+
playing->m_audioEventRTS->decreaseLoopCount();
1612+
1613+
// Now, try to start the next loop
1614+
if (startNextLoop(playing)) {
1615+
return;
1616+
}
1617+
}
15511618
}
15521619
}
15531620

15541621
playing->m_audioEventRTS->advanceNextPlayPortion();
1622+
15551623
if (playing->m_audioEventRTS->getNextPlayPortion() != PP_Done) {
15561624
if (playing->m_type == PAT_Sample) {
15571625
closeFile(playing->m_file); // close it so as not to leak it.

0 commit comments

Comments
 (0)