Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. [SOLVED] QAudioOutput playback doesn't work on OSX
Forum Updated to NodeBB v4.3 + New Features

[SOLVED] QAudioOutput playback doesn't work on OSX

Scheduled Pinned Locked Moved General and Desktop
10 Posts 2 Posters 4.5k Views 1 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.
  • M Offline
    M Offline
    mcallegari79
    wrote on last edited by
    #1

    Hi again, this is my third post about a QtMultimedia issue. I'm afraid to say it's really painful to use it.
    This time I've found that a method working fine on Linux and Windows, doesn't work on OSX.
    I'm using Qt 5.2.1 on OSX 10.8.1

    Here it is:
    @
    bool AudioRendererQt::initialize(quint32 freq, int chan, AudioFormat format)
    {
    QAudioDeviceInfo audioDevice = QAudioDeviceInfo::defaultOutputDevice();
    m_format.setChannelCount(chan);
    m_format.setSampleRate(freq);
    m_format.setCodec("audio/pcm");

    switch (format)
    {
    case PCM_S8:
        m_format.setSampleSize(8);
        m_format.setSampleType(QAudioFormat::UnSignedInt);
        break;
    case PCM_S16LE:
        m_format.setSampleSize(16);
        m_format.setSampleType(QAudioFormat::SignedInt);
        m_format.setByteOrder(QAudioFormat::LittleEndian);
        break;
    case PCM_S24LE:
        m_format.setSampleSize(24);
        m_format.setSampleType(QAudioFormat::SignedInt);
        m_format.setByteOrder(QAudioFormat::LittleEndian);
        break;
    case PCM_S32LE:
        m_format.setSampleSize(32);
        m_format.setSampleType(QAudioFormat::SignedInt);
        m_format.setByteOrder(QAudioFormat::LittleEndian);
        break;
    default:
        qWarning("AudioRendererQt: unsupported format detected");
        return false;
    }
    
    if (!audioDevice.isFormatSupported(m_format))
    {
        qWarning() << "Default format not supported - trying to use nearest";
        m_format = audioDevice.nearestFormat(m_format);
        qDebug() << "New format:" << m_format.sampleRate() << m_format.channelCount() << m_format.sampleSize();
    }
    
    m_audioOutput = new QAudioOutput(audioDevice, m_format, this);
    
    if( m_audioOutput == NULL )
    {
        qWarning() << "Cannot open audio output stream from device" <&lt; audioDevice.deviceName();
        return false;
    }
    
    m_audioOutput-&gt;setBufferSize(8192 * 4);
    m_output = m_audioOutput->start();
    
    if( m_audioOutput->error() != QAudio::NoError )
    {
        qDebug() << "Error in starting QAudioOutput";
        return false;
    }
    
    return true;
    

    }
    @

    Even if I try to play an audio file with sample rate 44.1Khz, 2 channels, 16 bit (very standard), OSX falls into a non supported format.
    When it tries to use the nearest format, the method gets stuck (I don't see the debug message after it)

    Anyone has a clue ?

    Thanks

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

      Hi,

      Can you post a code sample that shows the behavior ?

      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
      • M Offline
        M Offline
        mcallegari79
        wrote on last edited by
        #3

        The code is in my post

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

          But it's not self-contained, so a rewrite is needed in order to try to reproduce your problem so the initial conditions are not the same and the failure might not occur.

          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
          • M Offline
            M Offline
            mcallegari79
            wrote on last edited by
            #5

            Have had a deeper look into this and it seems to be a deployment issue.
            The code above works fine if it's not bundled or if it is bundled with macdeployqt (which is the most inefficient tool I've ever seen: a 42MB DMG for a 50 lines app !)

            Unfortunately I still haven't figured how to correctly deploy QtMultimedia 5.3.2 and plugins on OSX. It's a nightmare.
            No errors, nothing at all to understand what I'm missing.
            The documentation is as well inappropriate. It still refers to Qt4 even if it's in the Qt5 docs:
            http://qt-project.org/doc/qt-5/macosx-deployment.html

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

              Depending on what your application uses e.g. network + multimedia + widgets + gui and there you have the size.

              Compare the plugins/mediaservice content of your bundle with the plugins/mediaservice in your Qt installation. Do they contain the same libraries ?

              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
              • M Offline
                M Offline
                mcallegari79
                wrote on last edited by
                #7

                @SGaist: 42 megs was referring to the self-contained 50-lines-code example + macdeployqt. If you like I can share it here later.

                My application (http://qlcplus.sourceforge.net/) is much more complex. It uses a lot of Qt libraries and on Qt4 it deploys in a DMG around 18megs.
                The thing is that the deployment is done "manually" via nametool commands in the .pro files.
                What I haven't able to figure out is how to include the Qt5 multimedia plugins. They are all there and they get copied in the right folder but it seems they're not loaded at runtime once bundled in a DMG.

                On the other hand, the Qt5 platform plugin (which is mandatory otherwise the app wouldn't even start) is correctly bundled and loaded.

                I'm getting crazy to figure this out. Seems I'm missing something but I don't understand what.

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

                  Did you check the paths of the multimedia plugins using otool -L ?

                  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
                  • M Offline
                    M Offline
                    mcallegari79
                    wrote on last edited by
                    #9

                    I solved it. You couldn't believe what it was.
                    Basically, in my code the "initialize" method and the "writeAudio" method are called from different threads.
                    This works fine on Linux and Windows, but not on OSX.
                    It seems that when you create a QAudioOutput and start it, the underneath platform code (CoreAudio) stores somewhere a reference to the thread that created the object. So any data pushed from a different thread is simply ignored or not processed.

                    The workaround is simple, even if it took months to figure it out.
                    I just need to push some empty data right after the QAudioOutput creation:
                    m_output->write(QByteArray(2048, 0));

                    Now, I tried different amount of data and I don't really know how much is needed for this to work. Surely pushing just 1 byte doesn't work.

                    This is absolutely ridiculous for two reasons:
                    1- there is no cross platform compatibility
                    2- there is no explanation at all for this behavior. All that I've written before it's just my guessing.

                    I'd appreciate if someone can give any sense to this.

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

                      Multithreading is one complex piece that changes for each platform.

                      One of the important thing is thread affinity, like e.g. GUI operation: they can only happen in the GUI thread which is generally the application main thread. Or the QTimer and QTcpSocket class which affinity must be with the same thread that uses them e.g. using moveToThread

                      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

                      • Login

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