diff --git a/src/GAudioOutput.cc b/src/GAudioOutput.cc index c296aa3ce9d8fbdb400967b78d9eaddaaf31a253..a6788f97bdf7850310f608c1a1738f516046ba75 100644 --- a/src/GAudioOutput.cc +++ b/src/GAudioOutput.cc @@ -64,6 +64,8 @@ GAudioOutput::GAudioOutput(QObject *parent) : QObject(parent), worker(new QGCAudioWorker()) { worker->moveToThread(thread); + // Initialize within right thread context + worker->init(); connect(this, SIGNAL(textToSpeak(QString,int)), worker, SLOT(say(QString,int))); connect(this, SIGNAL(beepOnce()), worker, SLOT(beep())); thread->start(); diff --git a/src/audio/QGCAudioWorker.cpp b/src/audio/QGCAudioWorker.cpp index 92ff74ae5b117e90938955ee75962a7025593db8..e56133206b93cb5a5cf65da3573ecd454684dc46 100644 --- a/src/audio/QGCAudioWorker.cpp +++ b/src/audio/QGCAudioWorker.cpp @@ -1,5 +1,8 @@ #include #include +#include +#include +#include #include "QGC.h" #include "QGCAudioWorker.h" @@ -19,22 +22,26 @@ #include #endif -#if defined _MSC_VER && defined QGC_SPEECH_ENABLED -ISpVoice *QGCAudioWorker::pVoice = NULL; -#endif - #define QGC_GAUDIOOUTPUT_KEY QString("QGC_AUDIOOUTPUT_") QGCAudioWorker::QGCAudioWorker(QObject *parent) : QObject(parent), voiceIndex(0), emergency(false), - muted(false) + muted(false), + #if defined _MSC_VER && defined QGC_SPEECH_ENABLED + pVoice(NULL), + #endif + sound(NULL) { // Load settings QSettings settings; muted = settings.value(QGC_GAUDIOOUTPUT_KEY + "muted", muted).toBool(); +} +void QGCAudioWorker::init() +{ + sound = new QSound(""); #if defined Q_OS_LINUX && defined QGC_SPEECH_ENABLED espeak_Initialize(AUDIO_OUTPUT_PLAYBACK, 500, NULL, 0); // initialize for playback with 500ms buffer and no options (see speak_lib.h) @@ -48,13 +55,11 @@ QGCAudioWorker::QGCAudioWorker(QObject *parent) : #endif #if defined _MSC_VER && defined QGC_SPEECH_ENABLED - pVoice = NULL; if (FAILED(::CoInitialize(NULL))) { qDebug() << "ERROR: Creating COM object for audio output failed!"; } - else { @@ -90,38 +95,39 @@ void QGCAudioWorker::say(QString text, int severity) // TODO Add severity filter Q_UNUSED(severity); - if (!emergency) - { + // Wait for the last sound to finish + while (!sound->isFinished()) { + QGC::SLEEP::msleep(100); + } - #if defined _MSC_VER && defined QGC_SPEECH_ENABLED - pVoice->Speak(text.toStdWString().c_str(), SPF_ASYNC, NULL); - - #elif defined Q_OS_LINUX && defined QGC_SPEECH_ENABLED - // Set size of string for espeak: +1 for the null-character - unsigned int espeak_size = strlen(text.toStdString().c_str()) + 1; - espeak_Synth(text.toStdString().c_str(), espeak_size, 0, POS_CHARACTER, 0, espeakCHARS_AUTO, NULL, NULL); - - #elif defined Q_OS_MAC && defined QGC_SPEECH_ENABLED - // Slashes necessary to have the right start to the sentence - // copying data prevents SpeakString from reading additional chars - text = "\\" + text; - std::wstring str = text.toStdWString(); - unsigned char str2[1024] = {}; - memcpy(str2, text.toLatin1().data(), str.length()); - SpeakString(str2); - - // Block the thread while busy - // because we run in our own thread, this doesn't - // halt the main application - while (SpeechBusy()) { - QGC::SLEEP::msleep(100); - } - - #else - // Make sure there isn't an unused variable warning when speech output is disabled - Q_UNUSED(text); - #endif +#if defined _MSC_VER && defined QGC_SPEECH_ENABLED + pVoice->Speak(text.toStdWString().c_str(), SPF_ASYNC, NULL); + +#elif defined Q_OS_LINUX && defined QGC_SPEECH_ENABLED + // Set size of string for espeak: +1 for the null-character + unsigned int espeak_size = strlen(text.toStdString().c_str()) + 1; + espeak_Synth(text.toStdString().c_str(), espeak_size, 0, POS_CHARACTER, 0, espeakCHARS_AUTO, NULL, NULL); + +#elif defined Q_OS_MAC && defined QGC_SPEECH_ENABLED + // Slashes necessary to have the right start to the sentence + // copying data prevents SpeakString from reading additional chars + text = "\\" + text; + std::wstring str = text.toStdWString(); + unsigned char str2[1024] = {}; + memcpy(str2, text.toLatin1().data(), str.length()); + SpeakString(str2); + + // Block the thread while busy + // because we run in our own thread, this doesn't + // halt the main application + while (SpeechBusy()) { + QGC::SLEEP::msleep(100); } + +#else + // Make sure there isn't an unused variable warning when speech output is disabled + Q_UNUSED(text); +#endif } } @@ -138,16 +144,13 @@ void QGCAudioWorker::mute(bool mute) void QGCAudioWorker::beep() { - // XXX beep beep if (!muted) { - // FIXME: Re-enable audio beeps // Use QFile to transform path for all OS - //QFile f(QCoreApplication::applicationDirPath() + QString("/files/audio/alert.wav")); - //qDebug() << "FILE:" << f.fileName(); - //m_media->setCurrentSource(Phonon::MediaSource(f.fileName().toStdString().c_str())); - //m_media->play(); + QFile f(QCoreApplication::applicationDirPath() + QString("/files/audio/alert.wav")); + qDebug() << "SOUND FILE:" << f.fileName(); + sound->play(f.fileName()); } } diff --git a/src/audio/QGCAudioWorker.h b/src/audio/QGCAudioWorker.h index 38077ead914763ba5d5ce1e91461e1f06ff1951b..062d9b306ce5d1470da13a76f8e6d9e6b102929b 100644 --- a/src/audio/QGCAudioWorker.h +++ b/src/audio/QGCAudioWorker.h @@ -3,6 +3,7 @@ #include #include +#include /* For Snow leopard and later #if defined Q_OS_MAC & defined QGC_SPEECH_ENABLED @@ -25,6 +26,7 @@ public: void mute(bool mute); bool isMuted(); + void init(); signals: @@ -43,12 +45,13 @@ protected: //cst_voice* voice; ///< The flite voice object #endif #if defined _MSC_VER && defined QGC_SPEECH_ENABLED - static ISpVoice *pVoice; + ISpVoice *pVoice; #endif int voiceIndex; ///< The index of the flite voice to use (awb, slt, rms) bool emergency; ///< Emergency status flag QTimer *emergencyTimer; bool muted; + QSound *sound; }; #endif // QGCAUDIOWORKER_H