QAudioOutput in a QThread - problem.
Hi there!
This is my first post on this great forum ;)
I found here many good answers and examples. But I cannot find solution for this one...
I'm writing a quite big project with network programming and i have to play sound when my client connect and send some message to server.
First step which i made was to create an object of my class which encapsulate QAudioOutput and just use function (QAudioOutput::start()) from examples which shows how to play sound using this Qt class. That works ok but when client send more same message in short time not all sounds were played. So i decided to use QThread subclass to hear multiple sounds at once. Unfortunately the sound wasn't heard.
Can someone could help me with this problem?
I post here en example of my other short app in which i tried join thread and QAudioOutput. Same result - i don't hear sound as if file wasn't played or not send to audio device from the thread.
Code:
PlayFile
::PlayFile(QString fn
) : format
(0), info
(new QAudioDeviceInfo
(QAudioDeviceInfo
::defaultOutputDevice())), ao
(0),
file(0) { filename = fn;
setQuality();
printSupportedFeatures();
// setObjectName("mythread");
}
void PlayFile::setQuality() {
if(!format)
format = new QAudioFormat();
format->setCodec("audio/pcm");
format->setChannels(1);
format->setFrequency(11025);
// format->setFrequency(22050);
format->setSampleSize(8);
}
void PlayFile::sPlayFile() {
// qDebug("Odtwarzanie dzwieku...");
if(!file) {
file = new QFile(filename
);
}
if(!ao)
ao = new QAudioOutput(*info, *format);
ao->start(file);
qDebug("error: %d", ao->error());
}
void PlayFile::run() {
// qDebug("Watek %s", this->objectName().toStdString().c_str());
sPlayFile();
// qDebug("buffer %d", ao->bufferSize());
// qDebug("bytes %d", ao->bytesFree());
}
int main(int argc, char *argv[])
{
PlayFile* pf = new PlayFile("./alarm.wav");
// using this slot to start thread doesn't produce sound on output.. why?
pf->start();
// when i use this fuction (slot) i hear the sound
// pf->sPlayFile();
MainWindow w;
w.show();
return a.exec();
}
Please help me to correct this problem.
Re: QAudioOutput in a QThread - problem.
I have a theory, but I am not sure its correct.
But we can test it easy:
put 2 seconds sleep in your run function before sPlayFile();.
Do you get the sound played then?
Re: QAudioOutput in a QThread - problem.
I would probably first check if the audio format is supported by your backend.
Re: QAudioOutput in a QThread - problem.
Quote:
I would probably first check if the audio format is supported by your backend.
Well, he said he gets sound when he plays the function outside the thread... so...
Re: QAudioOutput in a QThread - problem.
Oh, I missed that... After reading the post again carefully I have a strong doubt using threads would solve the problem at all. If the audio output is busy playing one sound, pushing more data to it from another thread won't cause two sounds to play simoultaneously, one needs a mixer for that. Otherwise the second sound will play only after the first one will have finished playing.
Re: QAudioOutput in a QThread - problem.
Hi,
Maybe you can stop the current playing sound and reproduce the new sound.
Re: QAudioOutput in a QThread - problem.
Quote:
If the audio output is busy playing one sound, pushing more data to it from another thread won't cause two sounds to play simoultaneously, one needs a mixer for that.
True, but that is still not his problem, since he only plays the sound once, over a thread.
I have a suspition, that it has to do with the fact the thread runs (and probably finishes) before QApplication::exec() is called.
My guess is, that there are some events that need the QApplication event loop... but as I said, this is only a guess.
This is why I suggested the sleep.
Another way to test it would be to start the thread after QApplication::exec() has been called.
When this is solved, the problem with multiple sounds on the sound system with out a mixer problem will still be there though...
Re: QAudioOutput in a QThread - problem.
Thanks to all for your responds.
Yes it's true that it has something to do with main event loop.
I check in debug and I hear a sound only when QApplication::exec() was processing.
So maybe I need do something with local event loop.
I'll still searching though.
Re: QAudioOutput in a QThread - problem.
Quote:
So maybe I need do something with local event loop.
I thought as much.
Nothing special to do, just start the thread after QApplication::exec() has been called, from your widget for example.
Re: QAudioOutput in a QThread - problem.
@high_flyer:
Thanks for your replies.
Pause between calling my function didn't change anything.
I tried to play a sound in separate thread when i press the QButton widget but it doesn't help neither.
I really don't know what to do next.
I start to thinking that is not possible to play sound in different threads than GUI's one...
Re: QAudioOutput in a QThread - problem.
Have a look at QEventLoop, maybe you could do something with that.
But I think playing sound in threads is more a design problem, if you design properly, you probably wont need this.
Re: QAudioOutput in a QThread - problem.
Quote:
Originally Posted by
high_flyer
True, but that is still not his problem, since he only plays the sound once, over a thread.
I don't think so, look:
Quote:
That works ok but when client send more same message in short time not all sounds were played.
Sound is played asynchronously so there is no benefit in doing that in a thread. You can run the event loop of the thread and the sound will probably play fine but it won't change the fact that sounds won't be able to mix. It could even crash the application.
Re: QAudioOutput in a QThread - problem.
Quote:
You can run the event loop of the thread and the sound will probably play fine but it won't change the fact that sounds won't be able to mix.
Yes, as I said before, I agree with that too.
These were to separate problems - one getting the events through, the other - parallel audio with out mixing.
Re: QAudioOutput in a QThread - problem.
So. Somebody now have a solution for use QAudioOutput within a QThread ?
Somebody speek about Events but how and which events ?
Please somebody help me.
Daniel
Re: QAudioOutput in a QThread - problem.
Hi.
I write for other people, because i already found a solution.
The key is : from the thread you create a QAudioOutput and start it, you need to enter the event loop, and this is only possible after executing exec().
So after start you QAudioOutput, in the run() function you need to write :
exec()
This is new for me, because i come from the World of MFC, and there for calling to IDirectSound, where i engage a sound without need to enter a event loop.
In fact, now i transport everything i do before with MFC, (for Windows), a project from before 10 years ago, to QT.
I am already 8 years Linux-user, but i want compatibility with every operativ system.
Greatings. Daniel