Add parallel export support for some asset types

This commit is contained in:
VaDiM
2024-03-25 05:00:58 +03:00
parent cadcf0b492
commit c9e9bc840c
21 changed files with 994 additions and 407 deletions

View File

@ -10,24 +10,34 @@ namespace AssetStudio
public bool IsSupport => m_AudioClip.IsConvertSupport();
private AudioClip m_AudioClip;
private static FMOD.System system;
static AudioClipConverter()
{
var result = Factory.System_Create(out system);
if (result != RESULT.OK)
{
Logger.Error($"FMOD error! {result} - {Error.String(result)}");
}
result = system.init(1, INITFLAGS.NORMAL, IntPtr.Zero);
if (result != RESULT.OK)
{
Logger.Error($"FMOD error! {result} - {Error.String(result)}");
}
}
public AudioClipConverter(AudioClip audioClip)
{
m_AudioClip = audioClip;
}
public byte[] ConvertToWav(byte[] m_AudioData)
public byte[] ConvertToWav(byte[] m_AudioData, out string debugLog)
{
debugLog = "";
var exinfo = new CREATESOUNDEXINFO();
var result = Factory.System_Create(out var system);
if (result != RESULT.OK)
return null;
result = system.init(1, INITFLAGS.NORMAL, IntPtr.Zero);
if (result != RESULT.OK)
return null;
exinfo.cbsize = Marshal.SizeOf(exinfo);
exinfo.length = (uint)m_AudioClip.m_Size;
result = system.createSound(m_AudioData, MODE.OPENMEMORY, ref exinfo, out var sound);
var result = system.createSound(m_AudioData, MODE.OPENMEMORY, ref exinfo, out var sound);
if (result != RESULT.OK)
return null;
result = sound.getNumSubSounds(out var numsubsounds);
@ -39,28 +49,29 @@ namespace AssetStudio
result = sound.getSubSound(0, out var subsound);
if (result != RESULT.OK)
return null;
buff = SoundToWav(subsound);
buff = SoundToWav(subsound, out debugLog);
subsound.release();
subsound.clearHandle();
}
else
{
buff = SoundToWav(sound);
buff = SoundToWav(sound, out debugLog);
}
sound.release();
system.release();
sound.clearHandle();
return buff;
}
public byte[] SoundToWav(Sound sound)
public byte[] SoundToWav(Sound sound, out string debugLog)
{
Logger.Debug($"[Fmod] Detecting sound format..\n");
debugLog = "[Fmod] Detecting sound format..\n";
var result = sound.getFormat(out SOUND_TYPE soundType, out SOUND_FORMAT soundFormat, out int channels, out int bits);
if (result != RESULT.OK)
return null;
Logger.Debug($"Detected sound type: {soundType}\n" +
$"Detected sound format: {soundFormat}\n" +
$"Detected channels: {channels}\n" +
$"Detected bit depth: {bits}");
debugLog += $"Detected sound type: {soundType}\n" +
$"Detected sound format: {soundFormat}\n" +
$"Detected channels: {channels}\n" +
$"Detected bit depth: {bits}\n";
result = sound.getDefaults(out var frequency, out _);
if (result != RESULT.OK)
return null;
@ -71,11 +82,11 @@ namespace AssetStudio
result = sound.@lock(0, length, out var ptr1, out var ptr2, out var len1, out var len2);
if (result != RESULT.OK)
return null;
byte[] buffer = new byte[len1 + 44];
var buffer = new byte[len1 + 44];
//添加wav头
Encoding.UTF8.GetBytes("RIFF").CopyTo(buffer, 0);
Encoding.ASCII.GetBytes("RIFF").CopyTo(buffer, 0);
BitConverter.GetBytes(len1 + 36).CopyTo(buffer, 4);
Encoding.UTF8.GetBytes("WAVEfmt ").CopyTo(buffer, 8);
Encoding.ASCII.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);
@ -83,7 +94,7 @@ namespace AssetStudio
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);
Encoding.ASCII.GetBytes("data").CopyTo(buffer, 36);
BitConverter.GetBytes(len1).CopyTo(buffer, 40);
Marshal.Copy(ptr1, buffer, 44, (int)len1);
result = sound.unlock(ptr1, ptr2, len1, len2);
@ -151,7 +162,6 @@ namespace AssetStudio
return ".fsb";
}
}
return ".AudioClip";
}
}

View File

@ -4,10 +4,12 @@
////
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using AssetStudio;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
@ -47,7 +49,7 @@ namespace CubismLive2DExtractor
ParametersCdi = new List<MonoBehaviour>();
PartsCdi = new List<MonoBehaviour>();
Logger.Info("Sorting model assets..");
Logger.Debug("Sorting model assets..");
foreach (var asset in assets)
{
switch (asset)
@ -133,7 +135,7 @@ namespace CubismLive2DExtractor
}
}
public void ExtractCubismModel(string destPath, string modelName, Live2DMotionMode motionMode, AssemblyLoader assemblyLoader, bool forceBezier = false)
public void ExtractCubismModel(string destPath, string modelName, Live2DMotionMode motionMode, AssemblyLoader assemblyLoader, bool forceBezier = false, int parallelTaskCount = 1)
{
Directory.CreateDirectory(destPath);
@ -174,17 +176,24 @@ namespace CubismLive2DExtractor
Directory.CreateDirectory(destTexturePath);
}
foreach (var texture2D in Texture2Ds)
var textureBag = new ConcurrentBag<string>();
var savePathHash = new ConcurrentDictionary<string, bool>();
Parallel.ForEach(Texture2Ds, new ParallelOptions { MaxDegreeOfParallelism = parallelTaskCount }, texture2D =>
{
var savePath = $"{destTexturePath}{texture2D.m_Name}.png";
if (!savePathHash.TryAdd(savePath, true))
return;
using (var image = texture2D.ConvertToImage(flip: true))
{
using (var file = File.OpenWrite($"{destTexturePath}{texture2D.m_Name}.png"))
using (var file = File.OpenWrite(savePath))
{
image.WriteToStream(file, ImageFormat.Png);
}
textures.Add($"textures/{texture2D.m_Name}.png");
textureBag.Add($"textures/{texture2D.m_Name}.png");
}
}
});
textures.UnionWith(textureBag);
#endregion
#region physics3.json