Skip to content

Commit 00cfda7

Browse files
committedJun 23, 2019
Use the new PortAudio option to enable WASAPI Shared conversions.
This feature was introduced in PortAudio commit aa0748a5b59491ba2cfa9943825653cde6e1f748. It is enabled by default since that makes WASAPI Shared much easier to use; it can be disabled through the new FlexASIO wasapiAutoConvert option. Fixes #32.
1 parent c727ee9 commit 00cfda7

File tree

6 files changed

+71
-34
lines changed

6 files changed

+71
-34
lines changed
 

‎BACKENDS.md

+11-21
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,6 @@ wanting to optimize their audio pipeline. In particular, this document provides
66
the necessary information to understand what the [`backend`][backend] and
77
[`wasapiExclusiveMode`][wasapiExclusiveMode] FlexASIO configuration options do.
88

9-
**Note:** this document is a work in progress, and does not go into much detail
10-
regarding the specific differences between the backends. For now, you will have
11-
to experiment for yourself. Comments and suggestions are welcome.
12-
139
A `backend` is just another term for what PortAudio calls the *host API*.
1410
FlexASIO uses the term "backend" to avoid potential confusion with the term
1511
"ASIO host".
@@ -105,8 +101,9 @@ ms, if not more.
105101
For example, it might expose 8 channels for a 5.1 output, downmixing the rear
106102
channels pairs.
107103

108-
Modern versions of Windows implement the MME API by using WASAPI internally,
109-
making this backend a "second-class citizen" compared to WASAPI and WDM-KS.
104+
Modern versions of Windows implement the MME API by using WASAPI Shared
105+
internally, making this backend a "second-class citizen" compared to WASAPI and
106+
WDM-KS.
110107

111108
## DirectSound backend
112109

@@ -122,7 +119,7 @@ if that's really the case in practice. The DirectSound backend has been observed
122119
to [behave very poorly][issue29] with small buffer sizes on the input side,
123120
making it a poor choice for low-latency capture use cases.
124121

125-
Modern versions of Windows implement the DirectSound API by using WASAPI
122+
Modern versions of Windows implement the DirectSound API by using WASAPI Shared
126123
internally, making this backend a "second-class citizen" compared to WASAPI and
127124
WDM-KS.
128125

@@ -147,16 +144,10 @@ used. The two modes behave very differently; in fact, they should probably be
147144
seen as two separate backends entirely.
148145

149146
In *shared* mode, WASAPI behaves similarly to MME and DirectSound, in that the
150-
audio goes through most of the normal Windows audio pipeline. One important
151-
limitation of this mode is that there is no sample rate conversion. Therefore,
152-
initialization will fail if the application sample rate is different from the
153-
sample rate of the input or output devices, as configured in the Windows sound
154-
settings. (Corollary: if the input and output devices are configured with
155-
different sample rates in Windows, WASAPI Shared won't work, period.) There is
156-
also no support for upmixing nor downmixing; the channel counts must match
157-
exactly. These limitations [are inherent to WASAPI itself][wasapisr]. It is
158-
reasonable to assume that this mode will provide the best possible latency for
159-
a shared backend.
147+
audio goes through most of the normal Windows audio pipeline. Indeed, in
148+
modern versions of Windows, MME and DirectSound are just thin wrappers
149+
implemented on top of WASAPI. For this reason it is reasonable to assume that
150+
this mode will provide the best possible latency for a shared backend.
160151

161152
In *exclusive* mode, WASAPI behaves completely differently and bypasses the
162153
entirety of the Windows audio pipeline, including mixing and APOs. As a result,
@@ -220,9 +211,8 @@ Streaming.
220211
[wasapiExclusiveMode]: CONFIGURATION.md#option-wasapiExclusiveMode
221212
[Windows Audio Session API]: https://docs.microsoft.com/en-us/windows/desktop/coreaudio/wasapi
222213
[Windows Driver Model]: https://en.wikipedia.org/wiki/Windows_Driver_Model
223-
[wasapisr]: https://docs.microsoft.com/windows/desktop/CoreAudio/device-formats
224214
[WDM-KS issue]: https://github.com/dechamps/FlexASIO/issues/21
225215

226-
<!-- Use the converter at http://http://gravizo.com/ to recover the source code
227-
of this graph. -->
228-
[diagram]: https://g.gravizo.com/svg?digraph%20G%20%7B%0A%09rankdir%3D%22LR%22%0A%09style%3D%22dashed%22%0A%09fontname%3D%22sans-serif%22%0A%09node%5Bfontname%3D%22sans-serif%22%5D%0A%0A%09subgraph%20clusterApplicationProcess%20%7B%0A%09%09label%3D%22Application%20process%22%0A%0A%09%09Host%5Blabel%3D%22ASIO%20host%20application%22%5D%0A%0A%09%09subgraph%20clusterFlexASIO%20%7B%0A%09%09%09label%3D%22FlexASIO%22%0A%09%09%09FlexASIO%5Blabel%3D%22ASIO%20driver%22%5D%0A%0A%09%09%09subgraph%20clusterPortAudio%20%7B%0A%09%09%09%09label%3D%22PortAudio%22%0A%0A%09%09%09%09PortAudio%5Blabel%20%3D%20%22Frontend%22%5D%0A%09%09%09%09subgraph%20%7B%0A%09%09%09%09%09rank%3D%22same%22%0A%09%09%09%09%09node%20%5Bcolor%3D%22red%22%3B%20penwidth%3D3%5D%0A%0A%09%09%09%09%09PortAudioMME%5Blabel%3D%22MME%22%5D%0A%09%09%09%09%09PortAudioDirectSound%5Blabel%3D%22DirectSound%22%5D%0A%09%09%09%09%09PortAudioWASAPI%5Blabel%3D%22WASAPI%22%5D%0A%09%09%09%09%09PortAudioWDMKS%5Blabel%3D%22WDM-KS%22%5D%0A%09%09%09%09%7D%0A%09%09%09%7D%0A%09%09%7D%0A%09%7D%0A%0A%09subgraph%20clusterWindows%20%7B%0A%09%09label%3D%22Windows%20audio%20subsystem%22%0A%09%09subgraph%20%7B%0A%09%09%09rank%3D%22same%22%0A%09%09%09MME%0A%09%09%09DirectSound%0A%09%09%09WASAPIShared%5Blabel%3D%22WASAPI%20(shared)%22%5D%0A%09%09%09WASAPIExclusive%5Blabel%3D%22WASAPI%20(exclusive)%22%5D%0A%09%09%09WDMKS%5Blabel%3D%22Kernel%20Streaming%22%5D%0A%09%09%7D%0A%0A%09%09SampleRateConversion%5Blabel%3D%22Sample%20rate%20conversion%22%5D%0A%09%09PreMix%5Blabel%3D%22Pre-mix%20APOs%22%5D%0A%09%09Mix%5Blabel%3D%22Mixing%22%5D%0A%09%09PostMix%5Blabel%3D%22Post-mix%20APOs%22%5D%0A%09%7D%0A%0A%09subgraph%20clusterHardware%20%7B%0A%09%09label%3D%22Audio%20hardware%22%0A%09%09HardwareDriver%5Blabel%3D%22Driver%22%5D%0A%09%09HardwareDevice%5Blabel%3D%22Device%22%5D%0A%09%7D%0A%0A%09Host-%3EFlexASIO%0A%09FlexASIO-%3EPortAudio%0A%0A%09PortAudio-%3E%7B%0A%09%09PortAudioMME%0A%09%09PortAudioDirectSound%0A%09%09PortAudioWASAPI%0A%09%09PortAudioWDMKS%0A%09%7D%0A%0A%09PortAudioMME-%3EMME%0A%09PortAudioDirectSound-%3EDirectSound%0A%09PortAudioWASAPI-%3EWASAPIShared%0A%09PortAudioWASAPI-%3EWASAPIExclusive%0A%09PortAudioWDMKS-%3EWDMKS%0A%0A%09MME-%3ESampleRateConversion%0A%09DirectSound-%3ESampleRateConversion%0A%09SampleRateConversion-%3EWASAPIShared%0A%09%0A%09WASAPIShared-%3EPreMix%0A%09WASAPIExclusive-%3EHardwareDriver%0A%09PreMix-%3EMix%0A%09Mix-%3EPostMix%0A%09PostMix-%3EHardwareDriver%0A%09%0A%09WDMKS-%3EHardwareDriver%0A%09%0A%09HardwareDriver-%3EHardwareDevice%0A%7D%0A
216+
<!-- Use the converter at http://gravizo.com/ to recover the source code of this
217+
graph. -->
218+
[diagram]: https://g.gravizo.com/svg?digraph%20G%20%7B%0A%09rankdir%3D%22LR%22%0A%09style%3D%22dashed%22%0A%09fontname%3D%22sans-serif%22%0A%09node%5Bfontname%3D%22sans-serif%22%5D%0A%0A%09subgraph%20clusterApplicationProcess%20%7B%0A%09%09label%3D%22Application%20process%22%0A%0A%09%09Host%5Blabel%3D%22ASIO%20host%20application%22%5D%0A%0A%09%09subgraph%20clusterFlexASIO%20%7B%0A%09%09%09label%3D%22FlexASIO%22%0A%09%09%09FlexASIO%5Blabel%3D%22ASIO%20driver%22%5D%0A%0A%09%09%09subgraph%20clusterPortAudio%20%7B%0A%09%09%09%09label%3D%22PortAudio%22%0A%0A%09%09%09%09PortAudio%5Blabel%20%3D%20%22Frontend%22%5D%0A%09%09%09%09subgraph%20%7B%0A%09%09%09%09%09rank%3D%22same%22%0A%09%09%09%09%09node%20%5Bcolor%3D%22red%22%3B%20penwidth%3D3%5D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20PortAudioMME%5Blabel%3D%22MME%22%5D%0A%09%09%09%09%09PortAudioDirectSound%5Blabel%3D%22DirectSound%22%5D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20PortAudioWASAPI%5Blabel%3D%22WASAPI%22%5D%0A%09%09%09%09%09PortAudioWDMKS%5Blabel%3D%22WDM-KS%22%5D%0A%09%09%09%09%7D%0A%09%09%09%7D%0A%09%09%7D%0A%09%7D%0A%0A%09subgraph%20clusterWindows%20%7B%0A%09%09label%3D%22Windows%20audio%20subsystem%22%0A%09%09subgraph%20%7B%0A%09%09%09rank%3D%22same%22%0A%09%09%09MME%0A%09%09%09DirectSound%0A%09%09%09%0A%09%09%7D%0A%09%09subgraph%20%7B%0A%09%09%09rank%3D%22same%22%0A%09%09%09WASAPIShared%5Blabel%3D%22WASAPI%20(shared)%22%5D%0A%09%09%09WASAPIExclusive%5Blabel%3D%22WASAPI%20(exclusive)%22%5D%0A%09%09%09WDMKS%5Blabel%3D%22Kernel%20Streaming%22%5D%0A%09%09%7D%0A%0A%09%09PreMix%5Blabel%3D%22Pre-mix%20APOs%22%5D%0A%09%09Mix%5Blabel%3D%22Mixing%22%5D%0A%09%09PostMix%5Blabel%3D%22Post-mix%20APOs%22%5D%0A%09%7D%0A%0A%09subgraph%20clusterHardware%20%7B%0A%09%09label%3D%22Audio%20hardware%22%0A%09%09HardwareDriver%5Blabel%3D%22Driver%22%5D%0A%09%09HardwareDevice%5Blabel%3D%22Device%22%5D%0A%09%7D%0A%0A%09Host-%3EFlexASIO%0A%09FlexASIO-%3EPortAudio%0A%0A%09PortAudio-%3E%7B%0A%09%09PortAudioMME%0A%09%09PortAudioDirectSound%0A%09%09PortAudioWASAPI%0A%09%09PortAudioWDMKS%0A%09%7D%0A%0A%09PortAudioMME-%3EMME%0A%09PortAudioDirectSound-%3EDirectSound%0A%09PortAudioWASAPI-%3EWASAPIShared%0A%09PortAudioWASAPI-%3EWASAPIExclusive%0A%09PortAudioWDMKS-%3EWDMKS%0A%0A%09MME-%3EWASAPIShared%0A%09DirectSound-%3EWASAPIShared%0A%09%0A%09WASAPIShared-%3EPreMix%0A%09WASAPIExclusive-%3EHardwareDriver%0A%09PreMix-%3EMix%0A%09Mix-%3EPostMix%0A%09PostMix-%3EHardwareDriver%0A%09%0A%09WDMKS-%3EHardwareDriver%0A%09%0A%09HardwareDriver-%3EHardwareDevice%0A%7D%0A

‎CONFIGURATION.md

+37
Original file line numberDiff line numberDiff line change
@@ -320,6 +320,42 @@ wasapiExclusiveMode = true
320320

321321
The default behaviour is to open the stream in *shared* mode.
322322

323+
#### Option `wasapiAutoConvert`
324+
325+
*Boolean*-typed option that determines if WASAPI Shared is allowed to convert
326+
the sample rate and channel count of the audio stream.
327+
328+
This option is ignored if the backend is not WASAPI. See the
329+
[`backend` option][backend]. Furthermore, it is only effective when WASAPI is
330+
used in *Shared mode*; WASAPI never converts *Exclusive mode* streams. See the
331+
[`wasapiExclusiveMode` option][wasapiExclusiveMode].
332+
333+
If set to `true`, WASAPI will automatically convert the stream's sample rate
334+
and channel count (upmixing/downmixing) if it doesn't match the *shared format*,
335+
i.e. the format configured in the Windows audio control panel for that device.
336+
337+
If set to `false`, WASAPI will not do any sample rate and channel count
338+
conversions and will only accept streams whose sample rate and channel count
339+
match the one configured in the Windows audio control panel for that device. If
340+
the sample rate or channel count don't match, FlexASIO will fail to initialize.
341+
Note that WASAPI Shared might still do additional processing besides sample rate
342+
and channel count conversion (e.g. sample format conversions, mixing, APOs).
343+
344+
Example:
345+
346+
```toml
347+
backend = "Windows WASAPI"
348+
349+
[output]
350+
wasapiAutoConvert = false
351+
```
352+
353+
The default behaviour is to allow conversions.
354+
355+
(Note: as explained in [BACKENDS][], in modern versions of Windows, DirectSound
356+
and MME use WASAPI Shared behind the scenes, and they implicitly enable the same
357+
automatic conversion mechanism as the one this option controls.)
358+
323359
[backend]: #option-backend
324360
[BACKENDS]: BACKENDS.md
325361
[bufferSizeSamples]: #option-bufferSizeSamples
@@ -334,3 +370,4 @@ The default behaviour is to open the stream in *shared* mode.
334370
[suggestedLatencySeconds]: #option-suggestedLatencySeconds
335371
[TOML]: https://en.wikipedia.org/wiki/TOML
336372
[WASAPI]: BACKENDS.md#wasapi-backend
373+
[wasapiExclusiveMode]: #option-wasapiExclusiveMode

‎FAQ.md

+13-13
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,18 @@ settings. Here are some common issues:
4040

4141
- **Invalid values for configuration options** (e.g. wrong type, typos in
4242
backend names or device names) will result in initialization failures.
43-
- **When using WASAPI Shared…**
43+
- **When using an exclusive backend (i.e. WASAPI Exclusive, WDM-KS)…**
44+
- The **sample rate** selected in the ASIO Host Application must be natively
45+
supported by the hardware audio device.
46+
- The **channel count** that FlexASIO is configured to use must be natively
47+
supported by the hardware audio device.
48+
- **WDM-KS will fail to initialize if the selected device is already in use**
49+
by any other application, even if no audio is actually playing. This means
50+
that WDM-KS is unlikely to initialize successfully on the Windows default
51+
devices; this can be worked around using the
52+
[`device` configuration option][device].
53+
- **When using WASAPI Shared with the [`wasapiAutoConvert` configuration
54+
option][wasapiAutoConvert] disabled…**
4455
- **Only one sample rate is supported**: the one configured in the Windows
4556
audio device settings for the input *and* output devices.
4657
- If the ASIO Host Application uses any other sample rate, FlexASIO will
@@ -52,17 +63,6 @@ settings. Here are some common issues:
5263
audio device settings for the selected device.
5364
- FlexASIO will fail to initialize if it is configured to use any other
5465
channel count.
55-
- These limitations are [inherent to WASAPI itself][wasapisr].
56-
- **When using an exclusive backend (i.e. WASAPI Exclusive, WDM-KS)…**
57-
- The **sample rate** selected in the ASIO Host Application must be natively
58-
supported by the hardware audio device.
59-
- The **channel count** that FlexASIO is configured to use must be natively
60-
supported by the hardware audio device.
61-
- **WDM-KS will fail to initialize if the selected device is already in use**
62-
by any other application, even if no audio is actually playing. This means
63-
that WDM-KS is unlikely to initialize successfully on the Windows default
64-
devices; this can be worked around using the
65-
[`device` configuration option][device].
6666
- A **FlexASIO (or PortAudio) bug**. If you believe that is the case, please
6767
[file a report][report].
6868
- In particular, please do file a report if FlexASIO fails to initialize with
@@ -231,4 +231,4 @@ wasapiExclusiveMode = true
231231
[report]: README.md#reporting-issues-feedback-feature-requests
232232
[sampleType]: CONFIGURATION.md#option-sampleType
233233
[suggestedLatencySeconds]: CONFIGURATION.md#option-suggestedLatencySeconds
234-
[wasapisr]: https://docs.microsoft.com/windows/desktop/CoreAudio/device-formats
234+
[wasapiAutoConvert]: CONFIGURATION.md#option-wasapiAutoConvert

‎src/flexasio/FlexASIO/config.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ namespace flexasio {
100100
SetOption(table, "sampleType", stream.sampleType);
101101
SetOption(table, "suggestedLatencySeconds", stream.suggestedLatencySeconds, ValidateSuggestedLatency);
102102
SetOption(table, "wasapiExclusiveMode", stream.wasapiExclusiveMode);
103+
SetOption(table, "wasapiAutoConvert", stream.wasapiAutoConvert);
103104
}
104105

105106
void SetConfig(const toml::Table& table, Config& config) {

‎src/flexasio/FlexASIO/config.h

+1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ namespace flexasio {
1515
std::optional<std::string> sampleType;
1616
std::optional<double> suggestedLatencySeconds;
1717
bool wasapiExclusiveMode = false;
18+
bool wasapiAutoConvert = true;
1819
};
1920
Stream input;
2021
Stream output;

‎src/flexasio/FlexASIO/flexasio.cpp

+8
Original file line numberDiff line numberDiff line change
@@ -521,6 +521,10 @@ namespace flexasio {
521521
if (config.input.wasapiExclusiveMode) {
522522
input_wasapi_stream_info.flags |= paWinWasapiExclusive;
523523
}
524+
Log() << (config.input.wasapiAutoConvert ? "Enabling" : "Disabling") << " auto-conversion for input WASAPI stream";
525+
if (config.input.wasapiAutoConvert) {
526+
input_wasapi_stream_info.flags |= paWinWasapiAutoConvert;
527+
}
524528
input_parameters.hostApiSpecificStreamInfo = &input_wasapi_stream_info;
525529
}
526530
}
@@ -545,6 +549,10 @@ namespace flexasio {
545549
if (config.output.wasapiExclusiveMode) {
546550
output_wasapi_stream_info.flags |= paWinWasapiExclusive;
547551
}
552+
Log() << (config.output.wasapiAutoConvert ? "Enabling" : "Disabling") << " auto-conversion for output WASAPI stream";
553+
if (config.output.wasapiAutoConvert) {
554+
output_wasapi_stream_info.flags |= paWinWasapiAutoConvert;
555+
}
548556
output_parameters.hostApiSpecificStreamInfo = &output_wasapi_stream_info;
549557
}
550558
}

0 commit comments

Comments
 (0)
Please sign in to comment.