libsdl-org / SDL

Simple Directmedia Layer
https://libsdl.org
zlib License
9.43k stars 1.75k forks source link

Retain old direct hw access callback based audio for SDL3 as an option #8074

Closed ell1e closed 1 year ago

ell1e commented 1 year ago

I wanted to heavily suggest you retain old direct hw access callback based audio for SDL3 as an option after seeing Ryan's video on the new audio system WITHOUT a mixer, buffer chain, "virtual" device forced in between. My apologies in advance since I might have misunderstood how it works. But it seems to me from that video that SDL3 forces a virtual device with a virtual mixer in between with another buffer chain, even when using the "traditional" callback API. If true, for properly written high performance audio apps geared for low latency audio this seems like a universal downgrade and very undesirable. I also find it a bit surprising to have this in the core lib at all, these mixers, what happened to having them in useful separate libs like SDL_mixer only for those users who actually want to stack a software mixer into their SDL setup? It seems potentially a worrying approach to me to force all this additional complexity into the core when many won't use it and still need everyone to ship it. Sorry again if I misunderstood some of the new systems from the info I saw.

icculus commented 1 year ago

There was no direct hw access, even with the callback, fwiw.

Very few (perhaps none) of the platforms we target let you get directly at the DMA buffer (even the ones that used to, like DirectSound, are now wrappers over WASAPI at the OS level, which does not).

That being said, each audiostream can have its own callback, which fires as more data is needed, and slots into almost the exact same place as the audio callback was in the SDL2 pipeline. If you have one open device with one audio stream bound to it, the way this goes down behind the scenes is almost equivalent to SDL2.

However, there is still an open question in the new API of what to do for the postmix--SDL_mixer needs this for one of its features if we were to move everything to audio streams, and other things might benefit from it, too, like visualizers and last-minute audio manipulation...and this is likely going to need a callback. :/

ell1e commented 1 year ago

Thanks so much for the quick response! For what it's worth when you say "almost equivalent", I'm almost purely just concerned with additional buffer copies. A stream object with mixer support sounds like it would use its own buffer to me before going to the OS API buffer, which to me sounds rather bad. (Whether DirectSound then adds another copy on top isn't of my concern since that seems unavoidable, but copying added by SDL3 is not.) I didn't quite gather from your response if SDL3 adds more copying, it just seemed to me like it naturally might need to for a mixer shoved in. If the mixer adds more copies and/or latency in some cases then IMHO it should be possible to bypass it to avoid that. The video made it sound like that's currently not possible, hence the ticket to voice my concern.

icculus commented 1 year ago

It might add an extra copy if necessary, but it doesn't add latency as we feed the audio device the same way internally that we did in SDL2.

And if there's a single device and a single stream, which would be normal in a game that provides its own mixing, SDL skips the mixing step and just provides the single source of data directly to the backend.

tl;dr: I think we're probably okay here.

ell1e commented 1 year ago

An extra copy always adds latency simply due to the duration of the copy itself which is why I brought it up, so I think that is undesirable. Is "provides ... to the backend" an extra copy compared to SDL2 too? If yes that might be worth avoiding. If not ignore me, and sorry for taking up your time.