Merge pull request #7524 from jherico/oculus_audio

Allow display plugins to expose a preferred audio device
This commit is contained in:
Brad Hefta-Gaub 2016-03-31 19:09:46 -07:00
commit 16f249ce6c
9 changed files with 100 additions and 24 deletions

View file

@ -97,3 +97,11 @@ bool HMDScriptingInterface::isMounted() const{
auto displayPlugin = qApp->getActiveDisplayPlugin(); auto displayPlugin = qApp->getActiveDisplayPlugin();
return (displayPlugin->isHmd() && displayPlugin->isDisplayVisible()); return (displayPlugin->isHmd() && displayPlugin->isDisplayVisible());
} }
QString HMDScriptingInterface::preferredAudioInput() const {
return qApp->getActiveDisplayPlugin()->getPreferredAudioInDevice();
}
QString HMDScriptingInterface::preferredAudioOutput() const {
return qApp->getActiveDisplayPlugin()->getPreferredAudioOutDevice();
}

View file

@ -34,6 +34,8 @@ public:
Q_INVOKABLE glm::vec2 sphericalToOverlay(const glm::vec2 & sphericalPos) const; Q_INVOKABLE glm::vec2 sphericalToOverlay(const glm::vec2 & sphericalPos) const;
Q_INVOKABLE glm::vec2 overlayToSpherical(const glm::vec2 & overlayPos) const; Q_INVOKABLE glm::vec2 overlayToSpherical(const glm::vec2 & overlayPos) const;
Q_INVOKABLE QString preferredAudioInput() const;
Q_INVOKABLE QString preferredAudioOutput() const;
public: public:
HMDScriptingInterface(); HMDScriptingInterface();

View file

@ -175,6 +175,50 @@ int numDestinationSamplesRequired(const QAudioFormat& sourceFormat, const QAudio
return (numSourceSamples * ratio) + 0.5f; return (numSourceSamples * ratio) + 0.5f;
} }
#ifdef Q_OS_WIN
QString friendlyNameForAudioDevice(IMMDevice* pEndpoint) {
QString deviceName;
IPropertyStore* pPropertyStore;
pEndpoint->OpenPropertyStore(STGM_READ, &pPropertyStore);
pEndpoint->Release();
pEndpoint = NULL;
PROPVARIANT pv;
PropVariantInit(&pv);
HRESULT hr = pPropertyStore->GetValue(PKEY_Device_FriendlyName, &pv);
pPropertyStore->Release();
pPropertyStore = NULL;
deviceName = QString::fromWCharArray((wchar_t*)pv.pwszVal);
if (!IsWindows8OrGreater()) {
// Windows 7 provides only the 31 first characters of the device name.
const DWORD QT_WIN7_MAX_AUDIO_DEVICENAME_LEN = 31;
deviceName = deviceName.left(QT_WIN7_MAX_AUDIO_DEVICENAME_LEN);
}
PropVariantClear(&pv);
return deviceName;
}
QString AudioClient::friendlyNameForAudioDevice(wchar_t* guid) {
QString deviceName;
HRESULT hr = S_OK;
CoInitialize(NULL);
IMMDeviceEnumerator* pMMDeviceEnumerator = NULL;
CoCreateInstance(__uuidof(MMDeviceEnumerator), NULL, CLSCTX_ALL, __uuidof(IMMDeviceEnumerator), (void**)&pMMDeviceEnumerator);
IMMDevice* pEndpoint;
hr = pMMDeviceEnumerator->GetDevice(guid, &pEndpoint);
if (hr == E_NOTFOUND) {
printf("Audio Error: device not found\n");
deviceName = QString("NONE");
} else {
deviceName = ::friendlyNameForAudioDevice(pEndpoint);
}
pMMDeviceEnumerator->Release();
pMMDeviceEnumerator = NULL;
CoUninitialize();
return deviceName;
}
#endif
QAudioDeviceInfo defaultAudioDeviceForMode(QAudio::Mode mode) { QAudioDeviceInfo defaultAudioDeviceForMode(QAudio::Mode mode) {
#ifdef __APPLE__ #ifdef __APPLE__
if (QAudioDeviceInfo::availableDevices(mode).size() > 1) { if (QAudioDeviceInfo::availableDevices(mode).size() > 1) {
@ -248,23 +292,7 @@ QAudioDeviceInfo defaultAudioDeviceForMode(QAudio::Mode mode) {
printf("Audio Error: device not found\n"); printf("Audio Error: device not found\n");
deviceName = QString("NONE"); deviceName = QString("NONE");
} else { } else {
IPropertyStore* pPropertyStore; deviceName = friendlyNameForAudioDevice(pEndpoint);
pEndpoint->OpenPropertyStore(STGM_READ, &pPropertyStore);
pEndpoint->Release();
pEndpoint = NULL;
PROPVARIANT pv;
PropVariantInit(&pv);
hr = pPropertyStore->GetValue(PKEY_Device_FriendlyName, &pv);
pPropertyStore->Release();
pPropertyStore = NULL;
deviceName = QString::fromWCharArray((wchar_t*)pv.pwszVal);
if (!IsWindows8OrGreater()) {
// Windows 7 provides only the 31 first characters of the device name.
const DWORD QT_WIN7_MAX_AUDIO_DEVICENAME_LEN = 31;
deviceName = deviceName.left(QT_WIN7_MAX_AUDIO_DEVICENAME_LEN);
}
qCDebug(audioclient) << (mode == QAudio::AudioOutput ? "output" : "input") << " device:" << deviceName;
PropVariantClear(&pv);
} }
pMMDeviceEnumerator->Release(); pMMDeviceEnumerator->Release();
pMMDeviceEnumerator = NULL; pMMDeviceEnumerator = NULL;

View file

@ -16,6 +16,7 @@
#include <memory> #include <memory>
#include <vector> #include <vector>
#include <QtCore/qsystemdetection.h>
#include <QtCore/QByteArray> #include <QtCore/QByteArray>
#include <QtCore/QElapsedTimer> #include <QtCore/QElapsedTimer>
#include <QtCore/QObject> #include <QtCore/QObject>
@ -126,6 +127,10 @@ public:
static const float CALLBACK_ACCELERATOR_RATIO; static const float CALLBACK_ACCELERATOR_RATIO;
#ifdef Q_OS_WIN
static QString friendlyNameForAudioDevice(wchar_t* guid);
#endif
public slots: public slots:
void start(); void start();
void stop(); void stop();

View file

@ -74,6 +74,9 @@ public:
/// whether the HMD is being worn /// whether the HMD is being worn
virtual bool isDisplayVisible() const { return false; } virtual bool isDisplayVisible() const { return false; }
virtual QString getPreferredAudioInDevice() const { return QString(); }
virtual QString getPreferredAudioOutDevice() const { return QString(); }
// Rendering support // Rendering support
/** /**

View file

@ -12,8 +12,8 @@ if (WIN32)
add_definitions(-DGLEW_STATIC) add_definitions(-DGLEW_STATIC)
set(TARGET_NAME oculus) set(TARGET_NAME oculus)
setup_hifi_plugin() setup_hifi_plugin(Multimedia)
link_hifi_libraries(shared gl gpu controllers ui plugins display-plugins input-plugins) link_hifi_libraries(shared gl gpu controllers ui plugins display-plugins input-plugins audio-client networking)
include_hifi_library_headers(octree) include_hifi_library_headers(octree)
@ -21,5 +21,6 @@ if (WIN32)
find_package(LibOVR REQUIRED) find_package(LibOVR REQUIRED)
target_include_directories(${TARGET_NAME} PRIVATE ${LIBOVR_INCLUDE_DIRS}) target_include_directories(${TARGET_NAME} PRIVATE ${LIBOVR_INCLUDE_DIRS})
target_link_libraries(${TARGET_NAME} ${LIBOVR_LIBRARIES}) target_link_libraries(${TARGET_NAME} ${LIBOVR_LIBRARIES})
target_link_libraries(${TARGET_NAME} Winmm.lib)
endif() endif()

View file

@ -21,6 +21,7 @@ public:
// Stereo specific methods // Stereo specific methods
virtual void resetSensors() override final; virtual void resetSensors() override final;
virtual void beginFrameRender(uint32_t frameIndex) override; virtual void beginFrameRender(uint32_t frameIndex) override;
float getTargetFrameRate() override { return _hmdDesc.DisplayRefreshRate; }
protected: protected:

View file

@ -6,7 +6,14 @@
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
// //
#include "OculusDisplayPlugin.h" #include "OculusDisplayPlugin.h"
// Odd ordering of header is required to avoid 'macro redinition warnings'
#include <AudioClient.h>
#include <OVR_CAPI_Audio.h>
#include <shared/NsightHelpers.h> #include <shared/NsightHelpers.h>
#include "OculusHelpers.h" #include "OculusHelpers.h"
const QString OculusDisplayPlugin::NAME("Oculus Rift"); const QString OculusDisplayPlugin::NAME("Oculus Rift");
@ -86,3 +93,26 @@ void OculusDisplayPlugin::hmdPresent() {
} }
} }
} }
bool OculusDisplayPlugin::isHmdMounted() const {
ovrSessionStatus status;
return (OVR_SUCCESS(ovr_GetSessionStatus(_session, &status)) &&
(ovrFalse != status.HmdMounted));
}
QString OculusDisplayPlugin::getPreferredAudioInDevice() const {
WCHAR buffer[OVR_AUDIO_MAX_DEVICE_STR_SIZE];
if (!OVR_SUCCESS(ovr_GetAudioDeviceInGuidStr(buffer))) {
return QString();
}
return AudioClient::friendlyNameForAudioDevice(buffer);
}
QString OculusDisplayPlugin::getPreferredAudioOutDevice() const {
WCHAR buffer[OVR_AUDIO_MAX_DEVICE_STR_SIZE];
if (!OVR_SUCCESS(ovr_GetAudioDeviceOutGuidStr(buffer))) {
return QString();
}
return AudioClient::friendlyNameForAudioDevice(buffer);
}

View file

@ -12,20 +12,18 @@
struct SwapFramebufferWrapper; struct SwapFramebufferWrapper;
using SwapFboPtr = QSharedPointer<SwapFramebufferWrapper>; using SwapFboPtr = QSharedPointer<SwapFramebufferWrapper>;
const float TARGET_RATE_Oculus = 75.0f;
class OculusDisplayPlugin : public OculusBaseDisplayPlugin { class OculusDisplayPlugin : public OculusBaseDisplayPlugin {
using Parent = OculusBaseDisplayPlugin; using Parent = OculusBaseDisplayPlugin;
public: public:
const QString& getName() const override { return NAME; } const QString& getName() const override { return NAME; }
float getTargetFrameRate() override { return TARGET_RATE_Oculus; } QString getPreferredAudioInDevice() const override;
QString getPreferredAudioOutDevice() const override;
protected: protected:
bool internalActivate() override; bool internalActivate() override;
void hmdPresent() override; void hmdPresent() override;
// FIXME update with Oculus API call once it's available in the SDK bool isHmdMounted() const override;
bool isHmdMounted() const override { return true; }
void customizeContext() override; void customizeContext() override;
void uncustomizeContext() override; void uncustomizeContext() override;
void cycleDebugOutput() override; void cycleDebugOutput() override;