mirror of
https://github.com/Facepunch/Facepunch.Steamworks.git
synced 2024-12-25 14:15:47 +03:00
Voice optimization, fixes
This commit is contained in:
parent
aa1aac50af
commit
e56ab1f62a
@ -1,5 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
|
using System.IO;
|
||||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||||
|
|
||||||
namespace Facepunch.Steamworks.Test
|
namespace Facepunch.Steamworks.Test
|
||||||
@ -18,6 +19,18 @@ public void Init()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void Init_10000()
|
||||||
|
{
|
||||||
|
for ( int i = 0; i < 100; i++ )
|
||||||
|
{
|
||||||
|
using ( var client = new Facepunch.Steamworks.Client( 252490 ) )
|
||||||
|
{
|
||||||
|
Assert.IsTrue( client.IsValid );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
public void Name()
|
public void Name()
|
||||||
{
|
{
|
||||||
@ -82,6 +95,8 @@ public void Update()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static MemoryStream decompressStream = new MemoryStream();
|
||||||
|
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
public void GetVoice()
|
public void GetVoice()
|
||||||
{
|
{
|
||||||
@ -90,14 +105,19 @@ public void GetVoice()
|
|||||||
int unCompressed = 0;
|
int unCompressed = 0;
|
||||||
int compressed = 0;
|
int compressed = 0;
|
||||||
|
|
||||||
client.Voice.OnCompressedData = ( data ) =>
|
client.Voice.OnCompressedData = ( ptr, length ) =>
|
||||||
{
|
{
|
||||||
compressed += data.Length;
|
compressed += length;
|
||||||
|
|
||||||
|
if ( !client.Voice.Decompress( ptr, 0, length, decompressStream ) )
|
||||||
|
{
|
||||||
|
Assert.Fail( "Decompress returned false" );
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
client.Voice.OnUncompressedData = ( data ) =>
|
client.Voice.OnUncompressedData = ( ptr, length ) =>
|
||||||
{
|
{
|
||||||
unCompressed += data.Length;
|
unCompressed += length;
|
||||||
};
|
};
|
||||||
|
|
||||||
client.Voice.WantsRecording = true;
|
client.Voice.WantsRecording = true;
|
||||||
@ -126,9 +146,9 @@ public void GetVoice_Compressed_Only()
|
|||||||
{
|
{
|
||||||
int compressed = 0;
|
int compressed = 0;
|
||||||
|
|
||||||
client.Voice.OnCompressedData = ( data ) =>
|
client.Voice.OnCompressedData = ( ptr, length ) =>
|
||||||
{
|
{
|
||||||
compressed += data.Length;
|
compressed += length;
|
||||||
};
|
};
|
||||||
|
|
||||||
client.Voice.WantsRecording = true;
|
client.Voice.WantsRecording = true;
|
||||||
@ -153,9 +173,9 @@ public void GetVoice_UnCompressed_Only()
|
|||||||
{
|
{
|
||||||
int unCompressed = 0;
|
int unCompressed = 0;
|
||||||
|
|
||||||
client.Voice.OnUncompressedData = ( data ) =>
|
client.Voice.OnUncompressedData = ( ptr, length ) =>
|
||||||
{
|
{
|
||||||
unCompressed += data.Length;
|
unCompressed += length;
|
||||||
};
|
};
|
||||||
|
|
||||||
client.Voice.WantsRecording = true;
|
client.Voice.WantsRecording = true;
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
namespace Facepunch.Steamworks
|
namespace Facepunch.Steamworks
|
||||||
@ -15,24 +16,27 @@ public Voice Voice
|
|||||||
get
|
get
|
||||||
{
|
{
|
||||||
if ( _voice == null )
|
if ( _voice == null )
|
||||||
_voice = new Voice { client = this };
|
_voice = new Voice( this );
|
||||||
|
|
||||||
return _voice;
|
return _voice;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Voice
|
public class Voice : IDisposable
|
||||||
{
|
{
|
||||||
|
const int ReadBufferSize = 1024 * 128;
|
||||||
|
const int UncompressBufferSize = 1024 * 256;
|
||||||
|
|
||||||
internal Client client;
|
internal Client client;
|
||||||
internal byte[] bufferRegular = new byte[ 1024 * 8 ];
|
|
||||||
internal uint bufferRegularLastWrite = 0;
|
|
||||||
|
|
||||||
internal byte[] bufferCompressed = new byte[ 1024 * 8 ];
|
internal IntPtr ReadCompressedBuffer;
|
||||||
internal uint bufferCompressedLastWrite = 0;
|
internal IntPtr ReadUncompressedBuffer;
|
||||||
|
|
||||||
public Action<byte[]> OnCompressedData;
|
internal IntPtr UncompressBuffer;
|
||||||
public Action<byte[]> OnUncompressedData;
|
|
||||||
|
public Action<IntPtr, int> OnCompressedData;
|
||||||
|
public Action<IntPtr, int> OnUncompressedData;
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -68,6 +72,12 @@ public bool WantsRecording
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The last time voice was detected, recorded
|
||||||
|
/// </summary>
|
||||||
|
public DateTime LastVoiceRecordTime { get; private set; }
|
||||||
|
|
||||||
|
public TimeSpan TimeSinceLastVoiceRecord { get { return DateTime.Now.Subtract( LastVoiceRecordTime ); } }
|
||||||
|
|
||||||
public bool IsRecording = false;
|
public bool IsRecording = false;
|
||||||
|
|
||||||
@ -76,70 +86,93 @@ public bool WantsRecording
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public uint DesiredSampleRate = 0;
|
public uint DesiredSampleRate = 0;
|
||||||
|
|
||||||
internal unsafe void Update()
|
public Voice( Client client )
|
||||||
|
{
|
||||||
|
this.client = client;
|
||||||
|
|
||||||
|
ReadCompressedBuffer = Marshal.AllocHGlobal( ReadBufferSize );
|
||||||
|
ReadUncompressedBuffer = Marshal.AllocHGlobal( ReadBufferSize );
|
||||||
|
UncompressBuffer = Marshal.AllocHGlobal( UncompressBufferSize );
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
Marshal.FreeHGlobal( ReadCompressedBuffer );
|
||||||
|
Marshal.FreeHGlobal( ReadUncompressedBuffer );
|
||||||
|
|
||||||
|
Marshal.FreeHGlobal( UncompressBuffer );
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void Update()
|
||||||
{
|
{
|
||||||
if ( OnCompressedData == null && OnUncompressedData == null )
|
if ( OnCompressedData == null && OnUncompressedData == null )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
fixed ( byte* pbufferRegular = bufferRegular )
|
|
||||||
fixed ( byte* pbufferCompressed = bufferCompressed )
|
uint bufferRegularLastWrite = 0;
|
||||||
|
uint bufferCompressedLastWrite = 0;
|
||||||
|
|
||||||
|
Valve.Steamworks.EVoiceResult result = (Valve.Steamworks.EVoiceResult) client.native.user.GetVoice( OnCompressedData != null, ReadCompressedBuffer, ReadBufferSize, ref bufferCompressedLastWrite,
|
||||||
|
OnUncompressedData != null, (IntPtr) ReadUncompressedBuffer, ReadBufferSize, ref bufferRegularLastWrite,
|
||||||
|
DesiredSampleRate == 0 ? OptimalSampleRate : DesiredSampleRate );
|
||||||
|
|
||||||
|
Console.WriteLine( result );
|
||||||
|
|
||||||
|
IsRecording = true;
|
||||||
|
|
||||||
|
if ( result == Valve.Steamworks.EVoiceResult.k_EVoiceResultOK )
|
||||||
{
|
{
|
||||||
bufferRegularLastWrite = 0;
|
if ( OnCompressedData != null && bufferCompressedLastWrite > 0 )
|
||||||
bufferCompressedLastWrite = 0;
|
|
||||||
|
|
||||||
Valve.Steamworks.EVoiceResult result = (Valve.Steamworks.EVoiceResult) client.native.user.GetVoice( OnCompressedData != null, (IntPtr) pbufferCompressed, (uint) bufferCompressed.Length, ref bufferCompressedLastWrite,
|
|
||||||
OnUncompressedData != null, (IntPtr) pbufferRegular, (uint) bufferRegular.Length, ref bufferRegularLastWrite,
|
|
||||||
DesiredSampleRate == 0 ? OptimalSampleRate : DesiredSampleRate );
|
|
||||||
|
|
||||||
IsRecording = true;
|
|
||||||
|
|
||||||
if ( result == Valve.Steamworks.EVoiceResult.k_EVoiceResultOK )
|
|
||||||
{
|
{
|
||||||
if ( OnCompressedData != null && bufferCompressedLastWrite > 0 )
|
OnCompressedData( ReadCompressedBuffer, (int)bufferCompressedLastWrite );
|
||||||
{
|
|
||||||
OnCompressedData( bufferRegular.Take( (int)bufferCompressedLastWrite ).ToArray() );
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( OnUncompressedData != null && bufferRegularLastWrite > 0 )
|
|
||||||
{
|
|
||||||
OnUncompressedData( bufferRegular.Take( (int)bufferRegularLastWrite ).ToArray() );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( result == Valve.Steamworks.EVoiceResult.k_EVoiceResultNotRecording ||
|
if ( OnUncompressedData != null && bufferRegularLastWrite > 0 )
|
||||||
result == Valve.Steamworks.EVoiceResult.k_EVoiceResultNotInitialized )
|
{
|
||||||
IsRecording = false;
|
OnUncompressedData( ReadUncompressedBuffer, (int)bufferRegularLastWrite );
|
||||||
|
}
|
||||||
|
|
||||||
|
LastVoiceRecordTime = DateTime.Now;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( result == Valve.Steamworks.EVoiceResult.k_EVoiceResultNotRecording ||
|
||||||
|
result == Valve.Steamworks.EVoiceResult.k_EVoiceResultNotInitialized )
|
||||||
|
IsRecording = false;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public unsafe bool Decompress( byte[] input, MemoryStream output, uint samepleRate = 0 )
|
||||||
|
{
|
||||||
|
fixed ( byte* p = input )
|
||||||
|
{
|
||||||
|
return Decompress( (IntPtr)p, 0, input.Length, output, samepleRate );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public unsafe bool Decompress( byte[] input, int inputoffset, int inputsize, MemoryStream output, uint samepleRate = 0 )
|
public unsafe bool Decompress( IntPtr input, int inputoffset, int inputsize, MemoryStream output, uint samepleRate = 0 )
|
||||||
{
|
{
|
||||||
if ( samepleRate == 0 )
|
if ( samepleRate == 0 )
|
||||||
samepleRate = OptimalSampleRate;
|
samepleRate = OptimalSampleRate;
|
||||||
|
|
||||||
//
|
uint bytesOut = 0;
|
||||||
// Guessing the uncompressed size cuz we're dicks
|
var result = (Valve.Steamworks.EVoiceResult) client.native.user.DecompressVoice( (IntPtr)( ((byte*)input) + inputoffset ), (uint) inputsize, UncompressBuffer, UncompressBufferSize, ref bytesOut, samepleRate );
|
||||||
//
|
|
||||||
|
if ( bytesOut > 0 )
|
||||||
|
output.SetLength( bytesOut );
|
||||||
|
|
||||||
|
if ( result == Valve.Steamworks.EVoiceResult.k_EVoiceResultOK )
|
||||||
{
|
{
|
||||||
var targetBufferSize = inputsize * 10;
|
if ( output.Capacity < bytesOut )
|
||||||
|
output.Capacity = (int) bytesOut;
|
||||||
|
|
||||||
if ( output.Capacity < targetBufferSize )
|
output.SetLength( bytesOut );
|
||||||
output.Capacity = targetBufferSize;
|
Marshal.Copy( UncompressBuffer, output.GetBuffer(), 0, (int) bytesOut );
|
||||||
|
|
||||||
output.SetLength( targetBufferSize );
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
fixed ( byte* pout = output.GetBuffer() )
|
return false;
|
||||||
fixed ( byte* p = input )
|
|
||||||
{
|
|
||||||
uint bytesOut = 0;
|
|
||||||
var result = (Valve.Steamworks.EVoiceResult) client.native.user.DecompressVoice( (IntPtr)( p + inputoffset ), (uint) inputsize, (IntPtr) pout, (uint) output.Length, ref bytesOut, (uint)samepleRate );
|
|
||||||
|
|
||||||
if ( bytesOut > 0 )
|
|
||||||
output.SetLength( bytesOut );
|
|
||||||
|
|
||||||
return result == Valve.Steamworks.EVoiceResult.k_EVoiceResultOK;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user