Forum

sound issues

Discuss programming topics for the various GPL'd game engine sources.

Moderator: InsideQC Admins

sound issues

Postby revelator » Fri Mar 12, 2010 3:28 am

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 :lol:

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).
User avatar
revelator
 
Posts: 2567
Joined: Thu Jan 24, 2008 12:04 pm
Location: inside tha debugger

Postby mh » Fri Mar 12, 2010 10:13 am

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.
We had the power, we had the space, we had a sense of time and place
We knew the words, we knew the score, we knew what we were fighting for
User avatar
mh
 
Posts: 2292
Joined: Sat Jan 12, 2008 1:38 am

Postby revelator » Fri Mar 12, 2010 5:57 pm

good question ill give it a look thx :)

not home atm ill post findings when i get to it.
User avatar
revelator
 
Posts: 2567
Joined: Thu Jan 24, 2008 12:04 pm
Location: inside tha debugger

Postby revelator » Sat Mar 13, 2010 12:59 am

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.
User avatar
revelator
 
Posts: 2567
Joined: Thu Jan 24, 2008 12:04 pm
Location: inside tha debugger

Postby revelator » Thu Mar 18, 2010 5:53 am

could you try this ftp://90.184.233.166:21/mingw-realm.7z

maybe it gives a hint of what might be wrong
User avatar
revelator
 
Posts: 2567
Joined: Thu Jan 24, 2008 12:04 pm
Location: inside tha debugger

Postby revelator » Tue Apr 13, 2010 10:26 pm

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: Select all
/*
=================
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 :lol:

the funny thing is it doesnt crash on malloc calls but in this wtf

:shock:

Code: Select all
void RemoveLink (link_t *l)
{
    l->next->prev = l->prev;
    l->prev->next = l->next;
}
User avatar
revelator
 
Posts: 2567
Joined: Thu Jan 24, 2008 12:04 pm
Location: inside tha debugger

Postby mh » Tue Apr 13, 2010 11:08 pm

It looks as though you're not freeing a valid pointer.

Alloc size + 1, then when you free do something like:
Code: Select all
byte *freebuf = ((byte *) buffer) - 1;
free (freebuf);

Using the Win32 Heap API is probably better than VirtualAlloc in these cases too.
We had the power, we had the space, we had a sense of time and place
We knew the words, we knew the score, we knew what we were fighting for
User avatar
mh
 
Posts: 2292
Joined: Sat Jan 12, 2008 1:38 am

Postby revelator » Wed Apr 14, 2010 7:48 am

yeah seems i need to sift through it for bad pointers :?
User avatar
revelator
 
Posts: 2567
Joined: Thu Jan 24, 2008 12:04 pm
Location: inside tha debugger

Postby revelator » Thu Apr 15, 2010 10:23 pm

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.
User avatar
revelator
 
Posts: 2567
Joined: Thu Jan 24, 2008 12:04 pm
Location: inside tha debugger

Postby revelator » Fri Apr 16, 2010 4:21 am

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 :(
User avatar
revelator
 
Posts: 2567
Joined: Thu Jan 24, 2008 12:04 pm
Location: inside tha debugger

Postby mh » Fri Apr 16, 2010 7:30 pm

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.
We had the power, we had the space, we had a sense of time and place
We knew the words, we knew the score, we knew what we were fighting for
User avatar
mh
 
Posts: 2292
Joined: Sat Jan 12, 2008 1:38 am

Postby revelator » Fri Apr 16, 2010 10:18 pm

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 :twisted:

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) :lol:
User avatar
revelator
 
Posts: 2567
Joined: Thu Jan 24, 2008 12:04 pm
Location: inside tha debugger

Postby Spike » Sat Apr 17, 2010 10:09 am

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.
Spike
 
Posts: 2892
Joined: Fri Nov 05, 2004 3:12 am
Location: UK

Postby revelator » Sat Apr 17, 2010 10:46 am

thanks for pointers guys :)

back to tha debugger 8)
User avatar
revelator
 
Posts: 2567
Joined: Thu Jan 24, 2008 12:04 pm
Location: inside tha debugger

Postby mh » Sat Apr 17, 2010 6:14 pm

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". :twisted:

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. :D

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. :wink:
We had the power, we had the space, we had a sense of time and place
We knew the words, we knew the score, we knew what we were fighting for
User avatar
mh
 
Posts: 2292
Joined: Sat Jan 12, 2008 1:38 am

Next

Return to Engine Programming

Who is online

Users browsing this forum: No registered users and 1 guest