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 504 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
    #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