Uploaded image for project: 'Qt'
  1. Qt
  2. QTBUG-55630

[WinRT] WASAPI implementation issues

    XMLWordPrintable

Details

    • Bug
    • Resolution: Won't Do
    • P2: Important
    • None
    • 5.7.0
    • Multimedia
    • None
    • Xbox One, any WinRT/UWP device with audio device set to surround output
    • WinRT
    • 462ed1af764603e1422664e51f4d83ded3fec7d1

    Description

      Tracking down WASAPI plugin issues I found 3 issues, 2 minor and one major.

      In QWasapiAudioDeviceInfo there is a minor typo 160000 instead of 16000, fairly insignificant except maybe for some low rate capture devices.

      --- a/qwasapiaudiodeviceinfo.cpp
      +++ b/qwasapiaudiodeviceinfo.cpp
      @@ -54,7 +54,7 @@
       
           QAudioFormat referenceFormat = m_interface->m_mixFormat;
       
      -    const int rates[] = {8000, 11025, 160000, 22050, 32000, 44100, 48000, 88200, 96000, 192000};
      +    const int rates[] = {8000, 11025, 16000, 22050, 32000, 44100, 48000, 88200, 96000, 192000};
           for (int rate : rates) {
               QAudioFormat f = referenceFormat;
               f.setSampleRate(rate);
      

      In QWasapiAudioOutput microseconds are incorrectly converted to 100-nanosecond units by multiplying by 100 instead of 10. This can be worked around by passing 1/10th of the buffer size to QAudioOutput::setBufferSize(), ugly but works.

      --- a/qwasapiaudiooutput.cpp
      +++ b/qwasapiaudiooutput.cpp
      @@ -303,7 +303,7 @@
       
           REFERENCE_TIME t = ((10000.0 * 10000 / nFmt.nSamplesPerSec * 1024) + 0.5);
           if (m_bufferBytes)
      -        t = m_currentFormat.durationForBytes(m_bufferBytes) * 100;
      +        t = m_currentFormat.durationForBytes(m_bufferBytes) * 10;
       
           DWORD flags = pull ? AUDCLNT_STREAMFLAGS_EVENTCALLBACK : 0;
           hr = m_interface->m_client->Initialize(AUDCLNT_SHAREMODE_SHARED, flags, t, 0, &nFmt, NULL);
      

      Final issue and the one that can not be worked around easily is that it doesn't support more than 2 channels. When the mix device is 2.1, 5.1, 7.1, etc.. then wFormatTag becomes WAVE_FORMAT_EXTENSIBLE and that is not handled correctly at all.

      Parsing/checking for PCM/float has to be done in some way similiar to this (taken from here):

          if ( (wfx->wFormatTag == WAVE_FORMAT_PCM) ||
               (  (wfx->wFormatTag == WAVE_FORMAT_EXTENSIBLE) &&
                  (reinterpret_cast<WAVEFORMATEXTENSIBLE *>(wfx)->SubFormat == KSDATAFORMAT_SUBTYPE_PCM) ) )
          {
              // ...
          }
          else if ( (wfx->wFormatTag == WAVE_FORMAT_IEEE_FLOAT) ||
                    ( (wfx->wFormatTag == WAVE_FORMAT_EXTENSIBLE) &&
                      (reinterpret_cast<WAVEFORMATEXTENSIBLE *>(wfx)->SubFormat == KSDATAFORMAT_SUBTYPE_IEEE_FLOAT) ) )
          {
              // ...
          }
      

      Similiary when converting back from QAudioFormat with more than 2 channels a WAVEFORMATEXTENSIBLE struct must be used and channel mapping set.

      This can be worked around on desktop by changing the device mode to stereo (not very desirable), but for things like Xbox One that always has 8 channels WASAPI plugin simply doesn't work there.

      I'm not sure yet what needs fixing for the WAVEFORMATEXTENSIBLE handling, but seems like a minimal fix might just be restricted to QWasapiUtils::convertToNativeFormat and QWasapiUtils::convertFromNativeFormat.

      It would be nice to be able to feed it stereo and have it setup stereo automatically mapping if possible, but I'd be just be very happy to be able to output any sound even if I have to do stereo to multiple channels myself.

      Attachments

        For Gerrit Dashboard: QTBUG-55630
        # Subject Branch Project Status CR V

        Activity

          People

            owolff Oliver Wolff
            kristjanbb Kristján Birgisson
            Votes:
            1 Vote for this issue
            Watchers:
            3 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved:

              Gerrit Reviews

                There are no open Gerrit changes