Detecting currently worn HMD using Windows Mixed Reality - c#

I am working with Unity and the Mixed Reality Toolkit. My issue is that "HP Reverb G2" is not detected using Windows Mixed Reality, but it works if I parse with SteamVR. My goal is to detect if the headset is on my head without using SteamVR.
My current solution, which doesn't work, is as follows:
public static bool IsHMDMounted()
{
if (headDevice == null || headDevice.isValid == false)
{
headDevice = InputDevices.GetDeviceAtXRNode(XRNode.Head);
}
if (headDevice != null)
{
bool presenceFeatureSupported = headDevice.TryGetFeatureValue(CommonUsages.userPresence, out bool userPresent);
if (headDevice.isValid && presenceFeatureSupported)
{
return userPresent;
}
else
{
return false;
}
}
else
{
return false;
}
}

There is a discussion related to this issue on the Unity forums - Question - OpenXR -- Is it no longer possible to get descriptive device names? - Unity Forum.
Referring to this thread, it seems that Unity does not expose the device information provided by Open XR, but you can get this information by intercepting the API of Open XR according to the method mentioned in the thread - https://forum.unity.com/threads/openxr-is-it-no-longer-possible-to-get-descriptive-device-names.1051493/#post-8275923.

Related

how do i get Android.Media.SetPreferredDevice() to work

So making a mobile application that works on UWP, IOS and Android but since not all librarys work on every platform I'm using the library based on what device is used by
if (Device.RuntimePlatform == Device.Android) { }
And I'm currently only working on the Android part of the application.
I'm using Android.Media to play a single audio file out of multiple speakers. And to do that I'm using a Picker that has the available audio output devices. This part works.
But I'm getting a error while trying to select the PreferredDevice:
Java.Lang.NoSuchMethodError: 'no non-static method "Landroid/media/MediaPlayer;.setPreferredDevice(Landroid/media/AudioDeviceInfo;)Z"'
The code line that is giving the error is:
mediaPlayer1.SetPreferredDevice(audioDeviceInfo);
the full method that is being run is:
newoutput.SelectedIndexChanged += (changed, args) =>
{
Context context = Android.App.Application.Context;
AudioManager audioMan = (AudioManager)context.GetSystemService(Context.AudioService);
AudioDeviceInfo audioDeviceInfo = audioMan.GetDevices(GetDevicesTargets.Outputs)[newoutput.SelectedIndex];
mediaPlayer1.SetPreferredDevice(audioDeviceInfo);
};
I can't find many examples that use the method and they don't usually go with a mediaplayer that is created by button press.
You can use this code
private AudioDeviceInfo findAudioDevice(int deviceType) {
AudioManager manager = (AudioManager) this.getSystemService(Context.AUDIO_SERVICE);
AudioDeviceInfo[] adis = manager.getDevices(GET_DEVICES_OUTPUTS);
for (AudioDeviceInfo adi : adis) {
if (adi.getType() == deviceType) {
return adi;
}
}
return null;
}
Then set your input:
audioRecord.setPreferredDevice(findAudioDevice([newoutput.SelectedIndex]));

Get current state of webcam in C#

I am trying to figure out how to check if a webcam/video capture device is already being used by another application without actually activating it.
My current approach is to use the AForge.NET library and using the .IsRunning property of the VideoCaptureDevice object like this:
var videoDevices = new FilterInfoCollection(FilterCategory.VideoInputDevice);
foreach (FilterInfo videoDevice in videoDevices)
{
VideoCaptureDevice camera new AForge.Video.DirectShow.VideoCaptureDevice(videoDevice.MonikerString);
Debug.Print(camera.IsRunning)
}
I guess the IsRunning property only works on VideoCaptureDevices that have been started using the library and I need lower-level DirectShow access to the device.
While there are many ways to use DirectShow in C#, I have been unable to find a way to check the state even using DirectShow in C++. Is there some magic I need to perform here?
Thanks
Tobias Timpe
I'm not entirely sure if this will be helpful to you, but I found your question because I wanted to write a custom app to control my busylight. This is very much 'Works On My Machine' certified - it's not an attempt to give a general answer. However, I figure it may help you, and possibly the next person who comes across this page while googling...
private static bool IsWebCamInUse()
{
using (var key = Registry.CurrentUser.OpenSubKey(#"SOFTWARE\Microsoft\Windows\CurrentVersion\CapabilityAccessManager\ConsentStore\webcam\NonPackaged"))
{
foreach (var subKeyName in key.GetSubKeyNames())
{
using (var subKey = key.OpenSubKey(subKeyName))
{
if (subKey.GetValueNames().Contains("LastUsedTimeStop"))
{
var endTime = subKey.GetValue("LastUsedTimeStop") is long ? (long) subKey.GetValue("LastUsedTimeStop") : -1;
if (endTime <= 0)
{
return true;
}
}
}
}
}
return false;
}

How to create fast duplex scanning with WIA C#?

i am new to WIA. And i have been asked to make scaning service scan faster and duplex. My current service scan one page, then put it in pdf and so on untill there is less then 20 pages(this number just a crutch used before me, will be glad if someone explane how to get "if there is any paper in there" variable). I started to dig and found docs on MSDN describing properties and after found this post describing duplex sanning, but with mysterious 5 in set. After I found this and figured out what i need WIA_DPS_DOCUMENT_HANDLING_SELECT to set to 0x205(FEEDER + DUPLEX + AUTO_ADVANCE). So I tried to setup them like this:
private static void SetProperty(Property property, int value)
{
IProperty x = (IProperty)property;
Object val = value;
x.set_Value(ref val);
}
...some code...
foreach (Property prop in device.Properties)
{
//LOGGER.Warn(prop.Name);
//LOGGER.Warn(prop.PropertyID);
switch ((Int32)prop.PropertyID)
{
// Document Handling Select
case 3088:
SetProperty(prop, 517);
break;
// Pages
case 3096:
SetProperty(prop, 1);
break;
}
}
And it did't worked for me... It just stuck on setting... Can Somebody explain how to setup AUTO_ADVANCE and DUPLEX props? Or maybe "make scanning faster and duplex" need something more then just AUTO_ADVANCE and DUPLEX and my perception about them is wrong? Or I should considering "ISIS / TWAIN (Windows XP / Vista / 7 / 8 / 8.1 / 10)" string in my scan description and use other libraries?
(Window 10, Canon DR-M160||, DR-M160 & DR-M160II Driver for Windows)
and also here is the current fetch function:
public List<ImageFile> FetchImageList()
{
List<ImageFile> imageList = new List<ImageFile>();
//bool hasMorePages = true;
int testcount = 0;
while (testcount >= 0)
{
testcount--;
WIA.Device device = FindDevice(_deviceId);
if (device == null)
{
LOGGER.Warn("Scanner device not found");
return null;
}
// get item
WIA.Item scanItem = device.Items[1] as WIA.Item;
LOGGER.Debug($"ScanItem: {scanItem.ItemID}");
try
{
foreach (Property prop in device.Properties)
{
//LOGGER.Warn(prop.Name);
//LOGGER.Warn(prop.PropertyID);
switch ((Int32)prop.PropertyID)
{
// Document Handling Select
case 3088:
LOGGER.Warn("here");
SetProperty(prop, 517);
LOGGER.Warn("here");
break;
// Pages
case 3096:
SetProperty(prop, 1);
break;
}
}
// scan image
WIA.ICommonDialog wiaCommonDialog = new WIA.CommonDialog();
WIA.ImageFile image = (WIA.ImageFile)scanItem.Transfer(WIA.FormatID.wiaFormatPNG);
imageList.Add(image);
LOGGER.Warn("Front");
//get back side
image = (WIA.ImageFile)scanItem.Transfer(WIA.FormatID.wiaFormatPNG);
imageList.Add(image);
LOGGER.Warn("Back");
}
catch (Exception e)
{
throw (e);
}
}
return imageList;
}
Well... I tried to make duplex scan without AUTO_ADVANCE and got HRESULT: 0x8000FFFF (E_UNEXPECTED) on Transfer call. According to this post(even though that was on Windows 7) I guess there is no way to solve this for me by using WIA, still hope there will other suggestions...
Solved problem
I used saraff.twain and it worked for me:
- git page :https://github.com/saraff-9EB1047A4BEB4cef8506B29BA325BD5A/Saraff.Twain.NET
good library with grate wiki page.(Also have similar library for .net 4.6.1)

How do I play the Windows Notification sound? (It is not defined in System.Media.SystemSounds)

When using System.Media, there is something called SystemSounds where you can easily play a couple of operating system sounds:
System.Media.SystemSounds.Asterisk.Play();
System.Media.SystemSounds.Beep.Play();
System.Media.SystemSounds.Exclamation.Play();
System.Media.SystemSounds.Hand.Play();
System.Media.SystemSounds.Question.Play();
Unfortunately, there are only these five options, and in Windows 10, three of them are the same while one of them doesn't even play anything.
What I really want to do is play the Notification sound, as defined in the Sound panel (seen here):
Does anyone know how to do this?
Solution found. Code here:
using System.Media;
using Microsoft.Win32;
public void PlayNotificationSound()
{
bool found = false;
try
{
using (RegistryKey key = Registry.CurrentUser.OpenSubKey(#"AppEvents\Schemes\Apps\.Default\Notification.Default\.Current"))
{
if (key != null)
{
Object o = key.GetValue(null); // pass null to get (Default)
if (o != null)
{
SoundPlayer theSound = new SoundPlayer((String)o);
theSound.Play();
found = true;
}
}
}
}
catch
{ }
if (!found)
SystemSounds.Beep.Play(); // consolation prize
}
You can browse the keys in the registry editor to see the other sounds. Also, this example is coded to work for Windows 10, and I'm not sure what the registry structure is for other versions of Windows, so you'll need to double check what OS the user is using if you're trying to code for multiple platforms.

Cosmos custom OS, addmapping?

I am new to C# and is currently using COSMOS to make a simple FileSystem for my OS class. Currently I'm trying to implement a "reformat" function that, when the word "reformat" is typed into the console, the OS (emulated via QEMU), partitions the disk. Currently this is my code:
public static void console()
{
while (true)
{
Console.WriteLine("Console: ");
String input = Console.ReadLine();
if (input == "exit")
{
Cosmos.Sys.Deboot.ShutDown();
}
else if (input == "cpumem")
{
Console.WriteLine(Cosmos.Kernel.CPU.AmountOfMemory.ToString());
}
else if (input == "restart")
{
Cosmos.Sys.Deboot.Reboot();
}
else if (input == "devices")
{
var devices = Cosmos.Sys.FileSystem.Disk.Devices.ToArray();
}
else if (input == "reformat")
{
try
{
Partition part = null;
for (int j = 0; j < Cosmos.Hardware.BlockDevice.Devices.Count; j++)
{
if (Cosmos.Hardware.BlockDevice.Devices[j] is Partition)
{
part = (Partition)Cosmos.Hardware.BlockDevice.Devices[j];
}
}
var fs = new Cosmos.Sys.FileSystem.FAT32.FAT32(part);
uint cluster = 100;
fs.Format("newCluster", cluster);
}
catch
{
//Do Something warn user.
}
}
}
}
Most important is this bit:
else if (input == "reformat")
{
try
{
Partition part = null;
for (int j = 0; j < Cosmos.Hardware.BlockDevice.Devices.Count; j++)
{
if (Cosmos.Hardware.BlockDevice.Devices[j] is Partition)
{
part = (Partition)Cosmos.Hardware.BlockDevice.Devices[j];
}
}
var fs = new Cosmos.Sys.FileSystem.FAT32.FAT32(part);
uint cluster = 100;
fs.Format("newCluster", cluster);
}
catch
{
//Do Something warn user.
}
}
Which is analogous to what is located here: http://cosmos-tutorials.webs.com/atafat.html
However, when I run it, I get this error:
I believe this is because I lack this line:
Cosmos.System.Filesystem.FileSystem.AddMapping("C", FATFS);
FATFileList = FATFS.GetRoot();
Located in the link above. Is there any other way to map? Or am I missing something completely? The COSMOS documentation doesn't really tell much, the source code is honestly confusing for a beginner like me as it has no comments whatsoever on how the functions work or what they do. I am using an older version of COSMOS (Milestone 4) as it's the only one that works for Visual Studio C# 2008. Newer versions run only in Visual Studio C# 2010.
Ah, I recognize this... had to debug a similar situation on a Cosmos project I'm working on myself (I'm using the VS2010-compatible Cosmos but the same situation might apply to older versions as well...)
This can happen if you try to call a method on a null object. Type 0x........, Method 0x........ is specifically mentioning the location in the compiled code where the call failed. "Not FOUND!" means that the method it is looking for cannot be found, presumably because you called it on a null reference.
I'm testing with VirtualBox myself, and found that if you're using a brand-new blank hard disk image, there will be no Partitions on it. Thus, the condition will never get satisfied, your Partition will never get set and then Cosmos will try to execute a method on the null Partition!
Look closely at how you set the Partition (it's initialized to null). For starters I would print a simple message each time the "if (block device is partition)" condition is satisfied... I would be willing to bet it will never print.
Hope this helps... I am still learning about Cosmos and custom kernels myself but fixing the null reference in my case solved my occurrence of the problem. If that's the problem, then the next step, of course, is figuring out why you're not getting any Partitions in the first place...
The rest of your code looks fine but I am not sure how you implemented the rest of your classes. Kernel debugging can be a nightmare, good luck to you!

Categories

Resources