Failed To Allocate Audio Channel

Find quick help here to get you started with Hollywood
Bugala
Posts: 1390
Joined: Sun Feb 14, 2010 7:11 pm

Re: Failed To Allocate Audio Channel

Post by Bugala »

Here are two options for you.

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

Here is simpler version that I have actually used:

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.
oceanarts
Posts: 111
Joined: Mon May 27, 2024 10:42 pm

Re: Failed To Allocate Audio Channel

Post by oceanarts »

Wow! Cool, that gives me something to consider. Thanks!

There isn't much happening sound wise on my project, really. It's just that the player can trigger an event that plays a short sample. But depending on the speed of the mouse pointer movement this may happen too many times for the sound system to keep up, I guess.
Development System : Imac G5, MorphOs 3.19
Post Reply