ZDoom with OpenAL

Moderator: GZDoom Developers

Post Reply
User avatar
Chris
Posts: 2940
Joined: Thu Jul 17, 2003 12:07 am
Graphics Processor: ATI/AMD with Vulkan/Metal Support

ZDoom with OpenAL

Post by Chris »

Decided to take today and see how well I could get ZDoom working with OpenAL. Attached is the result (based on the 2.2.0 sources, but I'll update as needed, if anyone cares).

On Linux using OpenAL Soft, it seems to work great. Full 3D/surround sound, and "local" sounds, working. Streaming and non-DMX formats aren't yet working, though I'll probably be getting to them next, if this really interests anyone. Further, I can probably get environmental effects working using EFX, which should also work on software devices (unlike FMOD, which only seems to provide EAX when hardware is there).

The attached zip contains oalsound.cpp/h (place in src/sound/) and a small diff for src/sound/i_sound.cpp. For Makefile.linux, add openal to the pkg-config commands so that you have:
CFLAGS += -MMD -DHAVE_FILELENGTH -D__forceinline=inline `sdl-config --cflags` `pkg-config gtk+-2.0 openal --cflags`
LDFLAGS += -lFLAC++ -lFLAC -lz -ljpeg -lfmod `sdl-config --libs` `pkg-config gtk+-2.0 openal --libs`

For Windows, make sure you download the OpenAL SDK, and add -lopenal32 to the LDFLAGS Makefile.mingw, or add openal32.lib to the MSVC project.
User avatar
TheDarkArchon
Posts: 7656
Joined: Sat Aug 07, 2004 5:14 am
Location: Some cold place

Re: ZDoom with OpenAL

Post by TheDarkArchon »

Heh, long time no see there. Where have you been hiding over the past few months?

Also, paging Graf to this thread. Repeat, paging Graf to this thread.

Just to reiterate that, paging Graf to this thread.
User avatar
Graf Zahl
Lead GZDoom+Raze Developer
Lead GZDoom+Raze Developer
Posts: 49053
Joined: Sat Jul 19, 2003 10:19 am
Location: Germany

Re: ZDoom with OpenAL

Post by Graf Zahl »

Basing this on 2.2.0 makes it a futile exercise. The low level sound interface has changed so much that almost nothing works directly. If you can port this to the latest revisions it would be really great because it's exactly what I need for a GPL GZDoom.
User avatar
Chris
Posts: 2940
Joined: Thu Jul 17, 2003 12:07 am
Graphics Processor: ATI/AMD with Vulkan/Metal Support

Re: ZDoom with OpenAL

Post by Chris »

Heh, long time no see there. Where have you been hiding over the past few months?
Got pulled away to more "modern" games, since I finally got a computer that could handle them. But recently I've had an itch to come back and play Doom/Heretic/Hexen again. :)

And I'll see what I can do about bringing it up against the latest SVN today.

EDIT:
Seems someone is currently doing work on the tree. I got it roughly moved over to SVN, and it wouldn't start a game (it froze on level load), updated, and now it won't compile. I'll wait a bit to try again, but just in case anyone's curious, these are the errors:

Code: Select all

zdoom/src/./basictypes.h:98:7: warning: no newline at end of file
zdoom/src/sdl/i_input.cpp: In function ‘void PostMouseMove(int, int)’:
zdoom/src/sdl/i_input.cpp:240: error: variable ‘event_t ev’ has initializer but incomplete type
zdoom/src/sdl/i_input.cpp:256: error: ‘EV_Mouse’ was not declared in this scope
zdoom/src/sdl/i_input.cpp: In function ‘void MessagePump(const SDL_Event&)’:
zdoom/src/sdl/i_input.cpp:333: error: variable ‘event_t event’ has initializer but incomplete type
zdoom/src/sdl/i_input.cpp:359: error: ‘EV_KeyDown’ was not declared in this scope
zdoom/src/sdl/i_input.cpp:359: error: ‘EV_KeyUp’ was not declared in this scope
zdoom/src/sdl/i_input.cpp:393: error: ‘EV_GUI_Event’ was not declared in this scope
User avatar
Chris
Posts: 2940
Joined: Thu Jul 17, 2003 12:07 am
Graphics Processor: ATI/AMD with Vulkan/Metal Support

Re: ZDoom with OpenAL

Post by Chris »

This try is against SVN r1225. I'm running into several issues, though. Some problems revolve around the use of FMOD's callbacks (mainly how it changes the associated FSoundChan when the sound playback ends asynchronously.. which is kind of evil, IMO). The callback for the rolloff is pretty evil as well, since no other API that I know of does it that way.. OpenAL in particular has a per-source rolloff factor, but a global distance model/rolloff type, and only predefined types (linear, inverse distance, exponent, and none). The rest of the problems seem to be because of changes the renderer needs to do to various structs its given, with not much info on who needs to change what, where, when and why.

Currently 2D sounds seem to work mostly alright. But the 3D sounds will eventually just stop as if its running out of channels (though 2D sounds will continue to work). As well, after going in-game, some 2D sounds will pan (which is odd to say the least because PlaySound doesn't take a panning parameter..).
EDIT: Figures I made a breakthrough with this just after I posted. 2D sounds seem to work fine, as do most 3D sounds, but some will still sometimes cutout for a bit, and come back. I might be able to fix this, but for now I'm just updating the zip.

The zip contains what's needed to get ZDoom compiling under Linux again, as well as the patches to CMakeLists.txt, i_sound.cpp, and the new oalsound files. If anyone could help me understand what's wrong, I'd be quite appreciative.
User avatar
Graf Zahl
Lead GZDoom+Raze Developer
Lead GZDoom+Raze Developer
Posts: 49053
Joined: Sat Jul 19, 2003 10:19 am
Location: Germany

Re: ZDoom with OpenAL

Post by Graf Zahl »

Chris wrote:This try is against SVN r1225. I'm running into several issues, though. Some problems revolve around the use of FMOD's callbacks (mainly how it changes the associated FSoundChan when the sound playback ends asynchronously.. which is kind of evil, IMO).
I tried to separate this code into proper low/high level parts but it's so messy that my first attempts failed. :(
The callback for the rolloff is pretty evil as well, since no other API that I know of does it that way.. OpenAL in particular has a per-source rolloff factor, but a global distance model/rolloff type, and only predefined types (linear, inverse distance, exponent, and none).
I'm afraid that this callback's functionality is necessary. It is essential for Doom's sound to work properly. Randy's first FmodEx version uses the stock rolloff calculations as well and it was horrible.

Chris wrote:The rest of the problems seem to be because of changes the renderer needs to do to various structs its given, with not much info on who needs to change what, where, when and why.
According to Randy this was so he 'doesn't need to jump through hoops.' I have been fighting against this sloppy organization for the last 2 weeks and I'm still not done separating the true interface code from improperly placed code. A few things I tried resulted in unexpected errors.
User avatar
Chris
Posts: 2940
Joined: Thu Jul 17, 2003 12:07 am
Graphics Processor: ATI/AMD with Vulkan/Metal Support

Re: ZDoom with OpenAL

Post by Chris »

Graf Zahl wrote:
Chris wrote:The callback for the rolloff is pretty evil as well, since no other API that I know of does it that way.. OpenAL in particular has a per-source rolloff factor, but a global distance model/rolloff type, and only predefined types (linear, inverse distance, exponent, and none).
I'm afraid that this callback's functionality is necessary. It is essential for Doom's sound to work properly. Randy's first FmodEx version uses the stock rolloff calculations as well and it was horrible.
I suppose. I was able to make a work around that hopefully shouldn't impose too much on CPU time. OpenAL's distance attenuation is disabled, while SoundRenderer::UpdateSounds goes through the list of all allocated channels. For each one that has an in-use and non-local source, it gets the distance from the listener, calculates the attenuation, then sets it as the source gain.

For this, I'm thinking I might propose an OpenAL extension to provide essentially what S_SoundCurve is for (an array of mulipliers that's used to get attenuation between min dist and max dist). A callback would be more fitting, but those don't go over so well between different languages and language bindings, nor does it seem to be OpenAL's "style". I notice though, that each sound is given its own rolloff type (or at least, a type passed to each PlaySound3D call). Is it expected that different sounds can have different rolloff types, or is it just passed for no real reason? If the latter, I think it may be a better idea to pass the type once beforehand, and just the min dist and max dist/rolloff factor for PlaySound3D (to avoid this kind of confusion). If the former, then I think OpenAL will need another extension for that.

It seems most of the sound issues are taken care of for now, though. I don't notice any anamolies with it in Heretic, although Hexen still has a habit of losing sounds (particularly in the first level). Updated oalsound.cpp attached. Properly handling priorities and killing lowest-priority sounds may help, but I'll need to do some testing with it (I didn't have this issue with 2.2.0, so it doesn't strike me that I'm using all 12 channels at start, especially when I don't hear anything).
According to Randy this was so he 'doesn't need to jump through hoops.' I have been fighting against this sloppy organization for the last 2 weeks and I'm still not done separating the true interface code from improperly placed code. A few things I tried resulted in unexpected errors.
Unfortunately it's making me jump through hoops, and causing a bit of code duplication. :P
User avatar
Graf Zahl
Lead GZDoom+Raze Developer
Lead GZDoom+Raze Developer
Posts: 49053
Joined: Sat Jul 19, 2003 10:19 am
Location: Germany

Re: ZDoom with OpenAL

Post by Graf Zahl »

Chris wrote:
According to Randy this was so he 'doesn't need to jump through hoops.' I have been fighting against this sloppy organization for the last 2 weeks and I'm still not done separating the true interface code from improperly placed code. A few things I tried resulted in unexpected errors.
Unfortunately it's making me jump through hoops, and causing a bit of code duplication. :P

Don't tell me. ;)
User avatar
Graf Zahl
Lead GZDoom+Raze Developer
Lead GZDoom+Raze Developer
Posts: 49053
Joined: Sat Jul 19, 2003 10:19 am
Location: Germany

Re: ZDoom with OpenAL

Post by Graf Zahl »

I just finished cleaning up the low level sound interface. No more messing around with high level flags and such stuff. Unfortunately this means that I can't use your code anymore as it is.
User avatar
randi
Site Admin
Posts: 7746
Joined: Wed Jul 09, 2003 10:30 pm
Contact:

Re: ZDoom with OpenAL

Post by randi »

Chris wrote:Some problems revolve around the use of FMOD's callbacks (mainly how it changes the associated FSoundChan when the sound playback ends asynchronously.. which is kind of evil, IMO).
FMOD Ex guarantees that callbacks only run when you update the system object, so they are never run asynchronously.
User avatar
Graf Zahl
Lead GZDoom+Raze Developer
Lead GZDoom+Raze Developer
Posts: 49053
Joined: Sat Jul 19, 2003 10:19 am
Location: Germany

Re: ZDoom with OpenAL

Post by Graf Zahl »

Good to know. I had concerns with a few changes I made today but this means that it won't cause any problems.
User avatar
Chris
Posts: 2940
Joined: Thu Jul 17, 2003 12:07 am
Graphics Processor: ATI/AMD with Vulkan/Metal Support

Re: ZDoom with OpenAL

Post by Chris »

Graf Zahl wrote:Unfortunately this means that I can't use your code anymore as it is.
These changes were easier than last time, at least. And it seems the missing sounds problem was due to running out of channels. I increased snd_channels from 12 to 32, and I'm not losing sounds in Hexen anymore. So as it seems, what I have done with the OpenAL backend works as expected. I just need to finish implementing the rest (pausing sounds, non-raw loading, streaming..), which I'll be getting to. Patch attached.
randy wrote:FMOD Ex guarantees that callbacks only run when you update the system object, so they are never run asynchronously.
It also seems it's run when you explicitly call the stop() method.

EDIT: And before I forget *again*, it seems sound isn't shutdown when quitting. The buffers are properly deleted, but the sound renderer object isn't deleted.
User avatar
Graf Zahl
Lead GZDoom+Raze Developer
Lead GZDoom+Raze Developer
Posts: 49053
Joined: Sat Jul 19, 2003 10:19 am
Location: Germany

Re: ZDoom with OpenAL

Post by Graf Zahl »

Chris wrote: EDIT: And before I forget *again*, it seems sound isn't shutdown when quitting. The buffers are properly deleted, but the sound renderer object isn't deleted.
Is this about your OpenAL code or FMOD?


One more thing: If your code becomes stable enough we will need a mechanism that allows to distribute ZDoom with only one of the needed sound libraries. On Windows I can write the code to dynamically reference the functions from DLLs but on Linux I have no idea how to do it.
User avatar
Chris
Posts: 2940
Joined: Thu Jul 17, 2003 12:07 am
Graphics Processor: ATI/AMD with Vulkan/Metal Support

Re: ZDoom with OpenAL

Post by Chris »

Graf Zahl wrote:
Chris wrote: EDIT: And before I forget *again*, it seems sound isn't shutdown when quitting. The buffers are properly deleted, but the sound renderer object isn't deleted.
Is this about your OpenAL code or FMOD?
Either. It seems it's not deleting the GSnd object because the destructor isn't being run.
One more thing: If your code becomes stable enough we will need a mechanism that allows to distribute ZDoom with only one of the needed sound libraries. On Windows I can write the code to dynamically reference the functions from DLLs but on Linux I have no idea how to do it.
Getting functions from a dynamic lib in Linux is nearly the same. Just instead of doing:

Code: Select all

HANDLE handle = LoadLibrary("foo.dll");
func = GetProcAddress(handle, "funcname");
if(!func) error();
You do:

Code: Select all

void *handle = dlopen("foo.so", RTLD_NOW); // RTLD_NOW means to resolve all symbols used by the lib before returning
func = dlsym(handle, "funcname");
if(dlerror() != NULL) error(); // dlerror returns a const char* to a string description of the last error, then clears the last error, or NULL for no error
.. being sure to include dlfcn.h and link with libdl. In the case of OpenAL, you'd load libopenal.so.1 in Linux (or libopenal.so.0 for the old SI, but generally you'd want to avoid that..).


Today, I was able to get CreateStream working. I also cleaned up a bit of the left-over flag-handling code in the renderer. Latest is attached.
User avatar
Chris
Posts: 2940
Joined: Thu Jul 17, 2003 12:07 am
Graphics Processor: ATI/AMD with Vulkan/Metal Support

Re: ZDoom with OpenAL

Post by Chris »

I have a question about S_GetRolloff. Was this intended?

Code: Select all

        float volume = (rolloff->MaxDistance - distance) / (rolloff->MaxDistance - rolloff->MinDistance);
        if (rolloff->RolloffType == ROLLOFF_Custom && S_SoundCurve != NULL)
        {
                volume = S_SoundCurve[int(S_SoundCurveSize * (1 - volume))] / 127.f;
        }
        if (rolloff->RolloffType == ROLLOFF_Linear)
        {
                return volume;
        }
        else
        {
                return (powf(10.f, volume) - 1.f) / 9.f;
        }
This applies the powf() on the S_SoundCurve result for custom rolloffs.
Post Reply

Return to “Closed Feature Suggestions [GZDoom]”