QAudioDecoder Fails to start from a thread
-
Hello all,
I have a weird issue with QAudioDecoder usage. When I call
decoder->start()from a widget class (GUI) it works fine.bufferReadysignal 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 -
Hello all,
I have a weird issue with QAudioDecoder usage. When I call
decoder->start()from a widget class (GUI) it works fine.bufferReadysignal 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@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
AudioDecoderinstance in the GUI threadvoid AudioDecoder::run() { m_pDecoder = new QAudioDecoder(); m_pDecoder->setSource(m_fileUrl); // .. }and here you create a new instance in
AudioDecoderCheck out the Qt Thread examples:
and the general threading options with Qt since you are mixing two approaches.
You've subsclassed
QThreadand use an infinite loop while expecting to receive signals.
I would go for the "Worker-Thread" approach and makeAudioDecoderaQObject(instead ofQThread). Then create a basicQThreadand move your object to the thread withmoveToThread.As also used here: