Bug 259719

Summary: audio/virtual_oss: I can't hear sound from Wine apps through Bluetooth headphones
Product: Ports & Packages Reporter: Patricio Villar <patovm04>
Component: Individual Port(s)Assignee: Hans Petter Selasky <hselasky>
Status: New ---    
Severity: Affects Only Me CC: grahamperrin, iwtcex
Priority: --- Flags: bugzilla: maintainer-feedback? (hselasky)
Version: Latest   
Hardware: Any   
OS: Any   

Description Patricio Villar 2021-11-08 19:30:05 UTC
Hi, I'm not sure whether it's a virtual_oss bug or a Wine one, but I decided to file it here first.

Recently, I was able to pair my Bluetooth headphones thanks to virtual_oss. It works great for most programs, but some needed either extra steps or a workaround:

-sndio: Had to make sure to enable the sndiod service.

-pulseaudio: The workaround I found is to record the sound output and immediately redirect it to /dev/dsp. Something like this:

pacat --record -d oss_output.dsp0.monitor > /dev/dsp &


With these, all but Wine apps send their audio to my Bt headphones. Any ideas how to make it work?
Thanks in advance.
Comment 1 Hans Petter Selasky freebsd_committer 2021-11-08 19:44:15 UTC
You should probably ktrace wine, then kdump . Search for /dev/dsp .

Maybe it opens /dev/dsp0 instead of /dev/dsp .

--HPS
Comment 2 Patricio Villar 2021-11-08 20:14:18 UTC
(In reply to Hans Petter Selasky from comment #1)
Thank you for your quick response!
I did it and I think you're right, Wine is opening /dev/dsp0.
But when I run winecfg and go to the Audio tab, /dev/dsp is not listed among the available devices, just dsp0 and dsp2...
What do you suggest doing next?
Comment 3 Hans Petter Selasky freebsd_committer 2021-11-08 20:23:37 UTC
Either you patch wine to list /dev/dsp, or you create a audio device named /dev/dsp20 ?

--HPS
Comment 4 Patricio Villar 2021-11-08 20:34:23 UTC
(In reply to Hans Petter Selasky from comment #3)
Hmm tried the second option but Wine didn't list it either. Maybe it can't see virtual audio devices at all?
Comment 5 Hans Petter Selasky freebsd_committer 2021-11-08 20:44:05 UTC
Yes, probably you need to patch the OSS backend in wine. Should not be too hard.
Comment 6 Hans Petter Selasky freebsd_committer 2021-11-08 20:44:33 UTC
It might also be some parameter you can give wine to override the audio device.
Comment 7 Patricio Villar 2021-11-08 20:49:22 UTC
Ok. Gonna file a bug for emulators/wine then.
Thanks for all your help!
Comment 8 Alex S 2021-11-10 12:30:47 UTC
I was suggesting filing a bug on GitHub, not there. (And this doesn't look like a Wine issue.)

Anyway, virtual_oss gives this output:

% env WINEDEBUG=-all,+oss,+mmaux,+midi wine64 winecfg
0110:trace:oss:AUDDRV_GetPriority Priority_Low: sysinfo.version[0]: 31
0110:trace:oss:AUDDRV_GetEndpointIDs 0 0x11bbe8 0x11bbe0 0x11bbdc 0x11bbd8
0110:trace:oss:AUDDRV_GetEndpointIDs OSS sysinfo:
0110:trace:oss:AUDDRV_GetEndpointIDs product: FreeBSD native OSS ABI
0110:trace:oss:AUDDRV_GetEndpointIDs version: 1300139
0110:trace:oss:AUDDRV_GetEndpointIDs versionnum: 40000
0110:trace:oss:AUDDRV_GetEndpointIDs numaudios: 29
0110:trace:oss:AUDDRV_GetEndpointIDs nummixers: 6
0110:trace:oss:AUDDRV_GetEndpointIDs numcards: 6
0110:trace:oss:AUDDRV_GetEndpointIDs numaudioengines: 29
0110:trace:oss:get_default_index Default devnode: 
0110:warn:oss:get_default_index Couldn't find default device! Choosing first.

While directly using native OSS looks like this:

% env WINEDEBUG=-all,+oss,+mmaux,+midi wine64 winecfg
0140:trace:oss:AUDDRV_GetPriority Priority_Low: sysinfo.version[0]: 31
0140:trace:oss:AUDDRV_GetEndpointIDs 0 0x11bbe8 0x11bbe0 0x11bbdc 0x11bbd8
0140:trace:oss:AUDDRV_GetEndpointIDs OSS sysinfo:
0140:trace:oss:AUDDRV_GetEndpointIDs product: FreeBSD native OSS ABI
0140:trace:oss:AUDDRV_GetEndpointIDs version: 1300139
0140:trace:oss:AUDDRV_GetEndpointIDs versionnum: 40000
0140:trace:oss:AUDDRV_GetEndpointIDs numaudios: 29
0140:trace:oss:AUDDRV_GetEndpointIDs nummixers: 6
0140:trace:oss:AUDDRV_GetEndpointIDs numcards: 6
0140:trace:oss:AUDDRV_GetEndpointIDs numaudioengines: 29
0140:trace:oss:get_default_index Default devnode: /dev/dsp5.vp1

The relevant code is https://github.com/wine-mirror/wine/blob/6a072b98c100f38a61fad00b6c96c86b3445efac/dlls/wineoss.drv/mmdevdrv.c#L419-L428.
Comment 9 Hans Petter Selasky freebsd_committer 2021-11-10 13:20:24 UTC
Hi,

Does your virtual_oss commands create a default device, "dsp" ?

WARN("Couldn't open default device!\n");

virtual_oss implements the SNDCTL_ENGINEINFO!

--HPS
Comment 10 Alex S 2021-11-10 13:32:22 UTC
(In reply to Hans Petter Selasky from comment #9)

> Does your virtual_oss commands create a default device, "dsp" ?

Why, yes. I'm using this command for testing: https://forums.freebsd.org/threads/switching-dsp-devices-on-the-fly.69773/#post-419290.

> virtual_oss implements the SNDCTL_ENGINEINFO!

It doesn't populate devnode field with anything, though.
Comment 11 Hans Petter Selasky freebsd_committer 2021-11-10 13:48:32 UTC
Does this virtual_oss patch solve the issue:

https://github.com/hselasky/virtual_oss/commit/070bfd5559f11c4d2dd8f24e5a6cc88389f4fa17

--HPS
Comment 12 Alex S 2021-11-10 14:27:36 UTC
(In reply to Hans Petter Selasky from comment #11)

Hmm… That apparently makes no difference. Looks like Wine only uses this value for comparison with /dev/dsp%d nodes. Thus what actually works for me is starting virtual_oss with `-l dsp -l dsp0`. Obviously not ideal workaround.
Comment 13 Hans Petter Selasky freebsd_committer 2021-11-10 14:54:44 UTC
So it's a bug in Wine, that it should also have a "Default" entry which use /dev/dsp ?
Comment 14 Alex S 2021-11-10 16:10:25 UTC
(In reply to Hans Petter Selasky from comment #13)

There is no /dev/dsp fallback logic, Wine chooses the first enumerated device instead. Now, it actually gets those devices from /dev/mixer, not /dev/dsp. That's why this is so confusing :)

With `virtual_oss -Q 0 -C 2 -c 2 -r 48000 -b 16 -s 1024 -P /dev/null -R /dev/null -w vdsp.wav -l dsp -l mixer` I receive

010c:trace:oss:AUDDRV_GetPriority Priority_Low: sysinfo.version[0]: 31
010c:trace:oss:AUDDRV_GetEndpointIDs 0 0x11bbe8 0x11bbe0 0x11bbdc 0x11bbd8
010c:trace:oss:AUDDRV_GetEndpointIDs OSS sysinfo:
010c:trace:oss:AUDDRV_GetEndpointIDs product: VOSS
010c:trace:oss:AUDDRV_GetEndpointIDs version: 1.0
010c:trace:oss:AUDDRV_GetEndpointIDs versionnum: 40000
010c:trace:oss:AUDDRV_GetEndpointIDs numaudios: 1
010c:trace:oss:AUDDRV_GetEndpointIDs nummixers: 0
010c:trace:oss:AUDDRV_GetEndpointIDs numcards: 1
010c:trace:oss:AUDDRV_GetEndpointIDs numaudioengines: 1
010c:warn:oss:AUDDRV_GetEndpointIDs Opening device "mixer" failed, pretending it doesn't exist: 2 (No such file or directory)
010c:trace:oss:get_default_index Default devnode: dsp
010c:warn:oss:get_default_index Couldn't find default device! Choosing first.

And after this patch

diff --git a/virtual_main.c b/virtual_main.c
index 1e6521b..662f758 100644
--- a/virtual_main.c
+++ b/virtual_main.c
@@ -1195,7 +1195,9 @@ vclient_ioctl_oss(struct cuse_dev *pdev, int fflags,
                memset(&data.audioinfo, 0, sizeof(data.audioinfo));
                strlcpy(data.audioinfo.name, pvc->profile->oss_name,
                    sizeof(data.audioinfo.name));
-               strlcpy(data.audioinfo.devnode, pvc->profile->oss_name,
+    char path[OSS_DEVNODE_SIZE];
+    snprintf(path, sizeof(path), "/dev/%s", pvc->profile->oss_name);
+               strlcpy(data.audioinfo.devnode, path,
                    sizeof(data.audioinfo.devnode));
                data.audioinfo.caps = DSP_CAP_INPUT | DSP_CAP_OUTPUT;
                data.audioinfo.iformats = VSUPPORTED_AFMT;

it starts to actually work, albeit with

00f4:trace:oss:get_default_index Default devnode: /dev/dsp
00f4:warn:oss:get_default_index Couldn't find default device! Choosing first.

(/dev/dsp != /dev/mixer)

Still awkward, but more tolerable behavior.