First this is my SFX functions that I am making currently. I am not sure I have tested this at all yet, I might have just copy-pasted this stuff from my other code, and I'm not even sure this is usable yet, but you can give it a try:
Code: Select all
SFX = {
Sounds = {},
Musics = {},
ChannelSFXPriority = {},
Settings = { SFXVolume = 64, MusicVolume = 64 },
ChannelForMusic = 1
}
SFX.numChannels = GetChannels()
For Local n = 1 To SFX.numChannels
SFX.ChannelSFXPriority[n] = 0
Next
Function SFX.PlayMusic()
EndFunction
Function SFX.LoadAllSamples()
ForEach(SFX.Sounds, Function(SampleName, SoundItem)
Local NewID = LoadSample(Nil, SoundItem.SampleFile)
SoundItem.Loaded = True
SoundItem.sfxID = NewID
EndFunction)
EndFunction
Function SFX.LoadAllMusics()
ForEach(SFX.Musics, Function(MusicName, MusicItem)
Local NewID = OpenMusic(Nil, MusicItem.MusicFile)
MusicItem.Loaded = True
MusicItem.ID = NewID
EndFunction)
EndFunction
Function SFX.SetSound(Samplename, SampleFile)
SFX.Sounds[LowerStr(SampleName)] = {File=SampleFile, Loaded=False, SFXID = Nil}
EndFunction
Function SFX.SetMusicChannel(n)
ChannelSFXPriority[n] = "Music"
SFX.ChannelForMusic = n
EndFunction
Function SFX.PlaySampleInternal()
EndFunction
Function SFX.LoadSample(SampleName, SampleFile)
Local sfxID = LoadSample(Nil, SampleFile)
SFX.Sounds[LowerStr(SampleName)].Loaded = True
SFX.Sounds[LowerStr(SampleName)].sfxID = sfxID
EndFunction
Function SFX.GetSampleID(SampleName, SampleFile)
Local sfxID
If HaveItem(SFX.Sounds, LowerStr(SampleName))
If SFX.Sounds[LowerStr(SampleName)].Loaded = False Then SFX.LoadSample(SampleName, SampleFile)
sfxID = SFX.Sounds[LowerStr(SampleName)].sfxID
Else
SFX.SetSound(Samplename, SampleFile)
sfxID = SFX.LoadSample(SampleName, SampleFile)
EndIf
Return(sfxID)
EndFunction
Function SFX.PlaySample(SampleName, Priority, Vol, SampleFile)
If GetType(Priority) = #NIL Then Priority = 0
If GetType(vol) = #NIL Then Vol = 64
Local sfxID = SFX.GetSampleID(SampleName, SampleFile)
Local n_Channel = HaveFreeChannel() /* Potential problem in that if there is no music playing, sample could occupy music channel */
If n_Channel = 0
For Local n = 1 To TableItems(SFX.ChannelSFXPriority)
If Priority > SFX.ChannelSFXPriority[n] And SFX.ChannelForMusic <> n Then n_Channel = n
Next
EndIf
If n_channel > 0
PlaySample(sfxID, { volume = (SFX.Settings.SFXVolume / 64) * Vol, channel = n_Channel })
SFX.ChannelSFXPriority[n_Channel] = priority
Else
Return(False)
EndIf
Return(True)
EndFunction
Function SetVolumeToSFXChannels(VolumePercentage) /* not done, going to make when needed to see how it should be implemented exactly */
For Local n = 2 To GetChannels()
SetChannelVolume(n, (SFX.Settings.SFXVolume / 100) * 64)
Next
EndFunction
Code: Select all
settings = {CurrentVolume=64}
samplechannelspriority = {}
For Local n = 2 To GetChannels()
samplechannelspriority[n] = 0
Next
samplechannelspriority[1]=100 /* this is the music channel */
Function My_PlaySample(sampletoplay, priority, vol)
If GetType(vol) = #NIL Then vol = 64
Local CurrentVolume = Settings.CurrentVolume
Local n_channel = HaveFreeChannel()
If n_channel > 0
PlaySample(sampletoplay, {volume=(CurrentVolume / 64) * vol, channel=n_channel})
samplechannelspriority[n_channel] = priority
Else
Local usechannel = -1
For Local n = 1 To TableItems(samplechannelspriority)
If priority > samplechannelspriority[n] Then usechannel = n
Next
If usechannel > -1
PlaySample(sampletoplay, {volume=(CurrentVolume / 64) * vol, channel=usechannel})
samplechannelspriority[usechannel] = priority
EndIf
EndIf
EndFunction
Function SetVolumeToSoundChannels(VolumePercentage)
For Local n = 2 To GetChannels()
SetChannelVolume(n, (Settings.SoundSettings.SFXVolume.SliderVar / 100) * 64)
Next
Idea with this one is that you use for example: My_SamplePlay(1, 10, 64)
In this case it would play sample number 1, give it priority 10, and play it with volume 64.
The idea with priority is that when it checks the channels if they are free, if there is no channel available, it will then next check each playing samples priority. If samples priority is lower than the one you are trying to play, then the new sample will override then previous sample.
In practice situation was that there was lot of shooting in my game, I gave very low priority for the shooting samples, since they would very quickly occupy all the channels, and then more important samples that would actually tell something more important to player wouldn't play. By using this priority tag I was able to override shooting sounds with more important sounds.
However, this system isn't very good, since basically if all the channels are occupied by priority 1 samples, and then you play priority 5, 10, 15, 20 in that order, in practice it would first override priority 1 with priority 5, then it would actually override the priority 5 with 10, then 10 with 15, 15 with 20, and in practice it would then be playing priority 20 sample in one channel, and priority 1 samples in all the other channels.
This is because this isn't checking through each channel to check to override the lowest priority sample, but instead, this goes through the channels in same order, and basically always ends up using the same channel, if it is able to override it with priority, only if it is not able to override it with its priority, will it replace next channels priority, so it isn't very clever system.
I am planning on having more clever system in the new SFX system.