diff --git a/src/vfmodsound.pas b/src/vfmodsound.pas index aa48e3b..077dee4 100644 --- a/src/vfmodsound.pas +++ b/src/vfmodsound.pas @@ -42,6 +42,8 @@ TFMODSound = class(TSound) procedure FreeMusic( aData : Pointer; const aType : String ); override; // Implementation of Sound Freeing procedure FreeSound( aData : Pointer ); override; + // Implementation of Number of Channels Playing + function NumChannelsPlaying: Integer; // Implementation of get error function GetError( ) : AnsiString; override; // Implementation of play Sound 3D @@ -66,7 +68,9 @@ implementation GLastError : FMOD_RESULT; GGroupSounds : PFMOD_CHANNELGROUP; GGroupMusic : PFMOD_CHANNELGROUP; + MaxConcurrentSounds : Integer; //Max number of sounds we can play before needing to steal a channel +const SoundLibMaxConcurrentChannels = 128; // Max number of channels playing at once by the library procedure FMOD_CHECK( aResult : FMOD_RESULT ); begin @@ -93,6 +97,8 @@ destructor TFMODSound.Destroy; if GGroupSounds <> nil then FMOD_ChannelGroup_Release( GGroupSounds ); if GGroupMusic <> nil then FMOD_ChannelGroup_Release( GGroupMusic ); + MaxConcurrentSounds := SoundLibMaxConcurrentChannels; + if GSystem <> nil then begin FMOD_System_Close(GSystem); @@ -106,6 +112,14 @@ procedure TFMODSound.Update; FMOD_System_Update( GSystem ); end; +function TFModSound.NumChannelsPlaying : Integer; +var Channels, RealChannels : Integer; +begin + Channels := 0; RealChannels := 0; + FMOD_System_GetChannelsPlaying( GSystem, Channels, RealChannels); + Exit(Channels); +end; + function TFMODSound.OpenDevice : Boolean; const CPos : FMOD_VECTOR = ( x : 0.0; y : 0.0; z : 0.0 ); CVel : FMOD_VECTOR = ( x : 0.0; y : 0.0; z : 0.0 ); @@ -134,6 +148,7 @@ function TFMODSound.OpenDevice : Boolean; FMOD_CHECK( FMOD_System_CreateChannelGroup( GSystem, 'sound', @GGroupSounds ) ); FMOD_CHECK( FMOD_System_CreateChannelGroup( GSystem, 'music', @GGroupMusic ) ); + MaxConcurrentSounds := SoundLibMaxConcurrentChannels - 1; // Reserve one channel for music FMOD_CHECK( FMOD_System_set3DListenerAttributes( GSystem, 0, @CPos, @CVel, @CFwd, @CUp ) ); Exit( True ); end; @@ -228,6 +243,7 @@ procedure TFMODSound.PlaySound3D(aData: Pointer; aRelative: TCoord2D); iPosition.x := aRelative.X * 0.2; iPosition.y := aRelative.Y * 0.2; iPosition.z := 0.0; + if NumChannelsPlaying() = MaxConcurrentSounds then Exit; //Do not allow more sounds than this or a channel will be stolen (e.g. music) FMOD_CHECK( FMOD_System_PlaySound( GSystem, PFMOD_SOUND(aData), GGroupSounds, 1, @iChannel ) ); FMOD_CHECK( FMOD_Channel_SetVolume( iChannel, Single( Min( SoundVolume, 128 ) / 128.0 ) ) ); FMOD_CHECK( FMOD_Channel_set3DAttributes( iChannel, @iPosition, nil ) ); @@ -237,6 +253,7 @@ procedure TFMODSound.PlaySound3D(aData: Pointer; aRelative: TCoord2D); procedure TFMODSound.PlaySound(aData: Pointer; aVolume: Byte; aPan: Integer); var iChannel : PFMOD_CHANNEL; begin + if NumChannelsPlaying() = MaxConcurrentSounds then Exit; //Do not allow more sounds than this or a channel will be stolen (e.g. music) FMOD_CHECK( FMOD_System_PlaySound( GSystem, PFMOD_SOUND(aData), GGroupSounds, 1, @iChannel ) ); FMOD_CHECK( FMOD_Channel_SetVolume( iChannel, ( Single(aVolume) / 255.0 ) ) ); if aPan <> -1