Robust native, compiled with ogg, opus, and vorbis

This commit is contained in:
PJB3005
2026-01-10 23:22:13 +01:00
parent 539d0563b8
commit 927f05fd3b
52 changed files with 1364 additions and 15 deletions

View File

@@ -0,0 +1,13 @@
using System.Runtime.CompilerServices;
using Robust.Shared.Interop.RobustNative;
namespace Robust.Client;
internal static class ModuleInit
{
[ModuleInitializer]
public static void Initialize()
{
RobustNativeDll.IsClientProcess = true;
}
}

View File

@@ -48,6 +48,7 @@
<ProjectReference Include="..\Lidgren.Network\Lidgren.Network.csproj" />
<ProjectReference Include="..\NetSerializer\NetSerializer\NetSerializer.csproj" />
<ProjectReference Include="..\Robust.LoaderApi\Robust.LoaderApi\Robust.LoaderApi.csproj" />
<ProjectReference Include="..\Robust.Shared.Interop.RobustNative\Robust.Shared.Interop.RobustNative.csproj" />
<ProjectReference Include="..\Robust.Shared.Maths\Robust.Shared.Maths.csproj" />
<ProjectReference Include="..\Robust.Shared\Robust.Shared.csproj" />
</ItemGroup>

View File

@@ -0,0 +1,13 @@
using System.Runtime.CompilerServices;
using Robust.Shared.Interop.RobustNative;
namespace Robust.Server;
internal static class ModuleInit
{
[ModuleInitializer]
public static void Initialize()
{
RobustNativeDll.IsServerProcess = true;
}
}

View File

@@ -44,6 +44,7 @@
<ItemGroup>
<ProjectReference Include="..\Lidgren.Network\Lidgren.Network.csproj" />
<ProjectReference Include="..\NetSerializer\NetSerializer\NetSerializer.csproj" />
<ProjectReference Include="..\Robust.Shared.Interop.RobustNative\Robust.Shared.Interop.RobustNative.csproj" />
<ProjectReference Include="..\Robust.Shared.Maths\Robust.Shared.Maths.csproj" />
<ProjectReference Include="..\Robust.Shared.Scripting\Robust.Shared.Scripting.csproj" />
<ProjectReference Include="..\Robust.Shared\Robust.Shared.csproj" />

View File

@@ -0,0 +1,5 @@
using System.Runtime.CompilerServices;
[assembly: InternalsVisibleTo("Robust.Shared")]
[assembly: InternalsVisibleTo("Robust.Client")]
[assembly: InternalsVisibleTo("Robust.Server")]

View File

@@ -0,0 +1,2 @@
global using System.Runtime.InteropServices;
global using Robust.Shared.Interop.RobustNative.Ogg;

View File

@@ -1,9 +1,9 @@
using System;
using System.Runtime.InteropServices;
// ReSharper disable IdentifierTypo
// ReSharper disable InconsistentNaming
namespace Robust.Shared.Native;
namespace Robust.Shared.Interop.RobustNative;
internal static class Libc
internal static partial class Libc
{
public const int RTLD_LAZY = 0x00001;
public const int RTLD_NOW = 0x00002;
@@ -14,6 +14,6 @@ internal static class Libc
public const int RTLD_LOCAL = 0;
public const int RTLD_NODELETE = 0x01000;
[DllImport("libdl.so.2")]
public static extern IntPtr dlopen([MarshalAs(UnmanagedType.LPUTF8Str)] string name, int flags);
[LibraryImport("dl", StringMarshalling = StringMarshalling.Utf8)]
public static partial IntPtr dlopen(string name, int flags);
}

View File

@@ -0,0 +1,22 @@
using System;
using System.Diagnostics;
namespace Robust.Shared.Interop.RobustNative.Ogg;
/// <summary>Defines the annotation found in a native declaration.</summary>
[AttributeUsage(AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.ReturnValue, AllowMultiple = true, Inherited = false)]
[Conditional("DEBUG")]
internal sealed partial class NativeAnnotationAttribute : Attribute
{
private readonly string _annotation;
/// <summary>Initializes a new instance of the <see cref="NativeAnnotationAttribute" /> class.</summary>
/// <param name="annotation">The annotation that was used in the native declaration.</param>
public NativeAnnotationAttribute(string annotation)
{
_annotation = annotation;
}
/// <summary>Gets the annotation that was used in the native declaration.</summary>
public string Annotation => _annotation;
}

View File

@@ -0,0 +1,22 @@
using System;
using System.Diagnostics;
namespace Robust.Shared.Interop.RobustNative.Ogg;
/// <summary>Defines the type of a member as it was used in the native signature.</summary>
[AttributeUsage(AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.ReturnValue, AllowMultiple = false, Inherited = true)]
[Conditional("DEBUG")]
internal sealed partial class NativeTypeNameAttribute : Attribute
{
private readonly string _name;
/// <summary>Initializes a new instance of the <see cref="NativeTypeNameAttribute" /> class.</summary>
/// <param name="name">The name of the type that was used in the native signature.</param>
public NativeTypeNameAttribute(string name)
{
_name = name;
}
/// <summary>Gets the name of the type that was used in the native signature.</summary>
public string Name => _name;
}

View File

@@ -0,0 +1,237 @@
using System.Runtime.InteropServices;
namespace Robust.Shared.Interop.RobustNative.Ogg;
internal static unsafe partial class Ogg
{
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern void oggpack_writeinit(oggpack_buffer* b);
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern int oggpack_writecheck(oggpack_buffer* b);
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern void oggpack_writetrunc(oggpack_buffer* b, [NativeTypeName("long")] CLong bits);
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern void oggpack_writealign(oggpack_buffer* b);
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern void oggpack_writecopy(oggpack_buffer* b, void* source, [NativeTypeName("long")] CLong bits);
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern void oggpack_reset(oggpack_buffer* b);
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern void oggpack_writeclear(oggpack_buffer* b);
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern void oggpack_readinit(oggpack_buffer* b, [NativeTypeName("unsigned char *")] byte* buf, int bytes);
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern void oggpack_write(oggpack_buffer* b, [NativeTypeName("unsigned long")] CULong value, int bits);
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
[return: NativeTypeName("long")]
public static extern CLong oggpack_look(oggpack_buffer* b, int bits);
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
[return: NativeTypeName("long")]
public static extern CLong oggpack_look1(oggpack_buffer* b);
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern void oggpack_adv(oggpack_buffer* b, int bits);
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern void oggpack_adv1(oggpack_buffer* b);
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
[return: NativeTypeName("long")]
public static extern CLong oggpack_read(oggpack_buffer* b, int bits);
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
[return: NativeTypeName("long")]
public static extern CLong oggpack_read1(oggpack_buffer* b);
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
[return: NativeTypeName("long")]
public static extern CLong oggpack_bytes(oggpack_buffer* b);
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
[return: NativeTypeName("long")]
public static extern CLong oggpack_bits(oggpack_buffer* b);
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
[return: NativeTypeName("unsigned char *")]
public static extern byte* oggpack_get_buffer(oggpack_buffer* b);
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern void oggpackB_writeinit(oggpack_buffer* b);
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern int oggpackB_writecheck(oggpack_buffer* b);
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern void oggpackB_writetrunc(oggpack_buffer* b, [NativeTypeName("long")] CLong bits);
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern void oggpackB_writealign(oggpack_buffer* b);
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern void oggpackB_writecopy(oggpack_buffer* b, void* source, [NativeTypeName("long")] CLong bits);
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern void oggpackB_reset(oggpack_buffer* b);
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern void oggpackB_writeclear(oggpack_buffer* b);
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern void oggpackB_readinit(oggpack_buffer* b, [NativeTypeName("unsigned char *")] byte* buf, int bytes);
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern void oggpackB_write(oggpack_buffer* b, [NativeTypeName("unsigned long")] CULong value, int bits);
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
[return: NativeTypeName("long")]
public static extern CLong oggpackB_look(oggpack_buffer* b, int bits);
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
[return: NativeTypeName("long")]
public static extern CLong oggpackB_look1(oggpack_buffer* b);
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern void oggpackB_adv(oggpack_buffer* b, int bits);
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern void oggpackB_adv1(oggpack_buffer* b);
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
[return: NativeTypeName("long")]
public static extern CLong oggpackB_read(oggpack_buffer* b, int bits);
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
[return: NativeTypeName("long")]
public static extern CLong oggpackB_read1(oggpack_buffer* b);
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
[return: NativeTypeName("long")]
public static extern CLong oggpackB_bytes(oggpack_buffer* b);
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
[return: NativeTypeName("long")]
public static extern CLong oggpackB_bits(oggpack_buffer* b);
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
[return: NativeTypeName("unsigned char *")]
public static extern byte* oggpackB_get_buffer(oggpack_buffer* b);
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern int ogg_stream_packetin(ogg_stream_state* os, ogg_packet* op);
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern int ogg_stream_iovecin(ogg_stream_state* os, ogg_iovec_t* iov, int count, [NativeTypeName("long")] CLong e_o_s, [NativeTypeName("ogg_int64_t")] CLong granulepos);
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern int ogg_stream_pageout(ogg_stream_state* os, ogg_page* og);
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern int ogg_stream_pageout_fill(ogg_stream_state* os, ogg_page* og, int nfill);
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern int ogg_stream_flush(ogg_stream_state* os, ogg_page* og);
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern int ogg_stream_flush_fill(ogg_stream_state* os, ogg_page* og, int nfill);
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern int ogg_sync_init(ogg_sync_state* oy);
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern int ogg_sync_clear(ogg_sync_state* oy);
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern int ogg_sync_reset(ogg_sync_state* oy);
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern int ogg_sync_destroy(ogg_sync_state* oy);
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern int ogg_sync_check(ogg_sync_state* oy);
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
[return: NativeTypeName("char *")]
public static extern sbyte* ogg_sync_buffer(ogg_sync_state* oy, [NativeTypeName("long")] CLong size);
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern int ogg_sync_wrote(ogg_sync_state* oy, [NativeTypeName("long")] CLong bytes);
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
[return: NativeTypeName("long")]
public static extern CLong ogg_sync_pageseek(ogg_sync_state* oy, ogg_page* og);
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern int ogg_sync_pageout(ogg_sync_state* oy, ogg_page* og);
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern int ogg_stream_pagein(ogg_stream_state* os, ogg_page* og);
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern int ogg_stream_packetout(ogg_stream_state* os, ogg_packet* op);
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern int ogg_stream_packetpeek(ogg_stream_state* os, ogg_packet* op);
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern int ogg_stream_init(ogg_stream_state* os, int serialno);
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern int ogg_stream_clear(ogg_stream_state* os);
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern int ogg_stream_reset(ogg_stream_state* os);
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern int ogg_stream_reset_serialno(ogg_stream_state* os, int serialno);
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern int ogg_stream_destroy(ogg_stream_state* os);
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern int ogg_stream_check(ogg_stream_state* os);
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern int ogg_stream_eos(ogg_stream_state* os);
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern void ogg_page_checksum_set(ogg_page* og);
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern int ogg_page_version([NativeTypeName("const ogg_page *")] ogg_page* og);
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern int ogg_page_continued([NativeTypeName("const ogg_page *")] ogg_page* og);
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern int ogg_page_bos([NativeTypeName("const ogg_page *")] ogg_page* og);
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern int ogg_page_eos([NativeTypeName("const ogg_page *")] ogg_page* og);
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
[return: NativeTypeName("ogg_int64_t")]
public static extern CLong ogg_page_granulepos([NativeTypeName("const ogg_page *")] ogg_page* og);
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern int ogg_page_serialno([NativeTypeName("const ogg_page *")] ogg_page* og);
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
[return: NativeTypeName("long")]
public static extern CLong ogg_page_pageno([NativeTypeName("const ogg_page *")] ogg_page* og);
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern int ogg_page_packets([NativeTypeName("const ogg_page *")] ogg_page* og);
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern void ogg_packet_clear(ogg_packet* op);
}

View File

@@ -0,0 +1,9 @@
namespace Robust.Shared.Interop.RobustNative.Ogg;
internal unsafe partial struct ogg_iovec_t
{
public void* iov_base;
[NativeTypeName("size_t")]
public nuint iov_len;
}

View File

@@ -0,0 +1,22 @@
namespace Robust.Shared.Interop.RobustNative.Ogg;
internal unsafe partial struct ogg_packet
{
[NativeTypeName("unsigned char *")]
public byte* packet;
[NativeTypeName("long")]
public CLong bytes;
[NativeTypeName("long")]
public CLong b_o_s;
[NativeTypeName("long")]
public CLong e_o_s;
[NativeTypeName("ogg_int64_t")]
public CLong granulepos;
[NativeTypeName("ogg_int64_t")]
public CLong packetno;
}

View File

@@ -0,0 +1,16 @@
namespace Robust.Shared.Interop.RobustNative.Ogg;
internal unsafe partial struct ogg_page
{
[NativeTypeName("unsigned char *")]
public byte* header;
[NativeTypeName("long")]
public CLong header_len;
[NativeTypeName("unsigned char *")]
public byte* body;
[NativeTypeName("long")]
public CLong body_len;
}

View File

@@ -0,0 +1,54 @@
namespace Robust.Shared.Interop.RobustNative.Ogg;
internal unsafe partial struct ogg_stream_state
{
[NativeTypeName("unsigned char *")]
public byte* body_data;
[NativeTypeName("long")]
public CLong body_storage;
[NativeTypeName("long")]
public CLong body_fill;
[NativeTypeName("long")]
public CLong body_returned;
public int* lacing_vals;
[NativeTypeName("ogg_int64_t *")]
public CLong* granule_vals;
[NativeTypeName("long")]
public CLong lacing_storage;
[NativeTypeName("long")]
public CLong lacing_fill;
[NativeTypeName("long")]
public CLong lacing_packet;
[NativeTypeName("long")]
public CLong lacing_returned;
[NativeTypeName("unsigned char[282]")]
public fixed byte header[282];
public int header_fill;
public int e_o_s;
public int b_o_s;
[NativeTypeName("long")]
public CLong serialno;
[NativeTypeName("long")]
public CLong pageno;
[NativeTypeName("ogg_int64_t")]
public CLong packetno;
[NativeTypeName("ogg_int64_t")]
public CLong granulepos;
}

View File

@@ -0,0 +1,19 @@
namespace Robust.Shared.Interop.RobustNative.Ogg;
internal unsafe partial struct ogg_sync_state
{
[NativeTypeName("unsigned char *")]
public byte* data;
public int storage;
public int fill;
public int returned;
public int unsynced;
public int headerbytes;
public int bodybytes;
}

View File

@@ -0,0 +1,18 @@
namespace Robust.Shared.Interop.RobustNative.Ogg;
internal unsafe partial struct oggpack_buffer
{
[NativeTypeName("long")]
public CLong endbyte;
public int endbit;
[NativeTypeName("unsigned char *")]
public byte* buffer;
[NativeTypeName("unsigned char *")]
public byte* ptr;
[NativeTypeName("long")]
public CLong storage;
}

View File

@@ -0,0 +1,22 @@
using System;
using System.Diagnostics;
namespace Robust.Shared.Interop.RobustNative.Opus;
/// <summary>Defines the annotation found in a native declaration.</summary>
[AttributeUsage(AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.ReturnValue, AllowMultiple = true, Inherited = false)]
[Conditional("DEBUG")]
internal sealed partial class NativeAnnotationAttribute : Attribute
{
private readonly string _annotation;
/// <summary>Initializes a new instance of the <see cref="NativeAnnotationAttribute" /> class.</summary>
/// <param name="annotation">The annotation that was used in the native declaration.</param>
public NativeAnnotationAttribute(string annotation)
{
_annotation = annotation;
}
/// <summary>Gets the annotation that was used in the native declaration.</summary>
public string Annotation => _annotation;
}

View File

@@ -0,0 +1,22 @@
using System;
using System.Diagnostics;
namespace Robust.Shared.Interop.RobustNative.Opus;
/// <summary>Defines the type of a member as it was used in the native signature.</summary>
[AttributeUsage(AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.ReturnValue, AllowMultiple = false, Inherited = true)]
[Conditional("DEBUG")]
internal sealed partial class NativeTypeNameAttribute : Attribute
{
private readonly string _name;
/// <summary>Initializes a new instance of the <see cref="NativeTypeNameAttribute" /> class.</summary>
/// <param name="name">The name of the type that was used in the native signature.</param>
public NativeTypeNameAttribute(string name)
{
_name = name;
}
/// <summary>Gets the name of the type that was used in the native signature.</summary>
public string Name => _name;
}

View File

@@ -0,0 +1,161 @@
using System.Runtime.InteropServices;
namespace Robust.Shared.Interop.RobustNative.Opus;
internal static unsafe partial class Opus
{
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
[return: NativeTypeName("const char *")]
public static extern sbyte* opus_strerror(int error);
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
[return: NativeTypeName("const char *")]
public static extern sbyte* opus_get_version_string();
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern int opus_encoder_get_size(int channels);
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern OpusEncoder* opus_encoder_create([NativeTypeName("opus_int32")] int Fs, int channels, int application, int* error);
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern int opus_encoder_init(OpusEncoder* st, [NativeTypeName("opus_int32")] int Fs, int channels, int application);
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
[return: NativeTypeName("opus_int32")]
public static extern int opus_encode(OpusEncoder* st, [NativeTypeName("const opus_int16 *")] short* pcm, int frame_size, [NativeTypeName("unsigned char *")] byte* data, [NativeTypeName("opus_int32")] int max_data_bytes);
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
[return: NativeTypeName("opus_int32")]
public static extern int opus_encode_float(OpusEncoder* st, [NativeTypeName("const float *")] float* pcm, int frame_size, [NativeTypeName("unsigned char *")] byte* data, [NativeTypeName("opus_int32")] int max_data_bytes);
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern void opus_encoder_destroy(OpusEncoder* st);
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern int opus_encoder_ctl(OpusEncoder* st, int request, __arglist);
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern int opus_decoder_get_size(int channels);
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern OpusDecoder* opus_decoder_create([NativeTypeName("opus_int32")] int Fs, int channels, int* error);
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern int opus_decoder_init(OpusDecoder* st, [NativeTypeName("opus_int32")] int Fs, int channels);
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern int opus_decode(OpusDecoder* st, [NativeTypeName("const unsigned char *")] byte* data, [NativeTypeName("opus_int32")] int len, [NativeTypeName("opus_int16 *")] short* pcm, int frame_size, int decode_fec);
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern int opus_decode_float(OpusDecoder* st, [NativeTypeName("const unsigned char *")] byte* data, [NativeTypeName("opus_int32")] int len, float* pcm, int frame_size, int decode_fec);
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern int opus_decoder_ctl(OpusDecoder* st, int request, __arglist);
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern void opus_decoder_destroy(OpusDecoder* st);
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern int opus_dred_decoder_get_size();
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern OpusDREDDecoder* opus_dred_decoder_create(int* error);
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern int opus_dred_decoder_init(OpusDREDDecoder* dec);
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern void opus_dred_decoder_destroy(OpusDREDDecoder* dec);
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern int opus_dred_decoder_ctl(OpusDREDDecoder* dred_dec, int request, __arglist);
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern int opus_dred_get_size();
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern OpusDRED* opus_dred_alloc(int* error);
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern void opus_dred_free(OpusDRED* dec);
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern int opus_dred_parse(OpusDREDDecoder* dred_dec, OpusDRED* dred, [NativeTypeName("const unsigned char *")] byte* data, [NativeTypeName("opus_int32")] int len, [NativeTypeName("opus_int32")] int max_dred_samples, [NativeTypeName("opus_int32")] int sampling_rate, int* dred_end, int defer_processing);
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern int opus_dred_process(OpusDREDDecoder* dred_dec, [NativeTypeName("const OpusDRED *")] OpusDRED* src, OpusDRED* dst);
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern int opus_decoder_dred_decode(OpusDecoder* st, [NativeTypeName("const OpusDRED *")] OpusDRED* dred, [NativeTypeName("opus_int32")] int dred_offset, [NativeTypeName("opus_int16 *")] short* pcm, [NativeTypeName("opus_int32")] int frame_size);
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern int opus_decoder_dred_decode_float(OpusDecoder* st, [NativeTypeName("const OpusDRED *")] OpusDRED* dred, [NativeTypeName("opus_int32")] int dred_offset, float* pcm, [NativeTypeName("opus_int32")] int frame_size);
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern int opus_packet_parse([NativeTypeName("const unsigned char *")] byte* data, [NativeTypeName("opus_int32")] int len, [NativeTypeName("unsigned char *")] byte* out_toc, [NativeTypeName("const unsigned char *[48]")] byte** frames, [NativeTypeName("opus_int16[48]")] short* size, int* payload_offset);
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern int opus_packet_get_bandwidth([NativeTypeName("const unsigned char *")] byte* data);
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern int opus_packet_get_samples_per_frame([NativeTypeName("const unsigned char *")] byte* data, [NativeTypeName("opus_int32")] int Fs);
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern int opus_packet_get_nb_channels([NativeTypeName("const unsigned char *")] byte* data);
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern int opus_packet_get_nb_frames([NativeTypeName("const unsigned char[]")] byte* packet, [NativeTypeName("opus_int32")] int len);
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern int opus_packet_get_nb_samples([NativeTypeName("const unsigned char[]")] byte* packet, [NativeTypeName("opus_int32")] int len, [NativeTypeName("opus_int32")] int Fs);
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern int opus_packet_has_lbrr([NativeTypeName("const unsigned char[]")] byte* packet, [NativeTypeName("opus_int32")] int len);
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern int opus_decoder_get_nb_samples([NativeTypeName("const OpusDecoder *")] OpusDecoder* dec, [NativeTypeName("const unsigned char[]")] byte* packet, [NativeTypeName("opus_int32")] int len);
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern void opus_pcm_soft_clip(float* pcm, int frame_size, int channels, float* softclip_mem);
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern int opus_repacketizer_get_size();
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern OpusRepacketizer* opus_repacketizer_init(OpusRepacketizer* rp);
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern OpusRepacketizer* opus_repacketizer_create();
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern void opus_repacketizer_destroy(OpusRepacketizer* rp);
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern int opus_repacketizer_cat(OpusRepacketizer* rp, [NativeTypeName("const unsigned char *")] byte* data, [NativeTypeName("opus_int32")] int len);
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
[return: NativeTypeName("opus_int32")]
public static extern int opus_repacketizer_out_range(OpusRepacketizer* rp, int begin, int end, [NativeTypeName("unsigned char *")] byte* data, [NativeTypeName("opus_int32")] int maxlen);
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern int opus_repacketizer_get_nb_frames(OpusRepacketizer* rp);
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
[return: NativeTypeName("opus_int32")]
public static extern int opus_repacketizer_out(OpusRepacketizer* rp, [NativeTypeName("unsigned char *")] byte* data, [NativeTypeName("opus_int32")] int maxlen);
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern int opus_packet_pad([NativeTypeName("unsigned char *")] byte* data, [NativeTypeName("opus_int32")] int len, [NativeTypeName("opus_int32")] int new_len);
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
[return: NativeTypeName("opus_int32")]
public static extern int opus_packet_unpad([NativeTypeName("unsigned char *")] byte* data, [NativeTypeName("opus_int32")] int len);
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern int opus_multistream_packet_pad([NativeTypeName("unsigned char *")] byte* data, [NativeTypeName("opus_int32")] int len, [NativeTypeName("opus_int32")] int new_len, int nb_streams);
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
[return: NativeTypeName("opus_int32")]
public static extern int opus_multistream_packet_unpad([NativeTypeName("unsigned char *")] byte* data, [NativeTypeName("opus_int32")] int len, int nb_streams);
}

View File

@@ -0,0 +1,5 @@
namespace Robust.Shared.Interop.RobustNative.Opus;
internal partial struct OpusDRED
{
}

View File

@@ -0,0 +1,5 @@
namespace Robust.Shared.Interop.RobustNative.Opus;
internal partial struct OpusDREDDecoder
{
}

View File

@@ -0,0 +1,5 @@
namespace Robust.Shared.Interop.RobustNative.Opus;
internal partial struct OpusDecoder
{
}

View File

@@ -0,0 +1,5 @@
namespace Robust.Shared.Interop.RobustNative.Opus;
internal partial struct OpusEncoder
{
}

View File

@@ -0,0 +1,5 @@
namespace Robust.Shared.Interop.RobustNative.Opus;
internal partial struct OpusRepacketizer
{
}

View File

@@ -0,0 +1,16 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\MSBuild\Robust.Engine.props" />
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="JetBrains.Annotations" PrivateAssets="All" />
</ItemGroup>
<Import Project="..\MSBuild\Robust.Properties.targets" />
</Project>

View File

@@ -0,0 +1,95 @@
namespace Robust.Shared.Interop.RobustNative;
internal static class RobustNativeDll
{
private const string DllName = "robust-native";
private static readonly Lock LoadLock = new();
public static bool IsClientProcess;
public static bool IsServerProcess;
private static nint _robustNativeHandle;
private static Exception? _loadFailed;
static RobustNativeDll()
{
NativeLibrary.SetDllImportResolver(typeof(RobustNativeDll).Assembly,
(name, _, _) =>
{
if (name == DllName)
return LoadRobustNative();
return 0;
});
}
public static nint LoadRobustNative()
{
using var _ = LoadLock.EnterScope();
if (_robustNativeHandle != 0)
return _robustNativeHandle;
if (_loadFailed != null)
throw _loadFailed;
try
{
_robustNativeHandle = LoadCore();
return _robustNativeHandle;
}
catch (Exception e)
{
_loadFailed = e;
throw _loadFailed;
}
}
private static nint LoadCore()
{
var dllName = GetDllName();
#if WINDOWS
return NativeLibrary.Load(dllName, typeof(RobustNativeDll).Assembly, DllImportSearchPath.SafeDirectories);
#elif UNIX
#if MACOS
dllName = $"lib{dllName}.dylib";
#else
dllName = $"lib{dllName}.so";
#endif
// On Unix platforms we *need* to load the native lib with RTLD_DEEPBIND | RTLD_LOCAL
// To avoid issues with symbol collisions.
var searchDirectories = (string?)AppContext.GetData("NATIVE_DLL_SEARCH_DIRECTORIES");
foreach (var dir in searchDirectories?.Split(':') ?? Array.Empty<string>()) {
var libraryPath = Path.Combine(dir, dllName);
var attempt = Libc.dlopen(libraryPath, Libc.RTLD_LAZY | Libc.RTLD_DEEPBIND | Libc.RTLD_LOCAL);
if (attempt != 0)
return attempt;
}
throw new DllNotFoundException($"Unable to locatee {dllName}");
#endif
}
private static string GetDllName()
{
#if DEVELOPMENT
// Always load universal on dev builds to avoid issues with test processes.
return "robust_native_universal";
#else
if (IsClientProcess && IsServerProcess)
return "robust_native_universal";
if (IsClientProcess)
return "robust_native_client";
if (IsServerProcess)
return "robust_native_server";
throw new InvalidOperationException("Is neither server or client process???");
#endif
}
}

View File

@@ -0,0 +1,22 @@
using System;
using System.Diagnostics;
namespace Robust.Shared.Interop.RobustNative.Vorbis;
/// <summary>Defines the annotation found in a native declaration.</summary>
[AttributeUsage(AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.ReturnValue, AllowMultiple = true, Inherited = false)]
[Conditional("DEBUG")]
internal sealed partial class NativeAnnotationAttribute : Attribute
{
private readonly string _annotation;
/// <summary>Initializes a new instance of the <see cref="NativeAnnotationAttribute" /> class.</summary>
/// <param name="annotation">The annotation that was used in the native declaration.</param>
public NativeAnnotationAttribute(string annotation)
{
_annotation = annotation;
}
/// <summary>Gets the annotation that was used in the native declaration.</summary>
public string Annotation => _annotation;
}

View File

@@ -0,0 +1,22 @@
using System;
using System.Diagnostics;
namespace Robust.Shared.Interop.RobustNative.Vorbis;
/// <summary>Defines the type of a member as it was used in the native signature.</summary>
[AttributeUsage(AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.ReturnValue, AllowMultiple = false, Inherited = true)]
[Conditional("DEBUG")]
internal sealed partial class NativeTypeNameAttribute : Attribute
{
private readonly string _name;
/// <summary>Initializes a new instance of the <see cref="NativeTypeNameAttribute" /> class.</summary>
/// <param name="name">The name of the type that was used in the native signature.</param>
public NativeTypeNameAttribute(string name)
{
_name = name;
}
/// <summary>Gets the name of the type that was used in the native signature.</summary>
public string Name => _name;
}

View File

@@ -0,0 +1,117 @@
using System.Runtime.InteropServices;
namespace Robust.Shared.Interop.RobustNative.Vorbis;
internal static unsafe partial class Vorbis
{
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern void vorbis_info_init(vorbis_info* vi);
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern void vorbis_info_clear(vorbis_info* vi);
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern int vorbis_info_blocksize(vorbis_info* vi, int zo);
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern void vorbis_comment_init(vorbis_comment* vc);
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern void vorbis_comment_add(vorbis_comment* vc, [NativeTypeName("const char *")] sbyte* comment);
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern void vorbis_comment_add_tag(vorbis_comment* vc, [NativeTypeName("const char *")] sbyte* tag, [NativeTypeName("const char *")] sbyte* contents);
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
[return: NativeTypeName("char *")]
public static extern sbyte* vorbis_comment_query(vorbis_comment* vc, [NativeTypeName("const char *")] sbyte* tag, int count);
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern int vorbis_comment_query_count(vorbis_comment* vc, [NativeTypeName("const char *")] sbyte* tag);
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern void vorbis_comment_clear(vorbis_comment* vc);
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern int vorbis_block_init(vorbis_dsp_state* v, vorbis_block* vb);
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern int vorbis_block_clear(vorbis_block* vb);
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern void vorbis_dsp_clear(vorbis_dsp_state* v);
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern double vorbis_granule_time(vorbis_dsp_state* v, [NativeTypeName("ogg_int64_t")] CLong granulepos);
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
[return: NativeTypeName("const char *")]
public static extern sbyte* vorbis_version_string();
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern int vorbis_analysis_init(vorbis_dsp_state* v, vorbis_info* vi);
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern int vorbis_commentheader_out(vorbis_comment* vc, ogg_packet* op);
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern int vorbis_analysis_headerout(vorbis_dsp_state* v, vorbis_comment* vc, ogg_packet* op, ogg_packet* op_comm, ogg_packet* op_code);
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern float** vorbis_analysis_buffer(vorbis_dsp_state* v, int vals);
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern int vorbis_analysis_wrote(vorbis_dsp_state* v, int vals);
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern int vorbis_analysis_blockout(vorbis_dsp_state* v, vorbis_block* vb);
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern int vorbis_analysis(vorbis_block* vb, ogg_packet* op);
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern int vorbis_bitrate_addblock(vorbis_block* vb);
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern int vorbis_bitrate_flushpacket(vorbis_dsp_state* vd, ogg_packet* op);
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern int vorbis_synthesis_idheader(ogg_packet* op);
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern int vorbis_synthesis_headerin(vorbis_info* vi, vorbis_comment* vc, ogg_packet* op);
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern int vorbis_synthesis_init(vorbis_dsp_state* v, vorbis_info* vi);
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern int vorbis_synthesis_restart(vorbis_dsp_state* v);
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern int vorbis_synthesis(vorbis_block* vb, ogg_packet* op);
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern int vorbis_synthesis_trackonly(vorbis_block* vb, ogg_packet* op);
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern int vorbis_synthesis_blockin(vorbis_dsp_state* v, vorbis_block* vb);
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern int vorbis_synthesis_pcmout(vorbis_dsp_state* v, float*** pcm);
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern int vorbis_synthesis_lapout(vorbis_dsp_state* v, float*** pcm);
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern int vorbis_synthesis_read(vorbis_dsp_state* v, int samples);
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
[return: NativeTypeName("long")]
public static extern CLong vorbis_packet_blocksize(vorbis_info* vi, ogg_packet* op);
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern int vorbis_synthesis_halfrate(vorbis_info* v, int flag);
[DllImport("robust-native", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
public static extern int vorbis_synthesis_halfrate_p(vorbis_info* v);
}

View File

@@ -0,0 +1,9 @@
namespace Robust.Shared.Interop.RobustNative.Vorbis;
internal unsafe partial struct alloc_chain
{
public void* ptr;
[NativeTypeName("struct alloc_chain *")]
public alloc_chain* next;
}

View File

@@ -0,0 +1,59 @@
namespace Robust.Shared.Interop.RobustNative.Vorbis;
internal unsafe partial struct vorbis_block
{
public float** pcm;
public oggpack_buffer opb;
[NativeTypeName("long")]
public CLong lW;
[NativeTypeName("long")]
public CLong W;
[NativeTypeName("long")]
public CLong nW;
public int pcmend;
public int mode;
public int eofflag;
[NativeTypeName("ogg_int64_t")]
public CLong granulepos;
[NativeTypeName("ogg_int64_t")]
public CLong sequence;
public vorbis_dsp_state* vd;
public void* localstore;
[NativeTypeName("long")]
public CLong localtop;
[NativeTypeName("long")]
public CLong localalloc;
[NativeTypeName("long")]
public CLong totaluse;
[NativeTypeName("struct alloc_chain *")]
public alloc_chain* reap;
[NativeTypeName("long")]
public CLong glue_bits;
[NativeTypeName("long")]
public CLong time_bits;
[NativeTypeName("long")]
public CLong floor_bits;
[NativeTypeName("long")]
public CLong res_bits;
public void* @internal;
}

View File

@@ -0,0 +1,14 @@
namespace Robust.Shared.Interop.RobustNative.Vorbis;
internal unsafe partial struct vorbis_comment
{
[NativeTypeName("char **")]
public sbyte** user_comments;
public int* comment_lengths;
public int comments;
[NativeTypeName("char *")]
public sbyte* vendor;
}

View File

@@ -0,0 +1,54 @@
namespace Robust.Shared.Interop.RobustNative.Vorbis;
internal unsafe partial struct vorbis_dsp_state
{
public int analysisp;
public vorbis_info* vi;
public float** pcm;
public float** pcmret;
public int pcm_storage;
public int pcm_current;
public int pcm_returned;
public int preextrapolate;
public int eofflag;
[NativeTypeName("long")]
public CLong lW;
[NativeTypeName("long")]
public CLong W;
[NativeTypeName("long")]
public CLong nW;
[NativeTypeName("long")]
public CLong centerW;
[NativeTypeName("ogg_int64_t")]
public CLong granulepos;
[NativeTypeName("ogg_int64_t")]
public CLong sequence;
[NativeTypeName("ogg_int64_t")]
public CLong glue_bits;
[NativeTypeName("ogg_int64_t")]
public CLong time_bits;
[NativeTypeName("ogg_int64_t")]
public CLong floor_bits;
[NativeTypeName("ogg_int64_t")]
public CLong res_bits;
public void* backend_state;
}

View File

@@ -0,0 +1,25 @@
namespace Robust.Shared.Interop.RobustNative.Vorbis;
internal unsafe partial struct vorbis_info
{
public int version;
public int channels;
[NativeTypeName("long")]
public CLong rate;
[NativeTypeName("long")]
public CLong bitrate_upper;
[NativeTypeName("long")]
public CLong bitrate_nominal;
[NativeTypeName("long")]
public CLong bitrate_lower;
[NativeTypeName("long")]
public CLong bitrate_window;
public void* codec_setup;
}

View File

@@ -0,0 +1,23 @@
--config
generate-helper-types
generate-file-scoped-namespaces
multi-file
--language
c
--output
Ogg/Gen/
--namespace
Robust.Shared.Interop.RobustNative.Ogg
--libraryPath
robust-native
--with-access-specifier
*=Internal
--file
include_ogg.h
--traverse
E:\ss14\native-build\vcpkg_installed\x64-windows\include\ogg\ogg.h
--methodClassName
Ogg
--remap
long=CLong
unsigned long=CULong

View File

@@ -0,0 +1,25 @@
--config
generate-helper-types
generate-file-scoped-namespaces
multi-file
--language
c
--output
Opus/Gen/
--namespace
Robust.Shared.Interop.RobustNative.Opus
--libraryPath
robust-native
--with-access-specifier
*=Internal
--file
include_opus.h
--traverse
E:\ss14\native-build\vcpkg_installed\x64-windows\include\opus\opus.h
E:\ss14\native-build\vcpkg_installed\x64-windows\include\opus\opus_defines.h
E:\ss14\native-build\vcpkg_installed\x64-windows\include\opus\opus_types.h
--methodClassName
Opus
--remap
long=CLong
unsigned long=CULong

View File

@@ -0,0 +1,23 @@
--config
generate-helper-types
generate-file-scoped-namespaces
multi-file
--language
c
--output
Vorbis/Gen/
--namespace
Robust.Shared.Interop.RobustNative.Vorbis
--libraryPath
robust-native
--with-access-specifier
*=Internal
--file
include_vorbis.h
--traverse
E:\ss14\native-build\vcpkg_installed\x64-windows\include\vorbis\codec.h
--methodClassName
Vorbis
--remap
long=CLong
unsigned long=CULong

View File

@@ -0,0 +1 @@
#include <ogg/ogg.h>

View File

@@ -0,0 +1 @@
#include <opus/opus.h>

View File

@@ -0,0 +1 @@
#include <vorbis/codec.h>

View File

@@ -35,6 +35,7 @@
<ItemGroup>
<ProjectReference Include="..\Lidgren.Network\Lidgren.Network.csproj" />
<ProjectReference Include="..\NetSerializer\NetSerializer\NetSerializer.csproj" />
<ProjectReference Include="..\Robust.Shared.Interop.RobustNative\Robust.Shared.Interop.RobustNative.csproj" />
<ProjectReference Include="..\Robust.Shared.Maths\Robust.Shared.Maths.csproj" />
</ItemGroup>
<ItemGroup>
@@ -58,6 +59,9 @@
<DependentUpon>RobustMappedStringSerializer.cs</DependentUpon>
</Compile>
</ItemGroup>
<ItemGroup>
<Folder Include="Native\" />
</ItemGroup>
<Import Project="..\MSBuild\Robust.Properties.targets" />
<Import Project="..\MSBuild\Robust.CompNetworkGenerator.targets" />

View File

@@ -7,7 +7,6 @@ using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;
using SharpZstd.Interop;
using static Robust.Shared.Native.Libc;
using static SharpZstd.Interop.Zstd;
namespace Robust.Shared.Utility;

View File

@@ -131,6 +131,10 @@
<Project Path="Robust.Server.Testing/Robust.Server.Testing.csproj" />
<Project Path="Robust.Server/Robust.Server.csproj" />
<Project Path="Robust.Shared.IntegrationTests/Robust.Shared.IntegrationTests.csproj" />
<Project Path="Robust.Shared.Interop.RobustNative/Robust.Shared.Interop.RobustNative.csproj">
<BuildType Solution="DebugOpt|*" Project="Debug" />
<BuildType Solution="Tools|*" Project="Debug" />
</Project>
<Project Path="Robust.Shared.Maths.Testing/Robust.Shared.Maths.Testing.csproj" />
<Project Path="Robust.Shared.Maths.Tests/Robust.Shared.Maths.Tests.csproj" />
<Project Path="Robust.Shared.Maths/Robust.Shared.Maths.csproj" />

9
native/Cargo.lock generated
View File

@@ -330,6 +330,15 @@ dependencies = [
name = "robust-native-shared"
version = "0.1.0"
[[package]]
name = "robust-native-universal"
version = "0.1.0"
dependencies = [
"mimalloc",
"robust-native-client",
"robust-native-server",
]
[[package]]
name = "robust-native-webview"
version = "0.1.0"

View File

@@ -1,6 +1,6 @@
[workspace]
resolver = "3"
members = ["cef-helper", "robust-apphost", "robust-native-client", "robust-native-server", "robust-native-shared", "robust-native-webview"]
members = ["cef-helper", "robust-apphost", "robust-native-client", "robust-native-server", "robust-native-shared", "robust-native-universal", "robust-native-webview"]
[workspace.dependencies]
cef = { git = "https://github.com/space-wizards/cef-rs.git", rev = "10afdf90bcafb0491adc4ef535530eeee77f4ef9", default-features = false }

30
native/README.md Normal file
View File

@@ -0,0 +1,30 @@
## Building
### Dependencies
`robust-native` has various dependencies on non-Rust code that must be procured using [native-build](https://github.com/space-wizards/native-build/). After procuring them, you should set your `PATH` as appropriate to make the build aware of vcpkg's artifacts. This looks something like this:
```powershell
# Windows powershell
push-location "path\to\native\build"
vcpkg\bootstrap-vcpkg.bat
vcpkg\vcpkg.exe install
$env:PKG_CONFIG_PATH="$pwd\vcpkg_installed\x64-windows\lib\pkgconfig"
$env:PATH="$pwd\vcpkg_installed\x64-windows\tools\;$env:PATH"
pop-location
```
```bash
# Linux/macOS
pushd "path/to/native/build"
vcpkg/bootstrap-vcpkg.sh
vcpkg/vcpkg.exe install
export PKG_CONFIG_PATH="$(pwd)/vcpkg_installed/x64-linux/lib/pkgconfig"
export PATH="$(pwd)/vcpkg_installed/x64-linux/tools/:$PATH"
popd
```
### Linking final shared library
Due to limitations of Rust, we cannot have rust directly output `cdylib`-type binaries.

View File

@@ -18,12 +18,14 @@ from dataclasses import dataclass, field
@dataclass
class LinkerData:
name: str
out_file: str
inputs: list[str] = field(default_factory=list)
libs: list[str] = field(default_factory=list)
lib_search_paths: list[str] = field(default_factory=list)
pkg_config_libs: list[str] = field(default_factory=list)
export_symbols: list[str] = field(default_factory=list)
debug: bool = True
os.chdir(os.path.dirname(os.path.realpath(__file__)))
@@ -32,7 +34,7 @@ def main():
parser.add_argument("--release", action="store_true")
args = parser.parse_args()
cmd = ["cargo", "build", "-p", "robust-native-server", "-p", "robust-native-client"]
cmd = ["cargo", "build", "-p", "robust-native-server", "-p", "robust-native-client", "-p", "robust-native-universal"]
if args.release:
cmd.append("--release")
@@ -43,22 +45,43 @@ def main():
target_dir = os.path.join("target", "release")
link(LinkerData(
name="robust_native_client",
out_file=os.path.join(target_dir, platform_dylib_name("robust_native_client")),
inputs=[os.path.join(target_dir, platform_staticlib_name("robust_native_client"))],
pkg_config_libs=["ogg", "opus", "vorbis"],
export_symbols=read_symbols_def("ogg")
+ read_symbols_def("vorbis")
+ read_symbols_def("opus")
+ read_symbols_def("client")))
+ read_symbols_def("client"),
debug=not args.release))
link(LinkerData(
name="robust_native_server",
out_file=os.path.join(target_dir, platform_dylib_name("robust_native_server")),
inputs=[os.path.join(target_dir, platform_staticlib_name("robust_native_server"))]))
inputs=[os.path.join(target_dir, platform_staticlib_name("robust_native_server"))],
pkg_config_libs=["ogg", "vorbis"],
export_symbols=read_symbols_def("ogg")
+ read_symbols_def("vorbis"),
debug=not args.release))
link(LinkerData(
name="robust_native_universal",
out_file=os.path.join(target_dir, platform_dylib_name("robust_native_universal")),
inputs=[os.path.join(target_dir, platform_staticlib_name("robust_native_universal"))],
pkg_config_libs=["ogg", "opus", "vorbis"],
export_symbols=read_symbols_def("ogg")
+ read_symbols_def("vorbis")
+ read_symbols_def("opus")
+ read_symbols_def("client"),
debug=not args.release))
def link(data: LinkerData):
system = platform.system()
if system == "Darwin":
link_macos(data)
if system == "Windows":
link_windows(data)
else:
raise NotImplementedError()
@@ -90,11 +113,54 @@ def link_macos(data: LinkerData):
subprocess.run(args, check=True)
def get_pkg_config_linker_flags(names: list[str]) -> list[str]:
def link_windows(data: LinkerData):
with tempfile.NamedTemporaryFile("w+", delete_on_close=False) as def_list_file:
def_list_file.write(f"LIBRARY {data.name}\n")
def_list_file.write(f"EXPORTS\n")
def_list_file.writelines((f" {n.strip()}\n" for n in data.export_symbols))
def_list_file.close()
(path, _) = os.path.splitext(data.out_file)
out_file_temp = path + "_.dll"
args = [
"link.exe",
"/NOLOGO",
"/IGNORE:4001",
"/MACHINE:X64",
f"/DEF:{def_list_file.name}",
"/NXCOMPAT",
"/DEBUG",
("/OPT:REF,NOICF" if data.debug else "/OPT:REF,ICF"),
f"/OUT:{out_file_temp}"
] + get_pkg_config_linker_flags(data.pkg_config_libs, msvc=True) + data.inputs
args.extend(("/LIBPATH:" + p for p in data.lib_search_paths))
args.extend(data.libs)
args.extend(["psapi.lib", "shell32.lib", "user32.lib", "advapi32.lib", "bcrypt.lib", "legacy_stdio_definitions.lib", "kernel32.lib", "ntdll.lib", "userenv.lib", "ws2_32.lib", "dbghelp.lib", "/defaultlib:msvcrt"])
subprocess.run(args, check=True)
if os.path.exists(data.out_file):
os.remove(data.out_file)
if os.path.exists(path + ".pdb"):
os.remove(path + ".pdb")
os.rename(out_file_temp, data.out_file)
os.rename(path + "_.pdb", path + ".pdb")
def get_pkg_config_linker_flags(names: list[str], msvc: bool = False) -> list[str]:
if not names:
return []
result = subprocess.run(["pkg-config", "--libs"] + names, check=True, stdout=subprocess.PIPE)
args = ["pkgconf", "--libs"]
if msvc:
args.append("--msvc-syntax")
args.extend(names)
result = subprocess.run(args + names, check=True, stdout=subprocess.PIPE)
return shlex.split(result.stdout.decode("utf-8"))
def read_symbols_def(name: str) -> list[str]:

View File

@@ -4,7 +4,7 @@ version = "0.1.0"
edition = "2024"
[lib]
crate-type = ["staticlib"]
crate-type = ["staticlib", "lib"]
[dependencies]
mimalloc = { workspace = true }

View File

@@ -4,7 +4,7 @@ version = "0.1.0"
edition = "2024"
[lib]
crate-type = ["staticlib"]
crate-type = ["staticlib", "lib"]
[dependencies]
mimalloc = { workspace = true }

View File

@@ -0,0 +1,12 @@
[package]
name = "robust-native-universal"
version = "0.1.0"
edition = "2024"
[lib]
crate-type = ["staticlib"]
[dependencies]
mimalloc = { workspace = true }
robust-native-client = { path = "../robust-native-client" }
robust-native-server = { path = "../robust-native-server" }

View File

@@ -0,0 +1,4 @@
use mimalloc::MiMalloc;
#[global_allocator]
static GLOBAL: MiMalloc = MiMalloc;

30
native/setup-env.ps1 Normal file
View File

@@ -0,0 +1,30 @@
param (
[Parameter(Mandatory=$true)][string]$nativeBuildPath
)
$platform = "windows"
if ($IsLinux) {
$platform = "linux"
} elseif ($IsMacOS) {
$platform = "osx"
}
$arch = switch ([System.Runtime.InteropServices.RuntimeInformation]::ProcessArchitecture) {
"X64" { "x64" }
"Arm64" { "arm64" }
}
$triple = "$arch-$platform"
Write-Host "Target triple is $triple"
$pkgConfigTools = $(Join-Path $nativeBuildPath "vcpkg_installed" $triple "tools" "pkgconf")
if ($IsWindows) {
$env:PATH="$pkgConfigTools;$env:PATH"
} else {
$env:PATH=$pkgConfigTools + ":$env:PATH"
}
$env:PKG_CONFIG_PATH = $(Join-Path $nativeBuildPath "vcpkg_installed" $triple "lib" "pkgconfig")
$env:INCLUDE = $(Join-Path $nativeBuildPath "vcpkg_installed" $triple "include")