Author Topic: 3D Stream distance decay  (Read 264 times)

Miran

  • Posts: 12
3D Stream distance decay
« on: 13 Sep '24 - 17:22 »
We are using BASS to play additional 3d sounds in existing game and I have problems with matching BASS' 3d streams to in-game audio.

Even quiet streams with small minDist set with BASS_ChannelSet3DAttributes are still audible even when very far away.
Setting maxDist to enormous values also does not help.
Using BASS_SAMPLE_MUTEMAX flag makes just the sound to be hard cut off when maxDist is reached.

I found BASS' formula on this forum:
Code: [Select]
vol = dist <= mindist ? 1 : mindist / (mindist + (dist - mindist) * rolloff);
Apparently it reflects some algorithm from DirectSound3D, but seems to be totally wrong. Interacting with the sound in game has unnatural feeling at close distances, then sound seems to be stuck to some minimum threshold when getting far away.

Even if ignoring air resistance/damping factors and using simple inverse square formula would give better result:


Green - current BASS' formula
Orange - 1/distance^2

It also highlights the problem, for sound with midDist 1.0 volume at distance 100.0 is still about 0.01, while inverse square gives 0.0001

Probably changing current decay curve is out of question due to legacy reasons.
Is it then an option to implement more decay curves to select in BASS?
It would be nice to be able to register callback function with user's desired formula inside.

Ian @ un4seen

  • Administrator
  • Posts: 26079
Re: 3D Stream distance decay
« Reply #1 on: 13 Sep '24 - 17:48 »
I'll look into this and get back to you next week. In the meantime, I can confirm that BASS's 3D volume calculations were made to emulate DirectSound3D. That was for consistency across platforms, as BASS used DirectSound3D on Windows and its own implementation on other platforms (that's used on Windows now too). Here's the DirectSound documentation for how the min/max distance settings work:

   https://learn.microsoft.com/en-us/previous-versions/windows/desktop/ee418662(v=vs.85)

Perhaps adjusting the rolloff factor (via BASS_Set3DFactors) can help in your case?

Miran

  • Posts: 12
Re: 3D Stream distance decay
« Reply #2 on: 13 Sep '24 - 18:50 »
Thanks.
Yes, I seen that link mentioned in other topics. It does not provide any formula, just explains what min and max does.

I messed with BASS_Set3DFactors already, increasing rollf param makes difference at close distances, but quiet residual still remains.

Previously after long fiddling I ended up with:
Code: [Select]
BASS_Set3DFactors(1.0f, 3.0f, 80.0f)Seems like rollf affects Doppler effects calculations, so I had to bump its factor up to counteract.

Miran

  • Posts: 12
Re: 3D Stream distance decay
« Reply #3 on: 15 Sep '24 - 13:18 »
I'm starting to believe issue is related to volume curve. I implemented distance decay by myself using channel volume and noticed that any value greater than zero leads to very audible sound.

I also battled with Doppler again, this time with standard BASS_Set3DFactors values. Despite using meters and calculating velocity as meter peer second I had way too strong Doppler effects with some additional artifacts.
Tried even to use BASS_3DMODE_RELATIVE and camera based coordinates, with still same effects. In last resort I tested what happen if I square root the velocity (with keeping sign for negative part) for camera and source and for my surprise it now works as it should.

Ian @ un4seen

  • Administrator
  • Posts: 26079
Re: 3D Stream distance decay
« Reply #4 on: 16 Sep '24 - 16:56 »
I looked into this, and found there is currently a bug with the listener velocity in the Doppler effect calculations. Are you using a non-0 listener velocity? If so, this may explain your troubles with it, and here's an update for you to try:

   www.un4seen.com/stuff/bass.zip

Let me know whether it helps. By the way, to clarify, the "rollf" setting doesn't affect Doppler but "distf" does (as well as "doppf").

I couldn't see any problem in the distance volume level calculations; it seems to be working as expected. The minimum distance is a reference distance at which (and within) the level is 100% (0dB). Each time the distance doubles from there, the level drops 50% (6dB). If you would like to have a certain level at a certain distance then you can calculate the minimum distance value for that like this:

Code: [Select]
mindist = level * dist

For example, for 0.0001 (-80dB) at 100 meters:

Code: [Select]
mindist = 0.0001 * 100 = 0.01

If what you're hearing doesn't seem to match the calculation, please try writing the BASS output to a WAV file and check that in a sample editor. You can use the BASSenc add-on to do that, like this:

Code: [Select]
output = BASS_StreamCreate(0, 0, 0, STREAMPROC_DEVICE, 0); // get device output stream
encoder = BASS_Encode_Start(output, "output.wav", BASS_ENCODE_PCM | BASS_ENCODE_QUEUE | BASS_ENCODE_AUTOFREE, 0, 0); // set a WAV writer on it

Miran

  • Posts: 12
Re: 3D Stream distance decay
« Reply #5 on: 18 Sep '24 - 03:00 »
Yeah, that mindist parameter is confusing. By reading documentation I understood it as physical size of the sound source. Meanwhile it is more like additional volume amplification with capping to avoid overdrive.
If it is meant to be source size, then why both Doppler and stereo processing still threats the sound source as infinitely small point?

According to the posted BASS version: now it works in opposite way. When moving towards the stationary sound source its tone is getting LOWER. Tried to mess with my forward and up vectors, but it changed nothing except switching left-right channels.

Ian @ un4seen

  • Administrator
  • Posts: 26079
Re: 3D Stream distance decay
« Reply #6 on: 18 Sep '24 - 14:46 »
The "mindist" value isn't really the size of the source, although I suppose it could be interpreted that way, as a small object is likely to have a lower value than a large object, like in the DirectSound doc's bee vs airplane example. It's really just a 0dB reference distance. If you use it in this online calculator, you'll get back the same result as the calculation in the 1st post with rolloff=1 (except that BASS doesn't amplify within the reference distance):

   https://www.wkcgroup.com/tools-room/inverse-square-law-sound-calculator/

To further investigate the Doppler issue, can you give example listener and source positions (BASS_Set3DPosition and BASS_ChannelSet3DPosition calls) for that?

Miran

  • Posts: 12
Re: 3D Stream distance decay
« Reply #7 on: 18 Sep '24 - 21:37 »
Oh I left experimental flipped velocity calculation for listener in code (prev-pos instead of pos-prev).
There are logs anyway of driving towards sound source (with fixed velocity calculations).

I'm wondering if my forward and up vectors are right. I had to do multiplication by -1 for UP vector to get correct left-right channels. In logs you can see Z of up vector is -1, despite game using positive Z as "going up".

Code: [Select]
BASS_Set3DFactors(1.0f, 0.0f, 1.0f); // rollf emulated by us in 3D streams
Stream:
Code: [Select]
BASS_ChannelSet3DAttributes(streamInternal, BASS_3DMODE_NORMAL, -1.0f, -1.0f, -1, -1, -1.0f);
Once (static source)
Code: [Select]
18/09/2024 22:40:48.190 BASS_ChannelSet3DPosition
18/09/2024 22:40:48.190  position: 1694.0 -2494.0 14.0
18/09/2024 22:40:48.190  orientation: 0.0 0.0 1.0
18/09/2024 22:40:48.190  velocity: 0.0 0.0 0.0

Peer frame:
Code: [Select]
18/09/2024 22:29:36.613 BASS_Set3DPosition
18/09/2024 22:29:36.613  position: 1674.1 -2494.0 14.8
18/09/2024 22:29:36.613  velocity: 20.1 0.5 -0.2
18/09/2024 22:29:36.613  forward: 1.0 0.0 -0.1
18/09/2024 22:29:36.613  up: -0.1 -0.0 -1.0
18/09/2024 22:29:36.613 BASS_Apply3D

Still I have feeling like some glitches occur when moving camera around:
https://streamable.com/oky9gs
Driving toward/away from source seems right, but standing away from it and moving camera left right seems to create too strong doppler effects.
« Last Edit: 18 Sep '24 - 22:54 by Miran »

Ian @ un4seen

  • Administrator
  • Posts: 26079
Re: 3D Stream distance decay
« Reply #8 on: 19 Sep '24 - 16:25 »
I'm wondering if my forward and up vectors are right. I had to do multiplication by -1 for UP vector to get correct left-right channels. In logs you can see Z of up vector is -1, despite game using positive Z as "going up".

In BASS, the Y-axis is vertical (positive = up), so perhaps you need to swap your Z and Y values in the BASS calls?

Miran

  • Posts: 12
Re: 3D Stream distance decay
« Reply #9 on: 20 Sep '24 - 02:27 »
Ok after flipping Y and Z coords before sending to BASS and using provided dll I do not have to do any other weird tweaks to input data.

Doppler effects still behave same as in the video. If this is intended behaviour I just going to root velocities before use.

Ian @ un4seen

  • Administrator
  • Posts: 26079
Re: 3D Stream distance decay
« Reply #10 on: 20 Sep '24 - 15:08 »
In the video, it sounded like the listener always had a velocity, even when the bike was stopped? If so, what does it sound like if you set the listener's velocity the same as bike's at all times?

Miran

  • Posts: 12
Re: 3D Stream distance decay
« Reply #11 on: 21 Sep '24 - 04:55 »
Sound is stationary source at the object spawned above the road.
Listener position and velocity is calculated from camera position.
Bass does not even know that the bike exists.

The stream is short clip about two seconds with looping flag. I noticed it is possible to make it totally stop playing when camera is moved quickly in continuos manner.
Problem is not occurring when file is replaced with one lasting about 30 seconds.

Reupload:
https://www.veed.io/view/bf2f416e-96bd-424c-aec4-b079814f2ca7?panel=

Ian @ un4seen

  • Administrator
  • Posts: 26079
Re: 3D Stream distance decay
« Reply #12 on: 23 Sep '24 - 13:24 »
Sound is stationary source at the object spawned above the road.
Listener position and velocity is calculated from camera position.

How are you calculating the listener's velocity, and is it always 0 when the camera isn't moving? In the previous video, it sounded like the listener's velocity wasn't 0 when the camera wasn't moving. Was that not the case?

The stream is short clip about two seconds with looping flag. I noticed it is possible to make it totally stop playing when camera is moved quickly in continuos manner.
Problem is not occurring when file is replaced with one lasting about 30 seconds.

Reupload:
https://www.veed.io/view/bf2f416e-96bd-424c-aec4-b079814f2ca7?panel=

That's strange. Please confirm whether the source is a sample (eg. using BASS_SampleLoad) or a stream (eg. using BASS_StreamCreateFile), and check what BASS_ChannelIsActive and BASS_ChannelFlags says about it when it seems to stop by itself.

Code: [Select]
active = BASS_ChannelIsActive(handle);
flags = BASS_ChannelFlags(handle, 0, 0);

Btw, I don't seem to be able to access that video. It says "This video has been archived. The video is not available to watch at this time". Can you try uploading it again?

Miran

  • Posts: 12
Re: 3D Stream distance decay
« Reply #13 on: 24 Sep '24 - 08:12 »
Ok seems like my problems are caused by calculated velocity.
When camera is rotated by mouse velocity tends to be twice as big every other frame. Works fine in when camera is attached to vehicle.

I was not able to replicate issue with lack of playback during fast camera movements, but I guess these were just creating such great velocity differences each frame that resulting Doppler effect was out of the charts.
I suspected also maybe it was not able to sample looped stream if steep was greater that whole stream data length, but with looped track of length 0.5s it does not happen.

So sorry for false alarm.
I will post updated video if I manage to solve camera velocity problem.

Ian @ un4seen

  • Administrator
  • Posts: 26079
Re: 3D Stream distance decay
« Reply #14 on: 24 Sep '24 - 12:41 »
Ok seems like my problems are caused by calculated velocity.
When camera is rotated by mouse velocity tends to be twice as big every other frame. Works fine in when camera is attached to vehicle.

I don't think camera rotation should affect listener velocity, only movement should. If the camera doesn't have a velocity, you could calculate one from recent movement, with some averaging/smoothing to prevent sudden big changes.

Miran

  • Posts: 12
Re: 3D Stream distance decay
« Reply #15 on: 25 Sep '24 - 08:08 »
By camera rotation I meant GTA's orbit camera controlled with mouse.

Heah, so much hunting to find out original in game sounds has exactly same problem:
https://www.mediafire.com/file/co0a8y33ckexupl/bandicam_2024-09-25_03-26-15-266.mp4/file
"Cleo sound 1" is BASS powered effect, 0 is game's engine. Sound is gong attached to the bike. When camera moves instead of smooth pitch changes some kind of additional vibrato effect can be heard.
This is caused by way the game handles mouse input. Same behaviour since GTA3. It can be experienced during other mouse control related tasks, like shooting with sniper rifle. Aiming is not smooth, it just jumps some intervals.

So at this point I can just try be better than game itself. Averaging listeners velocity across several render frames seems valid solution.