Add automatic switching the Oculus headphones and mic when activating the plugin

This commit is contained in:
Brad Davis 2016-03-30 23:12:53 -07:00
parent 74633ca8c8
commit b53968fd64
5 changed files with 118 additions and 7 deletions

View file

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

View file

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

View file

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

View file

@ -6,7 +6,22 @@
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
#include "OculusDisplayPlugin.h"
#ifdef WIN32
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <Mmsystem.h>
#include <mmdeviceapi.h>
#include <devicetopology.h>
#include <Functiondiscoverykeys_devpkey.h>
#include <VersionHelpers.h>
#endif
#include <OVR_CAPI_Audio.h>
#include <QtCore/QThread>
#include <shared/NsightHelpers.h>
#include <AudioClient.h>
#include "OculusHelpers.h"
const QString OculusDisplayPlugin::NAME("Oculus Rift");
@ -18,9 +33,38 @@ bool OculusDisplayPlugin::internalActivate() {
if (result && _session) {
ovr_SetInt(_session, OVR_PERF_HUD_MODE, currentDebugMode);
}
auto audioClient = DependencyManager::get<AudioClient>();
QString riftAudioIn = getPreferredAudioInDevice();
if (riftAudioIn != QString()) {
_savedAudioIn = audioClient->getDeviceName(QAudio::Mode::AudioInput);
QMetaObject::invokeMethod(audioClient.data(), "switchInputToAudioDevice", Q_ARG(const QString&, riftAudioIn));
} else {
_savedAudioIn.clear();
}
QString riftAudioOut = getPreferredAudioOutDevice();
if (riftAudioOut != QString()) {
_savedAudioOut = audioClient->getDeviceName(QAudio::Mode::AudioOutput);
QMetaObject::invokeMethod(audioClient.data(), "switchOutputToAudioDevice", Q_ARG(const QString&, riftAudioOut));
} else {
_savedAudioOut.clear();
}
return result;
}
void OculusDisplayPlugin::internalDeactivate() {
auto audioClient = DependencyManager::get<AudioClient>();
if (_savedAudioIn != QString()) {
QMetaObject::invokeMethod(audioClient.data(), "switchInputToAudioDevice", Q_ARG(const QString&, _savedAudioIn));
}
if (_savedAudioOut != QString()) {
QMetaObject::invokeMethod(audioClient.data(), "switchOutputToAudioDevice", Q_ARG(const QString&, _savedAudioOut));
}
Parent::internalDeactivate();
}
void OculusDisplayPlugin::cycleDebugOutput() {
if (_session) {
currentDebugMode = static_cast<ovrPerfHudMode>((currentDebugMode + 1) % ovrPerfHud_Count);
@ -86,3 +130,64 @@ void OculusDisplayPlugin::hmdPresent() {
}
}
}
bool OculusDisplayPlugin::isHmdMounted() const {
ovrSessionStatus status;
return (OVR_SUCCESS(ovr_GetSessionStatus(_session, &status)) &&
(ovrFalse != status.HmdMounted));
}
static QString audioDeviceFriendlyName(LPCWSTR device) {
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(device, &pEndpoint);
if (hr == E_NOTFOUND) {
printf("Audio Error: device not found\n");
deviceName = QString("NONE");
} else {
IPropertyStore* pPropertyStore;
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);
}
qDebug() << " device:" << deviceName;
PropVariantClear(&pv);
}
pMMDeviceEnumerator->Release();
pMMDeviceEnumerator = NULL;
CoUninitialize();
return deviceName;
}
QString OculusDisplayPlugin::getPreferredAudioInDevice() const {
WCHAR buffer[OVR_AUDIO_MAX_DEVICE_STR_SIZE];
if (!OVR_SUCCESS(ovr_GetAudioDeviceInGuidStr(buffer))) {
return QString();
}
return audioDeviceFriendlyName(buffer);
}
QString OculusDisplayPlugin::getPreferredAudioOutDevice() const {
WCHAR buffer[OVR_AUDIO_MAX_DEVICE_STR_SIZE];
if (!OVR_SUCCESS(ovr_GetAudioDeviceOutGuidStr(buffer))) {
return QString();
}
return audioDeviceFriendlyName(buffer);
}

View file

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