1

Closed

Crashes with this ogg

description

Not sure if it's an issue with the file or OpenAL but this consistently fails the ALHelper.Check routine. Skipping all checks allows the sound to play in the test app but the memory grows with each play.

This sound is an ogg created from this wav file:

http://opengameart.org/content/menu-selection-click

Using an online converter (tried two different ones).

file attachments

Closed Aug 1, 2013 at 1:11 PM by ioctlLR
Appears to be fixed

comments

gwicksted wrote Jun 14, 2013 at 7:38 PM

I should mention this is in an OpenTK project.

Crashes here:

   at NVorbis.OpenTKSupport.ALHelper.Check()
   at NVorbis.OpenTKSupport.OggStreamer.EnsureBuffersFilled()
   at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Threading.ThreadHelper.ThreadStart()

ioctlLR wrote Jun 14, 2013 at 8:27 PM

Hmmm.... NVorbis decodes this just fine in my testing app (using NAudio to play it back). Do you have any further information on the exact error being encountered?

Thanks!

gwicksted wrote Jun 14, 2013 at 9:14 PM

I modified OpenTKStreamingTest such that the first entry in StreamFiles was the attached ogg.

(obviously) I added the ogg to the project and made it Copy if newer


Then ran in Debug mode. Crashes without any user input:

   at NVorbis.OpenTKSupport.ALHelper.Check() in c:\dev\test\opentk\nvorbis-master\nvorbis-master\OpenTKSupport\OggStream.cs:line 29
   at NVorbis.OpenTKSupport.OggStreamer.EnsureBuffersFilled() in c:\dev\test\opentk\nvorbis-master\nvorbis-master\OpenTKSupport\OggStream.cs:line 473
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Threading.ThreadHelper.ThreadStart()
If I comment out all the ALHelper.Check() calls, it still plays the sound.

ioctlLR wrote Jun 14, 2013 at 10:08 PM

OK... Can you give me the full Exception.ToString()? A stacktrace is really nice, but the actual error message is kinda important, too. :)

The best I can figure is that OpenAL is experiencing some kind of error. It's blowing up in the call to AL.SourceQueueBuffers(...), so that's where I'd start looking.

On a related note, ALHelper.Check() just checks the error codes set by the previous call to AL and throws an exception if something isn't right. You'll want to look at the previous statement to see where the error actually happened.

gwicksted wrote Jun 15, 2013 at 4:07 AM

Sorry, I was hoping it would be easy for you to reproduce with the ogg
file and the test app...

The message wasn't very helpful: "Invalid Operation"

It is of type System.InvalidOperationException


The ALError enum value is IllegalCommand

I verified that AL.GetErrorString is really returning "Invalid Operation"


EnsureBuffersFilled hits the for statement like so:
tempBuffers.Length=2 // before for statement
finished=True // after FillBuffer
Removing stream // stream.IsLooped=false
SourceQueueBuffers(4, 2, tempBuffers)
tempBuffers[0] = 2
tempBuffers[1] = 3
This happens both from my game and from the test application.

I have tried both single and multi-threaded access.


It seems to be related to very short ogg files.


TestApp is .net 4 client profile. My game is .net 4.5


(hoping the following doesn't matter but I'll provide it)

I'm on a 64 bit Lenovo Thinkpad W520 running Windows 7 with 16gb of ram,
an SSD and an i7 processor.

The sound card is a Conexant 20672 SmartAudio HD.


Maybe it's a timing issue due to the speed of my PC and the small size
of the file? It crashes 100% of the time.


I'll try on another Win7 64 PC tonight (4gb ram on a Core2 Quad 6600
with SSD).

P.S. I'm running from Visual Studio 2012 Professional. Happens in
Release and Debug mode.

gwicksted wrote Jun 15, 2013 at 3:57 PM

Reproduced on my Q6600 desktop w/ Realtek sound card.

ioctlLR wrote Jun 15, 2013 at 4:35 PM

Looks like you are probably on to something with this being a timing issue. My recommendation: Don't decode small files on demand. Pre-decode them, then use the raw PCM data to play back as needed.

Unfortunately, I believe this is purely an OpenAL issue, so I'm not going to be much help beyond this (the OpenTK support was written by someone else).

gwicksted wrote Jun 19, 2013 at 4:27 PM

NOTE: if I comment out the following line, it works perfectly - no crashes, plays the sound properly, no memory leaks. Can you confirm this line is required for normal operation?
i = tempBuffers.Length;
The code becomes this:
                            if (finished)
                            {
                                if (stream.IsLooped)
                                {
                                    stream.Reader.DecodedTime = TimeSpan.Zero;
                                }
                                else
                                {
                                    streams.Remove(stream);
                                    //i = tempBuffers.Length;
                                }
                            }

ioctlLR wrote Jul 17, 2013 at 2:58 PM

I think the correct fix is:
                        int bufIdx = 0;
                        for (; bufIdx < tempBuffers.Length; bufIdx++)
                        {
                            finished |= FillBuffer(stream, tempBuffers[bufIdx]);

                            if (finished)
                            {
                                if (stream.IsLooped)
                                    stream.Reader.DecodedTime = TimeSpan.Zero;
                                else
                                {
                                    streams.Remove(stream);
                                    break;
                                }
                            }
                        }

                        AL.SourceQueueBuffers(stream.alSourceId, bufIdx, tempBuffers);
                        ALHelper.Check();
This is based on the idea that AL.SourceQueueBuffers(...) will set an error flag if any of the buffers are not filled. Telling it the real count of filled buffers should sidestep the issue nicely while maintaining the original intent.

jjxtra wrote Jul 22, 2013 at 8:19 PM

Are you still seeing this issue in the latest code?

ioctlLR wrote Jul 22, 2013 at 8:43 PM

I haven't heard any updates from the reporting user. If you can't repro it with the latest code, I think it's probably fixed.

gwicksted wrote Sep 30, 2013 at 7:01 PM

Confirmed this scenario works now (doesn't crash) with the latest version.