Commit daefb0bd authored by Lorenz Meier's avatar Lorenz Meier

Move Windows sound API to right thread context and make it an object member....

Move Windows sound API to right thread context and make it an object member. Perform init within the right thread context. Add capability to play .wav files in addition via QMultiMedia
parent 35050b88
...@@ -64,6 +64,8 @@ GAudioOutput::GAudioOutput(QObject *parent) : QObject(parent), ...@@ -64,6 +64,8 @@ GAudioOutput::GAudioOutput(QObject *parent) : QObject(parent),
worker(new QGCAudioWorker()) worker(new QGCAudioWorker())
{ {
worker->moveToThread(thread); worker->moveToThread(thread);
// Initialize within right thread context
worker->init();
connect(this, SIGNAL(textToSpeak(QString,int)), worker, SLOT(say(QString,int))); connect(this, SIGNAL(textToSpeak(QString,int)), worker, SLOT(say(QString,int)));
connect(this, SIGNAL(beepOnce()), worker, SLOT(beep())); connect(this, SIGNAL(beepOnce()), worker, SLOT(beep()));
thread->start(); thread->start();
......
#include <QSettings> #include <QSettings>
#include <QDebug> #include <QDebug>
#include <QCoreApplication>
#include <QFile>
#include <QSound>
#include "QGC.h" #include "QGC.h"
#include "QGCAudioWorker.h" #include "QGCAudioWorker.h"
...@@ -19,22 +22,26 @@ ...@@ -19,22 +22,26 @@
#include <espeak/speak_lib.h> #include <espeak/speak_lib.h>
#endif #endif
#if defined _MSC_VER && defined QGC_SPEECH_ENABLED
ISpVoice *QGCAudioWorker::pVoice = NULL;
#endif
#define QGC_GAUDIOOUTPUT_KEY QString("QGC_AUDIOOUTPUT_") #define QGC_GAUDIOOUTPUT_KEY QString("QGC_AUDIOOUTPUT_")
QGCAudioWorker::QGCAudioWorker(QObject *parent) : QGCAudioWorker::QGCAudioWorker(QObject *parent) :
QObject(parent), QObject(parent),
voiceIndex(0), voiceIndex(0),
emergency(false), emergency(false),
muted(false) muted(false),
#if defined _MSC_VER && defined QGC_SPEECH_ENABLED
pVoice(NULL),
#endif
sound(NULL)
{ {
// Load settings // Load settings
QSettings settings; QSettings settings;
muted = settings.value(QGC_GAUDIOOUTPUT_KEY + "muted", muted).toBool(); muted = settings.value(QGC_GAUDIOOUTPUT_KEY + "muted", muted).toBool();
}
void QGCAudioWorker::init()
{
sound = new QSound("");
#if defined Q_OS_LINUX && defined QGC_SPEECH_ENABLED #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) 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) : ...@@ -48,13 +55,11 @@ QGCAudioWorker::QGCAudioWorker(QObject *parent) :
#endif #endif
#if defined _MSC_VER && defined QGC_SPEECH_ENABLED #if defined _MSC_VER && defined QGC_SPEECH_ENABLED
pVoice = NULL;
if (FAILED(::CoInitialize(NULL))) if (FAILED(::CoInitialize(NULL)))
{ {
qDebug() << "ERROR: Creating COM object for audio output failed!"; qDebug() << "ERROR: Creating COM object for audio output failed!";
} }
else else
{ {
...@@ -90,38 +95,39 @@ void QGCAudioWorker::say(QString text, int severity) ...@@ -90,38 +95,39 @@ void QGCAudioWorker::say(QString text, int severity)
// TODO Add severity filter // TODO Add severity filter
Q_UNUSED(severity); 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 #if defined _MSC_VER && defined QGC_SPEECH_ENABLED
pVoice->Speak(text.toStdWString().c_str(), SPF_ASYNC, NULL); pVoice->Speak(text.toStdWString().c_str(), SPF_ASYNC, NULL);
#elif defined Q_OS_LINUX && defined QGC_SPEECH_ENABLED #elif defined Q_OS_LINUX && defined QGC_SPEECH_ENABLED
// Set size of string for espeak: +1 for the null-character // Set size of string for espeak: +1 for the null-character
unsigned int espeak_size = strlen(text.toStdString().c_str()) + 1; 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); 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 #elif defined Q_OS_MAC && defined QGC_SPEECH_ENABLED
// Slashes necessary to have the right start to the sentence // Slashes necessary to have the right start to the sentence
// copying data prevents SpeakString from reading additional chars // copying data prevents SpeakString from reading additional chars
text = "\\" + text; text = "\\" + text;
std::wstring str = text.toStdWString(); std::wstring str = text.toStdWString();
unsigned char str2[1024] = {}; unsigned char str2[1024] = {};
memcpy(str2, text.toLatin1().data(), str.length()); memcpy(str2, text.toLatin1().data(), str.length());
SpeakString(str2); SpeakString(str2);
// Block the thread while busy // Block the thread while busy
// because we run in our own thread, this doesn't // because we run in our own thread, this doesn't
// halt the main application // halt the main application
while (SpeechBusy()) { while (SpeechBusy()) {
QGC::SLEEP::msleep(100); QGC::SLEEP::msleep(100);
}
#else
// Make sure there isn't an unused variable warning when speech output is disabled
Q_UNUSED(text);
#endif
} }
#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) ...@@ -138,16 +144,13 @@ void QGCAudioWorker::mute(bool mute)
void QGCAudioWorker::beep() void QGCAudioWorker::beep()
{ {
// XXX beep beep
if (!muted) if (!muted)
{ {
// FIXME: Re-enable audio beeps
// Use QFile to transform path for all OS // Use QFile to transform path for all OS
//QFile f(QCoreApplication::applicationDirPath() + QString("/files/audio/alert.wav")); QFile f(QCoreApplication::applicationDirPath() + QString("/files/audio/alert.wav"));
//qDebug() << "FILE:" << f.fileName(); qDebug() << "SOUND FILE:" << f.fileName();
//m_media->setCurrentSource(Phonon::MediaSource(f.fileName().toStdString().c_str())); sound->play(f.fileName());
//m_media->play();
} }
} }
......
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
#include <QObject> #include <QObject>
#include <QTimer> #include <QTimer>
#include <QSound>
/* For Snow leopard and later /* For Snow leopard and later
#if defined Q_OS_MAC & defined QGC_SPEECH_ENABLED #if defined Q_OS_MAC & defined QGC_SPEECH_ENABLED
...@@ -25,6 +26,7 @@ public: ...@@ -25,6 +26,7 @@ public:
void mute(bool mute); void mute(bool mute);
bool isMuted(); bool isMuted();
void init();
signals: signals:
...@@ -43,12 +45,13 @@ protected: ...@@ -43,12 +45,13 @@ protected:
//cst_voice* voice; ///< The flite voice object //cst_voice* voice; ///< The flite voice object
#endif #endif
#if defined _MSC_VER && defined QGC_SPEECH_ENABLED #if defined _MSC_VER && defined QGC_SPEECH_ENABLED
static ISpVoice *pVoice; ISpVoice *pVoice;
#endif #endif
int voiceIndex; ///< The index of the flite voice to use (awb, slt, rms) int voiceIndex; ///< The index of the flite voice to use (awb, slt, rms)
bool emergency; ///< Emergency status flag bool emergency; ///< Emergency status flag
QTimer *emergencyTimer; QTimer *emergencyTimer;
bool muted; bool muted;
QSound *sound;
}; };
#endif // QGCAUDIOWORKER_H #endif // QGCAUDIOWORKER_H
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment