Replies: 4 comments 3 replies
-
Generally, I'm open to support this use-case. However, I would refrain from abusing
Not to my knowledge.
Regarding the implementation of "24bit audio": There are three options that come to my mind:
It's not yet entirely clear to me which of the two latter options you would be using in the end. I looked up the Microsoft docs, but couldn't find the answer either. If you would be using option 3. the name of the new option should be Other things to consider:
|
Beta Was this translation helpful? Give feedback.
-
|
I’m open to adding an explicit "24bits" option if that’s the preferred direction, but I am concerned about the blast radius: audio.sample-format is global, and we’d need to ensure that all existing drivers either handle the new value sensibly or fail in a clearly defined way. As a smaller-scope alternative that keeps the change tightly confined to the exclusive mode of the WASAPI driver, we could make the effective transport explicit in the -Q output. Concretely, the WASAPI exclusive path could emit a single FLUID_INFO log message when an integer PCM transport format is used. This would cause -Q to report the mode as OK(I), making it visible that the requested format was realized using an integer transport. Using FLUID_INFO logging in this way parallels what the driver is already doing to report supported modes with resampling in shared mode. The corresponding footnote could be updated to:
This keeps the behavior explicit and discoverable (via -Q) without expanding audio.sample-format semantics beyond what’s already documented. Would this address your concern about overloading audio.sample-format="float"? The transport format is dictated by what the audio hardware will accept. On Windows, in exclusive mode, the audio hardware either accepts or rejects an exact WAVEFORMAT* that we propose via IAudioClient::IsFormatSupported / Initialize, so the driver can explicitly probe whichever representations we care about. For the common “24-bit PCM in a 32-bit container” case, the Windows expectation (per WAVEFORMATEXTENSIBLE) is that the valid bits are left-aligned in the container (wBitsPerSample = 32, wValidBitsPerSample = 24, least-significant byte zero). That corresponds to your option (3), and it’s also the convention used by libsndfile. A 32-bit container with only the lower 24 bits used (option 2) doesn’t appear to be a meaningful or commonly accepted PCM representation on WASAPI, so we likely wouldn’t probe that format. Packed 24-bit (3-byte) PCM can be probed, but it is only occasionally supported by endpoints. A possible probing order for the transport format, when the intent is to transmit the greatest available resolution, could be:
|
Beta Was this translation helpful? Give feedback.
-
Adding 24bit support to all the other drivers is out of scope. They should simply fail. This table could be extended to include the supported options.
No. I expect that other audio drivers might follow in the future with 24bit support (ALSA for instance), and I don't want to live with that silent float-to-int hack forever.
Thanks for the clarification! In this case however, I'd recommend the new option setting to be called I could support in adjusting the other audio drivers to fail with the new option, document it, or inventing the new synth rendering function. |
Beta Was this translation helpful? Give feedback.
-
|
Adding
Would you like me to open Issues for these four tasks? |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
I’d like to get feedback on a possible enhancement of the fluid_wasapi.c Windows driver to support 24-bit PCM in WASAPI exclusive mode when audio.sample-format is set to "float".
Background
The Miditzer is a theatre pipe organ emulation that supports real-time performance. In this context, latency—the time from pressing a key on a MIDI keyboard to hearing a corresponding sound—is very important. The addition of the Windows WASAPI driver is a very welcome improvement in FluidSynth for reducing latency.
WASAPI supports two modes, shared and exclusive. Shared mode presents the Windows Audio Engine (WAE) as a virtual audio device. It is an “omnivorous” device that accepts many audio formats from multiple applications and then resamples and mixes as necessary to deliver audio samples to the real audio DAC hardware. While this abstraction is convenient, it comes at a cost in latency. In a few tests on one mid-grade consumer laptop, latency in WASAPI shared mode was around 40 milliseconds, which is enough to be perceived as lag by a performer.
WASAPI exclusive mode talks directly to the audio hardware. This is a brittle interface: there is no translation of the audio samples provided by the driver, and the driver must supply samples in a format accepted by the hardware. The set of formats accepted by audio hardware is usually very limited. The fluidsynth -Q command can be used on a Windows machine to enumerate supported formats.
Issue
The issue we encountered when implementing FluidSynth’s WASAPI exclusive mode in the Miditzer is that, on most audio hardware, we are effectively limited to using "16bits" as the audio.sample-format setting. In shared mode we can use "float" to provide the full precision of FluidSynth’s synthesizer output to the WAE, which can then resample and deliver 24-bit samples to the audio hardware if configured appropriately. With the current limitations of the FluidSynth WASAPI driver, we can reduce latency by using exclusive mode, but at the potential cost of reduced output precision. As it stands, we can offer two options in the Miditzer:
(high and low are used here in a relative sense; both latency and quality are good in absolute terms)
At a hardware level, DACs are fixed-point devices. Any “float” audio path must be converted to fixed-point somewhere before being presented to the analog conversion hardware. From that perspective, 24-in-32 PCM is a hardware realization of “float” intent: full-scale linear PCM with more resolution than the analog noise floor. Recognition of IEEE float format by audio hardware has no direct analog meaning at the DAC interface.
In exclusive mode, many audio devices reject IEEE float formats but accept high-resolution PCM (commonly 24-bit PCM in a 32-bit container). When audio.sample-format=float is requested, this can cause exclusive-mode initialization to fail, even though the hardware is capable of full-resolution, low-latency output.
Proposal
I propose enhancing fluid_wasapi.c so that, in WASAPI exclusive mode, a request for audio.sample-format="float" may be realized using a 24-in-32 PCM format when IEEE float is not accepted but higher-resolution PCM is supported by the selected device. This behavior would apply only to WASAPI exclusive mode and would not affect shared mode behavior.
Questions
Would such an enhancement align with FluidSynth’s design goals?
Are there other commonly supported hardware formats that should be considered in addition to 24-in-32 PCM for realizing float-quality output?
Should fluidsynth -Q report exclusive-mode float support realized via 24-bit PCM simply as float support (as it does now), or should this distinction be reported explicitly?
I believe I can provide an implementation of the enhancement I’m proposing.
Thanks for any thoughts.
Beta Was this translation helpful? Give feedback.
All reactions