OpenAL channel bug. Please help me test.

BlitzMax Forums/BlitzMax Programming/OpenAL channel bug. Please help me test.

I believe I've got to the route of a problem I encountered a while back with Open AL.

Basically there is a 256 channel limit which is reached EVEN IF you use Stop Channel to free up a channel for reuse.

Get this sample:

http://www.greyaliengames.com/misc/test.wav

and put it in the same folder as the test app:

and if you don't have OpenAL installed, put these in the same folder as the app:

http://www.greyaliengames.com/misc/OpenAL.zip (234k)

Strict

EnableOpenALAudio()
SetAudioDriver("OpenAL Generic Software") 'comment this out for no crash

Const MAX_CHANNELS=16
Global channels:TChannel[MAX_CHANNELS]
Global CurrentChannel=0

Local sound:TSound = LoadSound("test.wav")

Local Counter=0
Local total=0
Const TEST_VALUE = 16 'anything up to and including 15 will result in a sound, anything over will not.

Graphics 400,300,0

While Not KeyHit(KEY_ESCAPE)
	Cls
	Counter:+1
	If Counter=5 Then
		If Total<TEST_VALUE Then
			CreateChannels()		
			KillChannels()
			Counter=0
		ElseIf total=TEST_VALUE
			CreateChannels()		
			Play(Sound)			
		EndIf
		Total:+1
	EndIf
	DrawText Total,10,10
	DrawText CurrentChannel,10,30
	Flip
Wend

Function Play(sample:TSound)
	Local ch:TChannel=channels[CurrentChannel]
	CueSound(sample, ch)
	ResumeChannel(ch)		
	CurrentChannel:+1
	If CurrentChannel=MAX_CHANNELS Then CurrentChannel=0
End Function

Function CreateChannels()
	For Local i=0 To MAX_CHANNELS-1
		channels[i]=AllocChannel()
	Next
End Function

Function KillChannels()
	For Local i=0 To MAX_CHANNELS-1
		StopChannel(Channels[i])
		Channels[i]=Null
	Next
End Function


When you run it, you will NOT hear any sound when the counter hits 17.

The bug exists with all OpenAL drivers:

'OpenAL Default
'OpenAL Generic Software
'OpenAL Generic Hardware
'OpenAL

It does NOT exist with FreeAudio or DirectSound.

What does the code do? It makes a channel array (of 16 channels) and destroys it 16 times then tries to play a sound on the 17th channel array. The astute of you will realise that 16x16=256 and thus it is failing to play on the 257th channel. HOWEVER, I'm using STOPCHANNEL to free the channels and setting the pointer to null for what it's worth and thus the channel should be completely freed up for reuse, but it is not.

Please see if you get the same results on your PC (different OSes welcome). If so, I'll post this in the bug forum.

Thanks in advance!

[edit] of course I'm quite prepared for someone to tell me I'm using this code in an "incorrect" manner, but I don't think I am especially as the behavious is inconsistent between the drivers - for example you can go over 4096 channel creations/freeings with DirectSound and FreeAudio using the above code.

This seems to be OK and doesn't use StopChannel and goes beyond 256. Am I missing something?
Strict

EnableOpenALAudio()
SetAudioDriver("OpenAL Generic Software") 'comment this out for no crash

'Global mychannel:TChannel=AllocChannel()
Local sound:TSound = LoadSound("test.wav")
Graphics 400,300,0
Local counter:Int = 0
Local mychannel:TChannel
While Not KeyHit(KEY_ESCAPE)
	Cls
	 mychannel=AllocChannel()
	PlaySound sound , mychannel
	DrawText counter , 0 , 0
	DrawText GCMemAlloced(),0,100
	counter:+ 1
	Flip
	If counter >300 End
Wend



<edit> on 1.24. In fact your code doesn't seem to fail on that level.

I forgot to say, if you comment out the KillChannels() line in my code you get the same result.

How strange that your code works and that mine doesn't...

If you change the array size in mine to 1 and you make the TEST_VALUE 256, the sound doesn't play so the bug is still present.

[edit] I just replaced my CueSound and ResumeSound with PlaySound sample,ch and same result i.e. bug.

Are you sure there is a limit on channels any more?
Strict

EnableOpenALAudio()
SetAudioDriver("OpenAL Generic Software") 'comment this out for no crash

Graphics 400 , 300 , 0
Local sound:TSound = LoadSound("test.wav")
Local counter:Int = 0
Local channel_dump:TChannel[300]
For Local x:Int = 0 To 299
	channel_dump[x] = AllocChannel()	
Next
Cls
For Local x:Int= 0 To 299
	PlaySound sound , channel_dump[x]
	counter:+1
Next
DrawText counter , 0 , 0
DrawText GCMemAlloced(),0,100
Flip
WaitKey()



check this out, I tried to make my code more like yours (i.e. not use an array, just a global channel which I never free) and it still results in the bug:

Strict

EnableOpenALAudio()
SetAudioDriver("OpenAL Generic Software") 'comment this out for no crash

Const MAX_CHANNELS=16
Global channels:TChannel[MAX_CHANNELS]
Global CurrentChannel=0

Local sound:TSound = LoadSound("test.wav")

Local Counter=0
Local total=0
Const TEST_VALUE = 256 'anything up to and including 15 will result in a sound, anything over will not.

Global ch:TChannel

Graphics 400,300,0

While Not KeyHit(KEY_ESCAPE)
	Cls
	Counter:+1
	If Counter=1 Then
		If Total<TEST_VALUE Then
			ch=AllocChannel()
'			CreateChannels()		
'			KillChannels()
			Counter=0
		ElseIf total=TEST_VALUE
'			CreateChannels()		
			Play(Sound)			
		EndIf
		Total:+1
	EndIf
	DrawText Total,10,10
	DrawText CurrentChannel,10,30
	Flip
Wend

Function Play(sample:TSound)
'	Local ch:TChannel=channels[CurrentChannel]
	ch=AllocChannel()
	PlaySound sample,ch
'	CueSound(sample, ch)
'	ResumeChannel(ch)		
	CurrentChannel:+1
	If CurrentChannel=MAX_CHANNELS Then CurrentChannel=0
End Function

Function CreateChannels()
	For Local i=0 To MAX_CHANNELS-1
		channels[i]=AllocChannel()
	Next
End Function

Function KillChannels()
	For Local i=0 To MAX_CHANNELS-1
		StopChannel(Channels[i])
		Channels[i]=Null
	Next
End Function


OK Tony, great test you made because I discovered THIS!

Replace your playsound line with this:

	If counter>250 Then PlaySound sound , mychannel


You'll get 250 no sounds as expected, 5 sounds, then NO SOUNDS until near the end then you'll hear a few more. For more weirdness, boost your exit line to not end until 500 or more is met, then you'll hear a few sounds every 50or so.

This is crazy.

So basically if you make OpenAL channels and DON'T USE THEM, they are NEVER freed up. If you use them, they are freed up fine.

This should be enough for BRL to fix it. yay! Well done TonyG!

What is your latest code supposed to do and how does it fail? For me it simply displays 0 to 257 and a 0 on the screen the stops at 257 and displays 1.

Didn't see your other post until just now. Change your play line to this:

	If x>260 Then PlaySound sound , channel_dump[x]


No sounds are played.

Isn't this the same as the DirectSound issue where the sounds are played in seperate channels so quickly that the buffers can't be cleared fast enough?

What is your latest code supposed to do and how does it fail? For me it simply displays 0 to 257 and a 0 on the screen the stops at 257 and displays 1.
It should play a sound when then 1 appears (i.e. straight after the loop of channelallocations) but it doesn't.

Isn't this the same as the DirectSound issue where the sounds are played in seperate channels so quickly that the buffers can't be cleared fast enough?

No, change the driver to DirectSound. No bug. These are two separate bugs. I noted this one about 3 months ago but was too busy to investigate more. Now as my project nears completion I have to choose a sound driver and I can't use FreeAudio in non-XP due to lag. DirectSound crashes on all OSes and OpenAL has this issue (plus some people say it doesn't work in Vista, but I haven't tested it on enough varied vista PCs).

Did you see my post above where I figured out why it's doing it?


So basically if you make OpenAL channels and DON'T USE THEM, they are NEVER freed up. If you use them, they are freed up fine.

This should be enough for BRL to fix it. yay! Well done TonyG!


I'm gonna post this in the bug forum now that we have a smaller test app (yours).

Here's my last bit of code which suggest there isn't a problem... I think :
Strict

EnableOpenALAudio()
SetAudioDriver("OpenAL Generic Software") 'comment this out for no crash

Graphics 400 , 300 , 0
Local sound:TSound = LoadSound("test.wav")
Local counter:Int = 0
Local channel_waster:TChannel[100]
For Local x:Int = 0 To 99
	channel_waster[x] = AllocChannel()
Next

Local channel_dump:TChannel[500]
'For Local x:Int = 0 To 499
'	channel_dump[x] = AllocChannel()	
'Next
Cls
For Local x:Int = 0 To 499
	Cls
	channel_dump[x]=AllocChannel()
	PlaySound sound , channel_dump[x]
	If x>0 StopChannel channel_dump[x-1]
	counter:+ 1
	DrawText counter , 0 , 0
	Flip
Next
DrawText counter , 0 , 0
DrawText GCMemAlloced(),0,100
Flip
WaitKey()

<edit> change the waster array to 1000 and you don't hear any sound. Really not sure what is going on really.

change it to 256 and fill it up and there are no sounds.

Isn't that right though if there is a 256limit?

yes for your latest code. BUT how come if you FREE those unused channels you still hit the 256 limit. If you play a sound on the channel BEFORE freeing it then the channel is properly freed thus it seems as though there is no limit. That's the bug, I'm 99% sure.

Regarding freeing a channel, I just recalled that nulling the pointer isn't good enough, you ARE supposed to use StopChannel first. However, as per my very first example, this doesn't work either. Good job you got me reminded of this as I've updated the code in the bug forum to use stopchannel properly like so:

Strict

EnableOpenALAudio()
SetAudioDriver("OpenAL Generic Software") 'change to FreeAudio or DirectSound for no crash

Local sound:TSound = LoadSound("test.wav")
Graphics 400,300,0
Local counter:Int = 0
Local mychannel:TChannel
While Not KeyHit(KEY_ESCAPE)
	Cls
	mychannel=AllocChannel()
	If counter>250 Then
		PlaySound sound , mychannel
	Else
		StopChannel(mychannel)
		mychannel = Null 'this line is not required
	EndIf

	DrawText counter , 0 , 0
	DrawText GCMemAlloced(),0,100
	counter:+ 1
	Flip
	If counter > 500 End
Wend