AssetStudio/AssetStudioUtility/AudioClipConverter.cs

174 lines
6.6 KiB
C#

using System;
using System.Runtime.InteropServices;
using System.Text;
namespace AssetStudio
{
public class AudioClipConverter
{
private AudioClip m_AudioClip;
public AudioClipConverter(AudioClip audioClip)
{
m_AudioClip = audioClip;
}
public byte[] ConvertToWav()
{
var m_AudioData = m_AudioClip.m_AudioData.GetData();
if (m_AudioData == null || m_AudioData.Length == 0)
return null;
var exinfo = new FMOD.CREATESOUNDEXINFO();
var result = FMOD.Factory.System_Create(out var system);
if (result != FMOD.RESULT.OK)
return null;
result = system.init(1, FMOD.INITFLAGS.NORMAL, IntPtr.Zero);
if (result != FMOD.RESULT.OK)
return null;
exinfo.cbsize = Marshal.SizeOf(exinfo);
exinfo.length = (uint)m_AudioClip.m_Size;
result = system.createSound(m_AudioData, FMOD.MODE.OPENMEMORY, ref exinfo, out var sound);
if (result != FMOD.RESULT.OK)
return null;
result = sound.getSubSound(0, out var subsound);
if (result != FMOD.RESULT.OK)
return null;
result = subsound.getFormat(out var type, out var format, out int channels, out int bits);
if (result != FMOD.RESULT.OK)
return null;
result = subsound.getDefaults(out var frequency, out int priority);
if (result != FMOD.RESULT.OK)
return null;
var sampleRate = (int)frequency;
result = subsound.getLength(out var length, FMOD.TIMEUNIT.PCMBYTES);
if (result != FMOD.RESULT.OK)
return null;
result = subsound.@lock(0, length, out var ptr1, out var ptr2, out var len1, out var len2);
if (result != FMOD.RESULT.OK)
return null;
byte[] buffer = new byte[len1 + 44];
//添加wav头
Encoding.UTF8.GetBytes("RIFF").CopyTo(buffer, 0);
BitConverter.GetBytes(len1 + 36).CopyTo(buffer, 4);
Encoding.UTF8.GetBytes("WAVEfmt ").CopyTo(buffer, 8);
BitConverter.GetBytes(16).CopyTo(buffer, 16);
BitConverter.GetBytes((short)1).CopyTo(buffer, 20);
BitConverter.GetBytes((short)channels).CopyTo(buffer, 22);
BitConverter.GetBytes(sampleRate).CopyTo(buffer, 24);
BitConverter.GetBytes(sampleRate * channels * bits / 8).CopyTo(buffer, 28);
BitConverter.GetBytes((short)(channels * bits / 8)).CopyTo(buffer, 32);
BitConverter.GetBytes((short)bits).CopyTo(buffer, 34);
Encoding.UTF8.GetBytes("data").CopyTo(buffer, 36);
BitConverter.GetBytes(len1).CopyTo(buffer, 40);
Marshal.Copy(ptr1, buffer, 44, (int)len1);
result = subsound.unlock(ptr1, ptr2, len1, len2);
if (result != FMOD.RESULT.OK)
return null;
subsound.release();
sound.release();
system.release();
return buffer;
}
public string GetExtensionName()
{
if (m_AudioClip.version[0] < 5)
{
switch (m_AudioClip.m_Type)
{
case AudioType.ACC:
return ".m4a";
case AudioType.AIFF:
return ".aif";
case AudioType.IT:
return ".it";
case AudioType.MOD:
return ".mod";
case AudioType.MPEG:
return ".mp3";
case AudioType.OGGVORBIS:
return ".ogg";
case AudioType.S3M:
return ".s3m";
case AudioType.WAV:
return ".wav";
case AudioType.XM:
return ".xm";
case AudioType.XMA:
return ".wav";
case AudioType.VAG:
return ".vag";
case AudioType.AUDIOQUEUE:
return ".fsb";
}
}
else
{
switch (m_AudioClip.m_CompressionFormat)
{
case AudioCompressionFormat.PCM:
return ".fsb";
case AudioCompressionFormat.Vorbis:
return ".fsb";
case AudioCompressionFormat.ADPCM:
return ".fsb";
case AudioCompressionFormat.MP3:
return ".fsb";
case AudioCompressionFormat.VAG:
return ".fsb";
case AudioCompressionFormat.HEVAG:
return ".fsb";
case AudioCompressionFormat.XMA:
return ".fsb";
case AudioCompressionFormat.AAC:
return ".m4a";
case AudioCompressionFormat.GCADPCM:
return ".fsb";
case AudioCompressionFormat.ATRAC9:
return ".fsb";
}
}
return ".AudioClip";
}
public bool IsSupport
{
get
{
if (m_AudioClip.version[0] < 5)
{
switch (m_AudioClip.m_Type)
{
case AudioType.AIFF:
case AudioType.IT:
case AudioType.MOD:
case AudioType.S3M:
case AudioType.XM:
case AudioType.XMA:
case AudioType.AUDIOQUEUE:
return true;
default:
return false;
}
}
else
{
switch (m_AudioClip.m_CompressionFormat)
{
case AudioCompressionFormat.PCM:
case AudioCompressionFormat.Vorbis:
case AudioCompressionFormat.ADPCM:
case AudioCompressionFormat.MP3:
case AudioCompressionFormat.XMA:
return true;
default:
return false;
}
}
}
}
}
}