Files
PCK-Studio/PCK-Studio/External/API/Miles/Binka.cs
T

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;
}
}
}