6

I'm writing a console program that uses DirectSound API to render some audio data. I stumbled on a curious problem when following the DirectSound Programming Guide (from Microsoft). According to the documentation :

After creating a device object, you must set the cooperative level for the device by using the IDirectSound8::SetCooperativeLevel method. Unless you do this, no sounds will be heard.

The problem is that I'm writing a console program, and SetCooperativeLevel requires a HWND as a first argument. I don't have any HWND to deal with in the console program. I tried providing a null pointer but it failed with a DSERR_INVALIDPARAM error code.

What HWND value should be provided to IDirectSound8::SetCooperativeLevel in a console program ? The audio part of the program is planned to be built as a shared library, so it has little to no knowledge of the "outside" program.

Thanks for any advice !

Note : I know that there is a somewhat better solution for simply rendering audio, like using SDL, OpenAL, SFML (based on OpenAL), but for my current project DirectSound is enforced.


Edit : I found a message from a Microsoft engineer that removes doubts about using the desktop window or the console window as a HWND for SetCooperativeLevel when creating GLOBAL_FOCUS buffers.

overcoder
  • 1,523
  • 14
  • 24

2 Answers2

3

Although I have not tested this myself, you may have some success creating a hidden window and passing its HWND to the SetCooperativeLevel method. SetCooperativeLevel uses this hwnd to determine when your application has input focus; therefore, if you select a cooperative level where the input focus doesn't matter (eg, DSSCL_NORMAL), a hidden window (which will never receive input focus) should be fine.

bdonlan
  • 224,562
  • 31
  • 268
  • 324
  • As you said, the input focus should not interfere when rendering audio. I innocently tested providing the HWND returned by `GetDesktopWindow()` to `SetCooperativeLevel`, and it seems to work. However, I don't know if it has any drawbacks compared to using a hidden window handle ... – overcoder Jul 15 '11 at 23:45
  • Passing a HWND you don't control seems like a very bad idea. It's one of those things that'll probably work just fine - until the day your code ends up being dissected at dailywtf or "the old new thing". – snemarch Jul 16 '11 at 00:37
  • @overcoder, I'd be worried about what happens if another program decides to do the same thing... – bdonlan Jul 16 '11 at 00:37
  • @snemarch, @bdonlan : You're right. I prefer writing it properly, as described by bdonlan. Murphy's law come to mind : 'Anything that can possibly go wrong, does' ... – overcoder Jul 16 '11 at 01:08
  • 1
    It's perfectly fine to pass another app's HWND to DirectSound. Not a great design, but it works. This is how certain gamer voice-comm app's like RogerWilco and Battlecom used to do it before DSSCL_EXCLUSIVE mode was deprecated (and all the games used that mode). The game could remain in the foreground with it's own HWND, yet the voice-comm app could play audio in the background. As a matter of fact, you don't even have to pass in a valid HWND at all if you're using coop mode that doesn't care about app focus. You could pass in anything non-zero. – selbie Jul 16 '11 at 05:02
  • 1
    @selbie : Thanks for your reply. I previously found that using some nonzero HWND works fine, but the doubt is still present without an explicit reference or documentation. I (heavily) googled to find one from a microsoft engineer : http://groups.google.com/group/microsoft.public.win32.programmer.directx.audio/msg/2145cdcf7753c9c3 – overcoder Jul 16 '11 at 15:08
2

you can use this ::GetDesktopWindow().

j0k
  • 22,600
  • 28
  • 79
  • 90
szhu
  • 21
  • 1