Author Topic: Considering BASSWASAPI  (Read 237 times)

SoundMike

  • Posts: 377
Considering BASSWASAPI
« on: 14 Jan '25 - 08:06 »
I currently use BASS and BASSASIO as well as some of the BASS extras such as BASSMix, BASS FX, etc. I have not included BASSWASAPI but the program successfully handles WASAPI anyway. However, one feature of BASSWASAPI that interests me is the BASS_WASAPI_NOTIFY_DISABLED notification as equivalent notifications do not appear to be supported in BASS or BASSASIO. But to use the 'set notify' to gain access to this would I have to handle all the WASAPI processing via BASSWASAPI? For example, if WASAPI is to be used then should I use BASS_WASAPI_Init() instead of BASS_Init()?

Ian @ un4seen

  • Administrator
  • Posts: 26264
Re: Considering BASSWASAPI
« Reply #1 on: 14 Jan '25 - 15:11 »
It is possible to use BASSWASAPI for the device notifications and BASS for playback/recording, ie. you can use BASS_WASAPI_SetNotify without BASS_WASAPI_Init. Note that the BASS and BASSWASAPI device lists are different, so you would need to translate the BASSWASAPI device numbers to BASS device numbers. Here's some code for doing that:

   www.un4seen.com/forum/?topic=19759.msg138285#msg138285

SoundMike

  • Posts: 377
Re: Considering BASSWASAPI
« Reply #2 on: 15 Jan '25 - 01:52 »
Thanks, Ian.

SoundMike

  • Posts: 377
Re: Considering BASSWASAPI
« Reply #3 on: 16 Jan '25 - 01:54 »
Is there some reason WASAPI devices appear to be duplicated? I think I've got my code right, but when I disconnect my Roland Octa-Capture the WASAPI notify procedure reports info like this:
wasapiNotifyProc: WASAPI device: 22 (Line-Level: 1-2 (OCTA-CAPTURE)), BASS device: 4 (1-2 (OCTA-CAPTURE)), notify: The device has been disabled/disconnected.
wasapiNotifyProc: WASAPI device: 23 (Line-Level: 1-2 (OCTA-CAPTURE)), BASS device: 4 (1-2 (OCTA-CAPTURE)), notify: The device has been disabled/disconnected.

What's the reason for WASAPI devices 22 and 23 appearing to be the same? This also applies to all the other channels. Is 22 for channel 1 and 23 for channel 2?

Ian @ un4seen

  • Administrator
  • Posts: 26264
Re: Considering BASSWASAPI
« Reply #4 on: 16 Jan '25 - 12:54 »
What are the flags of each of those devices? You will see output devices duplicated in the list (at n and n+1), with the 2nd device having the BASS_DEVICE_LOOPBACK flag set to indicate that it's for "loopback" recording of the 1st device's output.

SoundMike

  • Posts: 377
Re: Considering BASSWASAPI
« Reply #5 on: 17 Jan '25 - 06:50 »
This is what I get when I include the flags:
wasapiNotifyProc: WASAPI device: 22 (Line-Level:1-2 (OCTA-CAPTURE), flags=BASS_DEVICE_DEFAULT), BASS device: 4 (1-2 (OCTA-CAPTURE)), notify: The device has been disabled/disconnected.
wasapiNotifyProc: WASAPI device: 23 (Line-Level:1-2 (OCTA-CAPTURE), flags=BASS_DEVICE_INPUT|BASS_DEVICE_LOOPBACK), BASS device: 4 (1-2 (OCTA-CAPTURE)), notify: The device has been disabled/disconnected.

I guess this is because the Octa-Capture does have both inputs and outputs, so presumably device 22 is the output device for the Octa-Capture's channels 1-2, and device 23 is for the corresponding input pair.

Ian @ un4seen

  • Administrator
  • Posts: 26264
Re: Considering BASSWASAPI
« Reply #6 on: 17 Jan '25 - 15:33 »
Yes, despite having "CAPTURE" in its name, that device appears to be an output/playback device (plus a loopback device).

SoundMike

  • Posts: 377
Re: Considering BASSWASAPI
« Reply #7 on: 21 Jan '25 - 06:55 »
Since this feature is not available with BASSASIO, if a user is using ASIO then is there some way I can identify a WASAPI device that is for the same physical device as a BASSASIO device? Sometimes the names contain the same words but from the equipment I've tested (primarily the Octa-Capture and an A&H Qu-16) there's no reliable way I can see to identify an ASIO device's corresponding WASAPI device.

Ian @ un4seen

  • Administrator
  • Posts: 26264
Re: Considering BASSWASAPI
« Reply #8 on: 21 Jan '25 - 13:07 »
No, unfortunately it isn't possible to reliably map WASAPI devices to ASIO devices, as ASIO is an entirely separate driver system. ASIO also doesn't have its own notification system. Trying to initialize an ASIO device/driver is really the only way to check if it's available.

elan

  • Posts: 76
Re: Considering BASSWASAPI
« Reply #9 on: 12 Feb '25 - 19:36 »
On the topic of duplicated entries, here's what I see with a USB AudioQuest device plugged in:

WASAPI Device 1: Speakers (AudioQuest DragonFly Red v1.0) - enabled input loopback speakers headphones digital ({0.0.0.00000000}.{373f5a70-22fc-4f67-9525-0d62b87035fb})
WASAPI Device 2: Speakers (High Definition Audio Device) - enabled default speakers headphones digital ({0.0.0.00000000}.{79e76ee7-1cd9-4eb0-863a-1a628347476b})
WASAPI Device 3: Speakers (High Definition Audio Device) - enabled input loopback speakers headphones digital ({0.0.0.00000000}.{79e76ee7-1cd9-4eb0-863a-1a628347476b})
WASAPI Device 4: Microphone (High Definition Audio Device) - enabled default input digital ({0.0.1.00000000}.{1d8c3817-96e0-4032-bd12-66613197914a})


The default device is duplicated (one with loopback + input), and the DragonFly only has a single entry with input, loopback, and speakers.

I'm not entirely sure how to process this into a sane list; I can skip the duplicate, but how do I know Device 1 is actually a real output device?

elan

  • Posts: 76
Re: Considering BASSWASAPI
« Reply #10 on: 13 Feb '25 - 02:03 »
In addition, I can't seem to play to the DragonFly device:

Code: [Select]
  // Initialize device.
  if (!BASS_WASAPI_Init(device, 0, 0, BASS_WASAPI_AUTOFORMAT | BASS_WASAPI_ASYNC | BASS_WASAPI_EXCLUSIVE | BASS_WASAPI_RAW | BASS_WASAPI_CATEGORY_MEDIA, 0.1f, 0.05f, WasapiProc, this))
  {
    eprintf("BASS: Error initializing WASAPI device %d with sample rate %d in exclusive mode: %d", device, bestSampleRate, BASS_ErrorGetCode());
    if (!BASS_WASAPI_Init(device, 0, 0, BASS_WASAPI_AUTOFORMAT | BASS_WASAPI_RAW | BASS_WASAPI_CATEGORY_MEDIA, 0.1f, 0.05f, WasapiProc, this))
    {
      eprintf("BASS: Error initializing WASAPI device %d with sample rate %d in shared mode: %d", device, bestSampleRate, BASS_ErrorGetCode());
      return false;
    }
  }

BASS: Error initializing WASAPI device 1 with sample rate 44100 in exclusive mode: 37
BASS: Error initializing WASAPI device 1 with sample rate 44100 in shared mode: -1

The other device (ID: 2) works great.

Curiously, in the Volume Mixer app in Windows 11. the AudioQuest DragonFly doesn't show up as an input device at all.

In BASS-land, things look more sane:

BASS: Device 1: Default - enabled default handset hdmi headset line speakers
BASS: Device 2: Speakers (AudioQuest DragonFly Red v1.0) - enabled default handset hdmi headset line speakers
BASS: Device 3: Speakers (High Definition Audio Device) - enabled handset hdmi headset line speakers


However, if I attempt to play to that device, I get a very similar errors:

BASS: Error initializing device 2 with sample rate 44100 and flags 00000000 (-1).

I've tested Foobar 2000 and the device works as expected (assuming it uses WASAPI as well but not sure)

(And forgive me for hjacking this thread, happy to open a new one if you'd like.)

Ian @ un4seen

  • Administrator
  • Posts: 26264
Re: Considering BASSWASAPI
« Reply #11 on: 13 Feb '25 - 13:00 »
On the topic of duplicated entries, here's what I see with a USB AudioQuest device plugged in:

WASAPI Device 1: Speakers (AudioQuest DragonFly Red v1.0) - enabled input loopback speakers headphones digital ({0.0.0.00000000}.{373f5a70-22fc-4f67-9525-0d62b87035fb})
WASAPI Device 2: Speakers (High Definition Audio Device) - enabled default speakers headphones digital ({0.0.0.00000000}.{79e76ee7-1cd9-4eb0-863a-1a628347476b})
WASAPI Device 3: Speakers (High Definition Audio Device) - enabled input loopback speakers headphones digital ({0.0.0.00000000}.{79e76ee7-1cd9-4eb0-863a-1a628347476b})
WASAPI Device 4: Microphone (High Definition Audio Device) - enabled default input digital ({0.0.1.00000000}.{1d8c3817-96e0-4032-bd12-66613197914a})


The default device is duplicated (one with loopback + input), and the DragonFly only has a single entry with input, loopback, and speakers.

I'm not entirely sure how to process this into a sane list; I can skip the duplicate, but how do I know Device 1 is actually a real output device?

BASSWASAPI doesn't have a "No Sound" device (like BASS does), so the real devices start at #0. You should find a non-loopback entry for the "Speakers (AudioQuest DragonFly Red v1.0)" device in that slot.

In addition, I can't seem to play to the DragonFly device:

Code: [Select]
  // Initialize device.
  if (!BASS_WASAPI_Init(device, 0, 0, BASS_WASAPI_AUTOFORMAT | BASS_WASAPI_ASYNC | BASS_WASAPI_EXCLUSIVE | BASS_WASAPI_RAW | BASS_WASAPI_CATEGORY_MEDIA, 0.1f, 0.05f, WasapiProc, this))
  {
    eprintf("BASS: Error initializing WASAPI device %d with sample rate %d in exclusive mode: %d", device, bestSampleRate, BASS_ErrorGetCode());
    if (!BASS_WASAPI_Init(device, 0, 0, BASS_WASAPI_AUTOFORMAT | BASS_WASAPI_RAW | BASS_WASAPI_CATEGORY_MEDIA, 0.1f, 0.05f, WasapiProc, this))
    {
      eprintf("BASS: Error initializing WASAPI device %d with sample rate %d in shared mode: %d", device, bestSampleRate, BASS_ErrorGetCode());
      return false;
    }
  }

BASS: Error initializing WASAPI device 1 with sample rate 44100 in exclusive mode: 37
BASS: Error initializing WASAPI device 1 with sample rate 44100 in shared mode: -1


The BASS_ERROR_NOTAVAIL (37) error will be because the BASS_WASAPI_EXCLUSIVE option isn't available on loopback devices.

The BASS_ERROR_UNKNOWN (-1) error is less obvious. Does it still happen with flags=0? One possible cause of BASS_ERROR_UNKNOWN is that BASS_WASAPI_Init is unable to get the device's sample format. Can you see/set the device's format in Window's Sound control panel?

In BASS-land, things look more sane:

BASS: Device 1: Default - enabled default handset hdmi headset line speakers
BASS: Device 2: Speakers (AudioQuest DragonFly Red v1.0) - enabled default handset hdmi headset line speakers
BASS: Device 3: Speakers (High Definition Audio Device) - enabled handset hdmi headset line speakers


However, if I attempt to play to that device, I get a very similar errors:

BASS: Error initializing device 2 with sample rate 44100 and flags 00000000 (-1).

Please try using the BASS_DEVICE_DSOUND flag in the BASS_Init call to see if that makes any difference.

elan

  • Posts: 76
Re: Considering BASSWASAPI
« Reply #12 on: 14 Feb '25 - 09:51 »
(Forgot to give system details: Windows ARM64 under VMware Fusion on macOS)

OK, got the devices sorted out properly starting at index 0, that let me select the correct device; I can play in exclusive (and shared) mode to both devices now.

For one of the devices (external USB), for some reason at some point after seconds to minutes, the WASAPI callback stops being called. I don't see WasapiNotifyProc being called with any notification, there's no obvious indication of why it would stop being called (flags are: BASS_WASAPI_ASYNC | BASS_WASAPI_RAW | BASS_WASAPI_CATEGORY_MEDIA | BASS_WASAPI_EXCLUSIVE).

In addition, in shared mode, I'm having a bit of trouble figuring out the resampling when sample rates don't match. The documentation says "WASAPI can resample when required in shared mode (if the BASS_WASAPI_AUTOFORMAT flag is not specified)" but what I think I'm seeing is that when the mixer sample rate differs from the device sample rate, there's no resampling happening.

Lastly, I still see the -1 error sporadically when calling BASS_WASAPI_Init. It's a bit weird, I get the -1, retry and get error 3 (one or more times) and then finally the device opens successfully.

Thanks as always for the help!

Ian @ un4seen

  • Administrator
  • Posts: 26264
Re: Considering BASSWASAPI
« Reply #13 on: 14 Feb '25 - 12:40 »
For one of the devices (external USB), for some reason at some point after seconds to minutes, the WASAPI callback stops being called. I don't see WasapiNotifyProc being called with any notification, there's no obvious indication of why it would stop being called (flags are: BASS_WASAPI_ASYNC | BASS_WASAPI_RAW | BASS_WASAPI_CATEGORY_MEDIA | BASS_WASAPI_EXCLUSIVE).

Sounds like that may need a debug version to get more info. To perhaps narrow it down a bit first, does changing the flags make any difference, eg. does it still happen with flags=0? And does BASS_WASAPI_IsStarted still return TRUE when the callbacks stop?

In addition, in shared mode, I'm having a bit of trouble figuring out the resampling when sample rates don't match. The documentation says "WASAPI can resample when required in shared mode (if the BASS_WASAPI_AUTOFORMAT flag is not specified)" but what I think I'm seeing is that when the mixer sample rate differs from the device sample rate, there's no resampling happening.

You can tell when WASAPI is resampling by comparing the values from BASS_WASAPI_GetInfo and BASS_WASAPI_GetDeviceInfo, eg. does BASS_WASAPI_INFO:freq (your rate) = BASS_WASAPI_DEVICEINFO:mixfreq (device's rate).

Lastly, I still see the -1 error sporadically when calling BASS_WASAPI_Init. It's a bit weird, I get the -1, retry and get error 3 (one or more times) and then finally the device opens successfully.

Is this only happening with the same external USB device as above, or other devices too? Do BASS_WASAPI_CheckFormat or BASS_WASAPI_GetDeviceLevel calls on the device also result in the same errors?