-
Notifications
You must be signed in to change notification settings - Fork 511
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
How to: accurately emulate 2D panning #194
Comments
Hi. There's currently no direct way to emulate 2D panning. But depending on the purpose of panning, you can do something similar which may be good enough. Like what you posted:
Except Given that OpenAL is a 3D audio API which simulates a 3D soundfield, you're moving sounds in 3D space rather than between discrete speaker feeds. There's no guarantee about what the output volume will be for the individual speakers. For plain stereo output, this should result in something like you expect ( For surround sound, UHJ, and HRTF, there is no guarantee at all about speaker levels. But it is guaranteed that OpenAL will do the best it can to focus the sound where it's placed (so regardless, with [1] The -4.5 reduction is to keep the apparent volume equal as it moves. If it was 0dB on each like "real" panning, it would be louder moving through the center compared to the sides, and -6dB would make it sound quieter as it moved through the center. It is possible to further widen the panning. If you use -1 and +1 then a full left pan will be to the immediate left of the listener, and a full right pan will be to the immediate right of the listener (+/-90 degrees instead of 30). This is fine also, but that may not be a wholly desirable result; for plain stereo output, going from 30 degrees to 90 degrees has no apparent change, while surround sound or HRTF may not have as noticeable of a change beyond a certain point. |
Thank you very much for that answer kcat. Your suggestion of moving -/+30 degrees is a big improvement compared to the original code. Actually though it is still much too aggressive in reducing the volume compared to the original panning. I've been using audacity to record the output and comparing to the original. I found that if I use only 10 degrees it seems much closer. I still wish there were a way to be more direct in getting the result I'm looking for. Based on your post I now understand that it's going to depend on the speaker setup how OpenAL renders it, however isn't there a standard formula that's used for the stereo case (as you say, "plain stereo output") which can be inverted to get the desired volumes? |
Roughly speaking, plain stereo output follows a sine/cosine amplitude response. A sound on the left speaker (-30 degrees) maps to
OpenAL Soft's plain stereo output may not be exactly that, but it should be fairly close. Current master is also going through some changes, but ultimately it should fall in line with that before release. |
I tried one based on the sine/cosine response that you described. Inverting both responses and averaging yields this formula:
It's not perfect but this seems to work pretty well. I plotted the gain function compared to the ideal one and the main difference is it's quieter in the middle. I think it's probably possible to get even closer but I'm happy with this for now. Thanks again for the help - would not have been able to do it without you. Hopefully someone else who searches this problem will now find this thread as well. |
support for missing mugen features: PlaySnd and SndPan sctrl pan / abspan parameters as well as auto sound panning based on how far character is from center of screen. Can be disabled via StereoEffects and adjusted with PanningRange (works similarly to mugen PanningWidth but operates at easier to understand range: 0-100). Enabled by default (as in mugen). After implementing most of the code I've found following article that can be likely used for better implementation than manually adjusting channels volume: kcat/openal-soft#194 If someone would like to work on it feel free to change any of this new code.
Hello,
I realize this question is not directly related to openal-soft, but since this question has been asked multiple times on stackoverflow and other sites without any satisfactory answers, I figured this is a place where a true expert reply might be found :)
I am porting an old game from DirectSound to OpenAL and I have not been able to figure out how to emulate IDirectSoundBuffer_SetPan(buffer, pan).
basically the pan parameter goes from -1 to 1, which should be interpreted as follows:
-1 => left channel is full volume, right channel is attenuated -100dB
-0.5 => left channel is full volume, right channel is attenuated -50dB
0 => both channels full volume
+0.5 => right channel is full volume, left channel is attenuated -50dB
+1 => right channel is full volume, left channel is attenuated -100dB
etc, etc. for other values.
Stuff I've seen on the net suggests something like:
// create a panning effect by moving the source in an arc around the listener
alDistanceModel(AL_NONE)
alSource(source, AL_SOURCE_RELATIVE, TRUE)
alSource(source, AL_POSITION, {pan, 0, sqrt(1-pan*pan)})
This pretty much works for -1 and +1, but for a lot of the inbetween values it is quite different (which is not that surprising, after all why would it be exactly the same). How does OpenAL calculate the left/right volume based on the relative position? If I knew that maybe I could invert it to find the position based on the desired volumes. Alternatively, is there another method of accurately emulating the panning functionality?
Thanks,
David
The text was updated successfully, but these errors were encountered: