Solved pumping audio on a background thread, not a timer?
-
i have a cross platform (mac / win) app that plays audio.
i'm using the push method for audio PCM
instead of using a timer, i'm just running the pump on a background thread.This works fine on mac, but produces silence on windows.
is this... a limitation?
the thread object:
class CT_AudioRender : public QThread { //Q_OBJECT typedef QThread _inherited; CAudioUnitChain *thiz; QIODevice *i_outP; CAudioUnit *i_auP; public: CT_AudioRender(CAudioUnitChain *in_thiz) : _inherited(), thiz(in_thiz), i_outP(NULL), i_auP(in_thiz->GetCUnit_Out()) { setObjectName("CT_AudioRender"); start(QThread::HighPriority); } void run() override { SetUpThread(); i_auP->Start(&i_outP); IX(thiz->render(i_outP)); i_auP->Stop(); thiz->i_stopped.signal(); } };
the pump:
void CAudioUnitChain::render(QIODevice *ioP) { CAudioUnit *auP = GetCUnit_Out(); QAudioOutput *audioOutput(auP->i_qGeneratorP->i_qOutputP.get()); QByteArray buffer(32768, 0); //CAudioPlayer *playerP((CAudioPlayer *)auP->i_source.inputProcRefCon); do { if (audioOutput->state() != QAudio::StoppedState) { int chunks = audioOutput->bytesFree() / audioOutput->periodSize(); while (chunks--) { qint64 len = 0; len = auP->i_qGeneratorP->read(buffer.data(), audioOutput->periodSize()); if (len) { ioP->write(buffer.data(), len); } if (len != audioOutput->periodSize()) { break; } } } MPDelay(0.002); } while (!i_doneB.Get()); }
Am I missing something critical?
-
a user suggested i make a minimum compileable example. and in doing so, i ironed out my problem. i'm now able to do both push and pull on a background thread
if you'd like to see how to properly do audio on a background thread, see the example in this post. note the bug i'm trying to fix in THAT post means the buttons in the UI don't update, but the audio example does in fact work.
-
@davecotter Please post your code as text, not pictures.
You should initialise your members in run() if you want to use them in your thread. Currently you're doing this in constructor. QThread instance itself lives in the old thread. -
(fixed pic to text, I liked the pic cuz it preserves syntax coloring and formatting (why are tabs 8 spaces?) )
To be clear: I'm not initting any Qt objects in the constructor, that all happens inside the
run()
function, in thei_auP->Start(&i_outP);
call.Specifically: both
i_qGeneratorP
andi_qOutputP
are allocated there. I think they're the only Qt objects use within the new thread?Is there some other object you think is being cross-thread abused?
You mention the QThread object itself? I don't see where I'm incorrectly using that in the new thread?notes:
on the back thread, i do interact withQAudioDeviceInfo::availableDevices()
, which was already initted, probably on the main thread, is this a problem? -
anyone else have any ideas?
is it possible i'm just using QThread wrong? and it HAPPENS to work fine on mac but fails on windows?
is this blogger really revealing the ONE TRUE NATURE of QThread:
https://mayaposch.wordpress.com/2011/11/01/how-to-really-truly-use-qthreads-the-full-explanation/?
-dave
-
a user suggested i make a minimum compileable example. and in doing so, i ironed out my problem. i'm now able to do both push and pull on a background thread
if you'd like to see how to properly do audio on a background thread, see the example in this post. note the bug i'm trying to fix in THAT post means the buttons in the UI don't update, but the audio example does in fact work.