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.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 -
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@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 threadvoid 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:
and the general threading options with Qt since you are mixing two approaches.
You've subsclassed
QThread
and use an infinite loop while expecting to receive signals.
I would go for the "Worker-Thread" approach and makeAudioDecoder
aQObject
(instead ofQThread
). Then create a basicQThread
and move your object to the thread withmoveToThread
.As also used here: