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? <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? |
| ||
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 : <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 |
| ||
Sorry to bump a very old topic but I got the same problems only when using OpenAL on 2 different computers. I'm currently using PulseAudio to fix this but some Linux would like support for OpenAL. I was wondering if you find a fix or a work around for this? |
| ||
I saw you created a bug thread about this ( http://www.blitzbasic.com/Community/posts.php?topic=96082 ). So you are using Global channel in your framework. Like declaring X global channels and check which one is available before cue it to your sound and finally play it ? Doesn't it limit the maximum available object with sounds to 255 ? The problem is that I'm doing some spacial detection code to pan / volume sound around multiple players. So it's easier to link a channel to a specific sound and that sound to the object. This working great with others Audio drivers... This bug exist since more than 5 years now, isn't it possible to fix this :( Last edited 2012 |
| ||
Yes without global channels you are severely limited unfortunately. Global channels worked out fine and isn't too much code, it's just not ideal. |
| ||
But how did you managed to control volume/pan/rate on a specific sound with global channels? You created a new channel type to know if the channel is already cue with a sound or you cue your sound at runtime just before playing the sample ? The first idea is cumbersome the next one is maybe a bit slower nah ? |
| ||
I create like a bank of 16 and iterate through them every time a new sound plays and the volume/pan/pitch when the sound plays. If I want to adjust volume over time then I create a handle to that channel and "lock" it so it can't be reused by other sounds until I'm finished with it. |
| ||
That's what I thought. I tried to do something like this but for the moment result are not great. Do you still use the Stop Channel function at least for the musics ? I though stopping a channel would destroy-it or something like that... But seriously, OpenAL is not made to work this way. Am I wrong ? |
| ||
Rather than using StopChannel playing a quick empty sound will have the same effect. It's ugly but again... |
| ||
My coordinates method to pan/volume channel is corrupted if I'm using Global Channel. Plus I get all kind of little squirk sounds here and there. It's working if I'm not changing too many channel pan/volume at the same time but unfortunately I have way too many objects emitting sounds with a moving player as listener that this solution does not work. I think I'm doom until someone fix the OpenAL Channel behavior, which will probably never happen this year :( Isn't it supposed to be a support for such basic stuff? EDIT Support exist! BlitzMax update 1.48 fix that OpenAL Channel Bug :D Last edited 2012 |