A mysterious performance issue

Low Level Wave Audio on Windows

Posted 10 March 2009 - 08:41 PM

Hi guys
Yesterday I came across what seems to be an unexplainable error with some low level wave audio code I've been working.

Basicly I am working on objects to encapsulate the functionality of the low level wave audio API on windows. Each form of wave audio has a set of objects. In my case I am working on wave input and output, which are broken up into a class to hold and release the device handle, a buffer responsible for preparing and unpreparing itself, as well as allowing data to be copied to or from the buffer depending on whether it is an input or output buffer, and the high level class that creates the handle object and the buffers as well as handling the starting and stopping of the devices.

For testing purposes I had a loop setup where a vector would be filled by the input device, and copied by the output device. However, over time it starts to slow down significantly, even to the point of almost causing a system crash. When I first noticed the problem I received a multimedia error code of 7, which is a memory allocation problem.

Before I continue, I will point out that I was using short buffers, and initially they played smoothly.

I thought that maybe I needed to prepare and unprepare the buffers as they were used, that is prepare before sending to the device, and unprepare after only 1 use by the device, originally the buffer would prepare itself on construction, and unprepare itself on destruction. To prevent a major rewrite to test the theory I started queueing buffers and deleting them after they were returned to my application. This resulted in the application running smoother for longer, but it eventually ran into the same issue later.

I am wonderring, could these issues actually be 2 seperat issues? Could the initial problem be that a buffer MUST be unprepared after single use by the device? Could the second issue be heap fragmentation as a result of creating and destroying vectors so quickly?

One more thing, my high level device classes maintain 2 internal queues of buffers, one for available buffers, one for queued buffers. The buffer at the front of the queued buffers queue is polled for the done flag when a buffer is needed by the buffer copying functionality, until the done flag is set, using a while loop with a Sleep(0) body.

Replies To: Low Level Wave Audio on Windows

Re: Low Level Wave Audio on Windows

Posted 11 March 2009 - 05:07 PM

wow, you've gotta be kidding right? Thousands of members, 1 day, and not 1 suggestion of things to try. No matter.

I present to everyone a warning. Do NOT use the STL queue object unless you can provide a container with a stable allocation algorithm, that is, do not use the STL queue with a container that frees unused allocation units automatically, such as the STL dequeue. If in particular your application rapidly queues and dequeues objects from a queue using a dequeue container, this can result in very fast heap fragmentation with the default allocator. Because of the way STL allocators must allocate it is mindlessly inefficient to create a custom allocator that directly allocates from virtual memory rather than from the heap. Also unfortunate is the fact that the vector container does not provide a pop_front method which is required by the queue adapter.