Multiple sound issue..

Posted by Shadowfyr on Thu 04 Dec 2003 09:36 PM — 12 posts, 27,174 views.

USA #0
Finally, after a bit of frustration and a lot of googling (which returned total garbage), I managed to find this page, which explains how this is done:

http://www.pocketpcdn.com/articles/multiplewaves.html

It is complicated and a serious mess, but apparently somehow manages to successfully play multiple sounds overlapping each other. Hopefully it actually does what is needed to solve the problem Mushclient currently has with killing its own sounds. It may also only work with WAV types, I am not sure.
USA #1
I have confirmed the worst.. I swear MS must have somehow been involved directly with this idea, but it seems to work like this:

1. Is there a output device?
2. Yes - Is it available?
3. Yes - Who cares, send the sound file anyway.
4. Driver/Card - Oops.. Someone needs me to play a
new sound, Voice 16 is free, lets put it there...

Note, there is no way to find how many voices a card has that I can tell, no way to tell if a voice is in use (i.e. your sound is playing) and no way to specify which voice to use. You just throw the sound at the wall and hope it sticks. This of course means that if the card still thinks everything is OK, but by pure chance you program crashes without releasing the sound properly, it can get locked in a loop that won't stop until you reboot. I have seen this happen in DOS and at least one Windows game get 'stuck' like that until I exited the game, but I guess it works *most* of the time, like pretty much everything else running under Windows. lol
USA #2
Well, if you want more precise sound control, you use things like DirectSound or fmod, or you write your own interface to the sound cards... the basic Windows API isn't meant to give you super-good control, it's just meant to let you play sounds without all the other hassle.
USA #3
Well, this is true, but it is a bit like providing an API that lets you write to a HD, but won't let you check how much space is on it or get a file directory list. These are fairly basic features being left out and since cards, ranging from the early SoundBlasters, to the newest ones can have anything from 8 to (in one case I saw) 96 seperate voice channels, not providing access to or control of those thing within the same API is kind of dumb. However, it doesn't surprise me that the 'solution' seems to consist or bloating the OS even more my adding the whole mess of DirectX drivers, just to manage sounds better. I consider it flat out stupid to not have.
USA #4
Do you even know what DirectX is for? Judging by what you said about it being a bloat I'm guessing you don't...

Back in the days of DOS, programmers had to provide drivers for all known sound cards themselves. That's why so many games ask you to choose your sound card and even video card. These could not be incorporated into the OS because they changed so often; they can't exactly release new service packs every time a card comes out.

DirectX - and other similar packages, which I won't bother naming - serve as centralized places to talk to the hardware. The whole point is that the programmer no longer has to worry about talking to hardware, and instead talks to the middle layer of the DX API. If DX hadn't been there, it would have to all be in Windows (ick) or all be in every program (even more ick.)

The comparison to hard drives is actually quite flawed because they almost all use the same kind of basic driver to talk to. Most hard drives will work, for instance, with a "generic IDE hard drive" or something like that. If you think about it, all hard drives are basically the same, except some are bigger/faster than others. Sound cards on the other hand are very different, because they can have different voices, different mixing features; some have wave-table synths, others don't... it's just not at all the same problem.

If you want, you can go ahead and make your own sound API that lets you do smarter things, but you'd just be reinventing the wheel. You'd also have to have all the drivers to talk to the cards - which is, I'm guessing, why it's not in Windows already. Hence, DirectX, fmod, etc.
USA #5
I know what DirectX is for. It does a lot more than just handle sound. Provides support for easy use of 3D cards and a mess of other things. My point is that if the *only* thinh you are trying to do is talk to the sound card more effectively it is overkill. I also have a book on the subjects of 3D games that includes details on using DirectSound. I wasn't that impressed with what it seemed to provide. Then again, it may have helped me a lot if the morons that write these books didn't assume you are going to be using the latest copy of Visual C++ and have a complete list of all API calls and parameters that you need to use them. lol

It is this last assumption that drove me bloody nuts when I tried to use basic Windows API functions in my fireworks gadget. I finally had to dig up a version I had of Visual C++ V3.0 or something to get a complete list of the parameter values needed. The stupidist thing about this is that the books I "couldn't" find them in where two 1100 page books, one titled "Microsoft MFC Class 4" and the other "NT 4/Windows 95 Developer's handbook". Now... If all the documentation I actually need is buried in the .h files of the VC++ compiler, what they heck good was it to buy the books, even when they where new books? lol

Seriously though.. I was considering the complications involved with some pour fool trying to run Mushclient on a real old machine that doesn't have 'any' DirectX version installed, when I went looking for a more universal and non-DLL dependant solution.
USA #6
I think it's fairly safe to assume that somebody has at least DX 3... it's been around for a long time, so I think it's a safe assumption. :)

Yes, it is overkill to use all of DX just for sound, but that's why you can use other packages, such as fmod, which I believe only does sound. fmod is meant to be a platform independent package, though, so for all I know its implementation on Windows may use DSound anyways. (It is possible to only load up parts of DX.)

The thing is that there isn't really a universal solution to the problem. You could in theory compile your program and include the libraries statically, but you'd get massive redistributables instead of needing people to have DirectX. That at least solves the DLL issue.. sort of like when for VB, you include the VB runtime libraries in your setup file. You go from a few hundred k to at least 1.5 mb, but, well, they don't need the VBRTL.

If you want a complete list of API calls, the MSDN help files are actually very good at that sort of thing. They also come with interesting tutorials that tell you how to use DX and that sort of thing. There is also a ton of reference material online; tutorials, manuals, etc.

You should buy a book on the Windows API, not on MFC, to get documentation on the Windows API. :P

To go back to the sound issue, if you don't use a package like DX or fmod, you have to write all the drivers yourself. Good luck doing that...
USA #7
> You should buy a book on the Windows API, not on MFC, to get documentation on the Windows API. :P

The problem is I do have that. And same problem. I also downloaded a program that provides a complete list of all API functions (from a website with the same). Same problem. It is all well and good telling you:

SomeFunction (hwnd HWND, parama, paramb)

parama can be WND_blah, WND_blah2, WND_blah2, etc., but as useful as this information may be, it is actually completely and totally useless if they don't bother to tell you what the hell those values are. They 'could' be 1, 2, 4, or they may for some insane reason be 1, 16, 64. Worse, you get some cases where two values are identical, but they don't tell you if they are 'identical' or just produce 'identical results'. Then there are situations where the value is maybe 3 or 7 or something, but you don't know, because someone could have just as easilly given it a number like 128 that performs all two or three things at once. Not a major issue, since ORing the values produces the same result, but since you still don't know what those values are...

But I get your point, maybe a book that actually specifically said Windows API in the title would be different. I somehow doubt it considering the spotty resources I have seen, but 'maybe'. lol

In any case, this has gotten a long way off track, so Nick.. If you have read all this, the ***important*** bit is in the first post. You can ignore the rest. ;) lol
USA #8
The MSDN provides all the information you could need under the "Platform API" or something like that; I think it's available for free at msdn.microsoft.com (at least, the online version, not the offline version) or you could buy it or something. Depends on how much you program and need a reference guide... I find it extremely useful, but I also got it for free as part of an academic package Stanford hands out in its CS classes, thanks to a deal with Microsoft. (Woohoo :P)

For example,
Quote:

The SetWindowPos function changes the size, position, and Z order of a child, pop-up, or top-level window. Child, pop-up, and top-level windows are ordered according to their appearance on the screen. The topmost window receives the highest rank and is the first window in the Z order.

Syntax

BOOL SetWindowPos(          HWND hWnd,
    HWND hWndInsertAfter,
    int X,
    int Y,
    int cx,
    int cy,
    UINT uFlags
);

Parameters

hWnd
[in] Handle to the window.
hWndInsertAfter
[in] Handle to the window to precede the positioned window in the Z order. This parameter must be a window handle or one of the following values.
HWND_BOTTOM
Places the window at the bottom of the Z order. If the hWnd parameter identifies a topmost window, the window loses its topmost status and is placed at the bottom of all other windows.
HWND_NOTOPMOST
Places the window above all non-topmost windows (that is, behind all topmost windows). This flag has no effect if the window is already a non-topmost window.
HWND_TOP
Places the window at the top of the Z order.
HWND_TOPMOST
Places the window above all non-topmost windows. The window maintains its topmost position even when it is deactivated.
For more information about how this parameter is used, see the following Remarks section.
X
[in] Specifies the new position of the left side of the window, in client coordinates.
Y
[in] Specifies the new position of the top of the window, in client coordinates.
cx
[in] Specifies the new width of the window, in pixels.
cy
[in] Specifies the new height of the window, in pixels.
uFlags
[in] Specifies the window sizing and positioning flags. This parameter can be a combination of the following values.
SWP_ASYNCWINDOWPOS
If the calling thread and the thread that owns the window are attached to different input queues, the system posts the request to the thread that owns the window. This prevents the calling thread from blocking its execution while other threads process the request.
SWP_DEFERERASE
Prevents generation of the WM_SYNCPAINT message.
SWP_DRAWFRAME
Draws a frame (defined in the window's class description) around the window.
SWP_FRAMECHANGED
Applies new frame styles set using the SetWindowLong function. Sends a WM_NCCALCSIZE message to the window, even if the window's size is not being changed. If this flag is not specified, WM_NCCALCSIZE is sent only when the window's size is being changed.
SWP_HIDEWINDOW
Hides the window.
SWP_NOACTIVATE
Does not activate the window. If this flag is not set, the window is activated and moved to the top of either the topmost or non-topmost group (depending on the setting of the hWndInsertAfter parameter).
SWP_NOCOPYBITS
Discards the entire contents of the client area. If this flag is not specified, the valid contents of the client area are saved and copied back into the client area after the window is sized or repositioned.
SWP_NOMOVE
Retains the current position (ignores X and Y parameters).
SWP_NOOWNERZORDER
Does not change the owner window's position in the Z order.
SWP_NOREDRAW
Does not redraw changes. If this flag is set, no repainting of any kind occurs. This applies to the client area, the nonclient area (including the title bar and scroll bars), and any part of the parent window uncovered as a result of the window being moved. When this flag is set, the application must explicitly invalidate or redraw any parts of the window and parent window that need redrawing.
SWP_NOREPOSITION
Same as the SWP_NOOWNERZORDER flag.
SWP_NOSENDCHANGING
Prevents the window from receiving the WM_WINDOWPOSCHANGING message.
SWP_NOSIZE
Retains the current size (ignores the cx and cy parameters).
SWP_NOZORDER
Retains the current Z order (ignores the hWndInsertAfter parameter).
SWP_SHOWWINDOW
Displays the window.
USA #9
Ok. First off, I have that. The MSDN came with my Professional edition of VB6.0. However, you miss my point. VB does not come with header files or other resources that define the values for any of those things. For instance:

HWND_BOTTOM
...

HWND_NOTOPMOST
...

HWND_TOP
...

HWND_TOPMOST
...

These are what?? VB has no definition for them built in and they could easilly be 0, 1, 2 and 4. But there actual values are:

HWND_BOTTOM = 1
HWND_NOTOPMOST = -2
HWND_TOP = 0
HWND_TOPMOST = -1

How the heck are you supposed to 'guess' what those are? In order to use it in VB, you must define these constants manually in some convenient place, like a global .BAS module, but without knowing them..

Worse is the rest of the settings. While you can find numerous examples of using one or more of the above settings, all the other settings are rarely listed in the examples. They may use SWP_NOSIZE and SWP_NOMOVE and even SWP_SHOWWINDOW, but you probably wont find example code that gives the value for SWP_NOCOPYBITS. To find that you must refer to the .h file for the API in C++, which is the *only* place you are likely to find all of them listed. Even the MSDN doesn't provide these constant values, only their names.
USA #10
Actually, VB *does* come with something that solves exactly your problem. It's called the API viewer or something like that; I don't have it here because it's in Visual Studio 6, not .NET.

It has a complete list of *all* Windows API functions and accompanying declarations.

You're too quick to complain without looking at the tools that come with your product :P
USA #11
Ack!! Hmm. For some reason that won't let itself be auto loaded as an available tool.. Who knows why.. It is also imho not terribly great. If you check for the declaration it will give you that (and no other information), but then selecting 'Constants', doesn't give you the constants usable by *that* API call, but instead a huge list of every one in existance. You still end up having to look at a real API document to find out which constants of the probably 500+ that are listed actually belong to that function.

Nice to know it is there, but it looks like something they threw in at the last moment and didn't bother to make work properly. :(