Skip to content

Commit

Permalink
chore: initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
lmichaelis committed Apr 29, 2024
0 parents commit ff1a3ff
Show file tree
Hide file tree
Showing 17 changed files with 533 additions and 0 deletions.
26 changes: 26 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
name: 'Build'
on:
- 'push'
jobs:
release:
runs-on: 'ubuntu-latest'
steps:
- uses: 'actions/checkout@v3'
- name: 'Setup .NET Core SDK'
uses: 'actions/setup-dotnet@v3'
with:
dotnet-version: '7.0.x'
- name: 'Build'
run: 'dotnet build ZenKit -c Release -o __build && dotnet pack -c Release -o ./__publish/ -v detailed ZenKit'
- name: 'Publish'
uses: 'actions/upload-artifact@v3'
with:
name: 'NuGet Package'
path: '__publish'
- name: 'Copy Artifacts'
run: 'mkdir Artifacts && mv ZenKit/runtimes Artifacts/ && cp __build/ZenKit.dll Artifacts/ && echo "Copy the native library for your OS from the `runtime` folder into the same folder `ZenKit.dll` is in." > Artifacts/README.md'
- name: 'Publish'
uses: 'actions/upload-artifact@v3'
with:
name: 'Managed DLL'
path: 'Artifacts'
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
bin/
obj/
/packages/
riderModule.iml
/_ReSharper.Caches/
56 changes: 56 additions & 0 deletions DirectMusic/DirectMusic.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>netstandard2.1</TargetFramework>
<Nullable>enable</Nullable>
<RootNamespace>DirectMusic</RootNamespace>
<PackRelease>true</PackRelease>
<PackageId>DirectMusic</PackageId>
<Version>0.1.13</Version>
<Authors>Luis Michaelis</Authors>
<Company>GothicKit</Company>
<Copyright>© 2024. GothicKit Contributors</Copyright>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
<PackageProjectUrl>https://github.com/GothicKit/dmusic-cs</PackageProjectUrl>
<PackageReadmeFile>README.md</PackageReadmeFile>
<RepositoryUrl>https://github.com/GothicKit/dmusic-cs</RepositoryUrl>

<RuntimeIdentifier Condition="$([MSBuild]::IsOSPlatform('Android'))">android-arm64</RuntimeIdentifier>
<RuntimeIdentifier Condition="$([MSBuild]::IsOSPlatform('Linux'))">linux-x64</RuntimeIdentifier>
<RuntimeIdentifier Condition="$([MSBuild]::IsOSPlatform('Windows'))">win-x64</RuntimeIdentifier>
</PropertyGroup>

<ItemGroup>
<None Include="..\README.md" Pack="true" PackagePath="/"/>
</ItemGroup>

<ItemGroup Label="Packaging">
<None Include="DirectMusic.targets" Pack="true" PackagePath="build"/>

<None Include="runtimes\**" Pack="true" PackagePath="runtimes">
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
<PackageCopyToOutput>true</PackageCopyToOutput>
</None>
</ItemGroup>

<ItemGroup Label="NativeLibraries">
<ContentWithTargetPath Include="runtimes\android-arm64\native\libdmusic.so" Condition="'$(RuntimeIdentifier)' == 'android-arm64'">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<TargetPath>libdmusic.so</TargetPath>
</ContentWithTargetPath>

<ContentWithTargetPath Include="runtimes\linux-x64\native\libdmusic.so" Condition="'$(RuntimeIdentifier)' == 'linux-x64'">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<TargetPath>libdmusic.so</TargetPath>
</ContentWithTargetPath>

<ContentWithTargetPath Include="runtimes\win-x64\native\dmusic.dll" Condition="'$(RuntimeIdentifier)' == 'win-x64'">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<TargetPath>dmusic.dll</TargetPath>
</ContentWithTargetPath>
</ItemGroup>

<ItemGroup>
<PackageReference Include="System.Text.Encoding.CodePages" Version="7.0.0"/>
</ItemGroup>
</Project>
21 changes: 21 additions & 0 deletions DirectMusic/DirectMusic.targets
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<RuntimeIdentifier Condition="$([MSBuild]::IsOSPlatform('Android'))">android-arm64</RuntimeIdentifier>
<RuntimeIdentifier Condition="$([MSBuild]::IsOSPlatform('Linux'))">linux-x64</RuntimeIdentifier>
<RuntimeIdentifier Condition="$([MSBuild]::IsOSPlatform('Windows'))">win-x64</RuntimeIdentifier>
</PropertyGroup>

<ItemGroup>
<NativeAndroid Include="$(MSBuildThisFileDirectory)..\runtimes\android-arm64\native\libdmusic.so"/>
<NativeLinux Include="$(MSBuildThisFileDirectory)..\runtimes\linux-x64\native\libdmusic.so"/>
<NativeWindows Include="$(MSBuildThisFileDirectory)..\runtimes\win-x64\native\dmusic.dll"/>
</ItemGroup>
<Target Name="CopyNativeLibraries" BeforeTargets="Build">
<Copy SourceFiles="@(NativeAndroid)" Condition="'$(RuntimeIdentifier)' == 'android-arm64'"
DestinationFiles="$(TargetDir)\libdmusic.so" ContinueOnError="true"/>
<Copy SourceFiles="@(NativeLinux)" Condition="'$(RuntimeIdentifier)' == 'linux-x64'"
DestinationFiles="$(TargetDir)\libdmusic.so" ContinueOnError="true"/>
<Copy SourceFiles="@(NativeWindows)" Condition="'$(RuntimeIdentifier)' == 'win-x64'"
DestinationFiles="$(TargetDir)\dmusic.dll" ContinueOnError="true"/>
</Target>
</Project>
72 changes: 72 additions & 0 deletions DirectMusic/Loader.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using DirectMusic.Util;

namespace DirectMusic
{
[Flags]
public enum LoaderOptions
{
Download = 1 << 0,
Default = 0
}

public class Loader
{
public delegate byte[]? ResolveCallback(string name);

private readonly List<GCHandle> _callbacks = new List<GCHandle>();
internal readonly IntPtr Handle;

public Loader(IntPtr handle)
{
Handle = handle;
}

~Loader()
{
_callbacks.ForEach(v => v.Free());
Native.DmLoader_release(Handle);
}

public void AddResolver(ResolveCallback resolve)
{
var cb = GCHandle.Alloc(resolve);
Native.DmLoader_addResolver(Handle, _nativeCallbackHandler, GCHandle.ToIntPtr(cb)).Check();
_callbacks.Add(cb);
}

public Segment GetSegment(string name)
{
Native.DmLoader_getSegment(Handle, name, out var segment).Check();
return new Segment(segment);
}

public static Loader Create(LoaderOptions opt)
{
Native.DmLoader_create(out var handle, opt).Check();
return new Loader(handle);
}

[MonoPInvokeCallback]
private static IntPtr _nativeCallbackHandler(IntPtr ctx, string name, out ulong size)
{
var gcHandle = GCHandle.FromIntPtr(ctx);
var cb = (ResolveCallback)gcHandle.Target;

var bytes = cb(name);
if (bytes == null)
{
size = 0;
return IntPtr.Zero;
}

var data = Marshal.AllocHGlobal(bytes.Length);
Marshal.Copy(bytes, 0, data, bytes.Length);

size = (ulong)bytes.Length;
return data;
}
}
}
51 changes: 51 additions & 0 deletions DirectMusic/Logger.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
using System;
using System.Runtime.InteropServices;
using DirectMusic.Util;

namespace DirectMusic
{
public enum LogLevel
{
Fatal = 10,
Error = 20,
Warning = 30,
Info = 40,
Debug = 50,
Trace = 60
}

public static class Logger
{
public delegate void Callback(LogLevel level, string message);

private static GCHandle? _handler;
private static readonly Native.DmLogHandler NativeHandler = _nativeCallbackHandler;

public static void Set(LogLevel lvl, Callback callback)
{
var handler = GCHandle.Alloc(callback);
Native.Dm_setLogger(lvl, NativeHandler, GCHandle.ToIntPtr(handler));

_handler?.Free();
_handler = handler;
}

public static void SetDefault(LogLevel level)
{
Native.Dm_setLoggerDefault(level);
}

public static void SetLevel(LogLevel level)
{
Native.Dm_setLoggerLevel(level);
}

[MonoPInvokeCallback]
private static void _nativeCallbackHandler(IntPtr ctx, LogLevel level, string message)
{
var gcHandle = GCHandle.FromIntPtr(ctx);
var cb = (Callback)gcHandle.Target;
cb(level, message);
}
}
}
104 changes: 104 additions & 0 deletions DirectMusic/Native.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
using System;
using System.Runtime.InteropServices;
using DirectMusic.Util;

namespace DirectMusic
{
internal enum DmResult
{
Success = 0,
InvalidArgument = 1,
InvalidState = 2,
MemoryExhausted = 3,
NotFound = 4,
FileCorrupt = 5,
InternalError = 6
}

[Flags]
internal enum DmRenderOptions
{
Short = 1 << 0,
Float = 1 << 1,
Stereo = 1 << 2
}

internal static class DmResultExtension
{
public static void Check(this DmResult result)
{
if (result == DmResult.Success) return;
throw new NativeAccessError(result);
}
}

internal static class Native
{
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate IntPtr DmLoaderResolverCallback(IntPtr ctx, string name, out ulong size);

[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void DmLogHandler(IntPtr ctx, LogLevel lvl, string message);

private const string DllName = "dmusic";

[DllImport(DllName)]
public static extern void Dm_setLogger(LogLevel lvl, DmLogHandler log, IntPtr ctx);

[DllImport(DllName)]
public static extern void Dm_setLoggerDefault(LogLevel lvl);

[DllImport(DllName)]
public static extern void Dm_setLoggerLevel(LogLevel lvl);

[DllImport(DllName)]
public static extern DmResult DmLoader_create(out IntPtr slf, LoaderOptions opt);

[DllImport(DllName)]
public static extern IntPtr DmLoader_retain(IntPtr slf);

[DllImport(DllName)]
public static extern void DmLoader_release(IntPtr slf);

[DllImport(DllName)]
public static extern DmResult DmLoader_addResolver(IntPtr slf, DmLoaderResolverCallback resolve, IntPtr ctx);

[DllImport(DllName)]
public static extern DmResult DmLoader_getSegment(IntPtr slf, string name, out IntPtr segment);

[DllImport(DllName)]
public static extern IntPtr DmSegment_retain(IntPtr slf);

[DllImport(DllName)]
public static extern void DmSegment_release(IntPtr slf);

[DllImport(DllName)]
public static extern DmResult DmSegment_download(IntPtr slf, IntPtr loader);

[DllImport(DllName)]
public static extern DmResult DmPerformance_create(out IntPtr slf);

[DllImport(DllName)]
public static extern IntPtr DmPerformance_retain(IntPtr slf);

[DllImport(DllName)]
public static extern void DmPerformance_release(IntPtr slf);

[DllImport(DllName)]
public static extern DmResult DmPerformance_playSegment(IntPtr slf, IntPtr sgt, PlaybackFlags flags);

[DllImport(DllName)]
public static extern DmResult DmPerformance_playTransition(IntPtr slf, IntPtr sgt, Embellishment embellishment,
PlaybackFlags flags);

[DllImport(DllName)]
public static extern DmResult DmPerformance_renderPcm(IntPtr slf, short[] buf, ulong len, DmRenderOptions opts);

[DllImport(DllName)]
public static extern DmResult DmPerformance_renderPcm(IntPtr slf, float[] buf, ulong len, DmRenderOptions opts);

public class Structs
{
}
}
}
Loading

0 comments on commit ff1a3ff

Please sign in to comment.