kcat / openal-soft

OpenAL Soft is a software implementation of the OpenAL 3D audio API.
Other
2.22k stars 536 forks source link

Device-less buffer support? #1006

Open Try opened 5 months ago

Try commented 5 months ago

From my understanding of OpenAL, ALbuffer is basically piece of cpu-memory + a bit of meta-information and should be compatible across different physical devices.

Would it be possible to have maybe new extension (or is there existing one?) to allocate a buffer without any context/device and use them across different physical devices?

Problem that I'm solving; In my engine class Sound, that is wrapper for ALbuffer playback data is not tied to sound physical device. However engine-level api allows to

  1. reset logical-device (already works via alcReopenDeviceSOFT)
  2. output to multiple playback devices in the same time, such as dynamic + headset.

Case 2 should work, except there is no openal support for it.

kcat commented 5 months ago

An ALbuffer is memory handled by a given device or driver. The audio data may be in system RAM, or audio device RAM, depending on the driver. Even in cases where different drivers both use system RAM, there's no global lookup and different drivers may represent their buffers differently, so drivers won't know how or be able to look up an ID it didn't make, and the memory/metadata layout is likely different.

At best, it could be made so different devices from the same driver can share buffers, at least for OpenAL Soft, but there's no reliable way to know which devices are on the same driver. You'd also still need a device and context to create/manage the buffer; when using the router, a context is necessary so it knows which driver to forward to when the app makes AL calls.

Try commented 5 months ago

Thanks for the answer @kcat !

As followup, can you please clarify then how alcReopenDeviceSOFT works? If I have 2 physical usb devices on a system and toggling my openal device between them, what suppose to happen?

In my case toggling works. But maybe works by accident, and may not work for other system with different set of drivers?

And what exactly is driver in this context? Driver, like driver, or you mean openal-backend? Thanks!

kcat commented 5 months ago

As followup, can you please clarify then how alcReopenDeviceSOFT works? If I have 2 physical usb devices on a system and toggling my openal device between them, what suppose to happen?

In my case toggling works. But maybe works by accident, and may not work for other system with different set of drivers?

It's fine as long as the devices are handled by the same driver. If the driver uses hardware acceleration for multiple hardware devices, it's responsible for ensuring audio data is copied to the new device and the internal ID mappings are updated so it's transparent to the app. For software drivers, it's not much more than simply starting up a another output stream and having that take over mixing for the context. If the output can't be moved to the specified device for whatever reason, the function will return an error and the original device will keep working as it was.

Realistically, I don't expect alcReopenDeviceSOFT to be supported outside of OpenAL Soft, so it will work fine when changing between OpenAL Soft devices. But if it does get supported elsewhere, that's the intention.

And what exactly is driver in this context? Driver, like driver, or you mean openal-backend?

Basically "OpenAL Soft", "Generic Hardware", "Generic Software", "Rapture3D", etc, are different drivers. Generally each *oal.dll on Windows is a driver (though that's not a hard rule; wrap_oal.dll for example is both "Generic Hardware" and "Generic Software", it's up to the implementation if devices can be moved between drivers that are implemented in one DLL).

Try commented 5 months ago

Based on you explanation above, will it be possible to support sharing of ALbuffer across "OpenAL Soft" devices?

kcat commented 5 months ago

Based on you explanation above, will it be possible to support sharing of ALbuffer across "OpenAL Soft" devices?

Technically it would be possible, though it would increase the amount of lock contention when using multiple devices simultaneously. Currently two ALCdevices hold separate ALbuffer lists, with separate locks to safely access them. So one thread can safely look up and modify buffers in one device, and another thread can lookup and modify buffers in another device at the same time since one device can't affect the other. If the buffers could be shared, one thread would get blocked and have to wait for the other to finish.

Try commented 4 months ago

Technically it would be possible, though it would increase the amount of lock contention when using multiple devices simultaneously.

That's more than fine, I think, assuming that extra locking happens only when buffer-sharing is in use. How we can process from here? Would it be fine, if I'll draft PR, with prototype of device-less buffers concept?