aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEgor Nemtsev <enemtsev@luxoft.com>2019-08-14 12:50:26 +0300
committerEgor Nemtsev <enemtsev@luxoft.com>2019-08-14 10:02:10 +0000
commit63b4c4754945ffbdc1ec9daca740304f23c80b53 (patch)
treeb5fa6120072ad66215a64be3f5482ad7dfd27d92
parent209dbf8c0f60c23ae3c3438c49508e233950e4a9 (diff)
Add QSettings property for changing capture device
- It might be needed to change default capture (microphone) device. For this case app reads QSettings with "Luxoft Sweden AB"/"AlexaApp" and from "capture/device_name" section reads device name. App prints avail devices in "--verbose" mode to console upon startup. Change-Id: I948435ecd29e7b31ed70ec0f25c2c60d155de037 Reviewed-by: Bramastyo Harimukti Santoso <bramastyo.harimukti.santoso@pelagicore.com>
-rw-r--r--plugins/alexainterface/AlexaInterface.cpp21
-rw-r--r--plugins/alexainterface/AlexaInterface.h4
-rw-r--r--plugins/alexainterface/QtMicrophoneWrapper.cpp105
-rw-r--r--plugins/alexainterface/QtMicrophoneWrapper.h7
4 files changed, 92 insertions, 45 deletions
diff --git a/plugins/alexainterface/AlexaInterface.cpp b/plugins/alexainterface/AlexaInterface.cpp
index 7f37995..6577177 100644
--- a/plugins/alexainterface/AlexaInterface.cpp
+++ b/plugins/alexainterface/AlexaInterface.cpp
@@ -33,6 +33,7 @@
#include <ACL/Transport/HTTP2TransportFactory.h>
#include <ACL/Transport/PostConnectSynchronizer.h>
#include <AVSCommon/Utils/LibcurlUtils/LibcurlHTTP2ConnectionFactory.h>
+#include <QSettings>
#include "KeywordObserver.h"
#include "AlexaInterface.h"
@@ -309,7 +310,7 @@ void AlexaInterface::initAlexaQMLClient()
// If avs-device-sdk is built without keyword support, kwdModelPath remains empty
QString kwdModelPath;
-#if KWD
+#ifdef KWD
if (!qEnvironmentVariableIsSet("ALEXA_KWD_MODEL_PATH")) {
qCritical() << "ALEXA_KWD_MODEL_PATH not defined";
return;
@@ -329,7 +330,7 @@ void AlexaInterface::initAlexaQMLClient()
kwdModelPath.toStdString(),
m_logLevelString.toStdString())) {
qCritical() << "Failed to initialize AlexaInterface.";
-#if KWD
+#ifdef KWD
qDebug() << "ALEXA_KWD_MODEL_PATH: " << qEnvironmentVariable("ALEXA_KWD_MODEL_PATH");
#endif
qDebug() << "ALEXA_SDK_CONFIG_FILE: " << qEnvironmentVariable("ALEXA_SDK_CONFIG_FILE");
@@ -903,9 +904,15 @@ bool AlexaInterface::initialize(
holdCanOverride,
holdCanBeOverridden);
-
- std::shared_ptr<QtMicrophoneWrapper> micWrapper = QtMicrophoneWrapper::create(sharedDataStream);
- if (!micWrapper) {
+ /*
+ * Read device name to change system default microphone input
+ */
+ QSettings settings(QStringLiteral("Luxoft Sweden AB"), QStringLiteral("AlexaApp"));
+ QString captureDeviceName = settings.value(QStringLiteral("capture/device_name"),
+ QStringLiteral("default")).toString();
+ std::shared_ptr<QtMicrophoneWrapper> m_micWrapper = QtMicrophoneWrapper::create(sharedDataStream,
+ captureDeviceName);
+ if (!m_micWrapper) {
ACSDK_CRITICAL(LX("Failed to create QtMicrophoneWrapper!"));
return false;
}
@@ -954,7 +961,7 @@ bool AlexaInterface::initialize(
m_interactionManager = std::make_shared<InteractionManager>(
this,
client,
- micWrapper,
+ m_micWrapper,
m_userInterfaceManager,
holdToTalkAudioProvider,
tapToTalkAudioProvider,
@@ -966,7 +973,7 @@ bool AlexaInterface::initialize(
#else
// If wake word is not enabled, then creating the interaction manager without a wake word audio provider.
m_interactionManager = std::make_shared<InteractionManager>(
- this, client, micWrapper, m_userInterfaceManager, holdToTalkAudioProvider, tapToTalkAudioProvider, m_guiRenderer);
+ this, client, m_micWrapper, m_userInterfaceManager, holdToTalkAudioProvider, tapToTalkAudioProvider, m_guiRenderer);
#endif
client->addAlexaDialogStateObserver(m_interactionManager);
diff --git a/plugins/alexainterface/AlexaInterface.h b/plugins/alexainterface/AlexaInterface.h
index 3c43824..46cb138 100644
--- a/plugins/alexainterface/AlexaInterface.h
+++ b/plugins/alexainterface/AlexaInterface.h
@@ -44,6 +44,7 @@
#include "ConnectionManager.h"
#include "DialogStateManager.h"
#include "CapabilitiesManager.h"
+#include "QtMicrophoneWrapper.h"
#ifdef KWD
#include <KWD/AbstractKeywordDetector.h>
@@ -274,6 +275,9 @@ private:
// Capabilities Manager
std::shared_ptr<CapabilitiesManager> m_capabilitiesManager;
+ // Microphone Wrapper
+ std::shared_ptr<QtMicrophoneWrapper> m_micWrapper;
+
/// The @c GuiRender which provides an abstraction to visual rendering
std::shared_ptr<GuiRenderer> m_guiRenderer;
diff --git a/plugins/alexainterface/QtMicrophoneWrapper.cpp b/plugins/alexainterface/QtMicrophoneWrapper.cpp
index cfbfed4..c3fe0ef 100644
--- a/plugins/alexainterface/QtMicrophoneWrapper.cpp
+++ b/plugins/alexainterface/QtMicrophoneWrapper.cpp
@@ -41,14 +41,15 @@ static const int SAMPLE_SIZE = 16;
static const double LATENCY = 0.2; //seconds
-std::unique_ptr<QtMicrophoneWrapper> QtMicrophoneWrapper::create(
- std::shared_ptr<AudioInputStream> stream) {
+std::unique_ptr<QtMicrophoneWrapper> QtMicrophoneWrapper::create(std::shared_ptr<AudioInputStream> stream,
+ const QString &deviceName)
+{
if (!stream) {
qWarning() << "QtMicrophoneWrapper: Invalid stream passed to QtMicrophoneWrapper";
return nullptr;
}
std::unique_ptr<QtMicrophoneWrapper> qtMicrophoneWrapper(new QtMicrophoneWrapper(stream));
- if (!qtMicrophoneWrapper->initialize()) {
+ if (!qtMicrophoneWrapper->initialize(deviceName)) {
qWarning() << "QtMicrophoneWrapper: Failed to initialize QtMicrophoneWrapper";
return nullptr;
}
@@ -62,45 +63,14 @@ QtMicrophoneWrapper::QtMicrophoneWrapper(std::shared_ptr<AudioInputStream> strea
QtMicrophoneWrapper::~QtMicrophoneWrapper() {
}
-bool QtMicrophoneWrapper::initialize() {
+bool QtMicrophoneWrapper::initialize(const QString &deviceName) {
m_writer = m_audioInputStream->createWriter(AudioInputStream::Writer::Policy::NONBLOCKABLE);
if (!m_writer) {
qWarning("QtMicrophoneWrapper: Failed to create stream writer");
return false;
}
- QAudioFormat format;
- format.setSampleRate(SAMPLE_RATE);
- format.setChannelCount(NUM_INPUT_CHANNELS);
- format.setSampleSize(SAMPLE_SIZE);
- format.setCodec("audio/pcm");
- format.setByteOrder(QAudioFormat::LittleEndian);
- format.setSampleType(QAudioFormat::SignedInt);
-
- QAudioDeviceInfo info = QAudioDeviceInfo::defaultInputDevice();
- if (!info.isFormatSupported(format)) {
- qWarning() << "QtMicrophoneWrapper: Default format not supported, trying to use the nearest.";
- format = info.nearestFormat(format);
- }
-
- m_audioInput = new QAudioInput(format, this);
- QObject::connect( m_audioInput, &QAudioInput::notify, this, [this](){
- QByteArray readBytes = m_audioInputIODevice->readAll();
- m_readAudioData.append(readBytes);
- m_readAudioDataBytes += readBytes.count();
-
- size_t nWords = m_writer->getWordSize() != 0 ?
- static_cast<size_t>(m_readAudioDataBytes)/m_writer->getWordSize() :
- static_cast<size_t>(m_readAudioDataBytes);
- m_writer->write(m_readAudioData.data(), nWords);
-
- m_readAudioData.clear();
- m_readAudioDataBytes = 0;
- });
-
- int latency = static_cast<int>(LATENCY * 1000);
- m_audioInput->setNotifyInterval(latency);
- qDebug("QtMicrophoneWrapper: Latency is configured to: %d ms", m_audioInput->notifyInterval());
+ setAudioDevice(deviceName);
return true;
}
@@ -110,6 +80,18 @@ bool QtMicrophoneWrapper::startStreamingMicrophoneData() {
m_readAudioDataBytes = 0;
m_audioInputIODevice = m_audioInput->start();
+
+ if (m_audioInput->error() != QAudio::NoError) {
+ qWarning() << "Start stream error:" << m_audioInput->error();
+ return false;
+ }
+
+ if (m_audioInput->state() != QAudio::ActiveState
+ && m_audioInput->state() != QAudio::IdleState) {
+ qWarning() << "Wrong input state:" << m_audioInput->state();
+ return false;
+ }
+
QByteArray readBytes = m_audioInputIODevice->readAll();
m_readAudioData.append(readBytes);
@@ -128,3 +110,54 @@ bool QtMicrophoneWrapper::stopStreamingMicrophoneData() {
return true;
}
+void QtMicrophoneWrapper::setAudioDevice(const QString &deviceName) {
+ qDebug() << "Trying to select input device: " << deviceName;
+
+ QAudioFormat format;
+ format.setSampleRate(SAMPLE_RATE);
+ format.setChannelCount(NUM_INPUT_CHANNELS);
+ format.setSampleSize(SAMPLE_SIZE);
+ format.setCodec("audio/pcm");
+ format.setByteOrder(QAudioFormat::LittleEndian);
+ format.setSampleType(QAudioFormat::SignedInt);
+
+ m_audioInfo = QAudioDeviceInfo::defaultInputDevice();
+
+ QList<QAudioDeviceInfo> devices = QAudioDeviceInfo::availableDevices(QAudio::AudioInput);
+
+ qDebug() << "Available capture devices:" << devices.size();
+ for (QAudioDeviceInfo &device : devices) {
+ qDebug() << " device name: " << device.deviceName();
+ if (device.deviceName() == deviceName) {
+ m_audioInfo = device;
+ }
+ }
+
+ qDebug() << "Selected capture device:" << m_audioInfo.deviceName();
+ qDebug() << "Requested format" << format;
+
+ if (!m_audioInfo.isFormatSupported(format)) {
+ qWarning() << "QtMicrophoneWrapper: Default format not supported, trying to use the nearest.";
+ format = m_audioInfo.nearestFormat(format);
+ qWarning() << "QtMicrophoneWrapper: Nearest format" << format;
+ }
+
+ m_audioInput = new QAudioInput(m_audioInfo, format, this);
+ QObject::connect(m_audioInput, &QAudioInput::notify, this, [this](){
+
+ QByteArray readBytes = m_audioInputIODevice->readAll();
+ m_readAudioData.append(readBytes);
+ m_readAudioDataBytes += readBytes.count();
+
+ size_t nWords = m_writer->getWordSize() != 0 ?
+ static_cast<size_t>(m_readAudioDataBytes)/m_writer->getWordSize() :
+ static_cast<size_t>(m_readAudioDataBytes);
+ m_writer->write(m_readAudioData.data(), nWords);
+ m_readAudioData.clear();
+ m_readAudioDataBytes = 0;
+ });
+
+ int latency = static_cast<int>(LATENCY * 1000);
+ m_audioInput->setNotifyInterval(latency);
+ qDebug("QtMicrophoneWrapper: Latency is configured to: %d ms", m_audioInput->notifyInterval());
+}
diff --git a/plugins/alexainterface/QtMicrophoneWrapper.h b/plugins/alexainterface/QtMicrophoneWrapper.h
index d3d5d12..cf81596 100644
--- a/plugins/alexainterface/QtMicrophoneWrapper.h
+++ b/plugins/alexainterface/QtMicrophoneWrapper.h
@@ -51,7 +51,8 @@ public:
* @param stream The shared data stream to write to.
* @return A unique_ptr to a @c QtMicrophoneWrapper if creation was successful and @c nullptr otherwise.
*/
- static std::unique_ptr<QtMicrophoneWrapper> create(std::shared_ptr<avsCommon::avs::AudioInputStream> stream);
+ static std::unique_ptr<QtMicrophoneWrapper> create(std::shared_ptr<avsCommon::avs::AudioInputStream> stream,
+ const QString &deviceName);
/**
* Stops streaming from the microphone.
@@ -76,13 +77,15 @@ private:
*/
QtMicrophoneWrapper(std::shared_ptr<avsCommon::avs::AudioInputStream> stream);
+ QAudioDeviceInfo m_audioInfo;
QAudioInput *m_audioInput = nullptr;
QIODevice *m_audioInputIODevice = nullptr;
int m_readAudioDataBytes = 0;
QByteArray m_readAudioData;
/// Initializes Audio
- bool initialize();
+ bool initialize(const QString &deviceName);
+ void setAudioDevice(const QString &deviceName);
/// The stream of audio data.
const std::shared_ptr<avsCommon::avs::AudioInputStream> m_audioInputStream;