mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/PCK-Studio.git
synced 2026-09-28 09:40:48 +00:00
108 lines
3.5 KiB
C#
108 lines
3.5 KiB
C#
using System;
|
|
using System.Diagnostics;
|
|
using System.IO;
|
|
using System.Runtime.InteropServices;
|
|
using PckStudio.Extensions;
|
|
using PckStudio.Internal;
|
|
using PckStudio.Internal.App;
|
|
using SharpMSS;
|
|
|
|
namespace PckStudio.External.API.Miles
|
|
{
|
|
internal static class Binka
|
|
{
|
|
private static ProcessStartInfo WavProcessStartInfo = new ProcessStartInfo
|
|
{
|
|
UseShellExecute = true,
|
|
CreateNoWindow = true,
|
|
WindowStyle = ProcessWindowStyle.Hidden
|
|
};
|
|
|
|
public static int ToBinka(string inputFilepath, string outputFilepath, int compressionLevel)
|
|
{
|
|
compressionLevel = MathExtensions.Clamp(compressionLevel, 1, 9);
|
|
ApplicationScope.DataCacher.Cache(Properties.Resources.binka_encode, "binka_encode.exe");
|
|
WavProcessStartInfo.FileName = ApplicationScope.DataCacher.GetCachedFilepath("binka_encode.exe");
|
|
WavProcessStartInfo.Arguments = $"\"{inputFilepath}\" \"{outputFilepath}\" -s -b{compressionLevel}";
|
|
var process = Process.Start(WavProcessStartInfo);
|
|
process.WaitForExit();
|
|
return process.ExitCode;
|
|
}
|
|
|
|
public static void ToWav(Stream source, Stream destination)
|
|
{
|
|
_ = source ?? throw new ArgumentNullException(nameof(source));
|
|
_ = destination ?? throw new ArgumentNullException(nameof(destination));
|
|
if (!source.CanRead)
|
|
{
|
|
throw new NotSupportedException("Can not read from source stream");
|
|
}
|
|
|
|
if (!destination.CanWrite)
|
|
{
|
|
throw new NotSupportedException("Can not read to destination stream");
|
|
}
|
|
|
|
using var sourceFs = new MemoryStream();
|
|
source.CopyTo(sourceFs);
|
|
byte[] buffer = ToWav(sourceFs.ToArray());
|
|
|
|
using(var ms = new MemoryStream(buffer))
|
|
{
|
|
ms.CopyTo(destination);
|
|
}
|
|
}
|
|
|
|
public static void ToWav(string inputFilepath, string outputFilepath)
|
|
{
|
|
byte[] buffer = ToWav(inputFilepath);
|
|
string destinationFilepath = Path.Combine(
|
|
Path.GetDirectoryName(outputFilepath),
|
|
Path.GetFileNameWithoutExtension(inputFilepath) + ".wav");
|
|
File.WriteAllBytes(destinationFilepath, buffer);
|
|
}
|
|
|
|
public static byte[] ToWav(string inputFilepath)
|
|
{
|
|
if (!File.Exists(inputFilepath))
|
|
{
|
|
throw new FileNotFoundException(nameof(inputFilepath));
|
|
}
|
|
if (!inputFilepath.EndsWith(".binka"))
|
|
{
|
|
throw new ArgumentException("Not a Bink Audio file.");
|
|
}
|
|
return ToWav(File.ReadAllBytes(inputFilepath));
|
|
}
|
|
|
|
public static byte[] ToWav(byte[] input)
|
|
{
|
|
ApplicationScope.DataCacher.Cache(Properties.Resources.mss32, "mss32.dll");
|
|
ApplicationScope.DataCacher.Cache(Properties.Resources.binkawin, "binkawin.asi");
|
|
|
|
LibHandle mss32LibHandle = new LibHandle(ApplicationScope.DataCacher.GetCachedFilepath("mss32.dll"));
|
|
|
|
AILAPI.SetRedistDirectory(ApplicationScope.DataCacher.CacheDirectory.Replace('\\', '/'));
|
|
|
|
RIBAPI.LoadApplicationProviders("*.asi");
|
|
|
|
int resultBufferSize = 0;
|
|
IntPtr resultBuffer = new IntPtr();
|
|
if (AILAPI.DecompressASI(input, input.Length, ".binka", ref resultBuffer, ref resultBufferSize, null) == 0)
|
|
{
|
|
Console.WriteLine(AILAPI.GetLastError());
|
|
return Array.Empty<byte>();
|
|
}
|
|
|
|
byte[] buffer = new byte[resultBufferSize];
|
|
Marshal.Copy(resultBuffer, buffer, 0, resultBufferSize);
|
|
|
|
AILAPI.MemFreeLock(resultBuffer);
|
|
RIBAPI.FreeProviderLibrary(0); // free all loaded providers
|
|
AILAPI.Shutdown();
|
|
mss32LibHandle.Release();
|
|
return buffer;
|
|
}
|
|
}
|
|
}
|