View previous topic :: View next topic |
Author |
Message |
reckless
Joined: 24 Jan 2008 Posts: 390 Location: inside tha debugger
|
Posted: Fri Mar 12, 2010 3:28 am Post subject: sound issues |
|
|
had a topic in general about it but this place might be better to ask such questions.
my problem lies in using mingw for compiling quake (that part works like a charm) but sound is utterly broken.
i tried a few different projects to make sure its not engine side and the only one that passes is darkplaces.
well not sure how much of the directsound api darkplaces uses anymore and reading through the code didnt bring me any clue.
linking with microsofts directx sdk does not work either well it links without any problems but the sound is like a chainsaw at high pitch. (closest description i can give).
or rather a badly tuned radio
im pretty stuck since the executables work without a hickup just not soundwise and id like to get it fixed now that i have a free compiler ready.
maybe someone has a hint (can only hope). |
|
Back to top |
|
 |
mh

Joined: 12 Jan 2008 Posts: 909
|
Posted: Fri Mar 12, 2010 10:13 am Post subject: |
|
|
Are you using 8 bit sound, or is something forcing your sound to 8 bit? I've seen (heard!) the same happen before with Q1's 8 bit sound code. _________________ DirectQ Engine - New release 1.8.666a, 9th August 2010
MHQuake Blog (General)
Direct3D 8 Quake Engines |
|
Back to top |
|
 |
reckless
Joined: 24 Jan 2008 Posts: 390 Location: inside tha debugger
|
Posted: Fri Mar 12, 2010 5:57 pm Post subject: |
|
|
good question ill give it a look thx
not home atm ill post findings when i get to it. |
|
Back to top |
|
 |
reckless
Joined: 24 Jan 2008 Posts: 390 Location: inside tha debugger
|
Posted: Sat Mar 13, 2010 12:59 am Post subject: |
|
|
hmm nope wasnt it
to make sure i totally disabled the 8 bit sound rendering code but its still not go.
turning on simsound(fakedma) kills sound completly.
quite an annoying bug tbh. |
|
Back to top |
|
 |
reckless
Joined: 24 Jan 2008 Posts: 390 Location: inside tha debugger
|
|
Back to top |
|
 |
reckless
Joined: 24 Jan 2008 Posts: 390 Location: inside tha debugger
|
Posted: Tue Apr 13, 2010 10:26 pm Post subject: |
|
|
well after toying a bit around it seems i brought this upon myself
i used your code from the last gl based mh quake and allocated with malloc anywhere it wasnt needed on the heap but made a small improvement or so i thought by adding this instead of malloc
Code: | /*
=================
Heap_MemAlloc
Standard windows memory interface
Can be used instead of malloc.
=================
*/
void *Heap_MemAlloc (size_t size)
{
LPVOID reserve;
LPVOID buff;
// if a null pointer was passed
// get the fuck out of here !!!
if (size < 0)
{
Sys_Error ("Heap_MemAlloc: bad size %i", size);
}
// reserve a chunk of memory the size the app called for
reserve = VirtualAlloc(NULL, size, MEM_RESERVE, PAGE_NOACCESS);
// bad puppy baaad
if (!reserve)
{
Sys_Error ("Heap_MemAlloc: could not reserve %i MB of memory!", size / 1024 / 1024);
}
// allocate the reserved memory now that we made sure its ours
buff = VirtualAlloc(reserve, size, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
// where did ma ram go boab !!!
if (!buff)
{
Sys_Error ("Heap_MemAlloc: could not allocate %i MB of memory!", size / 1024 / 1024);
}
return buff;
}
/*
=================
Heap_MemAllocFree
Standard windows memory interface
Can be used instead of free.
=================
*/
void Heap_MemAllocFree (void *buffer)
{
if (buffer)
{
VirtualFree(buffer, 0, MEM_RELEASE);
}
}
|
now so far this works fine with msvc but for some ugly reason it doesnt with gcc.
here comes the funny thing i then reverted to malloc and the engine crashes instantly
the funny thing is it doesnt crash on malloc calls but in this wtf
Code: | void RemoveLink (link_t *l)
{
l->next->prev = l->prev;
l->prev->next = l->next;
} |
|
|
Back to top |
|
 |
mh

Joined: 12 Jan 2008 Posts: 909
|
Posted: Tue Apr 13, 2010 11:08 pm Post subject: |
|
|
It looks as though you're not freeing a valid pointer.
Alloc size + 1, then when you free do something like:
Code: | byte *freebuf = ((byte *) buffer) - 1;
free (freebuf); |
Using the Win32 Heap API is probably better than VirtualAlloc in these cases too. _________________ DirectQ Engine - New release 1.8.666a, 9th August 2010
MHQuake Blog (General)
Direct3D 8 Quake Engines |
|
Back to top |
|
 |
reckless
Joined: 24 Jan 2008 Posts: 390 Location: inside tha debugger
|
Posted: Wed Apr 14, 2010 7:48 am Post subject: |
|
|
yeah seems i need to sift through it for bad pointers  |
|
Back to top |
|
 |
reckless
Joined: 24 Jan 2008 Posts: 390 Location: inside tha debugger
|
Posted: Thu Apr 15, 2010 10:23 pm Post subject: |
|
|
hmm after some debugging sessions i found this to be the problem
qboolean pr_free[MAX_EDICTS];
this was part of the overhaul i made from bengt jardrups quake source.
for some reason it causes a buffer overflow crashing malloc but the darn thing isnt even on the hunk so i suspect its messing with some other stuff also. |
|
Back to top |
|
 |
reckless
Joined: 24 Jan 2008 Posts: 390 Location: inside tha debugger
|
Posted: Fri Apr 16, 2010 4:21 am Post subject: |
|
|
ok found the bad pointer (had mistakenly replaced a zalloc call with plain malloc somewhere it wasnt free'd)
so this part should be good atleast.
now im getting SZ_GetSpace errors from MSG_WriteByte  |
|
Back to top |
|
 |
mh

Joined: 12 Jan 2008 Posts: 909
|
Posted: Fri Apr 16, 2010 7:30 pm Post subject: |
|
|
reckless wrote: | ok found the bad pointer (had mistakenly replaced a zalloc call with plain malloc somewhere it wasnt free'd) |
The best thing to do is drop malloc and free entirely and use the Heap API. Write some wrappers around it and just use those instead. Search your code for all occurances, purge them, and get into the habit of never using them.
Why?
Firstly, malloc itself is just a wrapper around the Heap API.
Secondly you can include error checking in your wrapper (like checking for 0 or negative sizes and NULL returns) instead of having to do it each time you allocate.
Thirdly the behavior of malloc is different in debug builds than it is in release builds. With your wrapper you can ensure that the allocated memory is always memset 0, marked no-execute or whatever else is needed. You control the behavior, and you know that what's true for a debug build will also be true for a release build.
Fourthly with the Heap API you can release all memory in one fell swoop using HeapDestroy instead of needing to keep track of pointers yourself.
Fifthly you can have multiple heaps independent of each other so you get a lot more flexibility.
malloc and free are crippled by comparison, so they really need to die a flaming death. _________________ DirectQ Engine - New release 1.8.666a, 9th August 2010
MHQuake Blog (General)
Direct3D 8 Quake Engines |
|
Back to top |
|
 |
reckless
Joined: 24 Jan 2008 Posts: 390 Location: inside tha debugger
|
Posted: Fri Apr 16, 2010 10:18 pm Post subject: |
|
|
aye may have to scrap whatever i used at that time and go for an os based solution.
i remember now i had quite a lot of problems when i first introduced pk3 handling in realm that the old allocation system simply couldnt handle the sizes so i went with the system in the last mhquake opengl based one and that seemingly worked.
atleast untill i started dabbling in making my own compiler
gcc seems even more strict than msvc in regards to bad coding practices (good thing) but makes it a bitch sometimes to exactly point out the problem.
in turn it might also be the reason why a free compiler like open watcom is completly unable to compile quake (nothing is more strict than watcom)  |
|
Back to top |
|
 |
Spike
Joined: 05 Nov 2004 Posts: 944 Location: UK
|
Posted: Sat Apr 17, 2010 10:09 am Post subject: |
|
|
mh wrote: |
Firstly, malloc itself is just a wrapper around the Heap API.
Secondly you can include error checking in your wrapper (like checking for 0 or negative sizes and NULL returns) instead of having to do it each time you allocate.
Thirdly the behavior of malloc is different in debug builds than it is in release builds. With your wrapper you can ensure that the allocated memory is always memset 0, marked no-execute or whatever else is needed. You control the behavior, and you know that what's true for a debug build will also be true for a release build.
Fourthly with the Heap API you can release all memory in one fell swoop using HeapDestroy instead of needing to keep track of pointers yourself.
Fifthly you can have multiple heaps independent of each other so you get a lot more flexibility.
malloc and free are crippled by comparison, so they really need to die a flaming death. |
Firstly, Malloc and Free are highly optimised functions that attempt to avoid memory fragmentation. Something which I doubt your own malloc would attempt.
Secondly, you should handle errors gracefully without just die("oh noes!"). Imagine I feed you a model with 0x7fffffff frames and 0x7ffffff skins. You're now dead, even if the model was correctly formatted. It would be an absolutely huge model though.
Having said that, in linux, malloc will only fail when your address space is filled. It'll let you allocate memory constantly, which can result in your other processes dying.
Thirdly, the behaviour of malloc differing between debug/release/compiler is a GOOD thing. Any memory bug you have is a memory bug. Generally involving breaking other bits of memory. Change some code somewhere and you get random differences elsewhere. Sure, okay, memory working the same way as debug builds always is easier, but results in minor errors that you'll never find. A malloc that is random every time is awesome.
Additionally, you can link your app against a third-party library that provides such debugging features instead of having to roll your own.
Fourthly, its not just memory that you have. You have other things. Mutexes, textures, buffer objects, etc. Just saying 'well I no longer need my models now' means 'I'm not going to release any of this stuff'. valgrind is your friend. Its awesome. And not just for leaks.
Fifthly, most malloc/free implementations already provide separate heaps based upon allocation size.
malloc and free are not to be underestimated.
With that said, its best to allocate your entire model in one block whatever algorithm you use. Lots of separate allocations is not only wasteful, its slower and could result in random access. That is, if you know you have 20 objects, work out the total size first then do a single alloc, instead of 20 allocs. This applies regardless of allocator. _________________ What's a signature? |
|
Back to top |
|
 |
reckless
Joined: 24 Jan 2008 Posts: 390 Location: inside tha debugger
|
Posted: Sat Apr 17, 2010 10:46 am Post subject: |
|
|
thanks for pointers guys
back to tha debugger  |
|
Back to top |
|
 |
mh

Joined: 12 Jan 2008 Posts: 909
|
Posted: Sat Apr 17, 2010 6:14 pm Post subject: |
|
|
Spike wrote: | Thirdly, the behaviour of malloc differing between debug/release/compiler is a GOOD thing. Any memory bug you have is a memory bug. Generally involving breaking other bits of memory. Change some code somewhere and you get random differences elsewhere. Sure, okay, memory working the same way as debug builds always is easier, but results in minor errors that you'll never find. A malloc that is random every time is awesome.
Additionally, you can link your app against a third-party library that provides such debugging features instead of having to roll your own. |
It depends. If the debug behaviour has tighter validation and constraints then yeah it's a good thing. If on the other hand you have a situation where debug malloc memsets 0 whereas release malloc doesn't, you've got a backdoor for subtle bugs to come in, and your debug build is effectively worthless for verifying correctness of your release build.
Spike wrote: | valgrind is your friend. Its awesome. And not just for leaks. |
If your idea of platform-neutrailty translates as "Unix, Unix and more Unix".
Spike wrote: | Fifthly, most malloc/free implementations already provide separate heaps based upon allocation size. |
Maybe so, but they don't let you specify which heap is used.
Spike wrote: | With that said, its best to allocate your entire model in one block whatever algorithm you use. Lots of separate allocations is not only wasteful, its slower and could result in random access. That is, if you know you have 20 objects, work out the total size first then do a single alloc, instead of 20 allocs. This applies regardless of allocator. |
Absolutely agreed.
All said, I think you may have taken some of my points the wrong way. Even writing a wrapper around malloc that just calls malloc itself and then memsets to 0 would go a long way towards ensuring that you can depend on the returned block being zero-filled all of the time. Writing a wrapper around free that NULLs the pointer after the free op would help catch attempts to use memory that had been released. Using something like the Win32 Heap API gives you the ability to defragment the heap when you want, as well as multiple independent heaps if you need them. It also gives you HeapDestroy, which I definitely wouldn't suggest be used as a tool for eliminating leaks, but rather for releasing a large block of related objects without having to keep track of the pointers to them yourself. If you're using something like that for eliminating leaks then you're definitely doing it wrong.  _________________ DirectQ Engine - New release 1.8.666a, 9th August 2010
MHQuake Blog (General)
Direct3D 8 Quake Engines |
|
Back to top |
|
 |
|