# Enabling Windows Audio's SRC

**URL:** <https://forum.juce.com/t/enabling-windows-audios-src/41509>\
**Category:** Windows\
**Created:** [August 31, 2020, 4:18pm UTC](https://forum.juce.com/t/enabling-windows-audios-src/41509 "2020-08-31T16:18:50Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![yairadix](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/yairadix/32/1114_2.png) [@yairadix](https://forum.juce.com/u/yairadix)\
**Post date:** [August 31, 2020, 4:18pm UTC](https://forum.juce.com/t/enabling-windows-audios-src/41509/1 "2020-08-31T16:18:50Z")

</div>

Some audio devices, like Microsoft’s LifeChat LX-3000 USB handset, have different input and output sample rates (41.1k & 48k Hz in its case), and JUCE with Windows Audio (WASAPI) doesn’t support that.

But, since Windows 8 it seems that Windows Audio supports SRC, if you ask it to. So I made a [commit](https://github.com/soundradix/JUCE/commit/1162b8d1ec2542ced126f1d00a7e4ea075615395) to enable it. Seems to work 🙂 Many thanks to [PortAudio](http://www.portaudio.com/) whose source I looked at to discover the right Win API chants for this.

Feel free to use it (note that our `master` branch is JUCE 5 based, and there’s also a `juce6` branch available) and/or incorporate it into JUCE!

---

<div class="post-metadata">

**Author:** ![yairadix](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/yairadix/32/1114_2.png) [@yairadix](https://forum.juce.com/u/yairadix)\
**Post date:** [September 1, 2020, 7:09am UTC](https://forum.juce.com/t/enabling-windows-audios-src/41509/2 "2020-09-01T07:09:19Z")

</div>

From a quick search in the forum it looks like this issue is much more common than I thought (left a note in a few relevant threads)

---

<div class="post-metadata">

**Author:** ![ed95](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/ed95/32/7635_2.png) [@ed95](https://forum.juce.com/u/ed95)\
**Post date:** [September 4, 2020, 4:34pm UTC](https://forum.juce.com/t/enabling-windows-audios-src/41509/3 "2020-09-04T16:34:03Z")

</div>

Thanks for the patch! We’ve added this to `develop` in [b01e927](https://github.com/juce-framework/JUCE/commit/b01e9276ba1542417240d286698b265cdd318ada) with a few modifications -

- The `Audiosessiontypes.h` and `audioclient.h` headers aren’t required as we can do local declarations for the bits we need (as we do already). This also means we don’t need to bump the `WINNT` define.

- When querying supported sample rates, `IsFormatSupported()` can succeed with a nearest supported format so we need to check the sample rate of this if it is valid otherwise all sample rates will “succeed” even though they aren’t supported by the device.

- `AUDCLNT_STREAMOPTIONS_MATCH_FORMAT` isn’t required for SRC so we can remove the property setting.

- We need to add all supported input and output device sample rates to the `sampleRates` array.

Whilst poking around in the WASAPI code, we’ve also added support for low latency shared streams via the `IAudioClient3` interface in [6195a5a](https://github.com/juce-framework/JUCE/commit/6195a5ab60835363640ea13900cd4d6e79e8c431).

---

<div class="post-metadata">

**Author:** ![yairadix](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/yairadix/32/1114_2.png) [@yairadix](https://forum.juce.com/u/yairadix)\
**Post date:** [September 6, 2020, 1:52pm UTC](https://forum.juce.com/t/enabling-windows-audios-src/41509/4 "2020-09-06T13:52:13Z")

</div>

I tested your patch and it doesn’t seem to work here with my setup. It might be worth-while to hear whether it works on some setups and doesn’t for others.

To reproduce: Using Windows 10 here with the Microsoft LifeChat LX-3000 USB headset (which only supports 48000 Hz for earphones and 44100 for mic), running the JUCE DemoRunner and going to its preferences to choose audio devices, with my fix it previously offered both rates for either its input or output or both together, and with the new fix it works like it did before (can only pick input with its rate, output with its rate, and can’t pick them together).

This appears to be the culprit:

> [@ed95](#):
>
> `AUDCLNT_STREAMOPTIONS_MATCH_FORMAT` isn’t required for SRC so we can remove the property setting.

It seems like it is indeed required. [Bringing it back](https://github.com/soundradix/JUCE/commit/8cbdcbf1639c2dd31737728e8d3f1aba2eec42fe) fixes the issue!

I know that the Windows API chants can be mysterious and that it may be difficult to find how to actually enable something and the code may have some spurious stuff left. So I understand that you suspected that some of my changes are not required. But I did make an effort to only keep the bare-minimum actually required API chants.

---

<div class="post-metadata">

**Author:** ![ed95](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/ed95/32/7635_2.png) [@ed95](https://forum.juce.com/u/ed95)\
**Post date:** [September 6, 2020, 4:50pm UTC](https://forum.juce.com/t/enabling-windows-audios-src/41509/5 "2020-09-06T16:50:43Z")

</div>

No, I don’t think it’s required and the reason for removing in the commit is because I think it’s actually incorrect. When using `AUDCLNT_STREAMOPTIONS_MATCH_FORMAT` you are asking the audio engine to change its mix format (the underlying stream used for shared mode) to match the proposed format in the call to `Initialize()`, not to perform sample rate conversion between streams. This can cause `IsFormatSupported()` to fail with `AUDCLNT_E_UNSUPPORTED_FORMAT` if you are trying to open a device with a sample rate that the mix format doesn’t actually support (I’ve seen this happen with a headset that only supports 8kHz).

I think what we should be doing instead is always using the requested sample rate if SRC is available and enabled, instead of using the one suggested by `nearestFormat`. Can you see if the following change to `tryFormat()` works for your headset?

```auto
auto supportsSRC = supportsSampleRateConversion (deviceMode);

if (hr == S_FALSE
    && nearestFormat != nullptr
    && (format.Format.nSamplesPerSec == nearestFormat->nSamplesPerSec
        || supportsSRC))
{
    copyWavFormat (format, nearestFormat);

    if (supportsSRC)
    {
        format.Format.nSamplesPerSec = (DWORD) newSampleRate;
        format.Format.nAvgBytesPerSec = (DWORD) (format.Format.nSamplesPerSec * format.Format.nBlockAlign);
    }

    hr = S_OK;
}

CoTaskMemFree (nearestFormat);
return hr == S_OK;

```

---

<div class="post-metadata">

**Author:** ![yairadix](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/yairadix/32/1114_2.png) [@yairadix](https://forum.juce.com/u/yairadix)\
**Post date:** [September 7, 2020, 7:07am UTC](https://forum.juce.com/t/enabling-windows-audios-src/41509/6 "2020-09-07T07:07:51Z")

</div>

Your new patch does work with my setup. Thanks!

---

<div class="post-metadata">

**Author:** ![ed95](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/ed95/32/7635_2.png) [@ed95](https://forum.juce.com/u/ed95)\
**Post date:** [September 7, 2020, 3:32pm UTC](https://forum.juce.com/t/enabling-windows-audios-src/41509/7 "2020-09-07T15:32:35Z")

</div>

Great. That’s on develop now:

> <https://github.com/juce-framework/JUCE/commit/99b3d85fcc4df8f76501d215a32c4bb35f22adc9>

There’s also the change to `ComSmartPtr` which you suggested, so thanks for that!

> <https://github.com/juce-framework/JUCE/commit/54164fac3fdd4a6e35965e24f42d76ee281768f4>

---

<div class="post-metadata">

**Author:** ![yairadix](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/yairadix/32/1114_2.png) [@yairadix](https://forum.juce.com/u/yairadix)\
**Post date:** [September 7, 2020, 3:43pm UTC](https://forum.juce.com/t/enabling-windows-audios-src/41509/8 "2020-09-07T15:43:12Z")

</div>

Awesome, thanks for such a quick response!

---

<div class="post-metadata">

**Author:** ![dave96](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/dave96/32/8487_2.png) [@dave96](https://forum.juce.com/u/dave96)\
**Post date:** [October 2, 2020, 10:06am UTC](https://forum.juce.com/t/enabling-windows-audios-src/41509/9 "2020-10-02T10:06:28Z")

</div>

I missed the discussion on this new feature and it slipped in to one of our recent releases without me realising. However, there seems to be some issues with one user and being able to change sample rate/buffer size: [https://www.kvraudio.com/forum/viewtopic.php?f=22&t=553345](https://www.kvraudio.com/forum/viewtopic.php?f=22&t=553345)

Is this a known issue? I tried it in my Parallels VM and was able to change the buffer size for all “Windows Audio” device types so I don’t know if this problem is device specific.  
Anybody else seen this?

---

<div class="post-metadata">

**Author:** ![yairadix](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/yairadix/32/1114_2.png) [@yairadix](https://forum.juce.com/u/yairadix)\
**Post date:** [October 2, 2020, 10:25am UTC](https://forum.juce.com/t/enabling-windows-audios-src/41509/10 "2020-10-02T10:25:38Z")

</div>

> and in Low Latency Mode I can’t change the audio buffer size

- It’s not a regression because Low Latency Mode wasn’t available before. Can they change buffer sizes in the mode that did exist (“Windows Audio”)?
- IIUC it’s probably a limitation of Low Latency Mode

---

<div class="post-metadata">

**Author:** ![dave96](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/dave96/32/8487_2.png) [@dave96](https://forum.juce.com/u/dave96)\
**Post date:** [October 2, 2020, 10:28am UTC](https://forum.juce.com/t/enabling-windows-audios-src/41509/11 "2020-10-02T10:28:39Z")

</div>

Ok, I’ll double check if the buffer size is only fixed in “Low Latency” mode.

The sample rate does seem to be fixed in all “Windows Audio” modes though:

> There’s just one problem with this 11.1.21 Public Beta, I can’t change the sample rate anymore, it’s get stuck on 48000hz (in any option of “Windows Audio”)

That seems like a regression.

---

<div class="post-metadata">

**Author:** ![oxxyyd](https://avatars.discourse-cdn.com/v4/letter/o/e47c2d/32.png) [@oxxyyd](https://forum.juce.com/u/oxxyyd)\
**Post date:** [October 2, 2020, 3:56pm UTC](https://forum.juce.com/t/enabling-windows-audios-src/41509/12 "2020-10-02T15:56:22Z")

</div>

As far as I know, the sample rate of Windows Audio have always been fixed to whatever value is selected in the OS’ control panel for the particular audio device. In contrast to DirectSound where you can choose between more values (typically 44100, 48k, 88.2k, 96k etc).

The Audio buffer size however is stuck at 448 samples (10.2ms) in Windows Audio Low latency mode but selectable (in Juce control panel) in WA mode between 132 and 2018 samples. Hence I’ve never really understood why it’s called low latency… 🙂

(Windows 10 version 2004, Focusrite external and Realtec integrated audio)

---

<div class="post-metadata">

**Author:** ![dave96](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/dave96/32/8487_2.png) [@dave96](https://forum.juce.com/u/dave96)\
**Post date:** [October 2, 2020, 4:58pm UTC](https://forum.juce.com/t/enabling-windows-audios-src/41509/13 "2020-10-02T16:58:58Z")

</div>

> [@oxxyyd](#):
>
> As far as I know, the sample rate of Windows Audio have always been fixed to whatever value is selected in the OS’ control panel for the particular audio device

I don’t think that was the case. At least from this user he’s reporting in older Waveform version he was able to choose different sample rates.

As you say, what’s the point of “Low Latency” mode if the buffer size is fixed at 448?

---

<div class="post-metadata">

**Author:** ![oxxyyd](https://avatars.discourse-cdn.com/v4/letter/o/e47c2d/32.png) [@oxxyyd](https://forum.juce.com/u/oxxyyd)\
**Post date:** [October 2, 2020, 11:15pm UTC](https://forum.juce.com/t/enabling-windows-audios-src/41509/14 "2020-10-02T23:15:55Z")

</div>

I don’t know about Waveform, but as long as I can remember dealing with the Juce framework (\>6 years), I’ve never been able to change the sample rate for Windows Audio from inside the framework, e.g in the Juce demo. I guess it could depend on the actual hardware though, I`ve only used the it with four or five different audio devices.

---

<div class="post-metadata">

**Author:** ![dave96](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/dave96/32/8487_2.png) [@dave96](https://forum.juce.com/u/dave96)\
**Post date:** [October 5, 2020, 12:48pm UTC](https://forum.juce.com/t/enabling-windows-audios-src/41509/15 "2020-10-05T12:48:48Z")

</div>

I think it depends on hardware. Something has definitely changed recently though.  
In my tests with a Parallels VM:

**Pre Low-Latency**

 ![image](https://us1.discourse-cdn.com/flex026/uploads/juce/original/2X/4/45025f9de96e2f74aa7400b5733be201a1685ead.png)

**Post Low-Latency:**

 ![Screenshot 2020-10-05 at 13.40.47](https://us1.discourse-cdn.com/flex026/uploads/juce/original/2X/6/6368c772c92b80cd05cc3c49dbcd580088ffead4.png)

In pre-low-latency, if I try to change assign the input as well as the input I get an error that the devices don’t share a common sample rate. In post-low-latency I get the option to do so though, is this because JUCE or the Windows layer is doing some sample-rate-conversion now so this configuration is allowed?

In Exclusive mode I used to be able to change the sample rate but now I can’t.

* * *

It would be nice to get some clarification on exactly how this behaviour has changed, at least so I can pass it on to my users. At the moment it’s like I’ve removed some functionality.

---

<div class="post-metadata">

**Author:** ![yairadix](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/yairadix/32/1114_2.png) [@yairadix](https://forum.juce.com/u/yairadix)\
**Post date:** [October 5, 2020, 1:02pm UTC](https://forum.juce.com/t/enabling-windows-audios-src/41509/16 "2020-10-05T13:02:20Z")

</div>

What you see directly relates to the topic of this discussion, which is the important one for me.

Background: for some reasons there are many devices that have 48k output and 44.1k input and JUCE didn’t support using them before, and now with enabling WASAPI’s built-in SRC it does! IIUC this only affects the plain “Windows Audio” mode.  
Before, even if you implemented SRC yourself - JUCE wouldn’t support the audio because it only supports matching input and output sample rates. Now, you can use these devices with JUCE with WASAPI. Btw ASIO and macOS with the same devices (such as USB headsets) did work.

And the two additional recent changes to JUCE:

- Exclusive mode was previously enabled only if you set some defines
- Low latency mode is now also supported

---

<div class="post-metadata">

**Author:** ![dave96](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/dave96/32/8487_2.png) [@dave96](https://forum.juce.com/u/dave96)\
**Post date:** [October 5, 2020, 1:10pm UTC](https://forum.juce.com/t/enabling-windows-audios-src/41509/17 "2020-10-05T13:10:32Z")

</div>

Ok, thanks. That I understand.

But I don’t understand why my users now can’t change sample rate from JUCE for any of the Windows Audio device types. What has changed to disallow that and why?

Has anyone experience being able to change the sample rate in pre-low-latency builds on Windows before? I need to verify this behaviour before I go back to my user and tell them they were mistake, this was never possible.

In my experience, at least in “Exclusive Mode” I was able to change the sample rate:

 ![image](https://us1.discourse-cdn.com/flex026/uploads/juce/original/2X/a/abfc03c4ab49dca9d3a36d399c7b4e892744e24b.png)  
Even if this was doing SRC to show me these sample rates, why is it not doing it now with this addition of SRC?

---

<div class="post-metadata">

**Author:** ![yairadix](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/yairadix/32/1114_2.png) [@yairadix](https://forum.juce.com/u/yairadix)\
**Post date:** [October 5, 2020, 1:23pm UTC](https://forum.juce.com/t/enabling-windows-audios-src/41509/18 "2020-10-05T13:23:23Z")

</div>

> [@dave96](#):
>
> In my experience, at least in “Exclusive Mode” I was able to change the sample rate:

Cool, so you have a reproducing setup then!

I suggest to bisect to find when the regression was introduced. It could be that one of the two changes of enabling SRC and enabling low latency audio somehow did it. If for example it’s some flags related to SRC somehow tell Windows to stop configuring sample rate in exclusive mode, then the solution could be to not enable that flag in that mode.

---

<div class="post-metadata">

**Author:** ![ed95](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/ed95/32/7635_2.png) [@ed95](https://forum.juce.com/u/ed95)\
**Post date:** [October 5, 2020, 2:14pm UTC](https://forum.juce.com/t/enabling-windows-audios-src/41509/19 "2020-10-05T14:14:14Z")

</div>

Are you actually able to open an exclusive device and select one of the different sample rates? I think the line responsible for this behaviour change is here:

> <https://github.com/juce-framework/JUCE/blob/5f0706ec0e218f474b8955052c0838927e041714/modules/juce_audio_devices/native/juce_win32_WASAPI.cpp#L748>

Previously we were using the `SUCCEEDED` macro which will return true for anything other than `S_FALSE`, but the `IsFormatSupported` method can also return `AUDCLNT_E_UNSUPPORTED_FORMAT` for formats not supported in exclusive mode:

> **[IAudioClient::IsFormatSupported (audioclient.h) - Win32 apps](https://docs.microsoft.com/en-us/windows/win32/api/audioclient/nf-audioclient-iaudioclient-isformatsupported)**
>
> The IsFormatSupported method indicates whether the audio endpoint device supports a particular stream format.

---

<div class="post-metadata">

**Author:** ![dave96](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/dave96/32/8487_2.png) [@dave96](https://forum.juce.com/u/dave96)\
**Post date:** [October 5, 2020, 2:59pm UTC](https://forum.juce.com/t/enabling-windows-audios-src/41509/20 "2020-10-05T14:59:37Z")

</div>

Yeah, in pre-low-latency JUCE if I select the 8K sample rate it succeeds and playback sounds suitably low-fi.

I’d love to do bisecting and really drill in to this but I’ve got so much other stuff on my plate at the moment I don’t really have the time. I mainly just wanted to report a regression or at least get a statement about the new behaviour I can pas on to my users, even if the new behaviour has to stay.

[Next page](https://forum.juce.com/t/enabling-windows-audios-src/41509.md?page=2)
