views:

150

answers:

3

I am playing back audio in C# using the waveOut functions with the callback method where messages are sent back to a window handle. I am creating a Windows Form with an overidden WndProc function to listen for the MM_WOM_DONE messages.

result = WaveInterop.waveOutOpen(out hWaveOut, devNumber, waveStream.WaveFormat, waveOutWindow.Handle, 0, WaveInterop.CallbackWindow);

All this works completely reliably when I am on the main GUI thread of my app. But if a background thread tries to do this, the waveOutWindow never receives any of the WOM_ messages. I thought at first that perhaps the window had not been created properly, and its message queue was not being serviced, but even if I put the following code in before the waveOutOpen, it still doesn't work.

waveOutWindow.Show();
Debug.Assert(waveOutWindow.IsHandleCreated, "Handle not created!");
Debug.Assert(waveOutWindow.Created, "Window not created!");

I should say that the call to waveOutOpen is successful as are the initial waveOutWrite calls, but I never get my callbacks back to know when to queue more audio.

Am I missing something really obvious about forms on background threads?

+1  A: 

Are you pumping messages on your secondary thread?

Luis Abreu
Its definitely pumping messages, as when I show the window, I get loads of messages through which I can break on. I just don't know where the WOM_ messages have ended up.
Mark Heath
doh! silly me. The message pump was not running. I've put a better explanation of what was going on in an answer below.
Mark Heath
A: 

You should monitor message input via WinSpector. You don't know how audio library implemented message handling - perhaps it sends to the main application window procedure. Maybe you can even construct it another way to feed hwnd of the window that is to receive notifications.

Anyway, if any message is sent, you will see it in WinSpector.

majkinetor
A: 

OK, I've figured it out now, and of course it was obvious. The message pump for the window is not running. The thing that threw me off the right track is that when you call waveOutOpen, the WndProc for the window gets run and various messages such as WM_CREATE, WM_ACTIVATE etc get processed. However, the WndProc function does not continue to run after leaving waveOutOpen (naturally, because this thread is running other code).

Mark Heath