non-vr lobby, version fix
This commit is contained in:
@@ -0,0 +1,70 @@
|
||||
#if PHOTON_VOICE_WINDOWS || UNITY_STANDALONE_WIN || UNITY_EDITOR_WIN
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Photon.Voice.Windows
|
||||
{
|
||||
/// <summary>Enumerates microphones available on device.
|
||||
/// </summary>
|
||||
public class AudioInEnumerator : DeviceEnumeratorBase
|
||||
{
|
||||
const string lib_name = "AudioIn";
|
||||
[DllImport(lib_name)]
|
||||
private static extern IntPtr Photon_Audio_In_CreateMicEnumerator();
|
||||
[DllImport(lib_name)]
|
||||
private static extern void Photon_Audio_In_DestroyMicEnumerator(IntPtr handle);
|
||||
[DllImport(lib_name)]
|
||||
private static extern int Photon_Audio_In_MicEnumerator_Count(IntPtr handle);
|
||||
[DllImport(lib_name)]
|
||||
private static extern IntPtr Photon_Audio_In_MicEnumerator_NameAtIndex(IntPtr handle, int idx);
|
||||
[DllImport(lib_name)]
|
||||
private static extern int Photon_Audio_In_MicEnumerator_IDAtIndex(IntPtr handle, int idx);
|
||||
|
||||
IntPtr handle;
|
||||
public AudioInEnumerator(ILogger logger) : base(logger)
|
||||
{
|
||||
Refresh();
|
||||
}
|
||||
|
||||
/// <summary>Refreshes the microphones list.
|
||||
/// </summary>
|
||||
public override void Refresh()
|
||||
{
|
||||
Dispose();
|
||||
try
|
||||
{
|
||||
handle = Photon_Audio_In_CreateMicEnumerator();
|
||||
var count = Photon_Audio_In_MicEnumerator_Count(handle);
|
||||
devices = new List<DeviceInfo>();
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
devices.Add(new DeviceInfo(Photon_Audio_In_MicEnumerator_IDAtIndex(handle, i), Marshal.PtrToStringAuto(Photon_Audio_In_MicEnumerator_NameAtIndex(handle, i))));
|
||||
}
|
||||
Error = null;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Error = e.ToString();
|
||||
if (Error == null) // should never happen but since Error used as validity flag, make sure that it's not null
|
||||
{
|
||||
Error = "Exception in AudioInEnumerator.Refresh()";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Disposes enumerator.
|
||||
/// Call it to free native resources.
|
||||
/// </summary>
|
||||
public override void Dispose()
|
||||
{
|
||||
if (handle != IntPtr.Zero && Error == null)
|
||||
{
|
||||
Photon_Audio_In_DestroyMicEnumerator(handle);
|
||||
handle = IntPtr.Zero;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 81007f7b708822448a7f5940c71ac788
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,124 @@
|
||||
#if PHOTON_VOICE_WINDOWS || UNITY_STANDALONE_WIN || UNITY_EDITOR_WIN
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Photon.Voice.Windows
|
||||
{
|
||||
#pragma warning disable 0414
|
||||
public class MonoPInvokeCallbackAttribute : System.Attribute
|
||||
{
|
||||
private Type type;
|
||||
public MonoPInvokeCallbackAttribute(Type t) { type = t; }
|
||||
}
|
||||
#pragma warning restore 0414
|
||||
|
||||
public class WindowsAudioInPusher : IAudioPusher<short>
|
||||
{
|
||||
enum SystemMode
|
||||
{
|
||||
SINGLE_CHANNEL_AEC = 0,
|
||||
OPTIBEAM_ARRAY_ONLY = 2,
|
||||
OPTIBEAM_ARRAY_AND_AEC = 4,
|
||||
SINGLE_CHANNEL_NSAGC = 5,
|
||||
}
|
||||
|
||||
[DllImport("AudioIn")]
|
||||
private static extern IntPtr Photon_Audio_In_Create(int instanceID, SystemMode systemMode, int micDevIdx, int spkDevIdx, Action<int, IntPtr, int> callback, bool featrModeOn, bool noiseSup, bool agc, bool cntrClip);
|
||||
|
||||
[DllImport("AudioIn")]
|
||||
private static extern void Photon_Audio_In_Destroy(IntPtr handler);
|
||||
|
||||
private delegate void CallbackDelegate(int instanceID, IntPtr buf, int len);
|
||||
|
||||
IntPtr handle;
|
||||
int instanceID;
|
||||
Action<short[]> pushCallback;
|
||||
ObjectFactory<short[], int> bufferFactory;
|
||||
|
||||
public WindowsAudioInPusher(int deviceID, ILogger logger)
|
||||
{
|
||||
try
|
||||
{
|
||||
lock (instancePerHandle)
|
||||
{
|
||||
// use default playback device
|
||||
handle = Photon_Audio_In_Create(instanceCnt, SystemMode.SINGLE_CHANNEL_AEC, deviceID, -1, nativePushCallback, true, true, true, true); // defaults in original ms sample: false, true, false, false
|
||||
this.instanceID = instanceCnt;
|
||||
instancePerHandle.Add(instanceCnt++, this);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Error = e.ToString();
|
||||
if (Error == null) // should never happen but since Error used as validity flag, make sure that it's not null
|
||||
{
|
||||
Error = "Exception in WindowsAudioInPusher constructor";
|
||||
}
|
||||
logger.LogError("[PV] WindowsAudioInPusher: " + Error);
|
||||
}
|
||||
}
|
||||
|
||||
// IL2CPP does not support marshaling delegates that point to instance methods to native code.
|
||||
// Using static method and per instance table.
|
||||
static int instanceCnt;
|
||||
private static Dictionary<int, WindowsAudioInPusher> instancePerHandle = new Dictionary<int, WindowsAudioInPusher>();
|
||||
[MonoPInvokeCallbackAttribute(typeof(CallbackDelegate))]
|
||||
private static void nativePushCallback(int instanceID, IntPtr buf, int len)
|
||||
{
|
||||
WindowsAudioInPusher instance;
|
||||
bool ok;
|
||||
lock (instancePerHandle)
|
||||
{
|
||||
ok = instancePerHandle.TryGetValue(instanceID, out instance);
|
||||
}
|
||||
if (ok)
|
||||
{
|
||||
instance.push(buf, len);
|
||||
}
|
||||
}
|
||||
|
||||
// Supposed to be called once at voice initialization.
|
||||
// Otherwise recreate native object (instead of adding 'set callback' method to native interface)
|
||||
public void SetCallback(Action<short[]> callback, ObjectFactory<short[], int> bufferFactory)
|
||||
{
|
||||
this.bufferFactory = bufferFactory;
|
||||
this.pushCallback = callback;
|
||||
}
|
||||
|
||||
private void push(IntPtr buf, int lenBytes)
|
||||
{
|
||||
if (pushCallback != null)
|
||||
{
|
||||
var len = lenBytes / sizeof(short);
|
||||
var bufManaged = this.bufferFactory.New(len);
|
||||
Marshal.Copy(buf, bufManaged, 0, len);
|
||||
pushCallback(bufManaged);
|
||||
}
|
||||
}
|
||||
|
||||
public int Channels { get { return 1; } }
|
||||
|
||||
// Hardcoded in AudioInAec.cpp
|
||||
// Supported sample rates: 8000, 11025, 16000, 22050
|
||||
// https://docs.microsoft.com/en-us/windows/win32/medfound/voicecapturedmo?redirectedfrom=MSDN (Voice Capture DSP)
|
||||
public int SamplingRate { get { return 16000; } }
|
||||
|
||||
public string Error { get; private set; }
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
lock (instancePerHandle)
|
||||
{
|
||||
instancePerHandle.Remove(instanceID);
|
||||
}
|
||||
if (handle != IntPtr.Zero)
|
||||
{
|
||||
Photon_Audio_In_Destroy(handle);
|
||||
handle = IntPtr.Zero;
|
||||
}
|
||||
// TODO: Remove this from instancePerHandle
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f2c69afb30794f445b1c5cebc5e6a3fe
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user