Author Topic: WASAPI, DirectX and 3D audio  (Read 136 times)

QuentinC

  • Posts: 43
WASAPI, DirectX and 3D audio
« on: 13 Jun '18 - 20:59 »
Hello,

I have downloaded the latest BASS and noticed that, from now on, it was using WASAPI instead of DirectX by default on windows 7 and up.
I have two questions regarding this, and others questions about 3D.

1. For a game, is it better to still use DirectX as for previous BASS versions ?
In fact, what are the advantages of using WASAPI instead of DirectX ?


2. When using WASAPI, does the distinction between sample and stream channels  still apply as before ? i.e. samples are cheaper in CPU but no effects/DSP can be set on them,
or they are now threated identically when using WASAPI ?
What let me perhaps think that the distinction is gone with WASAPI is the fact that I can now set a general DSP/effect that applies to everything, while it was totally impossible with DirectX (because BASS didn't handle the final mix itself).


3. Given a sample loaded with the flag BASS_SAMPLE_3D, is it possible for a particular HCHANNEL instance of that sample to turn off 3D and be able to set BASS_ATTRIB_PAN ?
Is it the purpose of BASS_3DMODE_OFF ?

4: Is there somewhere a better explanations of the parameters for BASS_ChannelSet3DAttributes ? I'm not sure to understand everything correctly for the parameters min and  max.
What happens if the source is too far from the listener ? Is the channel automatically muted, paused, stopped, or something ? Or do I have to handle this myself ?

I was expecting that when the listener is beyond max distance, it was silence (or almost), i.e. I don't hear the channel, but in fact not necessary.
If I decide to manually stop channels as soon as the listener goes outside max distance (assuming no at the previous question), the cut is clear.

So, question: how the volume is calculated according to the distance and these parameters ? Which values am I supposed to set so to have smooth and natural volume changes as I'm moving in the 3D world ?
For a numerical example, let's say that I have a looping sample of a noisy machine that can be heard within a 10 meters range, i.e. I should start hearing it at 10 meters when approaching it, and stop hearing it at 10 meters when going away from it.


Thank you for your answers.

Ian @ un4seen

  • Administrator
  • Posts: 20845
Re: WASAPI, DirectX and 3D audio
« Reply #1 on: 14 Jun '18 - 16:37 »
1. For a game, is it better to still use DirectX as for previous BASS versions ?
In fact, what are the advantages of using WASAPI instead of DirectX ?

The main advantage of using WASAPI output is that BASS generates the final output mix (containing all playing channels) itself then, so you get more control over the end result, eg. latency and resampling quality. It is also more consistent with what happens on other platforms, where BASS has always been generating the final mix.

Since Windows Vista, DirectSound is built on top WASAPI (there are no DirectSound drivers anymore), so there isn't really any advantage to using DirectSound output instead of WASAPI when BASS can implement the DirectSound features (eg. mixing) itself.

2. When using WASAPI, does the distinction between sample and stream channels  still apply as before ? i.e. samples are cheaper in CPU but no effects/DSP can be set on them,
or they are now threated identically when using WASAPI ?
What let me perhaps think that the distinction is gone with WASAPI is the fact that I can now set a general DSP/effect that applies to everything, while it was totally impossible with DirectX (because BASS didn't handle the final mix itself).

Yes, samples still use less CPU (because the sample's data is all in memory). The ability to apply DSP/FX to everything is something that's made possible by BASS generating the final mix.

3. Given a sample loaded with the flag BASS_SAMPLE_3D, is it possible for a particular HCHANNEL instance of that sample to turn off 3D and be able to set BASS_ATTRIB_PAN ?
Is it the purpose of BASS_3DMODE_OFF ?

No, it isn't currently possible to toggle the BASS_SAMPLE_3D flag, although there's no technical reason preventing it (when DirectSound isn't used). Perhaps that ability can added in a future BASS version. BASS_3DMODE_OFF will just put the sound in the centre.

4: Is there somewhere a better explanations of the parameters for BASS_ChannelSet3DAttributes ? I'm not sure to understand everything correctly for the parameters min and  max.
What happens if the source is too far from the listener ? Is the channel automatically muted, paused, stopped, or something ? Or do I have to handle this myself ?

BASS emulates the DirectSound3D system, so the 3D settings work the same as there. Here's Microsoft's documentation on volume levels, including an example:

   https://msdn.microsoft.com/en-us/library/ee418662.aspx

So the volume will stop decreasing at the maximum distance. It won't be muted unless the BASS_SAMPLE_MUTEMAX flag is set (equivalent to DSBCAPS_MUTE3DATMAXDISTANCE in the link above).

So, question: how the volume is calculated according to the distance and these parameters ? Which values am I supposed to set so to have smooth and natural volume changes as I'm moving in the 3D world ?
For a numerical example, let's say that I have a looping sample of a noisy machine that can be heard within a 10 meters range, i.e. I should start hearing it at 10 meters when approaching it, and stop hearing it at 10 meters when going away from it.

It's the minimum distance setting that determines how quickly the sound fades over distance. The volume at any distance can be calculated like this:

Code: [Select]
vol = dist <= mindist ? 1 : mindist / (mindist + (dist - mindist) * rolloff);

If you want a certain volume level at a certain distance then you can calculate the minimum distance like this:

Code: [Select]
mindist = vol * dist

For example, for -40 dB (0.01) at 10 meters:

Code: [Select]
mindist = 0.01 * 10 = 0.1

QuentinC

  • Posts: 43
Re: WASAPI, DirectX and 3D audio
« Reply #2 on: 15 Jun '18 - 03:59 »
Thank you very much for your answers.

So I can consider that DirectSound specific features have all definitely gone ? e.g. BASS_3DALGORITHM_FULL and EAX effects.



By the way, to add to question 2, samples still behave like before with WASAPI, it is impossible to set an effect on them. When I need to set an effect on a sample, I transform it to a stream by retrieving its data and then generating an in-memory WAV file. That's the easiest way I have found so far.

Ian @ un4seen

  • Administrator
  • Posts: 20845
Re: WASAPI, DirectX and 3D audio
« Reply #3 on: 15 Jun '18 - 13:43 »
So I can consider that DirectSound specific features have all definitely gone ? e.g. BASS_3DALGORITHM_FULL and EAX effects.

Yes, unless you will be running on Windows XP or older, it is best to avoid using those 2 features as they depend on DirectSound's hardware mixing feature, which was removed in Vista.

By the way, to add to question 2, samples still behave like before with WASAPI, it is impossible to set an effect on them. When I need to set an effect on a sample, I transform it to a stream by retrieving its data and then generating an in-memory WAV file. That's the easiest way I have found so far.

Yes, DSP/FX still can't be applied directly to samples. That is because they do not have playbck buffers (the sample data goes directly to the final mix), so there is no intermediate buffer that can be modified by DSP/FX without affecting the original sample data. You can indeed get around that limitation by using a stream instead, which does have a playback buffer that can be modified. If you are currently creating another copy of the sample data (with WAV header) in memory to pass to BASS_StreamCreateFile, that can be avoided by using BASS_StreamCreate instead and having your STREAMPROC function read from the existing memory block.

Falcosoft

  • Guest
Re: WASAPI, DirectX and 3D audio
« Reply #4 on: 15 Jun '18 - 21:00 »

The main advantage of using WASAPI output is that BASS generates the final output mix (containing all playing channels) itself then, so you get more control over the end result, eg. latency and resampling quality. It is also more consistent with what happens on other platforms, where BASS has always been generating the final mix.

Since Windows Vista, DirectSound is built on top WASAPI (there are no DirectSound drivers anymore), so there isn't really any advantage to using DirectSound output instead of WASAPI when BASS can implement the DirectSound features (eg. mixing) itself.

Actually it seems there can be advantages using Directsound output even on Vista+ systems and this is likely because of using WASAPI output 'BASS generates the final output mix'. Namely I have experienced that with some soundcards (SB Audigy1/2/4, Realtek HD audio) and stereo sources  CMSS 3D/Speaker Fill like effects do not work when using the now default WASAPI output but work when you specify Directsound output explicitly (by adding BASS_DEVICE_DSOUND flag to BASS_Init()).


QuentinC

  • Posts: 43
Re: WASAPI, DirectX and 3D audio
« Reply #5 on: 15 Jun '18 - 21:36 »
> If you are currently creating another copy of the sample data (with WAV header) in memory to pass to BASS_StreamCreateFile, that can be avoided by using BASS_StreamCreate instead and having your STREAMPROC function read from the existing memory block.

I tried this first about 2 years ago in a previous version of my program.

The big disadvantage is that looping doesn't natively work, I have to handle it myself.

It isn't very complicated to handle loop by yourself, but I also had another problem which made me change: one or more threads where randomly hanging on BASS_ChannelIsActive or BASS_ChannelFlags. It could happen just after 2 minutes as well as one hour of play of the game.
I have never understood what happened exactly and have never been able to make a systematically reproducible example to post here (that's why there isn't)


Since I'm using this approach of in-memory WAV file, I have never seen this problem again.

Ian @ un4seen

  • Administrator
  • Posts: 20845
Re: WASAPI, DirectX and 3D audio
« Reply #6 on: 18 Jun '18 - 13:17 »
It isn't very complicated to handle loop by yourself, but I also had another problem which made me change: one or more threads where randomly hanging on BASS_ChannelIsActive or BASS_ChannelFlags. It could happen just after 2 minutes as well as one hour of play of the game.

That's strange. I can't really think of a reason for those 2 functions to hang. BASS_ChannelFlags could possibly get in a deadlock with a STREAMPROC if it's changing SPEAKER flags and the STREAMPROC is waiting for the BASS_ChannelFlags call's thread. Did your STREAMPROC function do anything that could require it to wait for another thread?

If you do try again with the latest BASS version and get the problem happening again, please upload a dump file of it. You can use Task Manager's "Create Dump File" option to generate the dump file.

   ftp.un4seen.com/incoming

QuentinC

  • Posts: 43
Re: WASAPI, DirectX and 3D audio
« Reply #7 on: 18 Jun '18 - 21:07 »
> Did your STREAMPROC function do anything that could
require it to wait for another thread?

I no longer have the code to send you a dump or any kind of debug file, but I don't think so.


Basicly the STREAMPROC first checked the state of the BASS_SAMPLE_LOOP flag, then copied a part of the audio data buffer as requested. I never changed the flags inside the STREAMPROC.


Perhaps the problem was in fact in a sync on BASS_SYNC_FREE that was used to free memory related to my custom sample (a shared_ptr/array on the audio data, the playback position, etc.). I don't know.

I just noticed in the debugger that when the sound hung, the calls were always in BASS-ChannelFlags or BASS_ChannelIsActive not itself in the STREAMPROC.