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. QAudioDecoder Fails to start from a thread
Forum Updated to NodeBB v4.3 + New Features

QAudioDecoder Fails to start from a thread

Scheduled Pinned Locked Moved Unsolved General and Desktop
2 Posts 2 Posters 278 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.
  • D Offline
    D Offline
    DukeReddy
    wrote on last edited by
    #1

    Hello all,

    I have a weird issue with QAudioDecoder usage. When I call decoder->start() from a widget class (GUI) it works fine. bufferReady signal is emitted and it works fine.

    I wanted to decode multiple WAV file at once. So, I created a QThread inherited class to decode concurrently. The problem is that decoder->start() does not result in the start of decoding process.

    void AudioDecoder::run()
    {
        m_pDecoder = new QAudioDecoder();
        m_pDecoder->setSource(m_fileUrl);
    
        // m_pDecoder->moveToThread(this);
    
        qDebug () << connect(m_pDecoder, &QAudioDecoder::bufferReady, this, &AudioDecoder::BufferReady);
        qDebug () << connect(m_pDecoder, &QAudioDecoder::finished, this, &AudioDecoder::DecodingFinished);
        qDebug () << connect(m_pDecoder, QOverload<QAudioDecoder::Error>::of(&QAudioDecoder::error), this, &AudioDecoder::HandleDecodingError);
    
        while(1)
        {
            //! Block for a result to be updated.
            m_pSem->acquire();
    
            if(this->isInterruptionRequested())
            {
                return;
            }
    
            m_pDecoder->start();
    
            qInfo() << "Source: " << m_pDecoder->source();
            qInfo() << "Error: " << m_pDecoder->errorString();
        }
    }
    

    Output

    Source:  QUrl("file:///home/duke/Test/AudioSamples/Dummy/sample-s16-16k-256kbps.wav")
    Error:  ""
    

    But the slots that are connected are not called.

    void AudioDecoder::BufferReady()
    {
        LogOutput(LOG_DEBUG, "Buffer Ready");
        QAudioBuffer buffer = m_pDecoder->read();
    
        const quint16 *data = buffer.data<quint16>();
        m_decodedAudio.append((const char *)data, buffer.byteCount());
    
        qDebug() << "Decoded audio buffer ready, duration:" << buffer.duration() / 1000 << "ms";
        qDebug() << "Decoded audio buffer ready, position:" << m_pDecoder->position();
        qDebug() << "Decoded audio buffer ready, decodedBytes:" << m_decodedAudio.size();
    }
    

    Threaded class

    class AudioDecoder : public QThread
    {
        Q_OBJECT
    public:
        explicit AudioDecoder(QObject *parent = nullptr);
        ~AudioDecoder();
    ...
    ...
    

    This is how the threads are instantiated in the GUI.

    void AudioStreamWidget::DecodeAudioFiles()
    {
        StopAllThreads();
    
        foreach (QFileInfo fileInfo, m_fileInfoList)
        {
            AudioDecoder* pDecoder = new AudioDecoder(this);
            connect(pDecoder, &AudioDecoder::finished, this, &AudioStreamWidget::ThreadFinished);
    
            pDecoder->StartDecoding(fileInfo.absoluteFilePath());
            pDecoder->start(); //! Thread start
        }
    }
    

    Qt Version 6.5.1.

    I believe the issue is with how I am using the threaded class.
    Can anyone help me figure out the issue?

    Best regards,
    Duke

    Pl45m4P 1 Reply Last reply
    0
    • D DukeReddy

      Hello all,

      I have a weird issue with QAudioDecoder usage. When I call decoder->start() from a widget class (GUI) it works fine. bufferReady signal is emitted and it works fine.

      I wanted to decode multiple WAV file at once. So, I created a QThread inherited class to decode concurrently. The problem is that decoder->start() does not result in the start of decoding process.

      void AudioDecoder::run()
      {
          m_pDecoder = new QAudioDecoder();
          m_pDecoder->setSource(m_fileUrl);
      
          // m_pDecoder->moveToThread(this);
      
          qDebug () << connect(m_pDecoder, &QAudioDecoder::bufferReady, this, &AudioDecoder::BufferReady);
          qDebug () << connect(m_pDecoder, &QAudioDecoder::finished, this, &AudioDecoder::DecodingFinished);
          qDebug () << connect(m_pDecoder, QOverload<QAudioDecoder::Error>::of(&QAudioDecoder::error), this, &AudioDecoder::HandleDecodingError);
      
          while(1)
          {
              //! Block for a result to be updated.
              m_pSem->acquire();
      
              if(this->isInterruptionRequested())
              {
                  return;
              }
      
              m_pDecoder->start();
      
              qInfo() << "Source: " << m_pDecoder->source();
              qInfo() << "Error: " << m_pDecoder->errorString();
          }
      }
      

      Output

      Source:  QUrl("file:///home/duke/Test/AudioSamples/Dummy/sample-s16-16k-256kbps.wav")
      Error:  ""
      

      But the slots that are connected are not called.

      void AudioDecoder::BufferReady()
      {
          LogOutput(LOG_DEBUG, "Buffer Ready");
          QAudioBuffer buffer = m_pDecoder->read();
      
          const quint16 *data = buffer.data<quint16>();
          m_decodedAudio.append((const char *)data, buffer.byteCount());
      
          qDebug() << "Decoded audio buffer ready, duration:" << buffer.duration() / 1000 << "ms";
          qDebug() << "Decoded audio buffer ready, position:" << m_pDecoder->position();
          qDebug() << "Decoded audio buffer ready, decodedBytes:" << m_decodedAudio.size();
      }
      

      Threaded class

      class AudioDecoder : public QThread
      {
          Q_OBJECT
      public:
          explicit AudioDecoder(QObject *parent = nullptr);
          ~AudioDecoder();
      ...
      ...
      

      This is how the threads are instantiated in the GUI.

      void AudioStreamWidget::DecodeAudioFiles()
      {
          StopAllThreads();
      
          foreach (QFileInfo fileInfo, m_fileInfoList)
          {
              AudioDecoder* pDecoder = new AudioDecoder(this);
              connect(pDecoder, &AudioDecoder::finished, this, &AudioStreamWidget::ThreadFinished);
      
              pDecoder->StartDecoding(fileInfo.absoluteFilePath());
              pDecoder->start(); //! Thread start
          }
      }
      

      Qt Version 6.5.1.

      I believe the issue is with how I am using the threaded class.
      Can anyone help me figure out the issue?

      Best regards,
      Duke

      Pl45m4P Offline
      Pl45m4P Offline
      Pl45m4
      wrote on last edited by Pl45m4
      #2

      @DukeReddy said in QAudioDecoder Fails to start from a thread:

      foreach (QFileInfo fileInfo, m_fileInfoList)
      {
          AudioDecoder* pDecoder = new AudioDecoder(this);
          connect(pDecoder, &AudioDecoder::finished, this, &AudioStreamWidget::ThreadFinished);
      
          pDecoder->StartDecoding(fileInfo.absoluteFilePath());
          pDecoder->start(); //! Thread start
      }
      

      Here you create a new AudioDecoder instance in the GUI thread

      void AudioDecoder::run()
      {
          m_pDecoder = new QAudioDecoder();
          m_pDecoder->setSource(m_fileUrl);
         // ..
      }
      

      and here you create a new instance in AudioDecoder

      Check out the Qt Thread examples:

      • https://doc.qt.io/qt-6/examples-threadandconcurrent.html

      and the general threading options with Qt since you are mixing two approaches.

      • https://doc.qt.io/qt-6/threads-technologies.html

      You've subsclassed QThread and use an infinite loop while expecting to receive signals.
      I would go for the "Worker-Thread" approach and make AudioDecoder a QObject (instead of QThread). Then create a basic QThread and move your object to the thread with moveToThread.

      As also used here:

      • https://wiki.qt.io/QThreads_general_usage

      If debugging is the process of removing software bugs, then programming must be the process of putting them in.

      ~E. W. Dijkstra

      1 Reply Last reply
      4

      • Login

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