From 47a5e756d4502f0691ae3ca0878c97569c13c1a0 Mon Sep 17 00:00:00 2001 From: ata4 Date: Sun, 29 Dec 2013 22:23:14 +0100 Subject: [PATCH] Added support for audio data from .resS files --- src/info/ata4/unity/asset/AssetFile.java | 15 ++++++++ .../unity/cli/extract/AssetExtractor.java | 5 +++ .../cli/extract/handler/AudioClipHandler.java | 35 +++++++++++++++---- 3 files changed, 49 insertions(+), 6 deletions(-) diff --git a/src/info/ata4/unity/asset/AssetFile.java b/src/info/ata4/unity/asset/AssetFile.java index 8f9a354c..6abedc89 100644 --- a/src/info/ata4/unity/asset/AssetFile.java +++ b/src/info/ata4/unity/asset/AssetFile.java @@ -44,6 +44,7 @@ public class AssetFile extends MappedFileHandler { private static final int HEADER_SIZE = 20; private ByteBuffer bbData; + private ByteBuffer bbAudio; private AssetHeader header = new AssetHeader(); private AssetTypeTree typeTree = new AssetTypeTree(); private AssetObjectPathTable objTable = new AssetObjectPathTable(); @@ -75,6 +76,12 @@ public void load(File file, boolean map) throws IOException { } else { super.load(file, map); } + + // load audio stream if existing + File audioStreamFile = new File(file.getParentFile(), fileName + ".resS"); + if (audioStreamFile.exists()) { + bbAudio = ByteBufferUtils.load(audioStreamFile.toPath()); + } } @Override @@ -183,6 +190,14 @@ public ByteBuffer getDataBuffer() { public void setDataBuffer(ByteBuffer bbData) { this.bbData = bbData; } + + public ByteBuffer getAudioBuffer() { + return bbAudio; + } + + public void setAudioBuffer(ByteBuffer bbAudio) { + this.bbAudio = bbAudio; + } public AssetHeader getHeader() { return header; diff --git a/src/info/ata4/unity/cli/extract/AssetExtractor.java b/src/info/ata4/unity/cli/extract/AssetExtractor.java index 88e81ddd..f43e598d 100644 --- a/src/info/ata4/unity/cli/extract/AssetExtractor.java +++ b/src/info/ata4/unity/cli/extract/AssetExtractor.java @@ -130,6 +130,11 @@ public void extract(File dir, boolean raw) throws IOException { for (AssetExtractHandler extractHandler : extractHandlerMap.values()) { extractHandler.setExtractDir(dir); extractHandler.setAssetFormat(format); + + // set external audio buffer for AudioClips + if (extractHandler instanceof AudioClipHandler) { + ((AudioClipHandler) extractHandler).setAudioBuffer(asset.getAudioBuffer()); + } } for (AssetObjectPath path : pathTable) { diff --git a/src/info/ata4/unity/cli/extract/handler/AudioClipHandler.java b/src/info/ata4/unity/cli/extract/handler/AudioClipHandler.java index ac17a896..7d9bf625 100644 --- a/src/info/ata4/unity/cli/extract/handler/AudioClipHandler.java +++ b/src/info/ata4/unity/cli/extract/handler/AudioClipHandler.java @@ -14,8 +14,10 @@ import info.ata4.unity.enums.AudioType; import info.ata4.unity.serdes.UnityBuffer; import info.ata4.unity.serdes.UnityObject; +import info.ata4.util.io.ByteBufferUtils; import java.io.IOException; import java.nio.ByteBuffer; +import java.nio.ByteOrder; import java.util.Collections; import java.util.EnumMap; import java.util.Map; @@ -46,19 +48,40 @@ public class AudioClipHandler extends AssetExtractHandler { extMap.put(AudioType.AUDIOQUEUE, "caf"); AUDIO_EXT = Collections.unmodifiableMap(extMap); } + + private ByteBuffer audioBufferAux; + + public ByteBuffer getAudioBuffer() { + return audioBufferAux; + } + + public void setAudioBuffer(ByteBuffer audioBufferAux) { + this.audioBufferAux = audioBufferAux; + } @Override public void extract(AssetObjectPath path, UnityObject obj) throws IOException { String name = obj.getValue("m_Name"); + UnityBuffer audioData = obj.getValue("m_AudioData"); ByteBuffer audioBuffer = audioData.getBuffer(); - - if (audioBuffer.capacity() == 0) { - L.log(Level.WARNING, "Audio clip {0} empty", name); - return; - } + audioBuffer.order(ByteOrder.LITTLE_ENDIAN); - AudioType type = AudioType.fromOrdinal((int) obj.getValue("m_Type")); + // load audio buffer from external buffer if stream is set to 2 + int stream = obj.getValue("m_Stream"); + if (stream == 2) { + L.log(Level.FINE, "{0} uses external audio buffer", name); + + int offset = audioBuffer.getInt(); + int size = audioBuffer.capacity(); + audioBuffer.rewind(); + + audioBuffer.put(ByteBufferUtils.getSlice(audioBufferAux, offset, size)); + audioBuffer.rewind(); + } + + int typeInt = obj.getValue("m_Type"); + AudioType type = AudioType.fromOrdinal(typeInt); if (type == null) { L.log(Level.WARNING, "Audio clip {0} uses unknown audio type {1}",