gamedevlists-windows Mailing List for gamedev (Page 17)
Brought to you by:
vexxed72
You can subscribe to this list here.
2001 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
(48) |
Oct
(58) |
Nov
(49) |
Dec
(38) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2002 |
Jan
(124) |
Feb
(83) |
Mar
(17) |
Apr
(37) |
May
(12) |
Jun
(20) |
Jul
(47) |
Aug
(74) |
Sep
(62) |
Oct
(72) |
Nov
(54) |
Dec
(13) |
2003 |
Jan
(36) |
Feb
(8) |
Mar
(38) |
Apr
(3) |
May
(6) |
Jun
(133) |
Jul
(20) |
Aug
(18) |
Sep
(12) |
Oct
(4) |
Nov
(28) |
Dec
(36) |
2004 |
Jan
(22) |
Feb
(51) |
Mar
(28) |
Apr
(9) |
May
(20) |
Jun
(9) |
Jul
(37) |
Aug
(20) |
Sep
(23) |
Oct
(15) |
Nov
(23) |
Dec
(27) |
2005 |
Jan
(22) |
Feb
(20) |
Mar
(5) |
Apr
(14) |
May
(10) |
Jun
|
Jul
(6) |
Aug
(6) |
Sep
|
Oct
(12) |
Nov
(1) |
Dec
|
2006 |
Jan
(18) |
Feb
(4) |
Mar
(3) |
Apr
(6) |
May
(4) |
Jun
(3) |
Jul
(16) |
Aug
(40) |
Sep
(6) |
Oct
(1) |
Nov
|
Dec
(2) |
2007 |
Jan
(5) |
Feb
(2) |
Mar
(4) |
Apr
(1) |
May
(13) |
Jun
|
Jul
(26) |
Aug
(3) |
Sep
(10) |
Oct
|
Nov
(4) |
Dec
(5) |
2008 |
Jan
(1) |
Feb
|
Mar
(4) |
Apr
|
May
|
Jun
(5) |
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
2011 |
Jan
|
Feb
|
Mar
|
Apr
|
May
(1) |
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
2015 |
Jan
|
Feb
(3) |
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
From: Jan W. <ur...@st...> - 2004-07-30 18:27:51
|
On Thu, 29 Jul 2004 01:04:04 -0700, Jon Watte <hp...@mi...> wrote: > May I suggest that you're not guaranteed that GetModuleHandle() returns a > pointer to your executable header, and you're not guaranteed that your > executable loads at 0x400000 ? They might have a hard time changing this > behavior for existing apps, especially because of hacky code like the > posted code, but you never know about future versions. > > If you want the header, use GetModuleFileName() on the main module, and > read the header yourself. Then check whether the header is actually a > "PE" header, and just assume you're not console if it isn't. At least, > that won't CRASH when you port your code, or some new version of > Windows comes out. That would be the more correct way of going about things :) However, I don't think these assumptions can ever be broken (famous last words). The app load address must stay the same, since PE relocation info is no longer generated (because 0x400000 is guaranteed). GetModuleHandle has to return a pointer, since crt0 currently uses it as such (checking if the app is managed). Now if they're willing to break every single (not recompileable) program in existence with future versions, all bets are off. Best Regards Jan |
From: Brian H. <ho...@bo...> - 2004-07-30 14:37:01
|
Let's say I make a toolbar window and add a slider to it. The slider will automatically send messages to the toolbar window, but I want those slider messages to get to the application. Is there a standard way of doing this (or does a toolbar automatically propagate child messages upstream if it doesn't understand them?). Thanks, Brian |
From: Jon W. <hp...@mi...> - 2004-07-29 08:05:24
|
May I suggest that you're not guaranteed that GetModuleHandle() returns a pointer to your executable header, and you're not guaranteed that your executable loads at 0x400000 ? They might have a hard time changing this behavior for existing apps, especially because of hacky code like the posted code, but you never know about future versions. If you want the header, use GetModuleFileName() on the main module, and read the header yourself. Then check whether the header is actually a "PE" header, and just assume you're not console if it isn't. At least, that won't CRASH when you port your code, or some new version of Windows comes out. Cheers, / h+ -----Original Message----- From: gam...@li... [mailto:gam...@li...]On Behalf Of Jan Wassenberg Sent: Wednesday, July 28, 2004 1:45 AM To: gam...@li... Subject: Re: [GD-Windows] Finding HWND of the current thread On Thu, 15 Jul 2004 14:19:49 -0400, Brian Hook <ho...@bo...> wrote: >> GetConsoleWindow > As a library, I won't know if it's a console window or not. You can check the Subsystem field of the PE "optional" header (always present): if it's equal IMAGE_SUBSYSTEM_WINDOWS_CUI (3), you've got a console app. void* base = (void*)0x400000 (or GetModuleHandle(0)) IMAGE_NT_HEADERS* h = ImageNtHeader(base) h->OptionalHeader.Subsystem == 3? Disclaimer: off the top of my head and ugly to boot ;) ------------------------------------------------------- This SF.Net email is sponsored by BEA Weblogic Workshop FREE Java Enterprise J2EE developer tools! Get your free copy of BEA WebLogic Workshop 8.1 today. http://ads.osdn.com/?ad_id=4721&alloc_id=10040&op=click _______________________________________________ Gamedevlists-windows mailing list Gam...@li... https://lists.sourceforge.net/lists/listinfo/gamedevlists-windows Archives: http://sourceforge.net/mailarchive/forum.php?forum_id=555 |
From: Jan W. <ur...@st...> - 2004-07-28 08:45:09
|
On Thu, 15 Jul 2004 14:19:49 -0400, Brian Hook <ho...@bo...> wrote: >> GetConsoleWindow > As a library, I won't know if it's a console window or not. You can check the Subsystem field of the PE "optional" header (always present): if it's equal IMAGE_SUBSYSTEM_WINDOWS_CUI (3), you've got a console app. void* base = (void*)0x400000 (or GetModuleHandle(0)) IMAGE_NT_HEADERS* h = ImageNtHeader(base) h->OptionalHeader.Subsystem == 3? Disclaimer: off the top of my head and ugly to boot ;) |
From: Andras B. <bn...@ma...> - 2004-07-15 19:56:09
|
Ok, I've found the bug: I've had my own memset routine, and my version of memset uses the int pattern as a 32 bit value to fill the memory, while the original memset uses only the first byte of the int pattern to fill... Now how funny is that! :-) Cheers, Andras |
From: Donavon K. <kei...@ea...> - 2004-07-15 19:41:55
|
Actually both windows would get WM_ACTIVATEAPP, even if they're different window classes, so let me change my bet... :-) Perhaps it's sufficient that the window be top-level? Donavon Keithley -----Original Message----- From: Donavon Keithley [mailto:kei...@ea...] Sent: Thursday, July 15, 2004 2:30 PM To: 'gam...@li...' Subject: RE: [GD-Windows] Finding HWND of the current thread > God knows what the HWND is really used for in DirectSound and > what can happen if you do something like create a hidden window > and bind DS to that instead of to your real application window. I would imagine that it's subclassing the window and sniffing for deactivation while in exclusive mode, as D3D does with the "focus" window. That would imply that it needs to be top-level and that the choice of window is quite significant. For instance in a D3D app, it should be the same window as the D3D focus window. As an experiment, I'd create a test app with two top-level windows. Give one to D3D and the other to DSound, go exclusive on both, and see what happens when you Alt-Tab away. Will DSound realize that it should relinquish? I don't have a lot of experience with DSound, but my chips are on "no". Donavon Keithley |
From: Donavon K. <kei...@ea...> - 2004-07-15 19:23:56
|
> God knows what the HWND is really used for in DirectSound and > what can happen if you do something like create a hidden window > and bind DS to that instead of to your real application window. I would imagine that it's subclassing the window and sniffing for deactivation while in exclusive mode, as D3D does with the "focus" window. That would imply that it needs to be top-level and that the choice of window is quite significant. For instance in a D3D app, it should be the same window as the D3D focus window. As an experiment, I'd create a test app with two top-level windows. Give one to D3D and the other to DSound, go exclusive on both, and see what happens when you Alt-Tab away. Will DSound realize that it should relinquish? I don't have a lot of experience with DSound, but my chips are on "no". Donavon Keithley |
From: Brian H. <ho...@bo...> - 2004-07-15 18:21:47
|
> Couldn't you just create a simple hidden window and pass that > handle in? You could, but that's not really the right thing to do, e.g. to handle minimization automatically. DirectSound really wants to have a handle to the application window, not just any handle. > Really though if this is a library wouldn't you want to allow the > user to pass in a handle and handle the case of being a console app > at a higher level... Yes, but expressing that portability is kind of gross. It's what I'm doing right now, in fact, but I don't like it, and if there was a way to isolate the user from this, that would be ideal. Brian |
From: Brian H. <ho...@bo...> - 2004-07-15 18:19:56
|
> GetConsoleWindow As a library, I won't know if it's a console window or not. > EnumThreadWindows > GetWindowThreadProcessId Right, that's what I was thinking might be the most robust way to do it for non-console apps (and for console apps, creating a dummy window). Brian |
From: Andras B. <bn...@ma...> - 2004-07-15 17:51:42
|
> (1) Could it be that "buf" is somehow corrupted before you check its > contents? Maybe try the following: > > sprintf( buf, "Hey!-->%.3f<--Look!", 0.05f ); > > (making sure "buf" can handle the extra text) and see that the > stuff before and after the floating-point field appears in "buf" > as expected. Tried that, and it's not corrupted (I can see the "Hey" "Look!" messages in buf, but it's still "0." In the middle). > (2) Try out the following code from MSDN -- perhaps changing "_fcvt" > to "_cfltcvt" as a wild guess if it fails to link with your crt0. > Maybe testing cases similar to your 0.05f case with this function > in particular will narrow down the problem. > > /* FCVT.C: This program converts the constant > * 3.1415926535 to a string and sets the pointer > * *buffer to point to that string. > */ > > #include <stdlib.h> > #include <stdio.h> > > void main( void ) > { > int decimal, sign; > char *buffer; > double source = 3.1415926535; > > buffer = _fcvt( source, 7, &decimal, &sign ); > printf( "source: %2.10f buffer: '%s' decimal: %d sign: %d\n", > source, buffer, decimal, sign ); > } > > // Output > // source: 3.1415926535 buffer: '31415927' decimal: 1 sign: 0 _fcvt seems to work fine! Strange! So what does that mean? > (3) Maybe put a memory breakpoint on "buf" to see when and how it is > modified. Perhaps you'll find some unexpected modifications > shortly AFTER your sprintf() call, and BEFORE your examination > of the result. Actually, I did step through printf, until the call of that _cfltcvt, when the result immediately appeared in the buffer, so the only thing that could screw up is _cfltcvt... > (4) Finally, I don't want to raise any undue panic, but you might > be having psychotic hallucinations. It goes without saying that > you are using your own crt0 on the advice of the voices in your head, > but the question is whether or not your paranoia has you believing > that space aliens tampered with your private crt0 to keep you > from learning more than "0." -- after all, knowing the full > value, 0.050, would expose the horrifying conspiracy. For sure > the sys admins of your region of the Matrix would have to change > some parameters to restore balanced gameplay. I have hallucinations all the time! I feel dizzy, and my eyes project words into my brain written by some guy called Colin.. but I don't think he really exists. I think he's just a helper bot installed into our brains (hmm, maybe he's responsible for my recent memory leaks? I really need a decent garbage collector!). Anyway, I don't fear the aliens, and I won't let them mess with my crt0!! Cheers, Andras |
From: Andras B. <bn...@ma...> - 2004-07-15 17:51:41
|
> Can you verify that the control word generated by your crt0 is IDENTICAL > to > the one generated by the standard crt? All bets are that's not the case. Yes, I've called _control87(0, 0) right before printf on both a standard app, and mine, and they returned the same result.. > sprintf() works under a number of assumptions about the state of the > run-time. I believe the source code is available, so you can check which > assumptions are those, and whether you comply with them or not. Yeah, the source code is available, but it uses the magic _cfltcvt, for which I have nothing... The funny thing is, that when the number is exactly 0, it prints "0.000" It only fails, when 0 < abs(x) < 0.1 Thanks, Andras |
From: Andrew G. <ag...@cl...> - 2004-07-15 17:14:51
|
Couldn't you just create a simple hidden window and pass that handle in? Really though if this is a library wouldn't you want to allow the user to pass in a handle and handle the case of being a console app at a higher level... Andy -----Original Message----- From: gam...@li... [mailto:gam...@li...] On Behalf Of Brian Hook Sent: 15 July 2004 17:38 To: gam...@li... Subject: [GD-Windows] Finding HWND of the current thread For my simple audio library I'm stuck doing something a little gross, and that's passing an HWND to the library upon initialization, only because IDirectSound::SetCooperativeLevel() needs an HWND. Now, you CAN use GetDesktopWindow() and NULL, but that's not the correct way and there are supposedly some failure cases when you use those (e.g. multiple instances using GetDesktopWindow()), and God knows what the HWND is really used for in DirectSound and what can happen if you do something like create a hidden window and bind DS to that instead of to your real application window. Anyway, that aside, instead of passing in HWND, I was thinking it might be possible to find the window of the current thread by enumerating all windows in the system and comparing their owner threads with the current thread and using that. Is there anything glaringly wrong with that, other than the potential situation that there is none (e.g. console application) and having to fallback at that point. Brian ------------------------------------------------------- This SF.Net email is sponsored by BEA Weblogic Workshop FREE Java Enterprise J2EE developer tools! Get your free copy of BEA WebLogic Workshop 8.1 today. http://ads.osdn.com/?ad_idG21&alloc_id040&op=click _______________________________________________ Gamedevlists-windows mailing list Gam...@li... https://lists.sourceforge.net/lists/listinfo/gamedevlists-windows Archives: http://sourceforge.net/mailarchive/forum.php?forum_idU5 |
From: Mat N. \(BUNGIE\) <mat...@mi...> - 2004-07-15 17:14:17
|
Useful functions: EnumThreadWindows GetConsoleWindow And for a brute force window search: GetWindowThreadProcessId MSN -----Original Message----- From: gam...@li... [mailto:gam...@li...] On Behalf Of Brian Hook Sent: Thursday, July 15, 2004 9:38 AM To: gam...@li... Subject: [GD-Windows] Finding HWND of the current thread For my simple audio library I'm stuck doing something a little gross,=20 and that's passing an HWND to the library upon initialization, only=20 because IDirectSound::SetCooperativeLevel() needs an HWND. Now, you CAN use GetDesktopWindow() and NULL, but that's not the=20 correct way and there are supposedly some failure cases when you use=20 those (e.g. multiple instances using GetDesktopWindow()), and God=20 knows what the HWND is really used for in DirectSound and what can=20 happen if you do something like create a hidden window and bind DS to=20 that instead of to your real application window. Anyway, that aside, instead of passing in HWND, I was thinking it=20 might be possible to find the window of the current thread by=20 enumerating all windows in the system and comparing their owner=20 threads with the current thread and using that. Is there anything glaringly wrong with that, other than the potential=20 situation that there is none (e.g. console application) and having to=20 fallback at that point. Brian ------------------------------------------------------- This SF.Net email is sponsored by BEA Weblogic Workshop FREE Java Enterprise J2EE developer tools! Get your free copy of BEA WebLogic Workshop 8.1 today. http://ads.osdn.com/?ad_idG21&alloc_id=10040&op=3Dick _______________________________________________ Gamedevlists-windows mailing list Gam...@li... https://lists.sourceforge.net/lists/listinfo/gamedevlists-windows Archives: http://sourceforge.net/mailarchive/forum.php?forum_idU5 |
From: Brian H. <ho...@bo...> - 2004-07-15 16:37:57
|
For my simple audio library I'm stuck doing something a little gross, and that's passing an HWND to the library upon initialization, only because IDirectSound::SetCooperativeLevel() needs an HWND. Now, you CAN use GetDesktopWindow() and NULL, but that's not the correct way and there are supposedly some failure cases when you use those (e.g. multiple instances using GetDesktopWindow()), and God knows what the HWND is really used for in DirectSound and what can happen if you do something like create a hidden window and bind DS to that instead of to your real application window. Anyway, that aside, instead of passing in HWND, I was thinking it might be possible to find the window of the current thread by enumerating all windows in the system and comparing their owner threads with the current thread and using that. Is there anything glaringly wrong with that, other than the potential situation that there is none (e.g. console application) and having to fallback at that point. Brian |
From: Javier A. <ja...@py...> - 2004-07-15 09:00:47
|
Andras Balogh wrote: > Now how's that? Is this a denormal issue?? 0.1 is quite big, isn't it? > Still, I suspect that the problem lies in me having my own crt0 > (don't ask why :) Yes it's very likely that your problem originates in your own crt0. > but I believe I do all the floating point > initializations that the original crt0 does (it calls _fpmath(1); or > (*_Fpinit)(1); whichever is defined somewhere (which btw only sets > the FPU control word AFAICT), but it's still not working the way it > should... What is happening here?? Can you verify that the control word generated by your crt0 is IDENTICAL to the one generated by the standard crt? All bets are that's not the case. sprintf() works under a number of assumptions about the state of the run-time. I believe the source code is available, so you can check which assumptions are those, and whether you comply with them or not. -- Javier Arevalo Pyro Studios |
From: Colin F. <cp...@ea...> - 2004-07-15 08:50:41
|
> Any ideas what's causing this behavior?? Could it be your "own crt0"? Hee, hee! But seriously: (1) Could it be that "buf" is somehow corrupted before you check its contents? Maybe try the following: sprintf( buf, "Hey!-->%.3f<--Look!", 0.05f ); (making sure "buf" can handle the extra text) and see that the stuff before and after the floating-point field appears in "buf" as expected. (2) Try out the following code from MSDN -- perhaps changing "_fcvt" to "_cfltcvt" as a wild guess if it fails to link with your crt0. Maybe testing cases similar to your 0.05f case with this function in particular will narrow down the problem. /* FCVT.C: This program converts the constant * 3.1415926535 to a string and sets the pointer * *buffer to point to that string. */ #include <stdlib.h> #include <stdio.h> void main( void ) { int decimal, sign; char *buffer; double source = 3.1415926535; buffer = _fcvt( source, 7, &decimal, &sign ); printf( "source: %2.10f buffer: '%s' decimal: %d sign: %d\n", source, buffer, decimal, sign ); } // Output // source: 3.1415926535 buffer: '31415927' decimal: 1 sign: 0 (3) Maybe put a memory breakpoint on "buf" to see when and how it is modified. Perhaps you'll find some unexpected modifications shortly AFTER your sprintf() call, and BEFORE your examination of the result. (4) Finally, I don't want to raise any undue panic, but you might be having psychotic hallucinations. It goes without saying that you are using your own crt0 on the advice of the voices in your head, but the question is whether or not your paranoia has you believing that space aliens tampered with your private crt0 to keep you from learning more than "0." -- after all, knowing the full value, 0.050, would expose the horrifying conspiracy. For sure the sys admins of your region of the Matrix would have to change some parameters to restore balanced gameplay. |
From: Andras B. <bn...@ma...> - 2004-07-15 05:15:02
|
Hi, In a normal app, when I write this: sprintf(buf, "%.3f", 0.05f); the contents of buf will be "0.050". But in my app, the result is "0." instead!! The magic barrier seems to be 0.1, as numbers above that (or below -0.1) work OK. Now how's that? Is this a denormal issue?? 0.1 is quite big, isn't it? Still, I suspect that the problem lies in me having my own crt0 (don't ask why :) but I believe I do all the floating point initializations that the original crt0 does (it calls _fpmath(1); or (*_Fpinit)(1); whichever is defined somewhere (which btw only sets the FPU control word AFAICT), but it's still not working the way it should... What is happening here?? I've tried to trace sprintf, but in the end it just uses a function called _cfltcvt, which is totally undocumented and the only thing I could do is reverse engineer the assembly code, which I'd rather not do.. Any ideas what's causing this behavior?? Thanks, Andras |
From: Jon W. <hp...@mi...> - 2004-07-14 21:30:54
|
> I don't change the process priority, I just set the thread priority of > the audio thread to HIGHEST (not real time) -- is there a particular > advantage to altering the process priority as well/first? I really recommend time critical priority for audio threads -- that's what that priority is for! If you get a permission error, then fall back to HIGHEST. SetPriorityClass() is what bumps up the priority for your process in general. I wouldn't set the process class to real time priority, though, that might have bad effects on the rest of the system :-) HIGH or ABOVE_NORMAL are the values you can play with here. ABOVE_NORMAL doesn't exist on DOS based Windows. The full table of class + priority mapping to actual thread priorities as used by the scheduler is found here: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dllproc/bas e/scheduling_priorities.asp It's too bad that you can't make a single thread real time without making the entire process real time, so TIME_CRITICAL is as good as it gets. Cheers, / h+ |
From: Brian H. <ho...@bo...> - 2004-07-14 18:05:40
|
> This is one of the few reasons to have a second thread in your > application, in my opinion. Agreed (along with a background resource loader if your application needs that). > If you set your process priority to > above normal, and the thread priority to real time (permissions > willing), then you can get 20 ms latency on NT based kernels, and > 50 ms or so on DOS based kernels. This is with three buffers, each > of which is 20 milliseconds. I don't change the process priority, I just set the thread priority of the audio thread to HIGHEST (not real time) -- is there a particular advantage to altering the process priority as well/first? Brian |
From: Jon W. <hp...@mi...> - 2004-07-14 15:49:44
|
This is one of the few reasons to have a second thread in your application, in my opinion. If you set your process priority to above normal, and the thread priority to real time (permissions willing), then you can get 20 ms latency on NT based kernels, and 50 ms or so on DOS based kernels. This is with three buffers, each of which is 20 milliseconds. Communication of sound events to the sound playing thread can be done using a non-blocking queue, so you interlock penalties need apply. Adding interlock would be dangerous, anyway, as you would be subject to priority inversion. Cheers, / h+ -----Original Message----- From: gam...@li... [mailto:gam...@li...]On Behalf Of Brian Hook Sent: Wednesday, July 14, 2004 7:37 AM To: gam...@li... Subject: RE: [GD-Windows] Streaming WAVE audio As it turns out I ended up going with many multiple small buffers and using an event to do the mixing, which is the ickiest way (the old method was really elegant -- sleep/wake/read position/write/sleep). The granularity for notifications absolutely sucks. I'll get signaled and sometimes find 0, 1, or N buffers waiting to be filled. I ended up going with 8 small buffers instead of 1 large buffer, and now it seems reasonably robust but I can't get my latency much below 50ms (if that) without having it crackle, whereas with my old code I think I could go below 40ms (since it wasn't dependent on being signaled by the sound backend). Thanks, Brian ------------------------------------------------------- This SF.Net email sponsored by Black Hat Briefings & Training. Attend Black Hat Briefings & Training, Las Vegas July 24-29 - digital self defense, top technical experts, no vendor pitches, unmatched networking opportunities. Visit www.blackhat.com _______________________________________________ Gamedevlists-windows mailing list Gam...@li... https://lists.sourceforge.net/lists/listinfo/gamedevlists-windows Archives: http://sourceforge.net/mailarchive/forum.php?forum_idU5 |
From: Brian H. <ho...@bo...> - 2004-07-14 14:37:47
|
As it turns out I ended up going with many multiple small buffers and using an event to do the mixing, which is the ickiest way (the old method was really elegant -- sleep/wake/read position/write/sleep). The granularity for notifications absolutely sucks. I'll get signaled and sometimes find 0, 1, or N buffers waiting to be filled. I ended up going with 8 small buffers instead of 1 large buffer, and now it seems reasonably robust but I can't get my latency much below 50ms (if that) without having it crackle, whereas with my old code I think I could go below 40ms (since it wasn't dependent on being signaled by the sound backend). Thanks, Brian |
From: Johnson, J. <Jam...@si...> - 2004-07-14 07:17:42
|
Buffer size and latency are different things. When a sound is queued it is immediately mixed into the current playing header sometime ahead of the current play position. On good hardware I was able to mix audio 10-15ms ahead of the play position without error. However like you, I discovered that to support most/all systems I had to mix a bit further ahead of the playback position; 50ms is what I chose. When I wrote this system I had some doubt about modifying the buffer addressed by a prepared and written WAVEHDR. The doco wasn't exactly clear on this point. It clearly states what members can be modified in the WAVEHDR after prepared, but doesn't mention the PCM data addressed by the header. I'm curious if others have had problems with this mixing strategy besides the obvious recomposition of the remaining playing buffer. James -----Original Message----- From: gam...@li... [mailto:gam...@li...] On Behalf Of Jon Watte Sent: Tuesday, July 13, 2004 11:40 PM To: gam...@li... Subject: RE: [GD-Windows] Streaming WAVE audio > 2) On some system there appears to be a minimum required buffer size,=0D > e.g. at least 250ms. On systems like these I got silence at best, and=0D > lock up at worst. I didn't spend a lot of time investigating this=0D > because 250ms is pretty short buffer. I was shooting for 4/8/16k=0D > buffer sizes at that time. In the end I don't think it matters. 250 ms is a REALLY BIG buffer. 250 ms of latency means you pull the trigger now, and hear the gunshot sound when the target's already dead. (When I say "buffer" I really mean "WAVHDR chunk"). I've found that once I went above 40 ms buffers, and used at least 3 buffers, any hardware I tested on worked well. Less that that in either variable caused problems. Note that the scheduler on Win98 is VERY jittery -- 20 ms scheduling jitter is common, and it can jerk higher than that, even on a quiescent system with a fast CPU. > Furthermore I recommend not using the ACM to up/down sample as it=0D > appears to perform point sampling(!) which can produce terrible audio. I always code my own re-sampler, which sits at the reader/input stage of the mixer, which I also code on my own, for the WAVE output. I prefer to use cubic Hermite interpolation, which runs fast and sounds good. Cheers, / h+ ---------------------------------------------------- Vivendi Universal Games- <<http://www.vugames.com>>:=0D The information transmitted is intended only for the=0D person or entity to which it is addressed and may=0D contain confidential and/or privileged material of=0D Vivendi Universal Games which is for the exclusive=0D use of the individual designated above as the=0D recipient. Any review, retransmission, dissemination=0D or other use of, or taking of any action in reliance=0D upon, this information by persons or entities other=0D than the intended recipient is prohibited. If you=0D received this in error, please contact immediately=0D the sender by returning e-mail and delete the=0D material from any computer. If you are not the=0D specified recipient, you are hereby notified that=0D all disclosure, reproduction, distribution or action taken on the basis of this message is prohibited. |
From: Jon W. <hp...@mi...> - 2004-07-14 06:41:37
|
> 2) On some system there appears to be a minimum required buffer size, > e.g. at least 250ms. On systems like these I got silence at best, and > lock up at worst. I didn't spend a lot of time investigating this > because 250ms is pretty short buffer. I was shooting for 4/8/16k buffer > sizes at that time. In the end I don't think it matters. 250 ms is a REALLY BIG buffer. 250 ms of latency means you pull the trigger now, and hear the gunshot sound when the target's already dead. (When I say "buffer" I really mean "WAVHDR chunk"). I've found that once I went above 40 ms buffers, and used at least 3 buffers, any hardware I tested on worked well. Less that that in either variable caused problems. Note that the scheduler on Win98 is VERY jittery -- 20 ms scheduling jitter is common, and it can jerk higher than that, even on a quiescent system with a fast CPU. > Furthermore I recommend not using the ACM to up/down sample as it > appears to perform point sampling(!) which can produce terrible audio. I always code my own re-sampler, which sits at the reader/input stage of the mixer, which I also code on my own, for the WAVE output. I prefer to use cubic Hermite interpolation, which runs fast and sounds good. Cheers, / h+ |
From: Johnson, J. <Jam...@si...> - 2004-07-14 05:37:11
|
You state DirectSound, but the example you give is standard windows audio waveOut. My experience with (bad) noise on waveOut is usually due to 1 of 3 things.=0D 1) Mixing audio close to the current play position may cause pops/static. When queuing a sound to play I try to mix at least 50ms ahead of the play position, but on some hardware I found that I could go as low as 10-15ms. This maybe due to DMA or inaccuracy of the returned play position.=0D 2) On some system there appears to be a minimum required buffer size, e.g. at least 250ms. On systems like these I got silence at best, and lock up at worst. I didn't spend a lot of time investigating this because 250ms is pretty short buffer. I was shooting for 4/8/16k buffer sizes at that time. In the end I don't think it matters. 3) Bad mixing code. We all make errors. First thing I check is decompressing the audio. The doco on the ACM isn't the best. Matter of fact we've noticed that buffered compression flat out fails on some CODECs in Win98/ME with an error code not identified in the doco. Furthermore I recommend not using the ACM to up/down sample as it appears to perform point sampling(!) which can produce terrible audio. My solution is based upon a hybrid approach. I allocate a single largish (2-4seconds) buffer from which I segment into a number of WAVEHDRs. I use 1 or 2 WAVEHDRs but the system doesn't care. Like the double buffer approach you queue the headers and can setup a callback (that's what I do). In the callback I mix audio and queue the header. The nice thing about a single buffer is just that. A single buffer is easy to manage and more cache friendly.=0D James -----Original Message----- From: gam...@li... [mailto:gam...@li...] On Behalf Of Brian Hook Sent: Thursday, July 08, 2004 10:21 PM To: gam...@li... Subject: RE: [GD-Windows] Streaming WAVE audio I may actually win the award for oldest thread resurrection (this is about 2.25 years old). So I'm rewriting my streaming audio code and open sourcing it (http://www.bookofhook.com/sal for those that are curious -- it's kind of pre-alpha right now but seems to work for the most part on DirectSound, OS X/CoreAudio, OSS/Linux, and ALSA/Linux). When revisiting my streaming audio code, I realized I was using three different buffers when in _theory_ I should be able to use one largish buffer and just query the output position and write the necessary number of bytes out to it when I'm done. The key to this is that the buffer is marked as WHDR_BEGINLOOP | WHDR_ENDLOOP. I then query the output position in my mixing thread with waveOutGetPosition(). This works on my system, but it seems to start failing on some systems randomly depending on the output format (e.g. one user reported that 44KHz worked fine, but there was massive noise/distortion on 22KHz, using the same executable I was using successfully). So the question is: is there a definite known problem doing it this way instead of multibuffering? I can go back to multibuffering fairly trivially and just do something like: queue( buffer[0] ); queue( buffer[1] ); Then in my main audio thread: while ( 1 ) { if ( buffer[ 0 ].is_done ) { fill( buffer[ 0 ] ); waveOutWrite( buffer[0] ); } if ( buffer[ 1 ].is_done ) { fill( buffer[ 1 ] ); waveOutWrite( buffer[ 0 ] ); } sleep( buffer_len/2); } You get the gist -- poll for completed buffers and then fill them up on demand, relying on sleep + poll instead of an event system or callbacks or a separate thread function. Brian ------------------------------------------------------- This SF.Net email sponsored by Black Hat Briefings & Training. Attend Black Hat Briefings & Training, Las Vegas July 24-29 - digital self defense, top technical experts, no vendor pitches, unmatched networking opportunities. Visit www.blackhat.com _______________________________________________ Gamedevlists-windows mailing list Gam...@li... https://lists.sourceforge.net/lists/listinfo/gamedevlists-windows Archives: http://sourceforge.net/mailarchive/forum.php?forum_idU5 ---------------------------------------------------- Vivendi Universal Games- <<http://www.vugames.com>>:=0D The information transmitted is intended only for the=0D person or entity to which it is addressed and may=0D contain confidential and/or privileged material of=0D Vivendi Universal Games which is for the exclusive=0D use of the individual designated above as the=0D recipient. Any review, retransmission, dissemination=0D or other use of, or taking of any action in reliance=0D upon, this information by persons or entities other=0D than the intended recipient is prohibited. If you=0D received this in error, please contact immediately=0D the sender by returning e-mail and delete the=0D material from any computer. If you are not the=0D specified recipient, you are hereby notified that=0D all disclosure, reproduction, distribution or action taken on the basis of this message is prohibited. |
From: Brian H. <ho...@bo...> - 2004-07-09 05:21:12
|
I may actually win the award for oldest thread resurrection (this is about 2.25 years old). So I'm rewriting my streaming audio code and open sourcing it (http://www.bookofhook.com/sal for those that are curious -- it's kind of pre-alpha right now but seems to work for the most part on DirectSound, OS X/CoreAudio, OSS/Linux, and ALSA/Linux). When revisiting my streaming audio code, I realized I was using three different buffers when in _theory_ I should be able to use one largish buffer and just query the output position and write the necessary number of bytes out to it when I'm done. The key to this is that the buffer is marked as WHDR_BEGINLOOP | WHDR_ENDLOOP. I then query the output position in my mixing thread with waveOutGetPosition(). This works on my system, but it seems to start failing on some systems randomly depending on the output format (e.g. one user reported that 44KHz worked fine, but there was massive noise/distortion on 22KHz, using the same executable I was using successfully). So the question is: is there a definite known problem doing it this way instead of multibuffering? I can go back to multibuffering fairly trivially and just do something like: queue( buffer[0] ); queue( buffer[1] ); Then in my main audio thread: while ( 1 ) { if ( buffer[ 0 ].is_done ) { fill( buffer[ 0 ] ); waveOutWrite( buffer[0] ); } if ( buffer[ 1 ].is_done ) { fill( buffer[ 1 ] ); waveOutWrite( buffer[ 0 ] ); } sleep( buffer_len/2); } You get the gist -- poll for completed buffers and then fill them up on demand, relying on sleep + poll instead of an event system or callbacks or a separate thread function. Brian |