ResumeChannel fails under OpenAL
Archives Forums/BlitzMax Bug Reports/ResumeChannel fails under OpenAL
| ||
I'm just adding a pause function for my game and discovered that ResumeChannel (or possibly PauseChannel) does not work correctly under OpenAL. Load a sound of your choice in the code below, and press P to pause/unpause. It works fine while the sound is still playing. Now wait for the sound to end, and press P to pause/unpause. When I unpause now, the sound starts playing again but it should not, as its ended. This code works as expected under the default driver (whatever that is these days) I'm using Windows 7. Graphics 400,300 EnableOpenALAudio() SetAudioDriver("OpenAL Generic Software") Local snd:TSound = LoadSound("newitem.ogg") Local channel:TChannel = New TChannel channel = PlaySound(snd) Local paused:Byte While Not KeyDown(key_escape) If KeyHit(key_p) paused = 1 - paused If paused = True PauseChannel(channel) Else ResumeChannel(channel) EndIf EndIf Cls DrawText "Paused: " + paused,50,50 Flip Wend [edit] Tested with the following: OpenAL Generic Software - Fails OpenAL - Fails OpenAL Default - Fails FreeAudio - Works FreeAudio Multimedia - Works FreeAudio DirectSound - Works DirectSound - Works |
| ||
I 'think' I've seen this before, and as such, its a bug in OpenAL itself, rather then BlitzMax. Dabz |
| ||
Dunno. Just tested in XP too - fails the same as above. |
| ||
OpenALAudio.BMX>TOpenALChannel...Method SetPaused( paused ) If _seq<>_source._seq Return If paused alSourcePause _source._id Else If _source.Paused() Then alSourcePlay _source._id EndIf End Method |
| ||
Awesome! Thanks Ian! Can this be put in an official release, please? :D |
| ||
Hi, Yep, in for 1.38! |
| ||
Wait a minute.... I think this has caused a new problem. (Sorry Mark - tested with the original code I reported the bug with - which did appear to be fixed) Using the code below, I only get sound for the first few (3) times I press X. After that - nothing. Graphics 800,600 EnableOpenALAudio() SetAudioDriver("OpenAL Generic Software") Local snd:TSound = LoadSound("chain.ogg") While Not KeyDown(key_escape) If KeyHit(key_x) PlaySound snd EndIf Delay 1 Wend |
| ||
Hmm...You can only play a new sound whilst the initial sound is still playing.:o/ I know next to nothing about OpenAL's inner workings but it appears that you can only pause a source when it's state is either AL_INITIAL or AL_PLAYING. Once the assigned buffer has played through, the state is set to AL_STOPPED. This means that subsequent calls to TOpenALChannel.Cue(), via TOpenALSound.Play(), don't pause the source. The source has to be rewound, thus forcing an AL_INITIAL state, *only* when TOpenALChannel.Cue() is called via TOpenSound.Play(). Unfortunately I can't yet see a 'nice' way to implement this. In the mean time, here's a bodge... In OpenALAudio.BMX TOpenALChannel Method Rewind() If _seq<>_source._seq Return alSourceRewind _source._id End Method Method SetPaused( paused ) If _seq<>_source._seq Return If paused alSourcePause _source._id Else If _source.Paused() Then alSourcePlay _source._id EndIf End Method TOpenALSound Method Play:TOpenALChannel( alloced_channel:TChannel=Null ) Local t:TOpenALChannel=Cue( alloced_channel ) t.Rewind() t.SetPaused False Return t End Method I don't really have any BMX code that uses the sound system to any great extent, so can't easily test this fully myself. |
| ||
It seems to be working fine here with that code. Here's the modified, horrible test code I'm using if you wanna give it a try (obviously this only pauses one channel so if you've jabbed the X key a few times, then press P, some sounds will still run).Graphics 400, 300 EnableOpenALAudio() SetAudioDriver("openal generic software") Local snd:TSound = LoadSound("select.ogg") Local channel:TChannel = New TChannel channel = PlaySound(snd) Local paused:Byte While Not KeyDown(key_escape) If KeyHit(key_x) channel = PlaySound(snd) EndIf If KeyHit(key_p) paused = 1 - paused If paused = True PauseChannel(channel) Else ResumeChannel(channel) EndIf EndIf Cls DrawText "Paused: " + paused,50,50 Flip Wend |
| ||
Hi, Slightly simpler fix in TOpenALChannel - use with Yan's first SetPaused() fix above: Method Cue( sound:TOpenALSound ) If _seq<>_source._seq Return _source._sound=sound alSourceRewind _source._id alSourcei _source._id,AL_LOOPING,sound._loop alSourcei _source._id,AL_BUFFER,sound._buffer End Method |
| ||
Cor... took me ages to even spot the difference with that! Trying now... completely buggered it up so just reinstalling! [edit] Got it sorted in the end. Having trouble even copying/pasting today. With Yan's SetPaused() and your Cue(), all seems good now. Thanks for your help! |
| ||
LOL...That was my first solution too. Unfortunately, I'd somehow got it into my head that CueSound() shouldn't *always* restart the sample, but of course it should...Doh! |
| ||
Just a lil update - been using this in my game for the past two days without any apparent errors whatsoever (you said it was a bodge - but whatever's bodgy about it, it works really well) |
| ||
The use of alSourceRewind is quite correct. It was my implementation, due to a misunderstanding of how CueSound() is supposed to work (brain spasm), that I considered to be a bodge. See my previous post. Now, can we just forget the whole thing. ;o) Wanders off, whistling at the ceiling |