Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. Qt Multimedia
  4. qt6 QMediaDevices::audioInputs() does not return all input devices
Forum Updated to NodeBB v4.3 + New Features

qt6 QMediaDevices::audioInputs() does not return all input devices

Scheduled Pinned Locked Moved Unsolved Qt Multimedia
11 Posts 4 Posters 273 Views 3 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • R Offline
    R Offline
    radiogeek381
    wrote last edited by
    #1

    I used the example programs from .../qt6/examples/multimedia/audiodevices and consistently find that the QMediaDevices method that replaced the qt5 QAudioDeviceInfo method returns just one device.

    This is not the case for the audio devices example from ..../qt5/examples/multimemdia/audiodevices .

    The problem occurs with both Fedora 42 and Fedora 43. The version in question is
    Fedora 42:

    > qmake6 --version
    QMake version 3.1
    Using Qt version 6.9.3 in /usr/lib64
    

    Fedora 43:

    $ qmake6 --version
    QMake version 3.1
    Using Qt version 6.10.1 in /usr/lib64
    

    So, what am I missing here? (I looked through the forums and was unable to find an earlier report of this issue. If there is one, please point me there.)

    matt

    1 Reply Last reply
    0
    • R Offline
      R Offline
      radiogeek381
      wrote last edited by
      #2

      It was rude of my not to include some code. Here is the relevant snippet from the qt6 example:

      void AudioTest::updateAudioDevices()
      {
          deviceBox->clear();
          const auto devices =
                  m_mode == QAudioDevice::Input ? m_devices->audioInputs() : m_devices->audioOutputs();
          for (auto &deviceInfo : devices) {
              QString description = deviceInfo.description();
              description.replace(u"\n"_s, u" - "_s);
              deviceBox->addItem(description, QVariant::fromValue(deviceInfo));
          }
      }
      
      1 Reply Last reply
      0
      • SGaistS Offline
        SGaistS Offline
        SGaist
        Lifetime Qt Champion
        wrote last edited by
        #3

        Hi and welcome to devnet,

        What is your audio software stack ?
        Can you show the output your get on each of them ?

        Interested in AI ? www.idiap.ch
        Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

        1 Reply Last reply
        0
        • R Offline
          R Offline
          radiogeek381
          wrote last edited by
          #4

          Thanks for the response.

          I'm not quite sure how to answer the question - I've always been a bit confused wrt Linux audio. So this might be more information than is needed...

          The stack: I believe the answer is "pipewire" though pulse-audio is in there somewhere.

          But the qt6 version dumps some disturbing chatter to stdout:

          qt.multimedia.ffmpeg: Using Qt multimedia with FFmpeg version 7.1.2 GPL version 3 or later
          Failed to open VDPAU backend libvdpau_nvidia.so: cannot open shared object file: No such file or directory
          libva info: VA-API version 1.22.0
          libva info: Trying to open /usr/lib64/dri-nonfree/iHD_drv_video.so
          libva info: Trying to open /usr/lib64/dri-freeworld/iHD_drv_video.so
          libva info: Trying to open /usr/lib64/dri/iHD_drv_video.so
          libva info: Found init function __vaDriverInit_1_22
          libva info: va_openDriver() returns 0
          libva info: VA-API version 1.22.0
          libva info: Trying to open /usr/lib64/dri-nonfree/iHD_drv_video.so
          libva info: Trying to open /usr/lib64/dri-freeworld/iHD_drv_video.so
          libva info: Trying to open /usr/lib64/dri/iHD_drv_video.so
          libva info: Found init function __vaDriverInit_1_22
          libva info: va_openDriver() returns 0
          

          I know that pulse is involved as I set up a couple of virtual devices like this:

          pactl load-module module-null-sink sink_name=RSink sink_properties=device.description="RadioSink"
          pactl load-module module-null-sink sink_name=MSink sink_properties=device.description="ModemSink"
          

          (These are to provide paths between a modem inside one app (wsjtx) and an SDR running in a separate process.)

          I modified both example programs to write directly to the qInfo stream:
          qt6 version:

          const auto devices =
                      m_mode == QAudioDevice::Input ? m_devices->audioInputs() : m_devices->audioOutputs();
              for (auto &deviceInfo : devices) {
                  QString description = deviceInfo.description();
                  description.replace(u"\n"_s, u" - "_s);
                  deviceBox->addItem(description, QVariant::fromValue(deviceInfo));
          	qInfo() << QString("audio device [%1] from audio%2()")
          	  .arg(description)
          	  .arg((m_mode == QAudioDevice::Input) ? "Inputs" : "Outputs")
          	  ;
              }
          

          which produces this output:

          ""
          "audio device [Built-in Audio Analog Stereo] from audioOutputs()"
          "audio device [RadioSink] from audioOutputs()"
          "audio device [ModemSink] from audioOutputs()"
          "audio device [NoMachine Output] from audioOutputs()"
          ""
          "audio device [Remapped nx_voice_out] from audioInputs()"
          ""
          

          The qt5 version looks like this:

          const QAudio::Mode mode = idx == 0 ? QAudio::AudioInput : QAudio::AudioOutput;
             for (auto &deviceInfo: QAudioDeviceInfo::availableDevices(mode)) {
                 deviceBox->addItem(deviceInfo.deviceName(), QVariant::fromValue(deviceInfo));
             qInfo() << QString("audio device [%1] from QAudioDeviceInfo::availableDevices(QAudio::Audio%2)")
               .arg(deviceInfo.deviceName())
               .arg((mode == 0) ? "Input" : "Output")
               ;
             }
          

          and I get this for the output:

          QSocketNotifier: Can only be used with threads started with QThread
          "audio device [pipewire] from QAudioDeviceInfo::availableDevices(QAudio::AudioInput)"
          "audio device [default] from QAudioDeviceInfo::availableDevices(QAudio::AudioInput)"
          "audio device [sysdefault:CARD=PCH] from QAudioDeviceInfo::availableDevices(QAudio::AudioInput)"
          "audio device [front:CARD=PCH,DEV=0] from QAudioDeviceInfo::availableDevices(QAudio::AudioInput)"
          "audio device [nx_remapped_out] from QAudioDeviceInfo::availableDevices(QAudio::AudioInput)"
          "audio device [alsa_output.pci-0000_00_1f.3.analog-stereo.monitor] from QAudioDeviceInfo::availableDevices(QAudio::AudioInput)"
          "audio device [RSink.monitor] from QAudioDeviceInfo::availableDevices(QAudio::AudioInput)"
          "audio device [MSink.monitor] from QAudioDeviceInfo::availableDevices(QAudio::AudioInput)"
          "audio device [nx_voice_out.monitor] from QAudioDeviceInfo::availableDevices(QAudio::AudioInput)"
          qt.qpa.wayland: Wayland does not support QWindow::requestActivate()
          "audio device [pipewire] from QAudioDeviceInfo::availableDevices(QAudio::AudioOutput)"
          "audio device [default] from QAudioDeviceInfo::availableDevices(QAudio::AudioOutput)"
          "audio device [sysdefault:CARD=PCH] from QAudioDeviceInfo::availableDevices(QAudio::AudioOutput)"
          "audio device [front:CARD=PCH,DEV=0] from QAudioDeviceInfo::availableDevices(QAudio::AudioOutput)"
          "audio device [surround21:CARD=PCH,DEV=0] from QAudioDeviceInfo::availableDevices(QAudio::AudioOutput)"
          "audio device [surround40:CARD=PCH,DEV=0] from QAudioDeviceInfo::availableDevices(QAudio::AudioOutput)"
          "audio device [surround41:CARD=PCH,DEV=0] from QAudioDeviceInfo::availableDevices(QAudio::AudioOutput)"
          "audio device [surround50:CARD=PCH,DEV=0] from QAudioDeviceInfo::availableDevices(QAudio::AudioOutput)"
          "audio device [surround51:CARD=PCH,DEV=0] from QAudioDeviceInfo::availableDevices(QAudio::AudioOutput)"
          "audio device [surround71:CARD=PCH,DEV=0] from QAudioDeviceInfo::availableDevices(QAudio::AudioOutput)"
          "audio device [hdmi:CARD=PCH,DEV=0] from QAudioDeviceInfo::availableDevices(QAudio::AudioOutput)"
          "audio device [hdmi:CARD=PCH,DEV=1] from QAudioDeviceInfo::availableDevices(QAudio::AudioOutput)"
          "audio device [hdmi:CARD=PCH,DEV=2] from QAudioDeviceInfo::availableDevices(QAudio::AudioOutput)"
          "audio device [hdmi:CARD=PCH,DEV=3] from QAudioDeviceInfo::availableDevices(QAudio::AudioOutput)"
          "audio device [alsa_output.pci-0000_00_1f.3.analog-stereo] from QAudioDeviceInfo::availableDevices(QAudio::AudioOutput)"
          "audio device [RSink] from QAudioDeviceInfo::availableDevices(QAudio::AudioOutput)"
          "audio device [MSink] from QAudioDeviceInfo::availableDevices(QAudio::AudioOutput)"
          "audio device [nx_voice_out] from QAudioDeviceInfo::availableDevices(QAudio::AudioOutput)"
          

          (Sorry for the monster blobs...)

          So. The qt5 operations do what I expect.

          I don't believe the problem comes from the virtual MSink and RSink devices.
          The complaint about the VDPAU backend may be a hint. I've been unable to figure out where it comes from. I don't have any nVidia hardware on this box.

          I'm building the dev branch from the git sources now. I'll see if a new built-from-source version has the same lib...nvidia problem. That'll take a while, it may take until the weekend.

          Thank you for your help.

          Is there more information I can provide.? I apologize for the lack of linux audio sophistication.

          1 Reply Last reply
          0
          • R Offline
            R Offline
            radiogeek381
            wrote last edited by
            #5

            I repeated the experiment with a build-from-git dev branch reporting "3.31.6" as the version. ( git hash e98fab4c4edfa49debfab549a81862922c0b52e8 )

            The results were identical to the earlier experiment. I did get this warning, however:

            build> ./audiodevices
            No QtMultimedia backends found. Only QMediaDevices, QAudioDevice, QSoundEffect, QAudioSink, and QAudioSource are available.
            

            (I built the Qt library and the test app after installing ffmpeg-free-devel. Though it doesn't appear to be referenced by the app or any of the lib files:

            build> ldd ~/exp/qt6/root/lib/lib*.so  | grep -i ffmpeg
            build>
            

            )

            I built with DEBUG support on. Is there something that you'd like me to try? A particular place to poke around?

            1 Reply Last reply
            0
            • SGaistS Offline
              SGaistS Offline
              SGaist
              Lifetime Qt Champion
              wrote last edited by
              #6

              Qt 5 uses GStreamer as backend on Linux while Qt 6 now uses ffmpeg by default. This is the main difference.
              It's strange that QtMultimedia did not build the ffmpeg backend.
              What are you getting from the configuration step output ?

              Interested in AI ? www.idiap.ch
              Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

              1 Reply Last reply
              0
              • R Offline
                R Offline
                radiogeek381
                wrote last edited by
                #7

                I've tried multiple schemes and configurations.
                In answer to no question at all: I've created a GitHub repo with a reproducer (scripts and source and a README) for the problem I'm having.

                git@github.com:kb1vc/qt_multimedia_audio_problem.git

                In answer to your last question:

                Building Qt6.10.1 under Fedora43 I see this mention of FFmpeg in the configure log:

                CMake Warning at qtmultimedia/src/plugins/multimedia/ffmpeg/cmake/QtAddFFmpegStubs.cmake:38 (message):
                  QT_FEATURE_vaapi is ON but FFmpeg includes VAAPI and dynamic symbols
                  resolve is enabled.
                Call Stack (most recent call first):
                  qtmultimedia/src/plugins/multimedia/ffmpeg/cmake/QtAddFFmpegStubs.cmake:189 (qt_internal_multimedia_check_ffmpeg_stubs_configuration)
                  qtmultimedia/src/plugins/multimedia/ffmpeg/CMakeLists.txt:107 (qt_internal_multimedia_add_ffmpeg_stubs)
                

                I'm not sure what that means, but I'll try another run of the configure command:
                Adding -DQT_FEATURE_vaapi=OFF got rid of the warning.

                The configure completed without warning. And the build completed.

                The result of the test program was still not right -- the inputs list was missing almost all the loopback devices, and the one it found (setup by pw-loopback) was named incorrectly.

                1 Reply Last reply
                0
                • R Offline
                  R Offline
                  radiogeek381
                  wrote last edited by
                  #8

                  I found the difference. In Qt 6.10.1

                  eab27c5cbd src/multimedia/pulseaudio/qaudioengine_pulse.cpp          (Mikko Hallamaa    2024-03-22 16:47:14 +0100 257)     }
                  ^2a34e88c1 src/plugins/pulseaudio/qpulseaudioengine.cpp              (Michael Goddard   2011-06-29 13:38:46 +1000 258) 
                  85e2f9712f src/multimedia/platform/pulseaudio/qaudioengine_pulse.cpp (Lars Knoll        2021-01-13 15:39:29 +0100 259)     // skip monitor channels
                  85e2f9712f src/multimedia/platform/pulseaudio/qaudioengine_pulse.cpp (Lars Knoll        2021-01-13 15:39:29 +0100 260)     if (info->monitor_of_sink != PA_INVALID_INDEX)
                  85e2f9712f src/multimedia/platform/pulseaudio/qaudioengine_pulse.cpp (Lars Knoll        2021-01-13 15:39:29 +0100 261)         return;
                  7b75983575 src/multimedia/pulseaudio/qaudioengine_pulse.cpp          (Artem Dyomin      2023-06-07 14:46:36 +0200 262)
                  

                  Qt5 lists the monitor devices. Ignoring monitor devices means that devices created like this:

                  pactl load-module module-null-sink sink_name=RadioOutput sink_properties=device.description="RadioOutput"
                  

                  Used to show up as "RadioOutput.monitor" from QAudioDeviceInfo::availableDevices(Audio::AudioInput).

                  This created a sink device called "RadioOutput" where the radio would send its output audio stream. The modem would listen on "RadioOutput.monitor."

                  The workaround is to use the pact remap module

                  pactl load-module module-remap-source master=RadioOutput.monitor source_name="FromRadio" source_properties=device.description=FromRadio
                  

                  in addition to the module-null-sink step.

                  This still leaves the question as to why Qt6 wants to ignore monitor devices? This breaks backward compatibility at the user level.

                  From what I can tell, this was introduced in v6.4.0 in src/multimedia/platform/pulseaudio/qaudioengine_pulse.cpp

                  As a workaround, (or adapting to the new reality) I've changed my loopback creator script to:

                  pactl load-module module-null-sink sink_name=RadioOutput \
                        sink_properties=device.description="RadioOutput"
                  pactl load-module module-null-sink sink_name=ModemOutput \
                        sink_properties=device.description="ModemOutput"
                  
                  pactl load-module module-remap-source master=RadioOutput.monitor \
                        source_name="FromRadio" source_properties=device.description=FromRadio
                  
                  pactl load-module module-remap-source master=ModemOutput.monitor \
                        source_name="FromModem" source_properties=device.description="FromModem"
                  

                  What is the Qt6 developer position on breaking backward application user level compatibility?

                  1 Reply Last reply
                  0
                  • aha_1980A Offline
                    aha_1980A Offline
                    aha_1980
                    Lifetime Qt Champion
                    wrote last edited by
                    #9

                    Hi @radiogeek381,

                    What is the Qt6 developer position on breaking backward application user level compatibility?

                    Note that this is a user forum. You may ask this question on the development mailing list or create a bugreport about this. You can find links to both in my link collection.

                    Regards

                    Qt has to stay free or it will die.

                    N 1 Reply Last reply
                    0
                    • R Offline
                      R Offline
                      radiogeek381
                      wrote last edited by
                      #10

                      aha_1980 Thank you. That will help.
                      I started here, rather than with a bug report, because I was pretty sure the problem was on my side. Despite my confidence in the previous note, I still don't have a solution - my experiments were against builds without PipeWire.

                      Thank you for the link collection. When I've got this a little more solid, I'll look at the development mailing list.

                      1 Reply Last reply
                      0
                      • aha_1980A aha_1980

                        Hi @radiogeek381,

                        What is the Qt6 developer position on breaking backward application user level compatibility?

                        Note that this is a user forum. You may ask this question on the development mailing list or create a bugreport about this. You can find links to both in my link collection.

                        Regards

                        N Offline
                        N Offline
                        NielsMayer
                        wrote last edited by NielsMayer
                        #11

                        @radiogeek381 said in qt6 QMediaDevices::audioInputs() does not return all input devices:

                        What is the Qt6 developer position on breaking backward application user level compatibility?

                        The position is they don't care:
                        https://qt-project.atlassian.net/browse/QTBUG-116015
                        https://qt-project.atlassian.net/browse/QTBUG-114846
                        https://qt-project.atlassian.net/browse/QTBUG-118766
                        https://qt-project.atlassian.net/browse/QTBUG-133298
                        https://qt-project.atlassian.net/browse/QTBUG-140658?focusedCommentId=2489187

                        Also on Linux , Qt6 no longer works (probably since 6.7) with QT_MEDIA_BACKEND=gstreamer environment-variable set to select the legacy media backend, in case FFMPEG isn't working for you.

                        1 Reply Last reply
                        0

                        • Login

                        • Login or register to search.
                        • First post
                          Last post
                        0
                        • Categories
                        • Recent
                        • Tags
                        • Popular
                        • Users
                        • Groups
                        • Search
                        • Get Qt Extensions
                        • Unsolved