mirror of
https://github.com/RHeavenStudioPlus/HeavenStudioPlus.git
synced 2024-11-11 12:15:11 +00:00
170 lines
6.7 KiB
C#
170 lines
6.7 KiB
C#
|
using System.Runtime.InteropServices;
|
|||
|
|
|||
|
namespace OggVorbis
|
|||
|
{
|
|||
|
public static class VorbisPlugin
|
|||
|
{
|
|||
|
public static void Save(
|
|||
|
string filePath,
|
|||
|
UnityEngine.AudioClip audioClip,
|
|||
|
float quality = 0.4f,
|
|||
|
int samplesToRead = 1024)
|
|||
|
{
|
|||
|
if (string.IsNullOrWhiteSpace(filePath))
|
|||
|
{
|
|||
|
throw new System.ArgumentException("The file path is null or white space");
|
|||
|
}
|
|||
|
if (audioClip == null)
|
|||
|
{
|
|||
|
throw new System.ArgumentNullException(nameof(audioClip));
|
|||
|
}
|
|||
|
if (samplesToRead <= 0)
|
|||
|
{
|
|||
|
throw new System.ArgumentOutOfRangeException(nameof(samplesToRead));
|
|||
|
}
|
|||
|
short finalChannelsCount = (short)audioClip.channels;
|
|||
|
if (finalChannelsCount != 1 && finalChannelsCount != 2)
|
|||
|
{
|
|||
|
throw new System.ArgumentException($"Only one or two channels are supported, provided channels count: {finalChannelsCount}");
|
|||
|
}
|
|||
|
if (!filePath.EndsWith(".ogg"))
|
|||
|
{
|
|||
|
filePath += ".ogg";
|
|||
|
}
|
|||
|
|
|||
|
float[] pcm = new float[audioClip.samples * audioClip.channels];
|
|||
|
audioClip.GetData(pcm, 0);
|
|||
|
int returnCode = NativeBridge.WriteAllPcmDataToFile(filePath, pcm, pcm.Length, finalChannelsCount, audioClip.frequency, quality, samplesToRead);
|
|||
|
NativeErrorException.ThrowExceptionIfNecessary(returnCode);
|
|||
|
}
|
|||
|
public static byte[] GetOggVorbis(
|
|||
|
UnityEngine.AudioClip audioClip,
|
|||
|
float quality = 0.4f,
|
|||
|
int samplesToRead = 1024)
|
|||
|
{
|
|||
|
if (audioClip == null)
|
|||
|
{
|
|||
|
throw new System.ArgumentNullException(nameof(audioClip));
|
|||
|
}
|
|||
|
if (samplesToRead <= 0)
|
|||
|
{
|
|||
|
throw new System.ArgumentOutOfRangeException(nameof(samplesToRead));
|
|||
|
}
|
|||
|
short finalChannelsCount = (short)audioClip.channels;
|
|||
|
if (finalChannelsCount != 1 && finalChannelsCount != 2)
|
|||
|
{
|
|||
|
throw new System.ArgumentException($"Only one or two channels are supported, provided channels count: {finalChannelsCount}");
|
|||
|
}
|
|||
|
int returnCode;
|
|||
|
System.IntPtr bytesPtr = System.IntPtr.Zero;
|
|||
|
byte[] bytes;
|
|||
|
try
|
|||
|
{
|
|||
|
float[] pcm = new float[audioClip.samples * audioClip.channels];
|
|||
|
audioClip.GetData(pcm, 0);
|
|||
|
returnCode = NativeBridge.WriteAllPcmDataToMemory(
|
|||
|
out bytesPtr,
|
|||
|
out int bytesLength,
|
|||
|
pcm,
|
|||
|
pcm.Length,
|
|||
|
finalChannelsCount,
|
|||
|
audioClip.frequency,
|
|||
|
quality,
|
|||
|
samplesToRead);
|
|||
|
NativeErrorException.ThrowExceptionIfNecessary(returnCode);
|
|||
|
bytes = new byte[bytesLength];
|
|||
|
Marshal.Copy(bytesPtr, bytes, 0, bytesLength);
|
|||
|
}
|
|||
|
finally
|
|||
|
{
|
|||
|
returnCode = NativeBridge.FreeMemoryArrayForWriteAllPcmData(bytesPtr);
|
|||
|
NativeErrorException.ThrowExceptionIfNecessary(returnCode);
|
|||
|
}
|
|||
|
return bytes;
|
|||
|
}
|
|||
|
|
|||
|
public static UnityEngine.AudioClip Load(string filePath, int maxSamplesToRead = 1024)
|
|||
|
{
|
|||
|
if (string.IsNullOrWhiteSpace(filePath))
|
|||
|
{
|
|||
|
throw new System.ArgumentException("The file path is null or white space");
|
|||
|
}
|
|||
|
if (maxSamplesToRead <= 0)
|
|||
|
{
|
|||
|
throw new System.ArgumentOutOfRangeException(nameof(maxSamplesToRead));
|
|||
|
}
|
|||
|
if (!System.IO.File.Exists(filePath))
|
|||
|
{
|
|||
|
throw new System.IO.FileNotFoundException();
|
|||
|
}
|
|||
|
int returnCode;
|
|||
|
System.IntPtr pcmPtr = System.IntPtr.Zero;
|
|||
|
UnityEngine.AudioClip audioClip;
|
|||
|
try
|
|||
|
{
|
|||
|
returnCode = NativeBridge.ReadAllPcmDataFromFile(
|
|||
|
filePath,
|
|||
|
out pcmPtr,
|
|||
|
out int pcmLength,
|
|||
|
out short channels,
|
|||
|
out int frequency,
|
|||
|
maxSamplesToRead);
|
|||
|
NativeErrorException.ThrowExceptionIfNecessary(returnCode);
|
|||
|
float[] pcm = new float[pcmLength];
|
|||
|
Marshal.Copy(pcmPtr, pcm, 0, pcmLength);
|
|||
|
audioClip = UnityEngine.AudioClip.Create(System.IO.Path.GetFileName(filePath), pcmLength / channels, channels, frequency, false);
|
|||
|
audioClip.SetData(pcm, 0);
|
|||
|
}
|
|||
|
finally
|
|||
|
{
|
|||
|
returnCode = NativeBridge.FreeSamplesArrayNativeMemory(ref pcmPtr);
|
|||
|
NativeErrorException.ThrowExceptionIfNecessary(returnCode);
|
|||
|
}
|
|||
|
return audioClip;
|
|||
|
}
|
|||
|
public static UnityEngine.AudioClip ToAudioClip(byte[] bytes, string audioClipName, int maxSamplesToRead = 1024)
|
|||
|
{
|
|||
|
if (bytes == null)
|
|||
|
{
|
|||
|
throw new System.ArgumentNullException(nameof(bytes));
|
|||
|
}
|
|||
|
if (bytes.Length < 10)
|
|||
|
{
|
|||
|
throw new System.ArgumentException(nameof(bytes));
|
|||
|
}
|
|||
|
if (string.IsNullOrWhiteSpace(audioClipName))
|
|||
|
{
|
|||
|
throw new System.ArgumentException("Please provide an audio clip name");
|
|||
|
}
|
|||
|
if (maxSamplesToRead <= 0)
|
|||
|
{
|
|||
|
throw new System.ArgumentOutOfRangeException(nameof(maxSamplesToRead));
|
|||
|
}
|
|||
|
int returnCode;
|
|||
|
System.IntPtr pcmPtr = System.IntPtr.Zero;
|
|||
|
UnityEngine.AudioClip audioClip = null;
|
|||
|
try
|
|||
|
{
|
|||
|
returnCode = NativeBridge.ReadAllPcmDataFromMemory(
|
|||
|
bytes,
|
|||
|
bytes.Length,
|
|||
|
out pcmPtr,
|
|||
|
out int pcmLength,
|
|||
|
out short channels,
|
|||
|
out int frequency,
|
|||
|
maxSamplesToRead);
|
|||
|
NativeErrorException.ThrowExceptionIfNecessary(returnCode);
|
|||
|
float[] pcm = new float[pcmLength];
|
|||
|
Marshal.Copy(pcmPtr, pcm, 0, pcmLength);
|
|||
|
audioClip = UnityEngine.AudioClip.Create(audioClipName, pcmLength / channels, channels, frequency, false);
|
|||
|
audioClip.SetData(pcm, 0);
|
|||
|
}
|
|||
|
finally
|
|||
|
{
|
|||
|
returnCode = NativeBridge.FreeSamplesArrayNativeMemory(ref pcmPtr);
|
|||
|
NativeErrorException.ThrowExceptionIfNecessary(returnCode);
|
|||
|
}
|
|||
|
return audioClip;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|