ZDoom with OpenAL
Moderator: GZDoom Developers
- Chris
- Posts: 2940
- Joined: Thu Jul 17, 2003 12:07 am
- Graphics Processor: ATI/AMD with Vulkan/Metal Support
ZDoom with OpenAL
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.
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.
- TheDarkArchon
- Posts: 7656
- Joined: Sat Aug 07, 2004 5:14 am
- Location: Some cold place
Re: ZDoom with OpenAL
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.
Also, paging Graf to this thread. Repeat, paging Graf to this thread.
Just to reiterate that, paging Graf to this thread.
- Graf Zahl
- Lead GZDoom+Raze Developer
- Posts: 49053
- Joined: Sat Jul 19, 2003 10:19 am
- Location: Germany
Re: ZDoom with OpenAL
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.
- Chris
- Posts: 2940
- Joined: Thu Jul 17, 2003 12:07 am
- Graphics Processor: ATI/AMD with Vulkan/Metal Support
Re: ZDoom with OpenAL
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.Heh, long time no see there. Where have you been hiding over the past few months?
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
- Chris
- Posts: 2940
- Joined: Thu Jul 17, 2003 12:07 am
- Graphics Processor: ATI/AMD with Vulkan/Metal Support
Re: ZDoom with OpenAL
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.
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.
- Graf Zahl
- Lead GZDoom+Raze Developer
- Posts: 49053
- Joined: Sat Jul 19, 2003 10:19 am
- Location: Germany
Re: ZDoom with OpenAL
I tried to separate this code into proper low/high level parts but it's so messy that my first attempts failed.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'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.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).
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.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.
- Chris
- Posts: 2940
- Joined: Thu Jul 17, 2003 12:07 am
- Graphics Processor: ATI/AMD with Vulkan/Metal Support
Re: ZDoom with OpenAL
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.Graf Zahl wrote: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 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).
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).
Unfortunately it's making me jump through hoops, and causing a bit of code duplication.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.
- Graf Zahl
- Lead GZDoom+Raze Developer
- Posts: 49053
- Joined: Sat Jul 19, 2003 10:19 am
- Location: Germany
Re: ZDoom with OpenAL
Chris wrote:Unfortunately it's making me jump through hoops, and causing a bit of code duplication.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.
Don't tell me.
- Graf Zahl
- Lead GZDoom+Raze Developer
- Posts: 49053
- Joined: Sat Jul 19, 2003 10:19 am
- Location: Germany
Re: ZDoom with OpenAL
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.
Re: ZDoom with OpenAL
FMOD Ex guarantees that callbacks only run when you update the system object, so they are never run asynchronously.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).
- Graf Zahl
- Lead GZDoom+Raze Developer
- Posts: 49053
- Joined: Sat Jul 19, 2003 10:19 am
- Location: Germany
Re: ZDoom with OpenAL
Good to know. I had concerns with a few changes I made today but this means that it won't cause any problems.
- Chris
- Posts: 2940
- Joined: Thu Jul 17, 2003 12:07 am
- Graphics Processor: ATI/AMD with Vulkan/Metal Support
Re: ZDoom with OpenAL
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.Graf Zahl wrote:Unfortunately this means that I can't use your code anymore as it is.
It also seems it's run when you explicitly call the stop() method.randy wrote:FMOD Ex guarantees that callbacks only run when you update the system object, so they are never run asynchronously.
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.
- Graf Zahl
- Lead GZDoom+Raze Developer
- Posts: 49053
- Joined: Sat Jul 19, 2003 10:19 am
- Location: Germany
Re: ZDoom with OpenAL
Is this about your OpenAL code or FMOD?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.
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.
- Chris
- Posts: 2940
- Joined: Thu Jul 17, 2003 12:07 am
- Graphics Processor: ATI/AMD with Vulkan/Metal Support
Re: ZDoom with OpenAL
Either. It seems it's not deleting the GSnd object because the destructor isn't being run.Graf Zahl wrote:Is this about your OpenAL code or FMOD?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.
Getting functions from a dynamic lib in Linux is nearly the same. Just instead of doing: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.
Code: Select all
HANDLE handle = LoadLibrary("foo.dll");
func = GetProcAddress(handle, "funcname");
if(!func) error();
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
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.
- Chris
- Posts: 2940
- Joined: Thu Jul 17, 2003 12:07 am
- Graphics Processor: ATI/AMD with Vulkan/Metal Support
Re: ZDoom with OpenAL
I have a question about S_GetRolloff. Was this intended?
This applies the powf() on the S_SoundCurve result for custom rolloffs.
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;
}