From 7607c8b4d22070722d7d2acad29f6a77f1d59565 Mon Sep 17 00:00:00 2001 From: "1605296300@qq.com" Date: Wed, 7 Sep 2022 01:22:44 +0800 Subject: [PATCH] add acb&awb support --- Assets/Plugins/NAudio.dll | Bin 0 -> 479232 bytes Assets/Plugins/NAudio.dll.meta | 33 + Assets/Scenes/Version2.unity | 1336 ++++++++++++++++- Assets/Scripts/Audio.meta | 8 + Assets/Scripts/Audio/ClHcaSharp.meta | 8 + Assets/Scripts/Audio/ClHcaSharp/Ath.cs | 115 ++ Assets/Scripts/Audio/ClHcaSharp/Ath.cs.meta | 11 + Assets/Scripts/Audio/ClHcaSharp/BitReader.cs | 107 ++ .../Audio/ClHcaSharp/BitReader.cs.meta | 11 + Assets/Scripts/Audio/ClHcaSharp/Channel.cs | 29 + .../Scripts/Audio/ClHcaSharp/Channel.cs.meta | 11 + Assets/Scripts/Audio/ClHcaSharp/Cipher.cs | 139 ++ .../Scripts/Audio/ClHcaSharp/Cipher.cs.meta | 11 + Assets/Scripts/Audio/ClHcaSharp/Crc.cs | 37 + Assets/Scripts/Audio/ClHcaSharp/Crc.cs.meta | 11 + .../Scripts/Audio/ClHcaSharp/Definitions.cs | 42 + .../Audio/ClHcaSharp/Definitions.cs.meta | 11 + Assets/Scripts/Audio/ClHcaSharp/HcaContext.cs | 53 + .../Audio/ClHcaSharp/HcaContext.cs.meta | 11 + Assets/Scripts/Audio/ClHcaSharp/HcaDecoder.cs | 732 +++++++++ .../Audio/ClHcaSharp/HcaDecoder.cs.meta | 11 + Assets/Scripts/Audio/ClHcaSharp/HcaInfo.cs | 26 + .../Scripts/Audio/ClHcaSharp/HcaInfo.cs.meta | 11 + Assets/Scripts/Audio/ClHcaSharp/Header.cs | 329 ++++ .../Scripts/Audio/ClHcaSharp/Header.cs.meta | 11 + .../Scripts/Audio/ClHcaSharp/JaggedArray.cs | 28 + .../Audio/ClHcaSharp/JaggedArray.cs.meta | 11 + Assets/Scripts/Audio/ClHcaSharp/Tables.cs | 335 +++++ .../Scripts/Audio/ClHcaSharp/Tables.cs.meta | 11 + Assets/Scripts/Audio/CriWareFormats.meta | 8 + .../Audio/CriWareFormats/AcbNameLoader.cs | 702 +++++++++ .../CriWareFormats/AcbNameLoader.cs.meta | 11 + .../Scripts/Audio/CriWareFormats/AcbReader.cs | 57 + .../Audio/CriWareFormats/AcbReader.cs.meta | 11 + .../Scripts/Audio/CriWareFormats/AwbReader.cs | 139 ++ .../Audio/CriWareFormats/AwbReader.cs.meta | 11 + .../Scripts/Audio/CriWareFormats/Common.meta | 8 + .../CriWareFormats/Common/BinaryPrimitives.cs | 51 + .../Common/BinaryPrimitives.cs.meta | 11 + .../Common/BinaryReaderEndian.cs | 69 + .../Common/BinaryReaderEndian.cs.meta | 11 + .../Audio/CriWareFormats/Common/Endian.cs | 27 + .../CriWareFormats/Common/Endian.cs.meta | 11 + .../Audio/CriWareFormats/SpliceStream.cs | 116 ++ .../Audio/CriWareFormats/SpliceStream.cs.meta | 11 + .../Scripts/Audio/CriWareFormats/UtfTable.cs | 435 ++++++ .../Audio/CriWareFormats/UtfTable.cs.meta | 11 + Assets/Scripts/Audio/HcaWaveStream.cs | 172 +++ Assets/Scripts/Audio/HcaWaveStream.cs.meta | 11 + Assets/Scripts/Audio/UmaWaveStream.cs | 54 + Assets/Scripts/Audio/UmaWaveStream.cs.meta | 11 + Assets/Scripts/Audio/WAV.cs | 118 ++ Assets/Scripts/Audio/WAV.cs.meta | 11 + Assets/Scripts/UmaViewerBuilder.cs | 64 +- Assets/Scripts/UmaViewerUI.cs | 62 +- ProjectSettings/ProjectSettings.asset | 7 +- app.config | 11 + 57 files changed, 5676 insertions(+), 34 deletions(-) create mode 100644 Assets/Plugins/NAudio.dll create mode 100644 Assets/Plugins/NAudio.dll.meta create mode 100644 Assets/Scripts/Audio.meta create mode 100644 Assets/Scripts/Audio/ClHcaSharp.meta create mode 100644 Assets/Scripts/Audio/ClHcaSharp/Ath.cs create mode 100644 Assets/Scripts/Audio/ClHcaSharp/Ath.cs.meta create mode 100644 Assets/Scripts/Audio/ClHcaSharp/BitReader.cs create mode 100644 Assets/Scripts/Audio/ClHcaSharp/BitReader.cs.meta create mode 100644 Assets/Scripts/Audio/ClHcaSharp/Channel.cs create mode 100644 Assets/Scripts/Audio/ClHcaSharp/Channel.cs.meta create mode 100644 Assets/Scripts/Audio/ClHcaSharp/Cipher.cs create mode 100644 Assets/Scripts/Audio/ClHcaSharp/Cipher.cs.meta create mode 100644 Assets/Scripts/Audio/ClHcaSharp/Crc.cs create mode 100644 Assets/Scripts/Audio/ClHcaSharp/Crc.cs.meta create mode 100644 Assets/Scripts/Audio/ClHcaSharp/Definitions.cs create mode 100644 Assets/Scripts/Audio/ClHcaSharp/Definitions.cs.meta create mode 100644 Assets/Scripts/Audio/ClHcaSharp/HcaContext.cs create mode 100644 Assets/Scripts/Audio/ClHcaSharp/HcaContext.cs.meta create mode 100644 Assets/Scripts/Audio/ClHcaSharp/HcaDecoder.cs create mode 100644 Assets/Scripts/Audio/ClHcaSharp/HcaDecoder.cs.meta create mode 100644 Assets/Scripts/Audio/ClHcaSharp/HcaInfo.cs create mode 100644 Assets/Scripts/Audio/ClHcaSharp/HcaInfo.cs.meta create mode 100644 Assets/Scripts/Audio/ClHcaSharp/Header.cs create mode 100644 Assets/Scripts/Audio/ClHcaSharp/Header.cs.meta create mode 100644 Assets/Scripts/Audio/ClHcaSharp/JaggedArray.cs create mode 100644 Assets/Scripts/Audio/ClHcaSharp/JaggedArray.cs.meta create mode 100644 Assets/Scripts/Audio/ClHcaSharp/Tables.cs create mode 100644 Assets/Scripts/Audio/ClHcaSharp/Tables.cs.meta create mode 100644 Assets/Scripts/Audio/CriWareFormats.meta create mode 100644 Assets/Scripts/Audio/CriWareFormats/AcbNameLoader.cs create mode 100644 Assets/Scripts/Audio/CriWareFormats/AcbNameLoader.cs.meta create mode 100644 Assets/Scripts/Audio/CriWareFormats/AcbReader.cs create mode 100644 Assets/Scripts/Audio/CriWareFormats/AcbReader.cs.meta create mode 100644 Assets/Scripts/Audio/CriWareFormats/AwbReader.cs create mode 100644 Assets/Scripts/Audio/CriWareFormats/AwbReader.cs.meta create mode 100644 Assets/Scripts/Audio/CriWareFormats/Common.meta create mode 100644 Assets/Scripts/Audio/CriWareFormats/Common/BinaryPrimitives.cs create mode 100644 Assets/Scripts/Audio/CriWareFormats/Common/BinaryPrimitives.cs.meta create mode 100644 Assets/Scripts/Audio/CriWareFormats/Common/BinaryReaderEndian.cs create mode 100644 Assets/Scripts/Audio/CriWareFormats/Common/BinaryReaderEndian.cs.meta create mode 100644 Assets/Scripts/Audio/CriWareFormats/Common/Endian.cs create mode 100644 Assets/Scripts/Audio/CriWareFormats/Common/Endian.cs.meta create mode 100644 Assets/Scripts/Audio/CriWareFormats/SpliceStream.cs create mode 100644 Assets/Scripts/Audio/CriWareFormats/SpliceStream.cs.meta create mode 100644 Assets/Scripts/Audio/CriWareFormats/UtfTable.cs create mode 100644 Assets/Scripts/Audio/CriWareFormats/UtfTable.cs.meta create mode 100644 Assets/Scripts/Audio/HcaWaveStream.cs create mode 100644 Assets/Scripts/Audio/HcaWaveStream.cs.meta create mode 100644 Assets/Scripts/Audio/UmaWaveStream.cs create mode 100644 Assets/Scripts/Audio/UmaWaveStream.cs.meta create mode 100644 Assets/Scripts/Audio/WAV.cs create mode 100644 Assets/Scripts/Audio/WAV.cs.meta create mode 100644 app.config diff --git a/Assets/Plugins/NAudio.dll b/Assets/Plugins/NAudio.dll new file mode 100644 index 0000000000000000000000000000000000000000..9425d4029143177f673c145b75691d720855fcac GIT binary patch literal 479232 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

}$t7K~NtfJUr6+5$yaQXB>}6l7L$_*o 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 I|2q!+KWhJT^Z)<= literal 0 HcmV?d00001 diff --git a/Assets/Plugins/NAudio.dll.meta b/Assets/Plugins/NAudio.dll.meta new file mode 100644 index 0000000..186f540 --- /dev/null +++ b/Assets/Plugins/NAudio.dll.meta @@ -0,0 +1,33 @@ +fileFormatVersion: 2 +guid: 2c0b0ac3e281b3f4c87f02a42e65baad +PluginImporter: + externalObjects: {} + serializedVersion: 2 + iconMap: {} + executionOrder: {} + defineConstraints: [] + isPreloaded: 0 + isOverridable: 0 + isExplicitlyReferenced: 0 + validateReferences: 1 + platformData: + - first: + Any: + second: + enabled: 1 + settings: {} + - first: + Editor: Editor + second: + enabled: 0 + settings: + DefaultValueInitialized: true + - first: + Windows Store Apps: WindowsStoreApps + second: + enabled: 0 + settings: + CPU: AnyCPU + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scenes/Version2.unity b/Assets/Scenes/Version2.unity index 77dec44..8aecf6e 100644 --- a/Assets/Scenes/Version2.unity +++ b/Assets/Scenes/Version2.unity @@ -249,6 +249,83 @@ CanvasRenderer: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 3821828} m_CullTransparentMesh: 1 +--- !u!1 &4067202 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 4067203} + - component: {fileID: 4067205} + - component: {fileID: 4067204} + m_Layer: 5 + m_Name: Content + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &4067203 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 4067202} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 1566898430} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 1} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0, y: 1} +--- !u!114 &4067204 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 4067202} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 59f8146938fff824cb5fd77236b75775, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Padding: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_ChildAlignment: 0 + m_Spacing: 0 + m_ChildForceExpandWidth: 1 + m_ChildForceExpandHeight: 1 + m_ChildControlWidth: 1 + m_ChildControlHeight: 0 + m_ChildScaleWidth: 0 + m_ChildScaleHeight: 0 + m_ReverseArrangement: 0 +--- !u!114 &4067205 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 4067202} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 3245ec927659c4140ac4f8d17403cc18, type: 3} + m_Name: + m_EditorClassIdentifier: + m_HorizontalFit: 0 + m_VerticalFit: 2 --- !u!1 &18660878 GameObject: m_ObjectHideFlags: 0 @@ -2160,6 +2237,7 @@ RectTransform: - {fileID: 1696082999} - {fileID: 1339030790} - {fileID: 755403585} + - {fileID: 829429200} m_Father: {fileID: 1300114664} m_RootOrder: 1 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} @@ -3313,6 +3391,132 @@ CanvasRenderer: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 354788360} m_CullTransparentMesh: 1 +--- !u!1 &354822016 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 354822017} + - component: {fileID: 354822020} + - component: {fileID: 354822019} + - component: {fileID: 354822018} + m_Layer: 5 + m_Name: Scrollbar Vertical + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &354822017 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 354822016} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: + - {fileID: 2119296308} + m_Father: {fileID: 1678768230} + m_RootOrder: 1 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 1, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 20, y: 0} + m_Pivot: {x: 1, y: 1} +--- !u!114 &354822018 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 354822016} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 2a4db7a114972834c8e4117be1d82ba3, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Navigation: + m_Mode: 3 + m_WrapAround: 0 + m_SelectOnUp: {fileID: 0} + m_SelectOnDown: {fileID: 0} + m_SelectOnLeft: {fileID: 0} + m_SelectOnRight: {fileID: 0} + m_Transition: 1 + m_Colors: + m_NormalColor: {r: 1, g: 1, b: 1, a: 1} + m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} + m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} + m_ColorMultiplier: 1 + m_FadeDuration: 0.1 + m_SpriteState: + m_HighlightedSprite: {fileID: 0} + m_PressedSprite: {fileID: 0} + m_SelectedSprite: {fileID: 0} + m_DisabledSprite: {fileID: 0} + m_AnimationTriggers: + m_NormalTrigger: Normal + m_HighlightedTrigger: Highlighted + m_PressedTrigger: Pressed + m_SelectedTrigger: Selected + m_DisabledTrigger: Disabled + m_Interactable: 1 + m_TargetGraphic: {fileID: 1141489498} + m_HandleRect: {fileID: 1141489497} + m_Direction: 2 + m_Value: 0 + m_Size: 1 + m_NumberOfSteps: 0 + m_OnValueChanged: + m_PersistentCalls: + m_Calls: [] +--- !u!114 &354822019 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 354822016} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 10907, guid: 0000000000000000f000000000000000, type: 0} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &354822020 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 354822016} + m_CullTransparentMesh: 1 --- !u!1 &399621053 GameObject: m_ObjectHideFlags: 0 @@ -3446,6 +3650,42 @@ CanvasRenderer: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 399621053} m_CullTransparentMesh: 1 +--- !u!1 &406861037 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 406861038} + m_Layer: 5 + m_Name: Sliding Area + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &406861038 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 406861037} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: + - {fileID: 1958159930} + m_Father: {fileID: 523153148} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: -20, y: -20} + m_Pivot: {x: 0.5, y: 0.5} --- !u!1 &418000888 GameObject: m_ObjectHideFlags: 0 @@ -5198,6 +5438,132 @@ CanvasRenderer: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 504748474} m_CullTransparentMesh: 1 +--- !u!1 &523153147 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 523153148} + - component: {fileID: 523153151} + - component: {fileID: 523153150} + - component: {fileID: 523153149} + m_Layer: 5 + m_Name: Scrollbar Vertical + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &523153148 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 523153147} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: + - {fileID: 406861038} + m_Father: {fileID: 931406426} + m_RootOrder: 1 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 1, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 20, y: 0} + m_Pivot: {x: 1, y: 1} +--- !u!114 &523153149 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 523153147} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 2a4db7a114972834c8e4117be1d82ba3, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Navigation: + m_Mode: 3 + m_WrapAround: 0 + m_SelectOnUp: {fileID: 0} + m_SelectOnDown: {fileID: 0} + m_SelectOnLeft: {fileID: 0} + m_SelectOnRight: {fileID: 0} + m_Transition: 1 + m_Colors: + m_NormalColor: {r: 1, g: 1, b: 1, a: 1} + m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} + m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} + m_ColorMultiplier: 1 + m_FadeDuration: 0.1 + m_SpriteState: + m_HighlightedSprite: {fileID: 0} + m_PressedSprite: {fileID: 0} + m_SelectedSprite: {fileID: 0} + m_DisabledSprite: {fileID: 0} + m_AnimationTriggers: + m_NormalTrigger: Normal + m_HighlightedTrigger: Highlighted + m_PressedTrigger: Pressed + m_SelectedTrigger: Selected + m_DisabledTrigger: Disabled + m_Interactable: 1 + m_TargetGraphic: {fileID: 1958159931} + m_HandleRect: {fileID: 1958159930} + m_Direction: 2 + m_Value: 0 + m_Size: 1 + m_NumberOfSteps: 0 + m_OnValueChanged: + m_PersistentCalls: + m_Calls: [] +--- !u!114 &523153150 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 523153147} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 10907, guid: 0000000000000000f000000000000000, type: 0} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &523153151 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 523153147} + m_CullTransparentMesh: 1 --- !u!1 &538060552 GameObject: m_ObjectHideFlags: 0 @@ -5481,6 +5847,140 @@ CanvasRenderer: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 544177723} m_CullTransparentMesh: 1 +--- !u!1 &544380814 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 544380815} + - component: {fileID: 544380817} + - component: {fileID: 544380816} + m_Layer: 5 + m_Name: Text (TMP) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &544380815 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 544380814} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 695996365} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &544380816 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 544380814} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_text: LiveSounds + m_isRightToLeft: 0 + m_fontAsset: {fileID: 11400000, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_sharedMaterial: {fileID: 2180264, guid: 8f586378b4e144a9851e7b34d9b748ee, type: 2} + m_fontSharedMaterials: [] + m_fontMaterial: {fileID: 0} + m_fontMaterials: [] + m_fontColor32: + serializedVersion: 2 + rgba: 4281479730 + m_fontColor: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1} + m_enableVertexGradient: 0 + m_colorMode: 3 + m_fontColorGradient: + topLeft: {r: 1, g: 1, b: 1, a: 1} + topRight: {r: 1, g: 1, b: 1, a: 1} + bottomLeft: {r: 1, g: 1, b: 1, a: 1} + bottomRight: {r: 1, g: 1, b: 1, a: 1} + m_fontColorGradientPreset: {fileID: 0} + m_spriteAsset: {fileID: 0} + m_tintAllSprites: 0 + m_StyleSheet: {fileID: 0} + m_TextStyleHashCode: -1183493901 + m_overrideHtmlColors: 0 + m_faceColor: + serializedVersion: 2 + rgba: 4294967295 + m_fontSize: 24 + m_fontSizeBase: 24 + m_fontWeight: 400 + m_enableAutoSizing: 0 + m_fontSizeMin: 18 + m_fontSizeMax: 72 + m_fontStyle: 0 + m_HorizontalAlignment: 2 + m_VerticalAlignment: 512 + m_textAlignment: 65535 + m_characterSpacing: 0 + m_wordSpacing: 0 + m_lineSpacing: 0 + m_lineSpacingMax: 0 + m_paragraphSpacing: 0 + m_charWidthMaxAdj: 0 + m_enableWordWrapping: 1 + m_wordWrappingRatios: 0.4 + m_overflowMode: 0 + m_linkedTextComponent: {fileID: 0} + parentLinkedComponent: {fileID: 0} + m_enableKerning: 1 + m_enableExtraPadding: 0 + checkPaddingRequired: 0 + m_isRichText: 1 + m_parseCtrlCharacters: 1 + m_isOrthographic: 1 + m_isCullingEnabled: 0 + m_horizontalMapping: 0 + m_verticalMapping: 0 + m_uvLineOffset: 0 + m_geometrySortingOrder: 0 + m_IsTextObjectScaleStatic: 0 + m_VertexBufferAutoSizeReduction: 0 + m_useMaxVisibleDescender: 1 + m_pageToDisplay: 1 + m_margin: {x: 0, y: 0, z: 0, w: 0} + m_isUsingLegacyAnimationComponent: 0 + m_isVolumetricText: 0 + m_hasFontAssetChanged: 0 + m_baseMaterial: {fileID: 0} + m_maskOffset: {x: 0, y: 0, z: 0, w: 0} +--- !u!222 &544380817 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 544380814} + m_CullTransparentMesh: 1 --- !u!1 &553103594 GameObject: m_ObjectHideFlags: 0 @@ -6369,6 +6869,139 @@ CanvasRenderer: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 685507282} m_CullTransparentMesh: 1 +--- !u!1 &695996364 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 695996365} + - component: {fileID: 695996368} + - component: {fileID: 695996367} + - component: {fileID: 695996366} + m_Layer: 5 + m_Name: LiveSounds + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &695996365 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 695996364} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: + - {fileID: 544380815} + m_Father: {fileID: 1200264883} + m_RootOrder: 8 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &695996366 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 695996364} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 4e29b1a8efbd4b44bb3f3716e73f07ff, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Navigation: + m_Mode: 3 + m_WrapAround: 0 + m_SelectOnUp: {fileID: 0} + m_SelectOnDown: {fileID: 0} + m_SelectOnLeft: {fileID: 0} + m_SelectOnRight: {fileID: 0} + m_Transition: 1 + m_Colors: + m_NormalColor: {r: 1, g: 1, b: 1, a: 1} + m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} + m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} + m_ColorMultiplier: 1 + m_FadeDuration: 0.1 + m_SpriteState: + m_HighlightedSprite: {fileID: 0} + m_PressedSprite: {fileID: 0} + m_SelectedSprite: {fileID: 0} + m_DisabledSprite: {fileID: 0} + m_AnimationTriggers: + m_NormalTrigger: Normal + m_HighlightedTrigger: Highlighted + m_PressedTrigger: Pressed + m_SelectedTrigger: Selected + m_DisabledTrigger: Disabled + m_Interactable: 1 + m_TargetGraphic: {fileID: 695996367} + m_OnClick: + m_PersistentCalls: + m_Calls: + - m_Target: {fileID: 1564959567} + m_TargetAssemblyTypeName: UmaViewerUI, Assembly-CSharp + m_MethodName: ToggleUIPanel + m_Mode: 2 + m_Arguments: + m_ObjectArgument: {fileID: 829429199} + m_ObjectArgumentAssemblyTypeName: UnityEngine.GameObject, UnityEngine + m_IntArgument: 0 + m_FloatArgument: 0 + m_StringArgument: + m_BoolArgument: 0 + m_CallState: 2 +--- !u!114 &695996367 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 695996364} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 10905, guid: 0000000000000000f000000000000000, type: 0} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &695996368 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 695996364} + m_CullTransparentMesh: 1 --- !u!1 &696629172 GameObject: m_ObjectHideFlags: 0 @@ -7810,6 +8443,43 @@ MonoBehaviour: m_EditorClassIdentifier: m_HorizontalFit: 0 m_VerticalFit: 2 +--- !u!1 &829429199 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 829429200} + m_Layer: 5 + m_Name: LiveSound + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 0 +--- !u!224 &829429200 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 829429199} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: + - {fileID: 1678768230} + - {fileID: 931406426} + m_Father: {fileID: 242004464} + m_RootOrder: 8 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} --- !u!1 &835845605 GameObject: m_ObjectHideFlags: 0 @@ -8720,6 +9390,114 @@ Transform: m_Father: {fileID: 0} m_RootOrder: 1 m_LocalEulerAnglesHint: {x: 50, y: -30, z: 0} +--- !u!1 &931406425 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 931406426} + - component: {fileID: 931406428} + - component: {fileID: 931406427} + - component: {fileID: 931406429} + m_Layer: 5 + m_Name: LiveCharaSound List + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &931406426 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 931406425} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: + - {fileID: 1537165047} + - {fileID: 523153148} + m_Father: {fileID: 829429200} + m_RootOrder: 1 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 1} + m_AnchoredPosition: {x: 398.68, y: -30} + m_SizeDelta: {x: 255, y: -60} + m_Pivot: {x: 0, y: 0.5} +--- !u!114 &931406427 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 931406425} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 0.392} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 0} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &931406428 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 931406425} + m_CullTransparentMesh: 1 +--- !u!114 &931406429 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 931406425} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 1aa08ab6e0800fa44ae55d278d1423e3, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Content: {fileID: 1297525977} + m_Horizontal: 0 + m_Vertical: 1 + m_MovementType: 2 + m_Elasticity: 0.1 + m_Inertia: 1 + m_DecelerationRate: 0.135 + m_ScrollSensitivity: 90 + m_Viewport: {fileID: 1537165047} + m_HorizontalScrollbar: {fileID: 0} + m_VerticalScrollbar: {fileID: 523153149} + m_HorizontalScrollbarVisibility: 2 + m_VerticalScrollbarVisibility: 2 + m_HorizontalScrollbarSpacing: -3 + m_VerticalScrollbarSpacing: -3 + m_OnValueChanged: + m_PersistentCalls: + m_Calls: [] --- !u!1 &952551663 GameObject: m_ObjectHideFlags: 0 @@ -9664,6 +10442,81 @@ RectTransform: m_AnchoredPosition: {x: 0, y: 0} m_SizeDelta: {x: -20, y: -20} m_Pivot: {x: 0.5, y: 0.5} +--- !u!1 &1141489496 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1141489497} + - component: {fileID: 1141489499} + - component: {fileID: 1141489498} + m_Layer: 5 + m_Name: Handle + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1141489497 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1141489496} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 2119296308} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 20, y: 20} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1141489498 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1141489496} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 10905, guid: 0000000000000000f000000000000000, type: 0} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &1141489499 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1141489496} + m_CullTransparentMesh: 1 --- !u!1 &1148283644 GameObject: m_ObjectHideFlags: 0 @@ -10007,7 +10860,7 @@ MonoBehaviour: m_HandleRect: {fileID: 1882365342} m_Direction: 2 m_Value: 1 - m_Size: 0.66019416 + m_Size: 0.6601942 m_NumberOfSteps: 0 m_OnValueChanged: m_PersistentCalls: @@ -10163,6 +11016,7 @@ RectTransform: - {fileID: 2011080537} - {fileID: 1259881231} - {fileID: 886856742} + - {fileID: 695996365} m_Father: {fileID: 733646225} m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} @@ -10806,6 +11660,83 @@ CanvasRenderer: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 1286086648} m_CullTransparentMesh: 1 +--- !u!1 &1297525976 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1297525977} + - component: {fileID: 1297525979} + - component: {fileID: 1297525978} + m_Layer: 5 + m_Name: Content + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1297525977 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1297525976} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 1537165047} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 1} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0, y: 1} +--- !u!114 &1297525978 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1297525976} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 59f8146938fff824cb5fd77236b75775, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Padding: + m_Left: 0 + m_Right: 0 + m_Top: 0 + m_Bottom: 0 + m_ChildAlignment: 0 + m_Spacing: 0 + m_ChildForceExpandWidth: 1 + m_ChildForceExpandHeight: 1 + m_ChildControlWidth: 1 + m_ChildControlHeight: 0 + m_ChildScaleWidth: 0 + m_ChildScaleHeight: 0 + m_ReverseArrangement: 0 +--- !u!114 &1297525979 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1297525976} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 3245ec927659c4140ac4f8d17403cc18, type: 3} + m_Name: + m_EditorClassIdentifier: + m_HorizontalFit: 0 + m_VerticalFit: 2 --- !u!1 &1300114663 GameObject: m_ObjectHideFlags: 0 @@ -12535,6 +13466,96 @@ MonoBehaviour: m_EditorClassIdentifier: m_HorizontalFit: 0 m_VerticalFit: 2 +--- !u!1 &1537165046 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1537165047} + - component: {fileID: 1537165050} + - component: {fileID: 1537165049} + - component: {fileID: 1537165048} + m_Layer: 5 + m_Name: Viewport + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1537165047 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1537165046} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: + - {fileID: 1297525977} + m_Father: {fileID: 931406426} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: -17, y: 0} + m_Pivot: {x: 0, y: 1} +--- !u!114 &1537165048 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1537165046} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 31a19414c41e5ae4aae2af33fee712f6, type: 3} + m_Name: + m_EditorClassIdentifier: + m_ShowMaskGraphic: 0 +--- !u!114 &1537165049 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1537165046} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 0} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &1537165050 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1537165046} + m_CullTransparentMesh: 1 --- !u!1 &1558324556 GameObject: m_ObjectHideFlags: 0 @@ -12715,6 +13736,8 @@ MonoBehaviour: SceneList: {fileID: 835845609} FacialList: {fileID: 1684693617} LiveList: {fileID: 1970310175} + LiveSoundList: {fileID: 1678768233} + LiveCharaSoundList: {fileID: 931406429} SSWidth: {fileID: 0} SSHeight: {fileID: 0} TogglablePanels: @@ -12726,6 +13749,7 @@ MonoBehaviour: - {fileID: 1696082998} - {fileID: 1339030789} - {fileID: 755403584} + - {fileID: 829429199} UmaContainerPrefab: {fileID: 648541853701480401, guid: 1b51367a8eeaf0146b7bff4005281a2c, type: 3} UmaContainerSliderPrefab: {fileID: 648541853701480401, guid: 75962a0f68455494db9858ad95fb4ae8, @@ -12756,7 +13780,98 @@ MonoBehaviour: CurrentUMAContainer: {fileID: 0} CurrentLiveContainer: {fileID: 0} CurrentOtherContainer: {fileID: 0} + CurrentAudioSource: {fileID: 0} OverrideController: {fileID: 22100000, guid: 130057757529b0f40a4fdc08bf0861ef, type: 2} +--- !u!1 &1566898429 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1566898430} + - component: {fileID: 1566898433} + - component: {fileID: 1566898432} + - component: {fileID: 1566898431} + m_Layer: 5 + m_Name: Viewport + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1566898430 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1566898429} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: + - {fileID: 4067203} + m_Father: {fileID: 1678768230} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: -17, y: 0} + m_Pivot: {x: 0, y: 1} +--- !u!114 &1566898431 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1566898429} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 31a19414c41e5ae4aae2af33fee712f6, type: 3} + m_Name: + m_EditorClassIdentifier: + m_ShowMaskGraphic: 0 +--- !u!114 &1566898432 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1566898429} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 0} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &1566898433 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1566898429} + m_CullTransparentMesh: 1 --- !u!1 &1576308332 GameObject: m_ObjectHideFlags: 0 @@ -13937,6 +15052,114 @@ CanvasRenderer: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 1677453984} m_CullTransparentMesh: 1 +--- !u!1 &1678768229 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1678768230} + - component: {fileID: 1678768232} + - component: {fileID: 1678768231} + - component: {fileID: 1678768233} + m_Layer: 5 + m_Name: LiveSound List + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1678768230 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1678768229} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: + - {fileID: 1566898430} + - {fileID: 354822017} + m_Father: {fileID: 829429200} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 1} + m_AnchoredPosition: {x: 0, y: -30} + m_SizeDelta: {x: 398.6807, y: -60} + m_Pivot: {x: 0, y: 0.5} +--- !u!114 &1678768231 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1678768229} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 0.392} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 0} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &1678768232 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1678768229} + m_CullTransparentMesh: 1 +--- !u!114 &1678768233 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1678768229} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 1aa08ab6e0800fa44ae55d278d1423e3, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Content: {fileID: 4067203} + m_Horizontal: 0 + m_Vertical: 1 + m_MovementType: 2 + m_Elasticity: 0.1 + m_Inertia: 1 + m_DecelerationRate: 0.135 + m_ScrollSensitivity: 90 + m_Viewport: {fileID: 1566898430} + m_HorizontalScrollbar: {fileID: 0} + m_VerticalScrollbar: {fileID: 354822018} + m_HorizontalScrollbarVisibility: 2 + m_VerticalScrollbarVisibility: 2 + m_HorizontalScrollbarSpacing: -3 + m_VerticalScrollbarSpacing: -3 + m_OnValueChanged: + m_PersistentCalls: + m_Calls: [] --- !u!1 &1684693613 GameObject: m_ObjectHideFlags: 0 @@ -16024,6 +17247,81 @@ CanvasRenderer: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 1949291610} m_CullTransparentMesh: 1 +--- !u!1 &1958159929 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1958159930} + - component: {fileID: 1958159932} + - component: {fileID: 1958159931} + m_Layer: 5 + m_Name: Handle + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1958159930 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1958159929} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 406861038} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 20, y: 20} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &1958159931 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1958159929} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 10905, guid: 0000000000000000f000000000000000, type: 0} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!222 &1958159932 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1958159929} + m_CullTransparentMesh: 1 --- !u!1 &1970310173 GameObject: m_ObjectHideFlags: 0 @@ -17011,6 +18309,42 @@ CanvasRenderer: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 2108058672} m_CullTransparentMesh: 1 +--- !u!1 &2119296307 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 2119296308} + m_Layer: 5 + m_Name: Sliding Area + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &2119296308 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2119296307} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: + - {fileID: 1141489497} + m_Father: {fileID: 354822017} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: -20, y: -20} + m_Pivot: {x: 0.5, y: 0.5} --- !u!1 &2126459760 GameObject: m_ObjectHideFlags: 0 diff --git a/Assets/Scripts/Audio.meta b/Assets/Scripts/Audio.meta new file mode 100644 index 0000000..7cdc4ad --- /dev/null +++ b/Assets/Scripts/Audio.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: e9030d1ab7c7dce4eb3d45b93c88e3c2 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Audio/ClHcaSharp.meta b/Assets/Scripts/Audio/ClHcaSharp.meta new file mode 100644 index 0000000..a025c4b --- /dev/null +++ b/Assets/Scripts/Audio/ClHcaSharp.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 7fc4162661dc2f8469c9c2f7f36d6357 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Audio/ClHcaSharp/Ath.cs b/Assets/Scripts/Audio/ClHcaSharp/Ath.cs new file mode 100644 index 0000000..8f9600c --- /dev/null +++ b/Assets/Scripts/Audio/ClHcaSharp/Ath.cs @@ -0,0 +1,115 @@ +using System; +using static ClHcaSharp.Constants; + +namespace ClHcaSharp +{ + internal static class Ath + { + private static readonly byte[] baseCurve = new byte[656] + { + 0x78, 0x5F, 0x56, 0x51, 0x4E, 0x4C, 0x4B, 0x49, 0x48, 0x48, 0x47, 0x46, 0x46, 0x45, 0x45, 0x45, + 0x44, 0x44, 0x44, 0x44, 0x43, 0x43, 0x43, 0x43, 0x43, 0x43, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, + 0x42, 0x42, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x40, 0x40, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, + 0x3F, 0x3F, 0x3F, 0x3E, 0x3E, 0x3E, 0x3E, 0x3E, 0x3E, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, + 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, + 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, + 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3B, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, + 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x3E, 0x3E, 0x3E, 0x3E, 0x3E, 0x3E, 0x3E, 0x3F, + 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, + 0x3F, 0x3F, 0x3F, 0x3F, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, + 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, + 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, + 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, + 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x43, 0x43, 0x43, + 0x43, 0x43, 0x43, 0x43, 0x43, 0x43, 0x43, 0x43, 0x43, 0x43, 0x43, 0x43, 0x43, 0x43, 0x44, 0x44, + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x45, 0x45, 0x45, 0x45, + 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, + 0x46, 0x46, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x48, 0x48, 0x48, 0x48, + 0x48, 0x48, 0x48, 0x48, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x4A, 0x4A, 0x4A, 0x4A, + 0x4A, 0x4A, 0x4A, 0x4A, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4C, 0x4C, 0x4C, 0x4C, 0x4C, + 0x4C, 0x4D, 0x4D, 0x4D, 0x4D, 0x4D, 0x4D, 0x4E, 0x4E, 0x4E, 0x4E, 0x4E, 0x4E, 0x4F, 0x4F, 0x4F, + 0x4F, 0x4F, 0x4F, 0x50, 0x50, 0x50, 0x50, 0x50, 0x51, 0x51, 0x51, 0x51, 0x51, 0x52, 0x52, 0x52, + 0x52, 0x52, 0x53, 0x53, 0x53, 0x53, 0x54, 0x54, 0x54, 0x54, 0x54, 0x55, 0x55, 0x55, 0x55, 0x56, + 0x56, 0x56, 0x56, 0x57, 0x57, 0x57, 0x57, 0x57, 0x58, 0x58, 0x58, 0x59, 0x59, 0x59, 0x59, 0x5A, + 0x5A, 0x5A, 0x5A, 0x5B, 0x5B, 0x5B, 0x5B, 0x5C, 0x5C, 0x5C, 0x5D, 0x5D, 0x5D, 0x5D, 0x5E, 0x5E, + 0x5E, 0x5F, 0x5F, 0x5F, 0x60, 0x60, 0x60, 0x61, 0x61, 0x61, 0x61, 0x62, 0x62, 0x62, 0x63, 0x63, + 0x63, 0x64, 0x64, 0x64, 0x65, 0x65, 0x66, 0x66, 0x66, 0x67, 0x67, 0x67, 0x68, 0x68, 0x68, 0x69, + 0x69, 0x6A, 0x6A, 0x6A, 0x6B, 0x6B, 0x6B, 0x6C, 0x6C, 0x6D, 0x6D, 0x6D, 0x6E, 0x6E, 0x6F, 0x6F, + 0x70, 0x70, 0x70, 0x71, 0x71, 0x72, 0x72, 0x73, 0x73, 0x73, 0x74, 0x74, 0x75, 0x75, 0x76, 0x76, + 0x77, 0x77, 0x78, 0x78, 0x78, 0x79, 0x79, 0x7A, 0x7A, 0x7B, 0x7B, 0x7C, 0x7C, 0x7D, 0x7D, 0x7E, + 0x7E, 0x7F, 0x7F, 0x80, 0x80, 0x81, 0x81, 0x82, 0x83, 0x83, 0x84, 0x84, 0x85, 0x85, 0x86, 0x86, + 0x87, 0x88, 0x88, 0x89, 0x89, 0x8A, 0x8A, 0x8B, 0x8C, 0x8C, 0x8D, 0x8D, 0x8E, 0x8F, 0x8F, 0x90, + 0x90, 0x91, 0x92, 0x92, 0x93, 0x94, 0x94, 0x95, 0x95, 0x96, 0x97, 0x97, 0x98, 0x99, 0x99, 0x9A, + 0x9B, 0x9B, 0x9C, 0x9D, 0x9D, 0x9E, 0x9F, 0xA0, 0xA0, 0xA1, 0xA2, 0xA2, 0xA3, 0xA4, 0xA5, 0xA5, + 0xA6, 0xA7, 0xA7, 0xA8, 0xA9, 0xAA, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAE, 0xAF, 0xB0, 0xB1, 0xB1, + 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, + 0xC0, 0xC1, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, + 0xCE, 0xCF, 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, + 0xDE, 0xDF, 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xED, 0xEE, + 0xEF, 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFF, 0xFF + }; + + public static byte[] Init(int type, int sampleRate) + { + return type switch + { + 0 => Init0(), + 1 => Init1(sampleRate), + _ => throw new ArgumentException("Invalid ATH type."), + }; + } + + private static byte[] Init0() + { + byte[] athCurve = new byte[SamplesPerSubframe]; + for (int i = 0; i < athCurve.Length; i++) + { + athCurve[i] = 0; + } + + return athCurve; + } + + private static byte[] Init1(int sampleRate) + { + byte[] athCurve = new byte[SamplesPerSubframe]; + int acc = 0; + + for (int i = 0; i < athCurve.Length; i++) + { + acc += sampleRate; + int index = acc >> 13; + + if (index >= 654) + { + Fill(athCurve, i, SamplesPerSubframe - i,0xFF); + break; + } + athCurve[i] = baseCurve[index]; + } + + return athCurve; + } + + public static void Fill(T[] array, int start, int end, T value) + { + if (array == null) + { + throw new ArgumentNullException("array"); + } + if (start < 0 || start >= end) + { + throw new ArgumentOutOfRangeException("fromIndex"); + } + if (end >= array.Length) + { + throw new ArgumentOutOfRangeException("toIndex"); + } + for (int i = start; i < end; i++) + { + array[i] = value; + } + } + } +} \ No newline at end of file diff --git a/Assets/Scripts/Audio/ClHcaSharp/Ath.cs.meta b/Assets/Scripts/Audio/ClHcaSharp/Ath.cs.meta new file mode 100644 index 0000000..aa03b9a --- /dev/null +++ b/Assets/Scripts/Audio/ClHcaSharp/Ath.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a39556ddea0390c469c2d1363dedb0c0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Audio/ClHcaSharp/BitReader.cs b/Assets/Scripts/Audio/ClHcaSharp/BitReader.cs new file mode 100644 index 0000000..e0fc9b2 --- /dev/null +++ b/Assets/Scripts/Audio/ClHcaSharp/BitReader.cs @@ -0,0 +1,107 @@ +namespace ClHcaSharp +{ + internal class BitReader + { + private static readonly uint[] mask32 = new uint[] + { + 0xFFFFFFFF, 0x7FFFFFFF, 0x3FFFFFFF, 0x1FFFFFFF, + 0x0FFFFFFF, 0x07FFFFFF, 0x03FFFFFF, 0x01FFFFFF + }; + + private static readonly uint[] mask24 = new uint[] + { + 0xFFFFFF, 0x7FFFFF, 0x3FFFFF, 0x1FFFFF, + 0x0FFFFF, 0x07FFFF, 0x03FFFF, 0x01FFFF + }; + + private static readonly uint[] mask16 = new uint[] + { + 0xFFFF, 0x7FFF, 0x3FFF, 0x1FFF, + 0x0FFF, 0x07FF, 0x03FF, 0x01FF + }; + + private static readonly uint[] mask8 = new uint[] + { + 0xFF, 0x7F, 0x3F, 0x1F, + 0x0F, 0x07, 0x03, 0x01 + }; + + private readonly byte[] data; + private readonly int dataSize; + private int currentBit; + + public BitReader(byte[] data) + { + this.data = data; + dataSize = data.Length * 8; + } + + public int Bit => currentBit; + + public int Peek(int bits) + { + int bit = currentBit; + int bitsRemaining = bit & 7; + int size = dataSize; + + uint value = 0; + + if (bit + bits <= size) + { + int bitOffset = bits + bitsRemaining; + int bitLeft = size - bit; + + if (bitLeft >= 32 && bitOffset >= 25) + { + int dataOffset = bit >> 3; + value = data[dataOffset]; + value = (value << 8) | data[dataOffset + 1]; + value = (value << 8) | data[dataOffset + 2]; + value = (value << 8) | data[dataOffset + 3]; + value &= mask32[bitsRemaining]; + value >>= 32 - bitsRemaining - bits; + } + else if (bitLeft >= 24 && bitOffset >= 17) + { + int dataOffset = bit >> 3; + value = data[dataOffset]; + value = (value << 8) | data[dataOffset + 1]; + value = (value << 8) | data[dataOffset + 2]; + value &= mask24[bitsRemaining]; + value >>= 24 - bitsRemaining - bits; + } + else if (bitLeft >= 16 && bitOffset >= 9) + { + int dataOffset = bit >> 3; + value = data[dataOffset]; + value = (value << 8) | data[dataOffset + 1]; + value &= mask16[bitsRemaining]; + value >>= 16 - bitsRemaining - bits; + } + else + { + int dataOffset = bit >> 3; + value = data[dataOffset]; + value &= mask8[bitsRemaining]; + value >>= 8 - bitsRemaining - bits; + } + + return (int)value; + } + + return (int)value; + } + + public int Read(int bits) + { + int value = Peek(bits); + currentBit += bits; + return value; + } + + public void Skip(int bits) + { + currentBit += bits; + } + } +} \ No newline at end of file diff --git a/Assets/Scripts/Audio/ClHcaSharp/BitReader.cs.meta b/Assets/Scripts/Audio/ClHcaSharp/BitReader.cs.meta new file mode 100644 index 0000000..cdb8f4c --- /dev/null +++ b/Assets/Scripts/Audio/ClHcaSharp/BitReader.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: cc08b7eb89558ea4d88cb74e8379b9bb +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Audio/ClHcaSharp/Channel.cs b/Assets/Scripts/Audio/ClHcaSharp/Channel.cs new file mode 100644 index 0000000..34c42c3 --- /dev/null +++ b/Assets/Scripts/Audio/ClHcaSharp/Channel.cs @@ -0,0 +1,29 @@ +using static ClHcaSharp.Constants; + +namespace ClHcaSharp +{ + internal class Channel + { + public ChannelType Type { get; set; } + public int CodedCount { get; set; } + + public byte[] Intensity { get; } = new byte[Subframes]; + public byte[] ScaleFactors { get; } = new byte[SamplesPerSubframe]; + public byte[] Resolution { get; } = new byte[SamplesPerSubframe]; + public byte[] Noises { get; } = new byte[SamplesPerSubframe]; + public int NoiseCount { get; set; } + public int ValidCount { get; set; } + + public float[] Gain { get; } = new float[SamplesPerSubframe]; + public float[][] Spectra { get; } = + JaggedArray.CreateJaggedArray( + Subframes, SamplesPerSubframe); + public float[] Temp { get; } = new float[SamplesPerSubframe]; + public float[] Dct { get; } = new float[SamplesPerSubframe]; + public float[] ImdctPrevious { get; } = new float[SamplesPerSubframe]; + + public float[][] Wave { get; } = + JaggedArray.CreateJaggedArray( + Subframes, SamplesPerSubframe); + } +} \ No newline at end of file diff --git a/Assets/Scripts/Audio/ClHcaSharp/Channel.cs.meta b/Assets/Scripts/Audio/ClHcaSharp/Channel.cs.meta new file mode 100644 index 0000000..782f2b0 --- /dev/null +++ b/Assets/Scripts/Audio/ClHcaSharp/Channel.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 498326e4dde9bc442b3552cb8902aabb +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Audio/ClHcaSharp/Cipher.cs b/Assets/Scripts/Audio/ClHcaSharp/Cipher.cs new file mode 100644 index 0000000..29cfa4f --- /dev/null +++ b/Assets/Scripts/Audio/ClHcaSharp/Cipher.cs @@ -0,0 +1,139 @@ +using System; + +namespace ClHcaSharp +{ + internal static class Cipher + { + public static void Decrypt(byte[] cipherData, byte[] data) + { + for (int i = 0; i < data.Length; i++) + { + data[i] = cipherData[data[i]]; + } + } + + public static byte[] Init(int type, ulong keyCode) + { + if (type == 56 && keyCode == 0) type = 0; + + return type switch + { + 0 => Init0(), + 1 => Init1(), + 56 => Init56(keyCode), + _ => throw new ArgumentException("Invalid cipher type."), + }; + } + + private static byte[] Init0() + { + byte[] cipherTable = new byte[256]; + + for (int i = 0; i < 256; i++) + { + cipherTable[i] = (byte)i; + } + + return cipherTable; + } + + private static byte[] Init1() + { + byte[] cipherTable = new byte[256]; + + const int mul = 13; + const int add = 11; + + uint v = 0; + for (int i = 1; i < 256 - 1; i++) + { + v = (v * mul + add) & 0xFF; + if (v == 0 || v == 0xFF) + v = (v * mul + add) & 0xFF; + cipherTable[i] = (byte)v; + } + cipherTable[0] = 0; + cipherTable[0xFF] = 0xFF; + + return cipherTable; + } + + private static void Init56CreateTable(byte[] table, byte key) + { + int mul = ((key & 1) << 3) | 5; + int add = (key & 0xE) | 1; + + key >>= 4; + + for (int i = 0; i < 16; i++) + { + key = (byte)((key * mul + add) & 0xF); + table[i] = key; + } + } + + private static byte[] Init56(ulong keyCode) + { + byte[] cipherTable = new byte[256]; + + byte[] kc = new byte[8]; + byte[] seed = new byte[16]; + byte[] baseTable = new byte[256]; + byte[] baseTableR = new byte[16]; + byte[] baseTableC = new byte[16]; + + if (keyCode != 0) keyCode--; + + for (int r = 0; r < (8 - 1); r++) + { + kc[r] = (byte)(keyCode & 0xFF); + keyCode >>= 8; + } + + seed[0x00] = kc[1]; + seed[0x01] = (byte)(kc[1] ^ kc[6]); + seed[0x02] = (byte)(kc[2] ^ kc[3]); + seed[0x03] = kc[2]; + seed[0x04] = (byte)(kc[2] ^ kc[1]); + seed[0x05] = (byte)(kc[3] ^ kc[4]); + seed[0x06] = kc[3]; + seed[0x07] = (byte)(kc[3] ^ kc[2]); + seed[0x08] = (byte)(kc[4] ^ kc[5]); + seed[0x09] = kc[4]; + seed[0x0A] = (byte)(kc[4] ^ kc[3]); + seed[0x0B] = (byte)(kc[5] ^ kc[6]); + seed[0x0C] = kc[5]; + seed[0x0D] = (byte)(kc[5] ^ kc[4]); + seed[0x0E] = (byte)(kc[6] ^ kc[1]); + seed[0x0F] = kc[6]; + + Init56CreateTable(baseTableR, kc[0]); + + for (int r = 0; r < 16; r++) + { + byte nb; + Init56CreateTable(baseTableC, seed[r]); + nb = (byte)(baseTableR[r] << 4); + for (int c = 0; c < 16; c++) + { + baseTable[r * 16 + c] = (byte)(nb | baseTableC[c]); + } + } + + uint x = 0; + uint pos = 1; + + for (int i = 0; i < 256; i++) + { + x = (x + 17) & 0xFF; + if (baseTable[x] != 0 && baseTable[x] != 0xFF) + cipherTable[pos++] = baseTable[x]; + } + + cipherTable[0] = 0; + cipherTable[0xFF] = 0xFF; + + return cipherTable; + } + } +} \ No newline at end of file diff --git a/Assets/Scripts/Audio/ClHcaSharp/Cipher.cs.meta b/Assets/Scripts/Audio/ClHcaSharp/Cipher.cs.meta new file mode 100644 index 0000000..16efa8e --- /dev/null +++ b/Assets/Scripts/Audio/ClHcaSharp/Cipher.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2df350f56f9f56749b44a838345aa543 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Audio/ClHcaSharp/Crc.cs b/Assets/Scripts/Audio/ClHcaSharp/Crc.cs new file mode 100644 index 0000000..cade072 --- /dev/null +++ b/Assets/Scripts/Audio/ClHcaSharp/Crc.cs @@ -0,0 +1,37 @@ +namespace ClHcaSharp +{ + internal static class Crc + { + private static readonly ushort[] crcMaskTable = new ushort[] + { + 0x0000, 0x8005, 0x800F, 0x000A, 0x801B, 0x001E, 0x0014, 0x8011, 0x8033, 0x0036, 0x003C, 0x8039, 0x0028, 0x802D, 0x8027, 0x0022, + 0x8063, 0x0066, 0x006C, 0x8069, 0x0078, 0x807D, 0x8077, 0x0072, 0x0050, 0x8055, 0x805F, 0x005A, 0x804B, 0x004E, 0x0044, 0x8041, + 0x80C3, 0x00C6, 0x00CC, 0x80C9, 0x00D8, 0x80DD, 0x80D7, 0x00D2, 0x00F0, 0x80F5, 0x80FF, 0x00FA, 0x80EB, 0x00EE, 0x00E4, 0x80E1, + 0x00A0, 0x80A5, 0x80AF, 0x00AA, 0x80BB, 0x00BE, 0x00B4, 0x80B1, 0x8093, 0x0096, 0x009C, 0x8099, 0x0088, 0x808D, 0x8087, 0x0082, + 0x8183, 0x0186, 0x018C, 0x8189, 0x0198, 0x819D, 0x8197, 0x0192, 0x01B0, 0x81B5, 0x81BF, 0x01BA, 0x81AB, 0x01AE, 0x01A4, 0x81A1, + 0x01E0, 0x81E5, 0x81EF, 0x01EA, 0x81FB, 0x01FE, 0x01F4, 0x81F1, 0x81D3, 0x01D6, 0x01DC, 0x81D9, 0x01C8, 0x81CD, 0x81C7, 0x01C2, + 0x0140, 0x8145, 0x814F, 0x014A, 0x815B, 0x015E, 0x0154, 0x8151, 0x8173, 0x0176, 0x017C, 0x8179, 0x0168, 0x816D, 0x8167, 0x0162, + 0x8123, 0x0126, 0x012C, 0x8129, 0x0138, 0x813D, 0x8137, 0x0132, 0x0110, 0x8115, 0x811F, 0x011A, 0x810B, 0x010E, 0x0104, 0x8101, + 0x8303, 0x0306, 0x030C, 0x8309, 0x0318, 0x831D, 0x8317, 0x0312, 0x0330, 0x8335, 0x833F, 0x033A, 0x832B, 0x032E, 0x0324, 0x8321, + 0x0360, 0x8365, 0x836F, 0x036A, 0x837B, 0x037E, 0x0374, 0x8371, 0x8353, 0x0356, 0x035C, 0x8359, 0x0348, 0x834D, 0x8347, 0x0342, + 0x03C0, 0x83C5, 0x83CF, 0x03CA, 0x83DB, 0x03DE, 0x03D4, 0x83D1, 0x83F3, 0x03F6, 0x03FC, 0x83F9, 0x03E8, 0x83ED, 0x83E7, 0x03E2, + 0x83A3, 0x03A6, 0x03AC, 0x83A9, 0x03B8, 0x83BD, 0x83B7, 0x03B2, 0x0390, 0x8395, 0x839F, 0x039A, 0x838B, 0x038E, 0x0384, 0x8381, + 0x0280, 0x8285, 0x828F, 0x028A, 0x829B, 0x029E, 0x0294, 0x8291, 0x82B3, 0x02B6, 0x02BC, 0x82B9, 0x02A8, 0x82AD, 0x82A7, 0x02A2, + 0x82E3, 0x02E6, 0x02EC, 0x82E9, 0x02F8, 0x82FD, 0x82F7, 0x02F2, 0x02D0, 0x82D5, 0x82DF, 0x02DA, 0x82CB, 0x02CE, 0x02C4, 0x82C1, + 0x8243, 0x0246, 0x024C, 0x8249, 0x0258, 0x825D, 0x8257, 0x0252, 0x0270, 0x8275, 0x827F, 0x027A, 0x826B, 0x026E, 0x0264, 0x8261, + 0x0220, 0x8225, 0x822F, 0x022A, 0x823B, 0x023E, 0x0234, 0x8231, 0x8213, 0x0216, 0x021C, 0x8219, 0x0208, 0x820D, 0x8207, 0x0202 + }; + + public static ushort Crc16Checksum(byte[] data) + { + ushort sum = 0; + + for (int i = 0; i < data.Length; i++) + { + sum = (ushort)((sum << 8) ^ crcMaskTable[(sum >> 8) ^ data[i]]); + } + + return sum; + } + } +} \ No newline at end of file diff --git a/Assets/Scripts/Audio/ClHcaSharp/Crc.cs.meta b/Assets/Scripts/Audio/ClHcaSharp/Crc.cs.meta new file mode 100644 index 0000000..55b2e7f --- /dev/null +++ b/Assets/Scripts/Audio/ClHcaSharp/Crc.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 12364682399d45244bee9579676101b4 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Audio/ClHcaSharp/Definitions.cs b/Assets/Scripts/Audio/ClHcaSharp/Definitions.cs new file mode 100644 index 0000000..cbb1ab6 --- /dev/null +++ b/Assets/Scripts/Audio/ClHcaSharp/Definitions.cs @@ -0,0 +1,42 @@ +using Assets.Scripts.Audio.CriWareFormats.Common; +using System; + +namespace ClHcaSharp +{ + internal static class Constants + { + public const int Version101 = 0x0101; + public const int Version102 = 0x0102; + public const int Version103 = 0x0103; + public const int Version200 = 0x0200; + public const int Version300 = 0x0300; + + public const int MinFrameSize = 0x8; + public const int MaxFrameSize = 0xFFFF; + + public const int Mask = 0x7F7F7F7F; + public const int Subframes = 8; + public const int SamplesPerSubframe = 128; + public const int SamplesPerFrame = Subframes * SamplesPerSubframe; + public const int MdctBits = 7; + + public const int MinChannels = 1; + public const int MaxChannels = 16; + public const int MinSampleRate = 1; + public const int MaxSampleRate = 0x7FFFFF; + + public const int DefaultRandom = 1; + + public static readonly float MsStereoRatio = BinaryPrimitives.Int32BitsToSingle(0x3F3504F3); + + + } + + + public enum ChannelType + { + Discrete = 0, + StereoPrimary = 1, + StereoSecondary = 2 + } +} \ No newline at end of file diff --git a/Assets/Scripts/Audio/ClHcaSharp/Definitions.cs.meta b/Assets/Scripts/Audio/ClHcaSharp/Definitions.cs.meta new file mode 100644 index 0000000..3456ddc --- /dev/null +++ b/Assets/Scripts/Audio/ClHcaSharp/Definitions.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9097dc5440eaa4241a8902e43ba0d270 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Audio/ClHcaSharp/HcaContext.cs b/Assets/Scripts/Audio/ClHcaSharp/HcaContext.cs new file mode 100644 index 0000000..406a10e --- /dev/null +++ b/Assets/Scripts/Audio/ClHcaSharp/HcaContext.cs @@ -0,0 +1,53 @@ +namespace ClHcaSharp +{ + internal class HcaContext + { + public int Version { get; set; } + public int HeaderSize { get; set; } + + public int ChannelCount { get; set; } + public int SampleRate { get; set; } + public int FrameCount { get; set; } + public int EncoderDelay { get; set; } + public int EncoderPadding { get; set; } + + public int FrameSize { get; set; } + public int MinResolution { get; set; } + public int MaxResolution { get; set; } + public int TrackCount { get; set; } + public int ChannelConfig { get; set; } + public int StereoType { get; set; } + public int TotalBandCount { get; set; } + public int BaseBandCount { get; set; } + public int StereoBandCount { get; set; } + public int BandsPerHfrGroup { get; set; } + public int MsStereo { get; set; } + public int Reserved { get; set; } + + public int VbrMaxFrameSize { get; set; } + public int VbrNoiseLevel { get; set; } + + public int AthType { get; set; } + + public int LoopStartFrame { get; set; } + public int LoopEndFrame { get; set; } + public int LoopStartDelay { get; set; } + public int LoopEndPadding { get; set; } + public bool LoopFlag { get; set; } + + public int CiphType { get; set; } + public ulong KeyCode { get; set; } + + public float RvaVolume { get; set; } + + public int CommentLength { get; set; } + public string Comment { get; set; } + + public int HfrGroupCount { get; set; } + public byte[] AthCurve { get; set; } + public byte[] CipherTable { get; set; } + + public int Random { get; set; } + public Channel[] Channels { get; set; } + } +} \ No newline at end of file diff --git a/Assets/Scripts/Audio/ClHcaSharp/HcaContext.cs.meta b/Assets/Scripts/Audio/ClHcaSharp/HcaContext.cs.meta new file mode 100644 index 0000000..0b94c39 --- /dev/null +++ b/Assets/Scripts/Audio/ClHcaSharp/HcaContext.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 58df776bbf57b404fac50ddf009fff77 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Audio/ClHcaSharp/HcaDecoder.cs b/Assets/Scripts/Audio/ClHcaSharp/HcaDecoder.cs new file mode 100644 index 0000000..3676a73 --- /dev/null +++ b/Assets/Scripts/Audio/ClHcaSharp/HcaDecoder.cs @@ -0,0 +1,732 @@ +using System; +using System.Collections.Generic; +using System.IO; +using UnityEngine; +using static ClHcaSharp.Constants; +using static ClHcaSharp.Header; +using static ClHcaSharp.Tables; + +namespace ClHcaSharp +{ + public class HcaDecoder + { + private readonly HcaContext hca; + + public HcaDecoder(Stream hcaStream, ulong key) + { + hca = new HcaContext(); + + InitializeTables(); + + DecodeHeader(hca, hcaStream); + SetKey(key); + } + + public HcaInfo GetInfo() + { + HcaInfo info = new HcaInfo() + { + Version = hca.Version, + HeaderSize = hca.HeaderSize, + SamplingRate = hca.SampleRate, + ChannelCount = hca.ChannelCount, + BlockSize = hca.FrameSize, + BlockCount = hca.FrameCount, + EncoderDelay = hca.EncoderDelay, + EncoderPadding = hca.EncoderPadding, + LoopEnabled = hca.LoopFlag, + LoopStartBlock = hca.LoopStartFrame, + LoopEndBlock = hca.LoopEndFrame, + LoopStartDelay = hca.LoopStartDelay, + LoopEndPadding = hca.LoopEndPadding, + SamplesPerBlock = SamplesPerFrame, + Comment = hca.Comment, + EncryptionEnabled = hca.CiphType == 56 + }; + return info; + } + + public void SetKey(ulong key) + { + hca.KeyCode = key; + hca.CipherTable = Cipher.Init(hca.CiphType, hca.KeyCode); + } + + public int TestBlock(byte[] data) + { + const int frameSamples = Subframes * SamplesPerSubframe; + const float scale = 32768.0f; + + int status; + int clips = 0; + int blanks = 0; + int[] channelBlanks = new int[MaxChannels]; + + byte[] buffer = data; + + { + bool isEmpty = true; + + for (int i = 0x02; i < data.Length - 0x02; i++) + { + if (buffer[i] != 0) + { + isEmpty = false; + break; + } + } + + if (isEmpty) return 0; + } + + status = DecodeBlockUnpack(data); + if (status < 0) return -1; + + { + int bitsMax = hca.FrameSize * 8; + int byteStart; + + if (status + 14 > bitsMax) + return -1; + //throw new Exception("BitReader error."); + + byteStart = (status / 8) + (status % 8 > 0 ? 0x01 : 0); + + for (int i = byteStart; i < hca.FrameSize - 0x02; i++) + { + if (buffer[i] != 0) + return -1; + } + } + + DecodeBlockTransform(); + for (int ch = 0; ch < hca.ChannelCount; ch++) + { + for (int sf = 0; sf < Subframes; sf++) + { + for (int s = 0; s < SamplesPerSubframe; s++) + { + float fSample = hca.Channels[ch].Wave[sf][s]; + + if (fSample > 1.0f || fSample < -1.0f) + clips++; + else + { + int pSample = (int)(fSample * scale); + if (pSample == 0 || pSample == -1) + { + blanks++; + channelBlanks[ch]++; + } + } + } + } + } + + if (clips == 1) + clips++; + if (clips > 1) + return clips; + + if (blanks == hca.ChannelCount * frameSamples) + return 0; + + if (hca.ChannelCount >= 2) + { + if (channelBlanks[0] == frameSamples && channelBlanks[1] != frameSamples) + return 3; + } + + return 1; + } + + public void ReadSamples16(short[][] samples) + { + for (int subframe = 0; subframe < Subframes; subframe++) + { + for (int sample = 0; sample < SamplesPerSubframe; sample++) + { + for (int channel = 0; channel < hca.ChannelCount; channel++) + { + float f = hca.Channels[channel].Wave[subframe][sample]; + int sInt = (int)(32768 * f); + if (sInt > 32767) + sInt = 32767; + else if (sInt < -32767) + sInt = -32767; + samples[channel][(SamplesPerSubframe * subframe) + sample] = (short)sInt; + } + } + } + } + + public void ReadSamples16(short[] samples) + { + int sampleIndex = 0; + for (int subframe = 0; subframe < Subframes; subframe++) + { + for (int sample = 0; sample < SamplesPerSubframe; sample++) + { + for (int channel = 0; channel < hca.ChannelCount; channel++) + { + float f = hca.Channels[channel].Wave[subframe][sample]; + int sInt = (int)(32768 * f); + if (sInt > 32767) + sInt = 32767; + else if (sInt < -32767) + sInt = -32767; + samples[sampleIndex++] = (short)sInt; + } + } + } + } + + public float[] ReadSamples16() + { + List data = new List(); + for (int subframe = 0; subframe < Subframes; subframe++) + { + for (int sample = 0; sample < SamplesPerSubframe; sample++) + { + for (int channel = 0; channel < hca.ChannelCount; channel++) + { + float f = hca.Channels[channel].Wave[subframe][sample]; + data.Add(f); + } + } + } + return data.ToArray(); + } + + public void DecodeReset() + { + if (hca != null) + { + hca.Random = DefaultRandom; + + for (int i = 0; i < hca.ChannelCount; i++) + { + Channel channel = hca.Channels[i]; + + Array.Clear(channel.ImdctPrevious, 0, channel.ImdctPrevious.Length); + } + } + } + + public int DecodeBlock(byte[] data) + { + int result = DecodeBlockUnpack(data); + + if (result < 0) return result; + + DecodeBlockTransform(); + + return result; + } + + private int DecodeBlockUnpack(byte[] data) + { + if (data.Length < hca.FrameSize) + throw new ArgumentException("Data is less than expected frame size."); + + BitReader bitReader = new BitReader(data); + + ushort sync = (ushort)bitReader.Read(16); + if (sync != 0xFFFF) throw new InvalidDataException("Sync error."); + + if (Crc.Crc16Checksum(data) > 0) throw new InvalidDataException("Checksum error."); + + Cipher.Decrypt(hca.CipherTable, data); + + int frameAcceptableNoiseLevel = bitReader.Read(9); + int frameEvaluationBoundary = bitReader.Read(7); + + int packedNoiseLevel = (frameAcceptableNoiseLevel << 8) - frameEvaluationBoundary; + + for (int channel = 0; channel < hca.ChannelCount; channel++) + { + UnpackScaleFactors(hca.Channels[channel], bitReader, hca.HfrGroupCount, hca.Version); + UnpackIntensity(hca.Channels[channel], bitReader, hca.HfrGroupCount, hca.Version); + CalculateResolution(hca.Channels[channel], packedNoiseLevel, hca.AthCurve, hca.MinResolution, hca.MaxResolution); + CalculateGain(hca.Channels[channel]); + } + + for (int subframe = 0; subframe < Subframes; subframe++) + { + for (int channel = 0; channel < hca.ChannelCount; channel++) + { + DequantizeCoefficients(hca.Channels[channel], bitReader, subframe); + } + } + + return bitReader.Bit; + } + + private void DecodeBlockTransform() + { + for (int subframe = 0; subframe < Subframes; subframe++) + { + for (int channel = 0; channel < hca.ChannelCount; channel++) + { + int random = hca.Random; + ReconstructNoise(hca.Channels[channel], hca.MinResolution, hca.MsStereo, ref random, subframe); + hca.Random = random; + ReconstructHighFrequency(hca.Channels[channel], hca.HfrGroupCount, hca.BandsPerHfrGroup, + hca.StereoBandCount, hca.BaseBandCount, hca.TotalBandCount, hca.Version, subframe); + } + + if (hca.StereoBandCount > 0) + { + for (int ch = 0; ch < hca.ChannelCount - 1; ch++) + { + ApplyIntensityStereo(hca.Channels, ch * 2, subframe, hca.BaseBandCount, hca.TotalBandCount); + ApplyMsStereo(hca.Channels, ch * 2, hca.MsStereo, hca.BaseBandCount, hca.TotalBandCount, subframe); + } + } + + for (int channel = 0; channel < hca.ChannelCount; channel++) + { + ImdctTransform(hca.Channels[channel], subframe); + } + } + } + + private static void UnpackScaleFactors(Channel channel, BitReader bitReader, int hfrGroupCount, int version) + { + int csCount = channel.CodedCount; + int extraCount; + byte deltaBits = (byte)bitReader.Read(3); + + if (channel.Type == ChannelType.StereoSecondary || hfrGroupCount <= 0 || version <= Version200) + extraCount = 0; + else + { + extraCount = hfrGroupCount; + csCount += extraCount; + + if (csCount > SamplesPerSubframe) + return; + //throw new InvalidDataException("Invalid scale count."); + } + + if (deltaBits >= 6) + { + for (int i = 0; i < csCount; i++) + { + channel.ScaleFactors[i] = (byte)bitReader.Read(6); + } + } + else if (deltaBits > 0) + { + byte expectedDelta = (byte)((1 << deltaBits) - 1); + byte value = (byte)bitReader.Read(6); + + channel.ScaleFactors[0] = value; + for (int i = 1; i < csCount; i++) + { + byte delta = (byte)bitReader.Read(deltaBits); + + if (delta == expectedDelta) + value = (byte)bitReader.Read(6); + else + { + int scaleFactorTest = value + (delta - (expectedDelta >> 1)); + if (scaleFactorTest < 0 || scaleFactorTest >= 64) + return; + //throw new InvalidDataException("Invalid scale factor."); + + value = (byte)(value - (expectedDelta >> 1) + delta); + value = (byte)(value & 0x3F); + } + + channel.ScaleFactors[i] = value; + } + } + else + { + for (int i = 0; i < SamplesPerSubframe; i++) + { + channel.ScaleFactors[i] = 0; + } + } + + for (int i = 0; i < extraCount; i++) + { + channel.ScaleFactors[SamplesPerSubframe - 1 - i] = channel.ScaleFactors[csCount - i]; + } + } + + private static void UnpackIntensity(Channel channel, BitReader bitReader, int hfrGroupCount, int version) + { + if (channel.Type == ChannelType.StereoSecondary) + { + if (version <= Version200) + { + byte value = (byte)bitReader.Peek(4); + + channel.Intensity[0] = value; + if (value < 15) + { + bitReader.Skip(4); + for (int i = 1; i < Subframes; i++) + { + channel.Intensity[i] = (byte)bitReader.Read(4); + } + } + } + else + { + byte value = (byte)bitReader.Peek(4); + + if (value < 15) + { + bitReader.Skip(4); + + byte deltaBits = (byte)bitReader.Read(2); + + channel.Intensity[0] = value; + if (deltaBits == 3) + { + for (int i = 1; i < Subframes; i++) + { + channel.Intensity[i] = (byte)bitReader.Read(4); + } + } + else + { + byte bMax = (byte)((2 << deltaBits) - 1); + byte bits = (byte)(deltaBits + 1); + + for (int i = 1; i < Subframes; i++) + { + byte delta = (byte)bitReader.Read(bits); + if (delta == bMax) + value = (byte)bitReader.Read(4); + else + { + value = (byte)(value - (bMax >> 1) + delta); + if (value > 15) + return; + //throw new InvalidDataException("Intensity value out of range."); + } + + channel.Intensity[i] = value; + } + } + } + else + { + bitReader.Skip(4); + for (int i = 0; i < Subframes; i++) + { + channel.Intensity[i] = 7; + } + } + } + } + else + { + if (version <= Version200) + { + byte[] hfrScales = channel.ScaleFactors; + int hfrScalesOffset = 128 - hfrGroupCount; + + for (int i = 0; i < hfrGroupCount; i++) + { + hfrScales[hfrScalesOffset + i] = (byte)bitReader.Read(6); + } + } + } + } + + private static void CalculateResolution(Channel channel, int packedNoiseLevel, byte[] athCurve, int minResolution, int maxResolution) + { + int crCount = channel.CodedCount; + int noiseCount = 0; + int validCount = 0; + + for (int i = 0; i < crCount; i++) + { + byte newResolution = 0; + byte scaleFactor = channel.ScaleFactors[i]; + + if (scaleFactor > 0) + { + int noiseLevel = athCurve[i] + ((packedNoiseLevel + i) >> 8); + int curvePosition = noiseLevel + 1 - ((5 * scaleFactor) >> 1); + + if (curvePosition < 0) + newResolution = 15; + else if (curvePosition <= 65) + newResolution = InvertTable[curvePosition]; + else + newResolution = 0; + + if (newResolution > maxResolution) + newResolution = (byte)maxResolution; + else if (newResolution < minResolution) + newResolution = (byte)minResolution; + + if (newResolution < 1) + { + channel.Noises[noiseCount] = (byte)i; + noiseCount++; + } + else + { + channel.Noises[SamplesPerSubframe - 1 - validCount] = (byte)i; + validCount++; + } + } + channel.Resolution[i] = newResolution; + } + + channel.NoiseCount = noiseCount; + channel.ValidCount = validCount; + + Array.Clear(channel.Resolution, crCount, SamplesPerSubframe - crCount); + } + + private static void CalculateGain(Channel channel) + { + int cgCount = channel.CodedCount; + for (int i = 0; i < cgCount; i++) + { + float scaleFactorScale = DequantizerScalingTable[channel.ScaleFactors[i]]; + float resolutionScale = DequantizerRangeTable[channel.Resolution[i]]; + channel.Gain[i] = scaleFactorScale * resolutionScale; + } + } + + private static void DequantizeCoefficients(Channel channel, BitReader bitReader, int subframe) + { + int ccCount = channel.CodedCount; + + for (int i = 0; i < ccCount; i++) + { + float qc; + byte resolution = channel.Resolution[i]; + byte bits = MaxBitTable[resolution]; + int code = bitReader.Read(bits); + + if (resolution > 7) + { + int signedCode = (1 - ((code & 1) << 1)) * (code >> 1); + if (signedCode == 0) + bitReader.Skip(-1); + qc = signedCode; + } + else + { + int index = (resolution << 4) + code; + int skip = ReadBitTable[index] - bits; + bitReader.Skip(skip); + qc = ReadValueTable[index]; + } + + channel.Spectra[subframe][i] = channel.Gain[i] * qc; + } + + Array.Clear(channel.Spectra[subframe], ccCount, SamplesPerSubframe - ccCount); + } + + private static void ReconstructNoise(Channel channel, int minResolution, int msStereo, ref int random, int subframe) + { + if (minResolution > 0) return; + if (channel.ValidCount <= 0 || channel.NoiseCount <= 0) return; + if (msStereo != 0 && channel.Type == ChannelType.StereoPrimary) return; + + for (int i = 0; i < channel.NoiseCount; i++) + { + random = 0x343FD * random + 0x269EC3; + + int randomIndex = SamplesPerSubframe - channel.ValidCount + (((random & 0x7FFF) * channel.ValidCount) >> 15); + + int noiseIndex = channel.Noises[i]; + int validIndex = channel.Noises[randomIndex]; + + int sfNoise = channel.ScaleFactors[noiseIndex]; + int sfValid = channel.ScaleFactors[validIndex]; + int scIndex = (sfNoise - sfValid + 62) & ~((sfNoise - sfValid + 62) >> 31); + + channel.Spectra[subframe][noiseIndex] = ScaleConversionTable[scIndex] * channel.Spectra[subframe][validIndex]; + } + } + + private static void ReconstructHighFrequency(Channel channel, int hfrGroupCount, int bandsPerHfrGroup, + int stereoBandCount, int baseBandCount, int totalBandCount, int version, int subframe) + { + if (bandsPerHfrGroup == 0) return; + if (channel.Type == ChannelType.StereoSecondary) return; + + int groupLimit; + int startBand = stereoBandCount + baseBandCount; + int highBand = startBand; + int lowBand = startBand - 1; + + int hfrScalesOffset = 128 - hfrGroupCount; + byte[] hfrScales = channel.ScaleFactors; + + if (version <= Version200) + groupLimit = hfrGroupCount; + else + { + groupLimit = hfrGroupCount >= 0 ? hfrGroupCount : hfrGroupCount + 1; + groupLimit >>= 1; + } + + for (int group = 0; group < hfrGroupCount; group++) + { + int lowBandSub = group < groupLimit ? 1 : 0; + + for (int i = 0; i < bandsPerHfrGroup; i++) + { + if (highBand >= totalBandCount || lowBand < 0) break; + + int scIndex = hfrScales[hfrScalesOffset + group]; + scIndex &= ~(scIndex >> 31); + + channel.Spectra[subframe][highBand] = ScaleConversionTable[scIndex] * channel.Spectra[subframe][lowBand]; + + highBand++; + lowBand -= lowBandSub; + } + } + + channel.Spectra[subframe][highBand - 1] = 0.0f; + } + + private static void ApplyIntensityStereo(Channel[] channelPair, int channelOffset, int subframe, int baseBandCount, int totalBandCount) + { + if (channelPair[channelOffset + 0].Type != ChannelType.StereoPrimary) return; + + float ratioL = IntensityRatioTable[channelPair[channelOffset + 1].Intensity[subframe]]; + float ratioR = 2.0f - ratioL; + float[] spectraL = channelPair[channelOffset + 0].Spectra[subframe]; + float[] spectraR = channelPair[channelOffset + 1].Spectra[subframe]; + + for (int band = baseBandCount; band < totalBandCount; band++) + { + float coefL = spectraL[band] * ratioL; + float coefR = spectraR[band] * ratioR; + spectraL[band] = coefL; + spectraR[band] = coefR; + } + } + + private static void ApplyMsStereo(Channel[] channelPair, int channelOffset, int msStereo, int baseBandCount, int totalBandCount, int subframe) + { + if (msStereo != 0) return; + if (channelPair[channelOffset + 0].Type != ChannelType.StereoPrimary) return; + + float ratio = MsStereoRatio; + float[] spectraL = channelPair[channelOffset + 0].Spectra[subframe]; + float[] spectraR = channelPair[channelOffset + 1].Spectra[subframe]; + + for (int band = baseBandCount; band < totalBandCount; band++) + { + float coefL = (spectraL[band] + spectraR[band]) * ratio; + float coefR = (spectraL[band] - spectraR[band]) * ratio; + spectraL[band] = coefL; + spectraR[band] = coefR; + } + } + + private static void ImdctTransform(Channel channel, int subframe) + { + const int size = SamplesPerSubframe; + const int half = SamplesPerSubframe / 2; + const int mdctBits = MdctBits; + + int count1 = 1; + int count2 = half; + float[] temp1 = channel.Spectra[subframe]; + float[] temp2 = channel.Temp; + int temp1Index = 0; + + for (int i = 0; i < mdctBits; i++) + { + float[] swap; + float[] d = temp2; + int d1Index = 0; + int d2Index = count2; + + for (int j = 0; j < count1; j++) + { + for (int k = 0; k < count2; k++) + { + float a = temp1[temp1Index++]; + float b = temp1[temp1Index++]; + d[d1Index++] = a + b; + d[d2Index++] = a - b; + } + + d1Index += count2; + d2Index += count2; + } + + temp1Index -= SamplesPerSubframe; + swap = temp1; + temp1 = temp2; + temp2 = swap; + + count1 <<= 1; + count2 >>= 1; + } + + count1 = half; + count2 = 1; + temp1 = channel.Temp; + temp2 = channel.Spectra[subframe]; + + for (int i = 0; i < mdctBits; i++) + { + int sinTableIndex = 0; + int cosTableIndex = 0; + + float[] swap; + float[] d = temp2; + float[] s = temp1; + int d1Index = 0; + int d2Index = count2 * 2 - 1; + int s1Index = 0; + int s2Index = count2; + + for (int j = 0; j < count1; j++) + { + for (int k = 0; k < count2; k++) + { + float a = s[s1Index++]; + float b = s[s2Index++]; + float sin = SinTable[i][sinTableIndex++]; + float cos = CosTable[i][cosTableIndex++]; + d[d1Index++] = a * sin - b * cos; + d[d2Index--] = a * cos + b * sin; + } + + s1Index += count2; + s2Index += count2; + d1Index += count2; + d2Index += count2 * 3; + } + + swap = temp1; + temp1 = temp2; + temp2 = swap; + + count1 >>= 1; + count2 <<= 1; + } + + float[] dct = channel.Spectra[subframe]; + float[] prev = channel.ImdctPrevious; + for (int i = 0; i < half; i++) + { + channel.Wave[subframe][i] = ImdctWindow[i] * dct[i + half] + prev[i]; + channel.Wave[subframe][i + half] = ImdctWindow[i + half] * dct[size - 1 - i] - prev[i + half]; + channel.ImdctPrevious[i] = ImdctWindow[size - 1 - i] * dct[half - i - 1]; + channel.ImdctPrevious[i + half] = ImdctWindow[half - i - 1] * dct[i]; + } + } + } +} \ No newline at end of file diff --git a/Assets/Scripts/Audio/ClHcaSharp/HcaDecoder.cs.meta b/Assets/Scripts/Audio/ClHcaSharp/HcaDecoder.cs.meta new file mode 100644 index 0000000..86fac35 --- /dev/null +++ b/Assets/Scripts/Audio/ClHcaSharp/HcaDecoder.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ac4b2f835ba632b46a03cf7190f73045 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Audio/ClHcaSharp/HcaInfo.cs b/Assets/Scripts/Audio/ClHcaSharp/HcaInfo.cs new file mode 100644 index 0000000..6c593cb --- /dev/null +++ b/Assets/Scripts/Audio/ClHcaSharp/HcaInfo.cs @@ -0,0 +1,26 @@ +namespace ClHcaSharp +{ + public class HcaInfo + { + public int Version { get; set; } + public int HeaderSize { get; set; } + public int SamplingRate { get; set; } + public int ChannelCount { get; set; } + public int BlockSize { get; set; } + public int BlockCount { get; set; } + public int EncoderDelay { get; set; } + public int EncoderPadding { get; set; } + public bool LoopEnabled { get; set; } + public int LoopStartBlock { get; set; } + public int LoopEndBlock { get; set; } + public int LoopStartDelay { get; set; } + public int LoopEndPadding { get; set; } + public int SamplesPerBlock { get; set; } + public string Comment { get; set; } + public bool EncryptionEnabled { get; set; } + + public int SampleCount => BlockCount * SamplesPerBlock - EncoderDelay - EncoderPadding; + public int LoopStartSample => LoopStartBlock * SamplesPerBlock - EncoderDelay + LoopStartDelay; + public int LoopEndSample => LoopEndBlock * SamplesPerBlock - EncoderDelay + (SamplesPerBlock - LoopEndPadding); + } +} \ No newline at end of file diff --git a/Assets/Scripts/Audio/ClHcaSharp/HcaInfo.cs.meta b/Assets/Scripts/Audio/ClHcaSharp/HcaInfo.cs.meta new file mode 100644 index 0000000..c32348e --- /dev/null +++ b/Assets/Scripts/Audio/ClHcaSharp/HcaInfo.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 951e0209b6d7c7e4e9d47d922cd7b490 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Audio/ClHcaSharp/Header.cs b/Assets/Scripts/Audio/ClHcaSharp/Header.cs new file mode 100644 index 0000000..e13f9e5 --- /dev/null +++ b/Assets/Scripts/Audio/ClHcaSharp/Header.cs @@ -0,0 +1,329 @@ +using System; +using System.IO; +using System.Text; +using static ClHcaSharp.Constants; + +namespace ClHcaSharp +{ + internal static class Header + { + public static bool IsHeaderValid(Stream hcaStream, out int headerSize) + { + BitReader bitReader = new BitReader(new BinaryReader(hcaStream).ReadBytes(8)); + + headerSize = 0; + if ((bitReader.Peek(32) & Mask) == StringToUInt32("HCA")) + { + bitReader.Skip(32 + 16); + headerSize = bitReader.Read(16); + + return true; + } + + return false; + } + + public static void DecodeHeader(HcaContext hca, Stream hcaStream) + { + if (!IsHeaderValid(hcaStream, out int headerSize)) + throw new InvalidDataException("Invalid HCA header."); + + BinaryReader binaryReader = new BinaryReader(hcaStream); + binaryReader.BaseStream.Position = 0; + + BitReader bitReader = new BitReader(binaryReader.ReadBytes((int)headerSize)); + + if ((bitReader.Peek(32) & Mask) == StringToUInt32("HCA")) + { + bitReader.Skip(32); + hca.Version = bitReader.Read(16); + hca.HeaderSize = bitReader.Read(16); + + headerSize -= 8; + } + else throw new InvalidDataException("Not an HCA file."); + + if (headerSize >= 16 && (bitReader.Peek(32) & Mask) == StringToUInt32("fmt")) + { + bitReader.Skip(32); + hca.ChannelCount = bitReader.Read(8); + hca.SampleRate = bitReader.Read(24); + hca.FrameCount = bitReader.Read(32); + hca.EncoderDelay = bitReader.Read(16); + hca.EncoderPadding = bitReader.Read(16); + + if (!(hca.ChannelCount >= MinChannels && hca.ChannelCount <= MaxChannels)) + throw new InvalidDataException("Invalid channel count."); + + if (hca.FrameCount == 0) + throw new InvalidDataException("Frame count is zero."); + + if (!(hca.SampleRate >= MinSampleRate && hca.SampleRate <= MaxSampleRate)) + throw new InvalidDataException("Invalid sample rate."); + + headerSize -= 16; + } + else throw new InvalidDataException("No format chunk."); + + if (headerSize >= 16 && (bitReader.Peek(32) & Mask) == StringToUInt32("comp")) + { + bitReader.Skip(32); + hca.FrameSize = bitReader.Read(16); + hca.MinResolution = bitReader.Read(8); + hca.MaxResolution = bitReader.Read(8); + hca.TrackCount = bitReader.Read(8); + hca.ChannelConfig = bitReader.Read(8); + hca.TotalBandCount = bitReader.Read(8); + hca.BaseBandCount = bitReader.Read(8); + hca.StereoBandCount = bitReader.Read(8); + hca.BandsPerHfrGroup = bitReader.Read(8); + hca.MsStereo = bitReader.Read(8); + hca.Reserved = bitReader.Read(8); + + headerSize -= 16; + } + else if (headerSize >= 12 && (bitReader.Peek(32) & Mask) == StringToUInt32("dec")) + { + bitReader.Skip(32); + hca.FrameSize = bitReader.Read(16); + hca.MinResolution = bitReader.Read(8); + hca.MaxResolution = bitReader.Read(8); + hca.TotalBandCount = bitReader.Read(8) + 1; + hca.BaseBandCount = bitReader.Read(8) + 1; + hca.TrackCount = bitReader.Read(4); + hca.ChannelConfig = bitReader.Read(4); + hca.StereoType = bitReader.Read(8); + + if (hca.StereoType == 0) hca.BaseBandCount = hca.TotalBandCount; + hca.StereoBandCount = hca.TotalBandCount - hca.BaseBandCount; + hca.BandsPerHfrGroup = 0; + + headerSize -= 12; + } + else throw new InvalidDataException("No compression or decode chunk."); + + if (headerSize >= 8 && (bitReader.Peek(32) & Mask) == StringToUInt32("vbr")) + { + bitReader.Skip(32); + hca.VbrMaxFrameSize = bitReader.Read(16); + hca.VbrNoiseLevel = bitReader.Read(16); + + if (!(hca.FrameSize == 0 && hca.VbrMaxFrameSize > 8 && hca.VbrMaxFrameSize <= 511)) + throw new InvalidDataException("Invalid frame size."); + + headerSize -= 8; + } + else + { + hca.VbrMaxFrameSize = 0; + hca.VbrNoiseLevel = 0; + } + + if (headerSize >= 6 && (bitReader.Peek(32) & Mask) == StringToUInt32("ath")) + { + bitReader.Skip(32); + hca.AthType = bitReader.Read(16); + } + else hca.AthType = (hca.Version < Version200) ? 1 : 0; + + if (headerSize >= 16 && (bitReader.Peek(32) & Mask) == StringToUInt32("loop")) + { + bitReader.Skip(32); + hca.LoopStartFrame = bitReader.Read(32); + hca.LoopEndFrame = bitReader.Read(32); + hca.LoopStartDelay = bitReader.Read(16); + hca.LoopEndPadding = bitReader.Read(16); + + hca.LoopFlag = true; + + if (!(hca.LoopStartFrame >= 0 && hca.LoopStartFrame <= hca.LoopEndFrame + && hca.LoopEndFrame < hca.FrameCount)) + throw new InvalidDataException("Invalid loop frames."); + + headerSize -= 16; + } + else + { + hca.LoopStartFrame = 0; + hca.LoopEndFrame = 0; + hca.LoopStartDelay = 0; + hca.LoopEndPadding = 0; + + hca.LoopFlag = false; + } + + if (headerSize >= 6 && (bitReader.Peek(32) & Mask) == StringToUInt32("ciph")) + { + bitReader.Skip(32); + hca.CiphType = bitReader.Read(16); + + if (!(hca.CiphType == 0 || hca.CiphType == 1 || hca.CiphType == 56)) + throw new InvalidDataException("Invalid cipher type."); + + headerSize -= 6; + } + + if (headerSize >= 8 && (bitReader.Peek(32) & Mask) == StringToUInt32("rva")) + { + bitReader.Skip(32); + int rvaVolumeInt = bitReader.Read(32); + hca.RvaVolume = BitConverter.ToSingle(BitConverter.GetBytes(rvaVolumeInt),0); + + headerSize -= 8; + } + else hca.RvaVolume = 1.0f; + + if (headerSize >= 5 && (bitReader.Peek(32) & Mask) == StringToUInt32("comm")) + { + bitReader.Skip(32); + hca.CommentLength = bitReader.Read(8); + + if (hca.CommentLength > headerSize) throw new InvalidDataException("Comment string out of bounds."); + + StringBuilder commentStringBuilder = new StringBuilder(); + + for (int i = 0; i < hca.CommentLength; i++) + { + commentStringBuilder.Append(bitReader.Read(8)); + } + + hca.Comment = commentStringBuilder.ToString(); + + //headerSize -= 5 + hca.CommentLength; + } + else hca.CommentLength = 0; + + // IDE0059 + //if (headerSize >= 4 && (bitReader.Peek(32) & Mask) == StringToUInt32("pad")) + //{ + // headerSize -= (headerSize - 2); + //} + + if (hca.FrameSize < MinFrameSize || hca.FrameSize > MaxFrameSize) + throw new InvalidDataException("Invalid frame size."); + + if (hca.Version <= Version200) + { + if (hca.MinResolution != 1 || hca.MaxResolution != 15) + throw new InvalidDataException("Incompatible resolution."); + } + + if (hca.TrackCount == 0) hca.TrackCount = 1; + + if (hca.TrackCount > hca.ChannelCount) throw new InvalidDataException("Invalid track count."); + + if (hca.TotalBandCount > SamplesPerSubframe || + hca.BaseBandCount > SamplesPerSubframe || + hca.StereoBandCount > SamplesPerSubframe || + hca.BaseBandCount + hca.StereoBandCount > SamplesPerSubframe || + hca.BandsPerHfrGroup > SamplesPerSubframe) + throw new InvalidDataException("Invalid bands."); + + hca.HfrGroupCount = HeaderCeil2( + hca.TotalBandCount - hca.BaseBandCount - hca.StereoBandCount, + hca.BandsPerHfrGroup); + + hca.AthCurve = Ath.Init(hca.AthType, hca.SampleRate); + hca.CipherTable = Cipher.Init(hca.CiphType, hca.KeyCode); + + int channelsPerTrack = hca.ChannelCount / hca.TrackCount; + ChannelType[] channelTypes = new ChannelType[channelsPerTrack]; + + for (int i = 0; i < channelTypes.Length; i++) + { + channelTypes[i] = ChannelType.Discrete; + } + + if (hca.StereoBandCount > 0 && channelsPerTrack > 1) + { + for (int i = 0; i < hca.TrackCount; i++) + { + switch (channelsPerTrack) + { + case 2: + case 3: + channelTypes[0] = ChannelType.StereoPrimary; + channelTypes[1] = ChannelType.StereoSecondary; + break; + + case 4: + channelTypes[0] = ChannelType.StereoPrimary; + channelTypes[1] = ChannelType.StereoSecondary; + if (hca.ChannelConfig == 0) + { + channelTypes[2] = ChannelType.StereoPrimary; + channelTypes[3] = ChannelType.StereoSecondary; + } + break; + + case 5: + channelTypes[0] = ChannelType.StereoPrimary; + channelTypes[1] = ChannelType.StereoSecondary; + if (hca.ChannelConfig <= 2) + { + channelTypes[3] = ChannelType.StereoPrimary; + channelTypes[4] = ChannelType.StereoSecondary; + } + break; + + case 6: + case 7: + channelTypes[0] = ChannelType.StereoPrimary; + channelTypes[1] = ChannelType.StereoSecondary; + channelTypes[4] = ChannelType.StereoPrimary; + channelTypes[5] = ChannelType.StereoSecondary; + break; + + case 8: + channelTypes[0] = ChannelType.StereoPrimary; + channelTypes[1] = ChannelType.StereoSecondary; + channelTypes[4] = ChannelType.StereoPrimary; + channelTypes[5] = ChannelType.StereoSecondary; + channelTypes[6] = ChannelType.StereoPrimary; + channelTypes[7] = ChannelType.StereoSecondary; + break; + + default: + break; + } + } + } + + hca.Channels = new Channel[hca.ChannelCount]; + for (int i = 0; i < hca.ChannelCount; i++) + { + hca.Channels[i] = new Channel + { + Type = channelTypes[i], + CodedCount = + channelTypes[i] != ChannelType.StereoSecondary ? + hca.BaseBandCount + hca.StereoBandCount : + hca.BaseBandCount + }; + } + + hca.Random = DefaultRandom; + + if (hca.MsStereo > 0) throw new InvalidDataException(); + if (hca.HfrGroupCount > 0 && hca.Version == Version300) + throw new InvalidDataException(); + } + + private static int HeaderCeil2(int a, int b) + { + if (b < 1) return 0; + return a / b + ((a % b) > 0 ? 1 : 0); + } + + private static uint StringToUInt32(string value) + { + uint result = 0; + int bytePos = 3; + for (int i = 0; i < value.Length; i++) + { + result |= (uint)(value[i] << 8 * bytePos--); + } + return result; + } + } +} \ No newline at end of file diff --git a/Assets/Scripts/Audio/ClHcaSharp/Header.cs.meta b/Assets/Scripts/Audio/ClHcaSharp/Header.cs.meta new file mode 100644 index 0000000..78eceff --- /dev/null +++ b/Assets/Scripts/Audio/ClHcaSharp/Header.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 366eb88aab2749c40bdd2255f763b075 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Audio/ClHcaSharp/JaggedArray.cs b/Assets/Scripts/Audio/ClHcaSharp/JaggedArray.cs new file mode 100644 index 0000000..5396a8d --- /dev/null +++ b/Assets/Scripts/Audio/ClHcaSharp/JaggedArray.cs @@ -0,0 +1,28 @@ +using System; + +namespace ClHcaSharp +{ + internal static class JaggedArray + { + public static T CreateJaggedArray(params int[] lengths) + { + return (T)InitJaggedArray(typeof(T).GetElementType(), lengths, 0); + } + + private static object InitJaggedArray(Type type, int[] lengths, int arrayIndex) + { + Array array = Array.CreateInstance(type, lengths[arrayIndex]); + Type subElementType = type.GetElementType(); + + if (type.HasElementType) + { + for (int i = 0; i < lengths[arrayIndex]; i++) + { + array.SetValue(InitJaggedArray(subElementType, lengths, arrayIndex + 1), i); + } + } + + return array; + } + } +} \ No newline at end of file diff --git a/Assets/Scripts/Audio/ClHcaSharp/JaggedArray.cs.meta b/Assets/Scripts/Audio/ClHcaSharp/JaggedArray.cs.meta new file mode 100644 index 0000000..1628a56 --- /dev/null +++ b/Assets/Scripts/Audio/ClHcaSharp/JaggedArray.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b866b2adde0b7ae4dbeaeb482c11f042 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Audio/ClHcaSharp/Tables.cs b/Assets/Scripts/Audio/ClHcaSharp/Tables.cs new file mode 100644 index 0000000..c33c4da --- /dev/null +++ b/Assets/Scripts/Audio/ClHcaSharp/Tables.cs @@ -0,0 +1,335 @@ +using Assets.Scripts.Audio.CriWareFormats.Common; +using System; + +namespace ClHcaSharp +{ + internal static class Tables + { + public static void InitializeTables() + { + for (int i = 0; i < DequantizerScalingTableHex.Length; i++) + { + DequantizerScalingTable[i] = BinaryPrimitives.Int32BitsToSingle((int)DequantizerScalingTableHex[i]); + } + + for (int i = 0; i < DequantizerRangeTableHex.Length; i++) + { + DequantizerRangeTable[i] = BinaryPrimitives.Int32BitsToSingle((int)DequantizerRangeTableHex[i]); + } + + for (int i = 0; i < ScaleConversionTableHex.Length; i++) + { + ScaleConversionTable[i] = BinaryPrimitives.Int32BitsToSingle((int)ScaleConversionTableHex[i]); + } + + for (int i = 0; i < IntensityRatioTableHex.Length; i++) + { + IntensityRatioTable[i] = BinaryPrimitives.Int32BitsToSingle((int)IntensityRatioTableHex[i]); + } + + for (int i = 0; i < SinTableHex.Length; i++) + { + SinTable[i] = new float[64]; + + for (int j = 0; j < SinTableHex[i].Length; j++) + { + SinTable[i][j] = BinaryPrimitives.Int32BitsToSingle((int)SinTableHex[i][j]); + } + } + + for (int i = 0; i < CosTableHex.Length; i++) + { + CosTable[i] = new float[64]; + + for (int j = 0; j < CosTableHex[i].Length; j++) + { + CosTable[i][j] = BinaryPrimitives.Int32BitsToSingle((int)CosTableHex[i][j]); + } + } + + for (int i = 0; i < ImdctWindowHex.Length; i++) + { + ImdctWindow[i] = BinaryPrimitives.Int32BitsToSingle((int)ImdctWindowHex[i]); + } + } + + public static readonly byte[] InvertTable = new byte[66] + { + 14, 14, 14, 14, 14, 14, 13, 13, 13, 13, 13, 13, 12, 12, 12, 12, + 12, 12, 11, 11, 11, 11, 11, 11, 10, 10, 10, 10, 10, 10, 10, 9, + 9, 9, 9, 9, 9, 8, 8, 8, 8, 8, 8, 7, 6, 6, 5, 4, + 4, 4, 3, 3, 3, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, + 1, 1 + }; + + public static readonly uint[] DequantizerScalingTableHex = new uint[64] + { + 0x342A8D26, 0x34633F89, 0x3497657D, 0x34C9B9BE, 0x35066491, 0x353311C4, 0x356E9910, 0x359EF532, + 0x35D3CCF1, 0x360D1ADF, 0x363C034A, 0x367A83B3, 0x36A6E595, 0x36DE60F5, 0x371426FF, 0x3745672A, + 0x37838359, 0x37AF3B79, 0x37E97C38, 0x381B8D3A, 0x384F4319, 0x388A14D5, 0x38B7FBF0, 0x38F5257D, + 0x3923520F, 0x39599D16, 0x3990FA4D, 0x39C12C4D, 0x3A00B1ED, 0x3A2B7A3A, 0x3A647B6D, 0x3A9837F0, + 0x3ACAD226, 0x3B071F62, 0x3B340AAF, 0x3B6FE4BA, 0x3B9FD228, 0x3BD4F35B, 0x3C0DDF04, 0x3C3D08A4, + 0x3C7BDFED, 0x3CA7CD94, 0x3CDF9613, 0x3D14F4F0, 0x3D467991, 0x3D843A29, 0x3DB02F0E, 0x3DEAC0C7, + 0x3E1C6573, 0x3E506334, 0x3E8AD4C6, 0x3EB8FBAF, 0x3EF67A41, 0x3F243516, 0x3F5ACB94, 0x3F91C3D3, + 0x3FC238D2, 0x400164D2, 0x402C6897, 0x4065B907, 0x40990B88, 0x40CBEC15, 0x4107DB35, 0x413504F3 + }; + + public static readonly float[] DequantizerScalingTable = new float[64]; + + + public static readonly uint[] DequantizerRangeTableHex = new uint[16] + { + 0x3F800000, 0x3F2AAAAB, 0x3ECCCCCD, 0x3E924925, 0x3E638E39, 0x3E3A2E8C, 0x3E1D89D9, 0x3E088889, + 0x3D842108, 0x3D020821, 0x3C810204, 0x3C008081, 0x3B804020, 0x3B002008, 0x3A801002, 0x3A000801 + }; + + public static readonly float[] DequantizerRangeTable = new float[16]; + + public static readonly byte[] MaxBitTable = new byte[16] + { + 0, 2, 3, 3, 4, 4, 4, 4, 5, 6, 7, 8, 9, 10, 11, 12 + }; + + public static readonly byte[] ReadBitTable = new byte[128] + { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 2, 2, 2, 2, 2, 2, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, + 2, 2, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, + 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4 + }; + + public static readonly float[] ReadValueTable = new float[128] + { + +0.0f, +0.0f, +0.0f, +0.0f, +0.0f, +0.0f, +0.0f, +0.0f, +0.0f, +0.0f, +0.0f, +0.0f, +0.0f, +0.0f, +0.0f, +0.0f, + +0.0f, +0.0f, +1.0f, -1.0f, +0.0f, +0.0f, +0.0f, +0.0f, +0.0f, +0.0f, +0.0f, +0.0f, +0.0f, +0.0f, +0.0f, +0.0f, + +0.0f, +0.0f, +1.0f, +1.0f, -1.0f, -1.0f, +2.0f, -2.0f, +0.0f, +0.0f, +0.0f, +0.0f, +0.0f, +0.0f, +0.0f, +0.0f, + +0.0f, +0.0f, +1.0f, -1.0f, +2.0f, -2.0f, +3.0f, -3.0f, +0.0f, +0.0f, +0.0f, +0.0f, +0.0f, +0.0f, +0.0f, +0.0f, + +0.0f, +0.0f, +1.0f, +1.0f, -1.0f, -1.0f, +2.0f, +2.0f, -2.0f, -2.0f, +3.0f, +3.0f, -3.0f, -3.0f, +4.0f, -4.0f, + +0.0f, +0.0f, +1.0f, +1.0f, -1.0f, -1.0f, +2.0f, +2.0f, -2.0f, -2.0f, +3.0f, -3.0f, +4.0f, -4.0f, +5.0f, -5.0f, + +0.0f, +0.0f, +1.0f, +1.0f, -1.0f, -1.0f, +2.0f, -2.0f, +3.0f, -3.0f, +4.0f, -4.0f, +5.0f, -5.0f, +6.0f, -6.0f, + +0.0f, +0.0f, +1.0f, -1.0f, +2.0f, -2.0f, +3.0f, -3.0f, +4.0f, -4.0f, +5.0f, -5.0f, +6.0f, -6.0f, +7.0f, -7.0f + }; + + public static readonly uint[] ScaleConversionTableHex = new uint[128] + { + 0x00000000, 0x32A0B051, 0x32D61B5E, 0x330EA43A, 0x333E0F68, 0x337D3E0C, 0x33A8B6D5, 0x33E0CCDF, + 0x3415C3FF, 0x34478D75, 0x3484F1F6, 0x34B123F6, 0x34EC0719, 0x351D3EDA, 0x355184DF, 0x358B95C2, + 0x35B9FCD2, 0x35F7D0DF, 0x36251958, 0x365BFBB8, 0x36928E72, 0x36C346CD, 0x370218AF, 0x372D583F, + 0x3766F85B, 0x3799E046, 0x37CD078C, 0x3808980F, 0x38360094, 0x38728177, 0x38A18FAF, 0x38D744FD, + 0x390F6A81, 0x393F179A, 0x397E9E11, 0x39A9A15B, 0x39E2055B, 0x3A16942D, 0x3A48A2D8, 0x3A85AAC3, + 0x3AB21A32, 0x3AED4F30, 0x3B1E196E, 0x3B52A81E, 0x3B8C57CA, 0x3BBAFF5B, 0x3BF9295A, 0x3C25FED7, + 0x3C5D2D82, 0x3C935A2B, 0x3CC4563F, 0x3D02CD87, 0x3D2E4934, 0x3D68396A, 0x3D9AB62B, 0x3DCE248C, + 0x3E0955EE, 0x3E36FD92, 0x3E73D290, 0x3EA27043, 0x3ED87039, 0x3F1031DC, 0x3F40213B, 0x3F800000, + 0x3FAA8D26, 0x3FE33F89, 0x4017657D, 0x4049B9BE, 0x40866491, 0x40B311C4, 0x40EE9910, 0x411EF532, + 0x4153CCF1, 0x418D1ADF, 0x41BC034A, 0x41FA83B3, 0x4226E595, 0x425E60F5, 0x429426FF, 0x42C5672A, + 0x43038359, 0x432F3B79, 0x43697C38, 0x439B8D3A, 0x43CF4319, 0x440A14D5, 0x4437FBF0, 0x4475257D, + 0x44A3520F, 0x44D99D16, 0x4510FA4D, 0x45412C4D, 0x4580B1ED, 0x45AB7A3A, 0x45E47B6D, 0x461837F0, + 0x464AD226, 0x46871F62, 0x46B40AAF, 0x46EFE4BA, 0x471FD228, 0x4754F35B, 0x478DDF04, 0x47BD08A4, + 0x47FBDFED, 0x4827CD94, 0x485F9613, 0x4894F4F0, 0x48C67991, 0x49043A29, 0x49302F0E, 0x496AC0C7, + 0x499C6573, 0x49D06334, 0x4A0AD4C6, 0x4A38FBAF, 0x4A767A41, 0x4AA43516, 0x4ADACB94, 0x4B11C3D3, + 0x4B4238D2, 0x4B8164D2, 0x4BAC6897, 0x4BE5B907, 0x4C190B88, 0x4C4BEC15, 0x00000000, 0x00000000 + }; + + public static float[] ScaleConversionTable = new float[128]; + + public static readonly uint[] IntensityRatioTableHex = new uint[16] + { + 0x40000000, 0x3FEDB6DB, 0x3FDB6DB7, 0x3FC92492, 0x3FB6DB6E, 0x3FA49249, 0x3F924925, 0x3F800000, + 0x3F5B6DB7, 0x3F36DB6E, 0x3F124925, 0x3EDB6DB7, 0x3E924925, 0x3E124925, 0x00000000, 0x00000000 + }; + + public static float[] IntensityRatioTable = new float[16]; + + public static readonly uint[][] SinTableHex = new uint[7][] + { + new uint[64] + { + 0x3DA73D75, 0x3DA73D75, 0x3DA73D75, 0x3DA73D75, 0x3DA73D75, 0x3DA73D75, 0x3DA73D75, 0x3DA73D75, + 0x3DA73D75, 0x3DA73D75, 0x3DA73D75, 0x3DA73D75, 0x3DA73D75, 0x3DA73D75, 0x3DA73D75, 0x3DA73D75, + 0x3DA73D75, 0x3DA73D75, 0x3DA73D75, 0x3DA73D75, 0x3DA73D75, 0x3DA73D75, 0x3DA73D75, 0x3DA73D75, + 0x3DA73D75, 0x3DA73D75, 0x3DA73D75, 0x3DA73D75, 0x3DA73D75, 0x3DA73D75, 0x3DA73D75, 0x3DA73D75, + 0x3DA73D75, 0x3DA73D75, 0x3DA73D75, 0x3DA73D75, 0x3DA73D75, 0x3DA73D75, 0x3DA73D75, 0x3DA73D75, + 0x3DA73D75, 0x3DA73D75, 0x3DA73D75, 0x3DA73D75, 0x3DA73D75, 0x3DA73D75, 0x3DA73D75, 0x3DA73D75, + 0x3DA73D75, 0x3DA73D75, 0x3DA73D75, 0x3DA73D75, 0x3DA73D75, 0x3DA73D75, 0x3DA73D75, 0x3DA73D75, + 0x3DA73D75, 0x3DA73D75, 0x3DA73D75, 0x3DA73D75, 0x3DA73D75, 0x3DA73D75, 0x3DA73D75, 0x3DA73D75 + }, + new uint[64] + { + 0x3F7B14BE, 0x3F54DB31, 0x3F7B14BE, 0x3F54DB31, 0x3F7B14BE, 0x3F54DB31, 0x3F7B14BE, 0x3F54DB31, + 0x3F7B14BE, 0x3F54DB31, 0x3F7B14BE, 0x3F54DB31, 0x3F7B14BE, 0x3F54DB31, 0x3F7B14BE, 0x3F54DB31, + 0x3F7B14BE, 0x3F54DB31, 0x3F7B14BE, 0x3F54DB31, 0x3F7B14BE, 0x3F54DB31, 0x3F7B14BE, 0x3F54DB31, + 0x3F7B14BE, 0x3F54DB31, 0x3F7B14BE, 0x3F54DB31, 0x3F7B14BE, 0x3F54DB31, 0x3F7B14BE, 0x3F54DB31, + 0x3F7B14BE, 0x3F54DB31, 0x3F7B14BE, 0x3F54DB31, 0x3F7B14BE, 0x3F54DB31, 0x3F7B14BE, 0x3F54DB31, + 0x3F7B14BE, 0x3F54DB31, 0x3F7B14BE, 0x3F54DB31, 0x3F7B14BE, 0x3F54DB31, 0x3F7B14BE, 0x3F54DB31, + 0x3F7B14BE, 0x3F54DB31, 0x3F7B14BE, 0x3F54DB31, 0x3F7B14BE, 0x3F54DB31, 0x3F7B14BE, 0x3F54DB31, + 0x3F7B14BE, 0x3F54DB31, 0x3F7B14BE, 0x3F54DB31, 0x3F7B14BE, 0x3F54DB31, 0x3F7B14BE, 0x3F54DB31 + }, + new uint[64] + { + 0x3F7EC46D, 0x3F74FA0B, 0x3F61C598, 0x3F45E403, 0x3F7EC46D, 0x3F74FA0B, 0x3F61C598, 0x3F45E403, + 0x3F7EC46D, 0x3F74FA0B, 0x3F61C598, 0x3F45E403, 0x3F7EC46D, 0x3F74FA0B, 0x3F61C598, 0x3F45E403, + 0x3F7EC46D, 0x3F74FA0B, 0x3F61C598, 0x3F45E403, 0x3F7EC46D, 0x3F74FA0B, 0x3F61C598, 0x3F45E403, + 0x3F7EC46D, 0x3F74FA0B, 0x3F61C598, 0x3F45E403, 0x3F7EC46D, 0x3F74FA0B, 0x3F61C598, 0x3F45E403, + 0x3F7EC46D, 0x3F74FA0B, 0x3F61C598, 0x3F45E403, 0x3F7EC46D, 0x3F74FA0B, 0x3F61C598, 0x3F45E403, + 0x3F7EC46D, 0x3F74FA0B, 0x3F61C598, 0x3F45E403, 0x3F7EC46D, 0x3F74FA0B, 0x3F61C598, 0x3F45E403, + 0x3F7EC46D, 0x3F74FA0B, 0x3F61C598, 0x3F45E403, 0x3F7EC46D, 0x3F74FA0B, 0x3F61C598, 0x3F45E403, + 0x3F7EC46D, 0x3F74FA0B, 0x3F61C598, 0x3F45E403, 0x3F7EC46D, 0x3F74FA0B, 0x3F61C598, 0x3F45E403 + }, + new uint[64] + { + 0x3F7FB10F, 0x3F7D3AAC, 0x3F7853F8, 0x3F710908, 0x3F676BD8, 0x3F5B941A, 0x3F4D9F02, 0x3F3DAEF9, + 0x3F7FB10F, 0x3F7D3AAC, 0x3F7853F8, 0x3F710908, 0x3F676BD8, 0x3F5B941A, 0x3F4D9F02, 0x3F3DAEF9, + 0x3F7FB10F, 0x3F7D3AAC, 0x3F7853F8, 0x3F710908, 0x3F676BD8, 0x3F5B941A, 0x3F4D9F02, 0x3F3DAEF9, + 0x3F7FB10F, 0x3F7D3AAC, 0x3F7853F8, 0x3F710908, 0x3F676BD8, 0x3F5B941A, 0x3F4D9F02, 0x3F3DAEF9, + 0x3F7FB10F, 0x3F7D3AAC, 0x3F7853F8, 0x3F710908, 0x3F676BD8, 0x3F5B941A, 0x3F4D9F02, 0x3F3DAEF9, + 0x3F7FB10F, 0x3F7D3AAC, 0x3F7853F8, 0x3F710908, 0x3F676BD8, 0x3F5B941A, 0x3F4D9F02, 0x3F3DAEF9, + 0x3F7FB10F, 0x3F7D3AAC, 0x3F7853F8, 0x3F710908, 0x3F676BD8, 0x3F5B941A, 0x3F4D9F02, 0x3F3DAEF9, + 0x3F7FB10F, 0x3F7D3AAC, 0x3F7853F8, 0x3F710908, 0x3F676BD8, 0x3F5B941A, 0x3F4D9F02, 0x3F3DAEF9 + }, + new uint[64] + { + 0x3F7FEC43, 0x3F7F4E6D, 0x3F7E1324, 0x3F7C3B28, 0x3F79C79D, 0x3F76BA07, 0x3F731447, 0x3F6ED89E, + 0x3F6A09A7, 0x3F64AA59, 0x3F5EBE05, 0x3F584853, 0x3F514D3D, 0x3F49D112, 0x3F41D870, 0x3F396842, + 0x3F7FEC43, 0x3F7F4E6D, 0x3F7E1324, 0x3F7C3B28, 0x3F79C79D, 0x3F76BA07, 0x3F731447, 0x3F6ED89E, + 0x3F6A09A7, 0x3F64AA59, 0x3F5EBE05, 0x3F584853, 0x3F514D3D, 0x3F49D112, 0x3F41D870, 0x3F396842, + 0x3F7FEC43, 0x3F7F4E6D, 0x3F7E1324, 0x3F7C3B28, 0x3F79C79D, 0x3F76BA07, 0x3F731447, 0x3F6ED89E, + 0x3F6A09A7, 0x3F64AA59, 0x3F5EBE05, 0x3F584853, 0x3F514D3D, 0x3F49D112, 0x3F41D870, 0x3F396842, + 0x3F7FEC43, 0x3F7F4E6D, 0x3F7E1324, 0x3F7C3B28, 0x3F79C79D, 0x3F76BA07, 0x3F731447, 0x3F6ED89E, + 0x3F6A09A7, 0x3F64AA59, 0x3F5EBE05, 0x3F584853, 0x3F514D3D, 0x3F49D112, 0x3F41D870, 0x3F396842 + }, + new uint[64] + { + 0x3F7FFB11, 0x3F7FD397, 0x3F7F84AB, 0x3F7F0E58, 0x3F7E70B0, 0x3F7DABCC, 0x3F7CBFC9, 0x3F7BACCD, + 0x3F7A7302, 0x3F791298, 0x3F778BC5, 0x3F75DEC6, 0x3F740BDD, 0x3F721352, 0x3F6FF573, 0x3F6DB293, + 0x3F6B4B0C, 0x3F68BF3C, 0x3F660F88, 0x3F633C5A, 0x3F604621, 0x3F5D2D53, 0x3F59F26A, 0x3F5695E5, + 0x3F531849, 0x3F4F7A1F, 0x3F4BBBF8, 0x3F47DE65, 0x3F43E200, 0x3F3FC767, 0x3F3B8F3B, 0x3F373A23, + 0x3F7FFB11, 0x3F7FD397, 0x3F7F84AB, 0x3F7F0E58, 0x3F7E70B0, 0x3F7DABCC, 0x3F7CBFC9, 0x3F7BACCD, + 0x3F7A7302, 0x3F791298, 0x3F778BC5, 0x3F75DEC6, 0x3F740BDD, 0x3F721352, 0x3F6FF573, 0x3F6DB293, + 0x3F6B4B0C, 0x3F68BF3C, 0x3F660F88, 0x3F633C5A, 0x3F604621, 0x3F5D2D53, 0x3F59F26A, 0x3F5695E5, + 0x3F531849, 0x3F4F7A1F, 0x3F4BBBF8, 0x3F47DE65, 0x3F43E200, 0x3F3FC767, 0x3F3B8F3B, 0x3F373A23 + }, + new uint[64] + { + 0x3F7FFEC4, 0x3F7FF4E6, 0x3F7FE129, 0x3F7FC38F, 0x3F7F9C18, 0x3F7F6AC7, 0x3F7F2F9D, 0x3F7EEA9D, + 0x3F7E9BC9, 0x3F7E4323, 0x3F7DE0B1, 0x3F7D7474, 0x3F7CFE73, 0x3F7C7EB0, 0x3F7BF531, 0x3F7B61FC, + 0x3F7AC516, 0x3F7A1E84, 0x3F796E4E, 0x3F78B47B, 0x3F77F110, 0x3F772417, 0x3F764D97, 0x3F756D97, + 0x3F748422, 0x3F73913F, 0x3F7294F8, 0x3F718F57, 0x3F708066, 0x3F6F6830, 0x3F6E46BE, 0x3F6D1C1D, + 0x3F6BE858, 0x3F6AAB7B, 0x3F696591, 0x3F6816A8, 0x3F66BECC, 0x3F655E0B, 0x3F63F473, 0x3F628210, + 0x3F6106F2, 0x3F5F8327, 0x3F5DF6BE, 0x3F5C61C7, 0x3F5AC450, 0x3F591E6A, 0x3F577026, 0x3F55B993, + 0x3F53FAC3, 0x3F5233C6, 0x3F5064AF, 0x3F4E8D90, 0x3F4CAE79, 0x3F4AC77F, 0x3F48D8B3, 0x3F46E22A, + 0x3F44E3F5, 0x3F42DE29, 0x3F40D0DA, 0x3F3EBC1B, 0x3F3CA003, 0x3F3A7CA4, 0x3F385216, 0x3F36206C + } + }; + + public static float[][] SinTable = new float[7][]; + + public static readonly uint[][] CosTableHex = new uint[7][] + { + new uint[64] + { + 0xBD0A8BD4, 0x3D0A8BD4, 0x3D0A8BD4, 0xBD0A8BD4, 0x3D0A8BD4, 0xBD0A8BD4, 0xBD0A8BD4, 0x3D0A8BD4, + 0x3D0A8BD4, 0xBD0A8BD4, 0xBD0A8BD4, 0x3D0A8BD4, 0xBD0A8BD4, 0x3D0A8BD4, 0x3D0A8BD4, 0xBD0A8BD4, + 0x3D0A8BD4, 0xBD0A8BD4, 0xBD0A8BD4, 0x3D0A8BD4, 0xBD0A8BD4, 0x3D0A8BD4, 0x3D0A8BD4, 0xBD0A8BD4, + 0xBD0A8BD4, 0x3D0A8BD4, 0x3D0A8BD4, 0xBD0A8BD4, 0x3D0A8BD4, 0xBD0A8BD4, 0xBD0A8BD4, 0x3D0A8BD4, + 0x3D0A8BD4, 0xBD0A8BD4, 0xBD0A8BD4, 0x3D0A8BD4, 0xBD0A8BD4, 0x3D0A8BD4, 0x3D0A8BD4, 0xBD0A8BD4, + 0xBD0A8BD4, 0x3D0A8BD4, 0x3D0A8BD4, 0xBD0A8BD4, 0x3D0A8BD4, 0xBD0A8BD4, 0xBD0A8BD4, 0x3D0A8BD4, + 0xBD0A8BD4, 0x3D0A8BD4, 0x3D0A8BD4, 0xBD0A8BD4, 0x3D0A8BD4, 0xBD0A8BD4, 0xBD0A8BD4, 0x3D0A8BD4, + 0x3D0A8BD4, 0xBD0A8BD4, 0xBD0A8BD4, 0x3D0A8BD4, 0xBD0A8BD4, 0x3D0A8BD4, 0x3D0A8BD4, 0xBD0A8BD4 + }, + new uint[64] + { + 0xBE47C5C2, 0xBF0E39DA, 0x3E47C5C2, 0x3F0E39DA, 0x3E47C5C2, 0x3F0E39DA, 0xBE47C5C2, 0xBF0E39DA, + 0x3E47C5C2, 0x3F0E39DA, 0xBE47C5C2, 0xBF0E39DA, 0xBE47C5C2, 0xBF0E39DA, 0x3E47C5C2, 0x3F0E39DA, + 0x3E47C5C2, 0x3F0E39DA, 0xBE47C5C2, 0xBF0E39DA, 0xBE47C5C2, 0xBF0E39DA, 0x3E47C5C2, 0x3F0E39DA, + 0xBE47C5C2, 0xBF0E39DA, 0x3E47C5C2, 0x3F0E39DA, 0x3E47C5C2, 0x3F0E39DA, 0xBE47C5C2, 0xBF0E39DA, + 0x3E47C5C2, 0x3F0E39DA, 0xBE47C5C2, 0xBF0E39DA, 0xBE47C5C2, 0xBF0E39DA, 0x3E47C5C2, 0x3F0E39DA, + 0xBE47C5C2, 0xBF0E39DA, 0x3E47C5C2, 0x3F0E39DA, 0x3E47C5C2, 0x3F0E39DA, 0xBE47C5C2, 0xBF0E39DA, + 0xBE47C5C2, 0xBF0E39DA, 0x3E47C5C2, 0x3F0E39DA, 0x3E47C5C2, 0x3F0E39DA, 0xBE47C5C2, 0xBF0E39DA, + 0x3E47C5C2, 0x3F0E39DA, 0xBE47C5C2, 0xBF0E39DA, 0xBE47C5C2, 0xBF0E39DA, 0x3E47C5C2, 0x3F0E39DA + }, + new uint[64] + { + 0xBDC8BD36, 0xBE94A031, 0xBEF15AEA, 0xBF226799, 0x3DC8BD36, 0x3E94A031, 0x3EF15AEA, 0x3F226799, + 0x3DC8BD36, 0x3E94A031, 0x3EF15AEA, 0x3F226799, 0xBDC8BD36, 0xBE94A031, 0xBEF15AEA, 0xBF226799, + 0x3DC8BD36, 0x3E94A031, 0x3EF15AEA, 0x3F226799, 0xBDC8BD36, 0xBE94A031, 0xBEF15AEA, 0xBF226799, + 0xBDC8BD36, 0xBE94A031, 0xBEF15AEA, 0xBF226799, 0x3DC8BD36, 0x3E94A031, 0x3EF15AEA, 0x3F226799, + 0x3DC8BD36, 0x3E94A031, 0x3EF15AEA, 0x3F226799, 0xBDC8BD36, 0xBE94A031, 0xBEF15AEA, 0xBF226799, + 0xBDC8BD36, 0xBE94A031, 0xBEF15AEA, 0xBF226799, 0x3DC8BD36, 0x3E94A031, 0x3EF15AEA, 0x3F226799, + 0xBDC8BD36, 0xBE94A031, 0xBEF15AEA, 0xBF226799, 0x3DC8BD36, 0x3E94A031, 0x3EF15AEA, 0x3F226799, + 0x3DC8BD36, 0x3E94A031, 0x3EF15AEA, 0x3F226799, 0xBDC8BD36, 0xBE94A031, 0xBEF15AEA, 0xBF226799 + }, + new uint[64] + { + 0xBD48FB30, 0xBE164083, 0xBE78CFCC, 0xBEAC7CD4, 0xBEDAE880, 0xBF039C3D, 0xBF187FC0, 0xBF2BEB4A, + 0x3D48FB30, 0x3E164083, 0x3E78CFCC, 0x3EAC7CD4, 0x3EDAE880, 0x3F039C3D, 0x3F187FC0, 0x3F2BEB4A, + 0x3D48FB30, 0x3E164083, 0x3E78CFCC, 0x3EAC7CD4, 0x3EDAE880, 0x3F039C3D, 0x3F187FC0, 0x3F2BEB4A, + 0xBD48FB30, 0xBE164083, 0xBE78CFCC, 0xBEAC7CD4, 0xBEDAE880, 0xBF039C3D, 0xBF187FC0, 0xBF2BEB4A, + 0x3D48FB30, 0x3E164083, 0x3E78CFCC, 0x3EAC7CD4, 0x3EDAE880, 0x3F039C3D, 0x3F187FC0, 0x3F2BEB4A, + 0xBD48FB30, 0xBE164083, 0xBE78CFCC, 0xBEAC7CD4, 0xBEDAE880, 0xBF039C3D, 0xBF187FC0, 0xBF2BEB4A, + 0xBD48FB30, 0xBE164083, 0xBE78CFCC, 0xBEAC7CD4, 0xBEDAE880, 0xBF039C3D, 0xBF187FC0, 0xBF2BEB4A, + 0x3D48FB30, 0x3E164083, 0x3E78CFCC, 0x3EAC7CD4, 0x3EDAE880, 0x3F039C3D, 0x3F187FC0, 0x3F2BEB4A + }, + new uint[64] + { + 0xBCC90AB0, 0xBD96A905, 0xBDFAB273, 0xBE2F10A2, 0xBE605C13, 0xBE888E93, 0xBEA09AE5, 0xBEB8442A, + 0xBECF7BCA, 0xBEE63375, 0xBEFC5D27, 0xBF08F59B, 0xBF13682A, 0xBF1D7FD1, 0xBF273656, 0xBF3085BB, + 0x3CC90AB0, 0x3D96A905, 0x3DFAB273, 0x3E2F10A2, 0x3E605C13, 0x3E888E93, 0x3EA09AE5, 0x3EB8442A, + 0x3ECF7BCA, 0x3EE63375, 0x3EFC5D27, 0x3F08F59B, 0x3F13682A, 0x3F1D7FD1, 0x3F273656, 0x3F3085BB, + 0x3CC90AB0, 0x3D96A905, 0x3DFAB273, 0x3E2F10A2, 0x3E605C13, 0x3E888E93, 0x3EA09AE5, 0x3EB8442A, + 0x3ECF7BCA, 0x3EE63375, 0x3EFC5D27, 0x3F08F59B, 0x3F13682A, 0x3F1D7FD1, 0x3F273656, 0x3F3085BB, + 0xBCC90AB0, 0xBD96A905, 0xBDFAB273, 0xBE2F10A2, 0xBE605C13, 0xBE888E93, 0xBEA09AE5, 0xBEB8442A, + 0xBECF7BCA, 0xBEE63375, 0xBEFC5D27, 0xBF08F59B, 0xBF13682A, 0xBF1D7FD1, 0xBF273656, 0xBF3085BB + }, + new uint[64] + { + 0xBC490E90, 0xBD16C32C, 0xBD7B2B74, 0xBDAFB680, 0xBDE1BC2E, 0xBE09CF86, 0xBE22ABB6, 0xBE3B6ECF, + 0xBE541501, 0xBE6C9A7F, 0xBE827DC0, 0xBE8E9A22, 0xBE9AA086, 0xBEA68F12, 0xBEB263EF, 0xBEBE1D4A, + 0xBEC9B953, 0xBED53641, 0xBEE0924F, 0xBEEBCBBB, 0xBEF6E0CB, 0xBF00E7E4, 0xBF064B82, 0xBF0B9A6B, + 0xBF10D3CD, 0xBF15F6D9, 0xBF1B02C6, 0xBF1FF6CB, 0xBF24D225, 0xBF299415, 0xBF2E3BDE, 0xBF32C8C9, + 0x3C490E90, 0x3D16C32C, 0x3D7B2B74, 0x3DAFB680, 0x3DE1BC2E, 0x3E09CF86, 0x3E22ABB6, 0x3E3B6ECF, + 0x3E541501, 0x3E6C9A7F, 0x3E827DC0, 0x3E8E9A22, 0x3E9AA086, 0x3EA68F12, 0x3EB263EF, 0x3EBE1D4A, + 0x3EC9B953, 0x3ED53641, 0x3EE0924F, 0x3EEBCBBB, 0x3EF6E0CB, 0x3F00E7E4, 0x3F064B82, 0x3F0B9A6B, + 0x3F10D3CD, 0x3F15F6D9, 0x3F1B02C6, 0x3F1FF6CB, 0x3F24D225, 0x3F299415, 0x3F2E3BDE, 0x3F32C8C9 + }, + new uint[64] + { + 0xBBC90F88, 0xBC96C9B6, 0xBCFB49BA, 0xBD2FE007, 0xBD621469, 0xBD8A200A, 0xBDA3308C, 0xBDBC3AC3, + 0xBDD53DB9, 0xBDEE3876, 0xBE039502, 0xBE1008B7, 0xBE1C76DE, 0xBE28DEFC, 0xBE354098, 0xBE419B37, + 0xBE4DEE60, 0xBE5A3997, 0xBE667C66, 0xBE72B651, 0xBE7EE6E1, 0xBE8586CE, 0xBE8B9507, 0xBE919DDD, + 0xBE97A117, 0xBE9D9E78, 0xBEA395C5, 0xBEA986C4, 0xBEAF713A, 0xBEB554EC, 0xBEBB31A0, 0xBEC1071E, + 0xBEC6D529, 0xBECC9B8B, 0xBED25A09, 0xBED8106B, 0xBEDDBE79, 0xBEE363FA, 0xBEE900B7, 0xBEEE9479, + 0xBEF41F07, 0xBEF9A02D, 0xBEFF17B2, 0xBF0242B1, 0xBF04F484, 0xBF07A136, 0xBF0A48AD, 0xBF0CEAD0, + 0xBF0F8784, 0xBF121EB0, 0xBF14B039, 0xBF173C07, 0xBF19C200, 0xBF1C420C, 0xBF1EBC12, 0xBF212FF9, + 0xBF239DA9, 0xBF26050A, 0xBF286605, 0xBF2AC082, 0xBF2D1469, 0xBF2F61A5, 0xBF31A81D, 0xBF33E7BC + } + }; + + public static float[][] CosTable = new float[7][]; + + public static readonly uint[] ImdctWindowHex = new uint[128] + { + 0x3A3504F0, 0x3B0183B8, 0x3B70C538, 0x3BBB9268, 0x3C04A809, 0x3C308200, 0x3C61284C, 0x3C8B3F17, + 0x3CA83992, 0x3CC77FBD, 0x3CE91110, 0x3D0677CD, 0x3D198FC4, 0x3D2DD35C, 0x3D434643, 0x3D59ECC1, + 0x3D71CBA8, 0x3D85741E, 0x3D92A413, 0x3DA078B4, 0x3DAEF522, 0x3DBE1C9E, 0x3DCDF27B, 0x3DDE7A1D, + 0x3DEFB6ED, 0x3E00D62B, 0x3E0A2EDA, 0x3E13E72A, 0x3E1E00B1, 0x3E287CF2, 0x3E335D55, 0x3E3EA321, + 0x3E4A4F75, 0x3E56633F, 0x3E62DF37, 0x3E6FC3D1, 0x3E7D1138, 0x3E8563A2, 0x3E8C72B7, 0x3E93B561, + 0x3E9B2AEF, 0x3EA2D26F, 0x3EAAAAAB, 0x3EB2B222, 0x3EBAE706, 0x3EC34737, 0x3ECBD03D, 0x3ED47F46, + 0x3EDD5128, 0x3EE6425C, 0x3EEF4EFF, 0x3EF872D7, 0x3F00D4A9, 0x3F0576CA, 0x3F0A1D3B, 0x3F0EC548, + 0x3F136C25, 0x3F180EF2, 0x3F1CAAC2, 0x3F213CA2, 0x3F25C1A5, 0x3F2A36E7, 0x3F2E9998, 0x3F32E705, + 0xBF371C9E, 0xBF3B37FE, 0xBF3F36F2, 0xBF431780, 0xBF46D7E6, 0xBF4A76A4, 0xBF4DF27C, 0xBF514A6F, + 0xBF547DC5, 0xBF578C03, 0xBF5A74EE, 0xBF5D3887, 0xBF5FD707, 0xBF6250DA, 0xBF64A699, 0xBF66D908, + 0xBF68E90E, 0xBF6AD7B1, 0xBF6CA611, 0xBF6E5562, 0xBF6FE6E7, 0xBF715BEF, 0xBF72B5D1, 0xBF73F5E6, + 0xBF751D89, 0xBF762E13, 0xBF7728D7, 0xBF780F20, 0xBF78E234, 0xBF79A34C, 0xBF7A5397, 0xBF7AF439, + 0xBF7B8648, 0xBF7C0ACE, 0xBF7C82C8, 0xBF7CEF26, 0xBF7D50CB, 0xBF7DA88E, 0xBF7DF737, 0xBF7E3D86, + 0xBF7E7C2A, 0xBF7EB3CC, 0xBF7EE507, 0xBF7F106C, 0xBF7F3683, 0xBF7F57CA, 0xBF7F74B6, 0xBF7F8DB6, + 0xBF7FA32E, 0xBF7FB57B, 0xBF7FC4F6, 0xBF7FD1ED, 0xBF7FDCAD, 0xBF7FE579, 0xBF7FEC90, 0xBF7FF22E, + 0xBF7FF688, 0xBF7FF9D0, 0xBF7FFC32, 0xBF7FFDDA, 0xBF7FFEED, 0xBF7FFF8F, 0xBF7FFFDF, 0xBF7FFFFC + }; + + public static float[] ImdctWindow = new float[128]; + } +} \ No newline at end of file diff --git a/Assets/Scripts/Audio/ClHcaSharp/Tables.cs.meta b/Assets/Scripts/Audio/ClHcaSharp/Tables.cs.meta new file mode 100644 index 0000000..b813531 --- /dev/null +++ b/Assets/Scripts/Audio/ClHcaSharp/Tables.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 50f6f92edea4fac4f9241320ffa4d4c3 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Audio/CriWareFormats.meta b/Assets/Scripts/Audio/CriWareFormats.meta new file mode 100644 index 0000000..4274f81 --- /dev/null +++ b/Assets/Scripts/Audio/CriWareFormats.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 0d19d8ce2b0439342b93e9026e190de3 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Audio/CriWareFormats/AcbNameLoader.cs b/Assets/Scripts/Audio/CriWareFormats/AcbNameLoader.cs new file mode 100644 index 0000000..8d0e6ea --- /dev/null +++ b/Assets/Scripts/Audio/CriWareFormats/AcbNameLoader.cs @@ -0,0 +1,702 @@ +using CriWareFormats.Common; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CriWareFormats +{ + struct CueName + { + public ushort CueIndex; + public string Name; + } + + struct Cue + { + public byte ReferenceType; + public ushort ReferenceIndex; + } + + struct BlockSequence + { + public ushort NumTracks; + public uint TrackIndexOffset; + public uint TrackIndexSize; + public ushort NumBlocks; + public uint BlockIndexOffset; + public uint BlockIndexSize; + } + + struct Block + { + public ushort NumTracks; + public uint TrackIndexOffset; + public uint TrackIndexSize; + } + + struct Sequence + { + public ushort NumTracks; + public uint TrackIndexOffset; + public uint TrackIndexSize; + public byte Type; + } + + struct Track + { + public ushort EventIndex; + } + + struct TrackCommand + { + public uint CommandOffset; + public uint CommandSize; + } + + struct Synth + { + public byte Type; + public uint ReferenceItemsOffset; + public uint ReferenceItemsSize; + } + + struct Waveform + { + public ushort Id; + public ushort PortNo; + public byte Streaming; + } + + public class AcbNameLoader + { + private Stream acbStream; + + private UtfTable header; + private UtfTable cueNames; + + private BinaryReaderEndian cueReader; + private BinaryReaderEndian cueNameReader; + private BinaryReaderEndian blockSequenceReader; + private BinaryReaderEndian blockReader; + private BinaryReaderEndian sequenceReader; + private BinaryReaderEndian trackReader; + private BinaryReaderEndian trackCommandReader; + private BinaryReaderEndian synthReader; + private BinaryReaderEndian waveformReader; + + private Cue[] cue; + private CueName[] cueName; + private BlockSequence[] blockSequence; + private Block[] block; + private Sequence[] sequence; + private Track[] track; + private TrackCommand[] trackCommand; + private Synth[] synth; + private Waveform[] waveform; + + private int cueRows; + private int cueNameRows; + private int blockSequenceRows; + private int blockRows; + private int sequenceRows; + private int trackRows; + private int trackCommandRows; + private int synthRows; + private int waveFormRows; + + private bool isMemory; + private int targetWaveId; + private int targetPort; + + private int synthDepth; + private int sequenceDepth; + + private short cueNameIndex; + private string cueNameName; + private int awbNameCount; + private List awbNameList; + private string name; + + public AcbNameLoader(Stream acb) + { + acbStream = acb; + header = new UtfTable(acb, (uint)acbStream.Position); + } + + bool OpenUtfSubtable(out BinaryReaderEndian tableReader, out UtfTable table, string tableName, out int rows) + { + if (!header.Query(0, tableName, out VLData data)) + throw new ArgumentException("Error reading table."); + + tableReader = new BinaryReaderEndian(acbStream); + table = new UtfTable(tableReader.BaseStream, data.Offset, out rows, out string _); + + return true; + } + + void AddAcbName(byte streaming) + { + if (cueNameName.Length == 0) + return; + + for (int i = 0; i < awbNameCount; i++) + { + if (awbNameList[i] == cueNameIndex) + return; + } + + if (awbNameCount > 0) + { + name += "; "; + name += cueNameName; + } + else + name = cueNameName; + + if (streaming == 2 && isMemory) + name += " [pre]"; + + awbNameList.Add(cueNameIndex); + awbNameCount++; + } + + void PreloadAcbWaveForm() + { + ref int rows = ref waveFormRows; + + if (rows != 0) return; + if (!OpenUtfSubtable(out waveformReader, out UtfTable table, "WaveformTable", out rows)) + throw new Exception("Failure opening Waveform table."); + if (rows == 0) return; + + waveform = new Waveform[rows]; + + int cId = table.GetColumn("Id"); + int cMemoryAwbId = table.GetColumn("MemoryAwbId"); + int cStreamAwbId = table.GetColumn("StreamAwbId"); + int cStreamAwbPortNo = table.GetColumn("StreamAwbPortNo"); + int cStreaming = table.GetColumn("Streaming"); + + for (int i = 0; i < rows; i++) + { + ref Waveform r = ref waveform[i]; + + if (!table.Query(i, cId, out r.Id)) + { + if (isMemory) + { + table.Query(i, cMemoryAwbId, out r.Id); + waveform[i].PortNo = 0xFFFF; + } + else + { + table.Query(i, cStreamAwbId, out r.Id); + table.Query(i, cStreamAwbPortNo, out r.PortNo); + } + } + else + waveform[i].PortNo = 0xFFFF; + + table.Query(i, cStreaming, out r.Streaming); + } + } + + void LoadAcbWaveForm(ushort index) + { + PreloadAcbWaveForm(); + + if (index > waveFormRows) + throw new ArgumentOutOfRangeException(nameof(index)); + + ref Waveform r = ref waveform[index]; + + if (r.Id != targetWaveId) + return; + + if (targetPort >= 0 && r.PortNo != 0xFFFF && r.PortNo != targetPort) + return; + + if ((isMemory && r.Streaming == 1) || (!isMemory && r.Streaming == 0)) + return; + + AddAcbName(r.Streaming); + + return; + } + + void PreloadAcbSynth() + { + ref int rows = ref synthRows; + + if (rows != 0) return; + if (!OpenUtfSubtable(out synthReader, out UtfTable table, "SynthTable", out rows)) + throw new Exception("Failure opening Synth table."); + if (rows == 0) return; + + synth = new Synth[rows]; + + int cType = table.GetColumn("Type"); + int cReferenceItems = table.GetColumn("ReferenceItems"); + + for (int i = 0; i < rows; i++) + { + ref Synth r = ref synth[i]; + + table.Query(i, cType, out r.Type); + table.Query(i, cReferenceItems, out r.ReferenceItemsOffset, out r.ReferenceItemsSize); + } + } + + void LoadAcbSynth(ushort index) + { + PreloadAcbSynth(); + + if (index > synthRows) + throw new ArgumentOutOfRangeException(nameof(index)); + + ref Synth r = ref synth[index]; + + synthDepth++; + + if (synthDepth > 3) + throw new Exception("Synth depth too high"); + + int count = (int)(r.ReferenceItemsSize / 4); + for (int i = 0; i < count; i++) + { + synthReader.BaseStream.Position = r.ReferenceItemsOffset + i * 4; + + ushort itemType = synthReader.ReadUInt16BE(); + ushort itemIndex = synthReader.ReadUInt16BE(); + + switch (itemType) + { + case 0: + count = 0; + break; + + case 1: + LoadAcbWaveForm(itemIndex); + break; + + case 2: + LoadAcbSynth(itemIndex); + break; + + case 3: + LoadAcbSequence(itemIndex); + break; + + case 6: + default: + count = 0; + break; + } + } + + synthDepth--; + } + + void LoadAcbCommandTlvs(BinaryReaderEndian reader, uint commandOffset, uint commandSize) + { + uint pos = 0; + uint maxPos = commandSize; + + while (pos < maxPos) + { + reader.BaseStream.Position = commandOffset + pos; + + ushort tlvCode = reader.ReadUInt16BE(); + ushort tlvSize = reader.ReadByte(); + + pos += 3; + + switch (tlvCode) + { + case 2000: + case 2003: + if (tlvSize < 4) + break; + + reader.BaseStream.Position = commandOffset + pos; + + ushort tlvType = reader.ReadUInt16BE(); + ushort tlvIndex = reader.ReadUInt16BE(); + + switch (tlvType) + { + case 2: + LoadAcbSynth(tlvIndex); + break; + + case 3: + LoadAcbSequence(tlvIndex); + break; + + default: + maxPos = 0; + break; + } + + break; + + default: + break; + } + + pos += tlvSize; + } + } + + void PreloadAcbTrackCommand() + { + ref int rows = ref trackCommandRows; + + if (rows != 0) return; + if (!OpenUtfSubtable(out trackCommandReader, out UtfTable table, "TrackEventTable", out rows)) + { + if (!OpenUtfSubtable(out trackCommandReader, out table, "CommandTable", out rows)) + throw new Exception("Failure opening Command table."); + } + if (rows == 0) return; + + trackCommand = new TrackCommand[rows]; + + int cCommand = table.GetColumn("Command"); + + for (int i = 0; i < rows; i++) + { + ref TrackCommand r = ref trackCommand[i]; + + table.Query(i, cCommand, out r.CommandOffset, out r.CommandSize); + } + } + + void LoadAcbTrackCommand(ushort index) + { + PreloadAcbTrackCommand(); + + if (index > trackCommandRows) + throw new ArgumentOutOfRangeException(nameof(index)); + + LoadAcbCommandTlvs( + trackCommandReader, + trackCommand[index].CommandOffset, + trackCommand[index].CommandSize); + } + + void PreloadAcbTrack() + { + ref int rows = ref trackRows; + + if (rows != 0) return; + if (!OpenUtfSubtable(out trackReader, out UtfTable table, "TrackTable", out rows)) + throw new Exception("Failure opening Track table."); + if (rows == 0) return; + + track = new Track[rows]; + + int cEventIndex = table.GetColumn("EventIndex"); + + for (int i = 0; i < rows; i++) + { + ref Track r = ref track[i]; + + table.Query(i, cEventIndex, out r.EventIndex); + } + } + + void LoadAcbTrack(ushort index) + { + PreloadAcbTrack(); + + if (index > trackRows) + throw new ArgumentOutOfRangeException(nameof(index)); + + ref Track r = ref track[index]; + + if (r.EventIndex == 65535) + return; + + LoadAcbTrackCommand(r.EventIndex); + } + + void PreloadAcbSequence() + { + ref int rows = ref sequenceRows; + + if (rows != 0) return; + if (!OpenUtfSubtable(out sequenceReader, out UtfTable table, "SequenceTable", out rows)) + throw new Exception("Failure opening Sequence table."); + if (rows == 0) return; + + sequence = new Sequence[rows]; + + int cNumTracks = table.GetColumn("NumTracks"); + int cTrackIndex = table.GetColumn("TrackIndex"); + int cType = table.GetColumn("Type"); + + for (int i = 0; i < rows; i++) + { + ref Sequence r = ref sequence[i]; + + table.Query(i, cNumTracks, out r.NumTracks); + table.Query(i, cTrackIndex, out r.TrackIndexOffset, out r.TrackIndexSize); + table.Query(i, cType, out r.Type); + } + } + + void LoadAcbSequence(uint index) + { + PreloadAcbSequence(); + + if (index > sequenceRows) + throw new ArgumentOutOfRangeException(nameof(index)); + + ref Sequence r = ref sequence[index]; + + sequenceDepth++; + + if (sequenceDepth > 3) + throw new Exception("Sequence depth too high."); + + if (r.NumTracks * 2 > r.TrackIndexSize) + throw new Exception("Wrong Sequence.TrackIndex size."); + + switch (r.Type) + { + default: + for (int i = 0; i < r.NumTracks; i++) + { + sequenceReader.BaseStream.Position = r.TrackIndexOffset + i * 2; + + short trackIndexIndex = sequenceReader.ReadInt16BE(); + LoadAcbTrack((ushort)trackIndexIndex); + } + break; + } + + sequenceDepth--; + } + + void PreloadAcbBlock() + { + ref int rows = ref blockRows; + + if (rows != 0) return; + if (!OpenUtfSubtable(out blockReader, out UtfTable table, "BlockTable", out rows)) + throw new Exception("Failure opening Block table."); + if (rows == 0) return; + + block = new Block[rows]; + + int cNumTracks = table.GetColumn("NumTracks"); + int cTrackIndex = table.GetColumn("TrackIndex"); + + for (int i = 0; i < rows; i++) + { + ref Block r = ref block[i]; + table.Query(i, cNumTracks, out r.NumTracks); + table.Query(i, cTrackIndex, out VLData data); + r.TrackIndexOffset = data.Offset; + r.TrackIndexSize = data.Size; + } + } + + void LoadAcbBlock(ushort index) + { + PreloadAcbBlock(); + + if (index > blockRows) + throw new ArgumentOutOfRangeException(nameof(index)); + + ref Block r = ref block[index]; + + if (r.NumTracks * 2 > r.TrackIndexSize) + throw new Exception("Wrong Block.TrackIndex size."); + + for (int i = 0; i < r.NumTracks; i++) + { + blockReader.BaseStream.Position = r.TrackIndexOffset + i * 2; + + short trackIndexIndex = blockReader.ReadInt16BE(); + LoadAcbTrack((ushort)trackIndexIndex); + } + } + + void PreloadAcbBlockSequence() + { + ref int rows = ref blockSequenceRows; + + if (rows != 0) return; + if (!OpenUtfSubtable(out blockSequenceReader, out UtfTable table, "BlockSequenceTable", out rows)) + throw new Exception("Failure opening BlockSequence table."); + if (rows == 0) return; + + blockSequence = new BlockSequence[rows]; + + int cNumTracks = table.GetColumn("NumTracks"); + int cTrackIndex = table.GetColumn("TrackIndex"); + int cNumBlocks = table.GetColumn("NumBlocks"); + int cBlockIndex = table.GetColumn("BlockIndex"); + + for (int i = 0; i < rows; i++) + { + ref BlockSequence r = ref blockSequence[i]; + + table.Query(i, cNumTracks, out r.NumTracks); + table.Query(i, cTrackIndex, out r.TrackIndexOffset, out r.TrackIndexSize); + table.Query(i, cNumBlocks, out r.NumBlocks); + table.Query(i, cBlockIndex, out r.BlockIndexOffset, out r.BlockIndexSize); + } + } + + void LoadAcbBlockSequence(ushort index) + { + PreloadAcbBlockSequence(); + + if (index > blockSequenceRows) + throw new ArgumentOutOfRangeException(nameof(index)); + + ref BlockSequence r = ref blockSequence[index]; + + if (r.NumTracks * 2 > r.TrackIndexSize) + throw new Exception("Wrong BlockSequence.TrackIndex size."); + + for (int i = 0; i < r.NumTracks; i++) + { + blockSequenceReader.BaseStream.Position = r.TrackIndexOffset + i * 2; + + short trackIndexIndex = blockSequenceReader.ReadInt16(); + LoadAcbTrack((ushort)trackIndexIndex); + } + + if (r.NumBlocks * 2 > r.BlockIndexSize) + throw new Exception("Wrong BlockSequence.BlockIndex size."); + + for (int i = 0; i < r.NumBlocks; i++) + { + blockSequenceReader.BaseStream.Position = r.BlockIndexOffset + i * 2; + + short blockIndexIndex = blockSequenceReader.ReadInt16(); + LoadAcbBlock((ushort)blockIndexIndex); + } + } + + void PreloadAcbCue() + { + ref int rows = ref cueRows; + + if (rows != 0) return; + if (!OpenUtfSubtable(out cueReader, out UtfTable table, "CueTable", out rows)) + throw new Exception("Failure opening Cue table."); + if (rows == 0) return; + + cue = new Cue[rows]; + + int cReferenceType = table.GetColumn("ReferenceType"); + int cReferenceIndex = table.GetColumn("ReferenceIndex"); + + for (int i = 0; i < rows; i++) + { + ref Cue r = ref cue[i]; + + table.Query(i, cReferenceType, out r.ReferenceType); + table.Query(i, cReferenceIndex, out r.ReferenceIndex); + } + } + + void LoadAcbCue(ushort index) + { + PreloadAcbCue(); + + if (index > cueRows) + throw new ArgumentOutOfRangeException(nameof(index)); + + ref Cue r = ref cue[index]; + + switch (r.ReferenceType) + { + case 1: + LoadAcbWaveForm(r.ReferenceIndex); + break; + + case 2: + LoadAcbSynth(r.ReferenceIndex); + break; + + case 3: + LoadAcbSequence(r.ReferenceIndex); + break; + + case 8: + LoadAcbBlockSequence(r.ReferenceIndex); + break; + + default: + break; + } + } + + void PreloadAcbCueName() + { + ref UtfTable table = ref cueNames; + ref int rows = ref cueNameRows; + + if (rows != 0) return; + if (!OpenUtfSubtable(out cueNameReader, out table, "CueNameTable", out rows)) + throw new Exception("Failure opening CueName table."); + if (rows == 0) return; + + cueName = new CueName[rows]; + + int cCueIndex = table.GetColumn("CueIndex"); + int cCueName = table.GetColumn("CueName"); + + for (int i = 0; i < rows; i++) + { + ref CueName r = ref cueName[i]; + + table.Query(i, cCueIndex, out r.CueIndex); + table.Query(i, cCueName, out r.Name); + } + } + + void LoadAcbCueName(ushort index) + { + PreloadAcbCueName(); + + if (index > cueNameRows) + throw new ArgumentOutOfRangeException(nameof(index)); + + ref CueName r = ref cueName[index]; + + cueNameIndex = (short)index; + cueNameName = r.Name; + + LoadAcbCue(r.CueIndex); + } + + public string LoadWaveName(int waveId, int port, bool memory) + { + targetWaveId = waveId; + targetPort = port; + isMemory = memory; + + name = ""; + awbNameCount = 0; + awbNameList = new List(); + + PreloadAcbCueName(); + for (ushort i = 0; i < cueNameRows; i++) + { + LoadAcbCueName(i); + } + + return name; + } + } +} diff --git a/Assets/Scripts/Audio/CriWareFormats/AcbNameLoader.cs.meta b/Assets/Scripts/Audio/CriWareFormats/AcbNameLoader.cs.meta new file mode 100644 index 0000000..c6f507e --- /dev/null +++ b/Assets/Scripts/Audio/CriWareFormats/AcbNameLoader.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 612a4d57772b3ad429b40eafbe7d0e3a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Audio/CriWareFormats/AcbReader.cs b/Assets/Scripts/Audio/CriWareFormats/AcbReader.cs new file mode 100644 index 0000000..16910e4 --- /dev/null +++ b/Assets/Scripts/Audio/CriWareFormats/AcbReader.cs @@ -0,0 +1,57 @@ +using CriWareFormats.Common; +using System; +using System.Collections.Generic; +using System.IO; + +namespace CriWareFormats +{ + public sealed class AcbReader : IDisposable + { + private readonly Stream outerStream; + private readonly long positionOffset; + private readonly uint awbOffset; + private readonly uint awbLength; + + private readonly AcbNameLoader acbNameLoader; + + public AcbReader(Stream acbStream) : this(acbStream, 0) { } + + public AcbReader(Stream acbStream, long offset) + { + outerStream = acbStream; + positionOffset = offset; + + acbStream.Position = positionOffset; + + UtfTable utfTable = new UtfTable(acbStream, (uint)offset, out int rows, out string name); + + if (rows != 1 || !name.Equals("Header")) + throw new InvalidDataException("No Header table."); + + if (!utfTable.Query(0, "AwbFile", out VLData awbValueData)) + throw new InvalidDataException("No embedded AWB file."); + + awbOffset = awbValueData.Offset; + awbLength = awbValueData.Size; + + outerStream.Position = positionOffset; + acbNameLoader = new AcbNameLoader(outerStream); + } + + public AwbReader GetAwb() + { + return new AwbReader(new SpliceStream(outerStream, awbOffset, awbLength), true); + } + + public string GetWaveName(int waveId, int port, bool memory) + { + outerStream.Position = positionOffset; + return acbNameLoader.LoadWaveName(waveId, port, memory); + } + + public void Dispose() + { + outerStream.Dispose(); + } + } +} \ No newline at end of file diff --git a/Assets/Scripts/Audio/CriWareFormats/AcbReader.cs.meta b/Assets/Scripts/Audio/CriWareFormats/AcbReader.cs.meta new file mode 100644 index 0000000..ce71d6a --- /dev/null +++ b/Assets/Scripts/Audio/CriWareFormats/AcbReader.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 407dbae8a66935f499cad063a996b044 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Audio/CriWareFormats/AwbReader.cs b/Assets/Scripts/Audio/CriWareFormats/AwbReader.cs new file mode 100644 index 0000000..8cd828a --- /dev/null +++ b/Assets/Scripts/Audio/CriWareFormats/AwbReader.cs @@ -0,0 +1,139 @@ +using CriWareFormats.Common; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; + +namespace CriWareFormats +{ + internal class Row + { + public string Name { get; set; } + public ushort Id { get; set; } + } + + public struct Wave + { + public int WaveId { get; set; } + public long Offset { get; set; } + public long Length { get; set; } + } + + public sealed class AwbReader : IDisposable + { + private readonly BinaryReader binaryReader; + + private readonly byte offsetSize; + private readonly int totalSubsongs; + private readonly ushort alignment; + private readonly ushort subkey; + + private readonly List cueNames; + private readonly List waves; + + public AwbReader(Stream awbStream, bool isEmbedded) : this(awbStream, 0) + { + IsEmbedded = isEmbedded; + } + + public AwbReader(Stream awbStream) : this(awbStream, 0) { } + + public AwbReader(Stream awbStream, long positionOffset) + { + binaryReader = new BinaryReader(awbStream); + + binaryReader.BaseStream.Position = positionOffset; + + if (!binaryReader.ReadChars(4).SequenceEqual("AFS2".ToCharArray())) + throw new InvalidDataException("Incorrect magic."); + + binaryReader.BaseStream.Position += 0x1; + offsetSize = binaryReader.ReadByte(); + binaryReader.BaseStream.Position += 0x2; + totalSubsongs = binaryReader.ReadInt32(); + alignment = binaryReader.ReadUInt16(); + subkey = binaryReader.ReadUInt16(); + + waves = new List(totalSubsongs); + + for (int subsong = 1; subsong <= totalSubsongs; subsong++) + { + long offset = 0x10; + + long waveIdOffset = offset + (subsong - 1) * 0x2; + + binaryReader.BaseStream.Position = waveIdOffset; + + int waveId = binaryReader.ReadUInt16(); + + offset += totalSubsongs * 0x2; + + long subfileOffset = 0; + long subfileNext = 0; + long fileSize = binaryReader.BaseStream.Length; + + offset += (subsong - 1) * offsetSize; + + binaryReader.BaseStream.Position = offset; + + switch (offsetSize) + { + case 0x4: + subfileOffset = binaryReader.ReadUInt32(); + subfileNext = binaryReader.ReadUInt32(); + break; + + case 0x2: + subfileOffset = binaryReader.ReadUInt16(); + subfileNext = binaryReader.ReadUInt16(); + break; + + default: + Fail(); + break; + } + + subfileOffset += subfileOffset % alignment > 0 ? + alignment - subfileOffset % alignment : 0; + subfileNext += subfileNext % alignment > 0 && subfileNext < fileSize ? + alignment - subfileNext % alignment : 0; + long subfileSize = subfileNext - subfileOffset; + + waves.Add(new Wave() + { + WaveId = waveId, + Offset = subfileOffset, + Length = subfileSize + }); + + //if (CueNames.Count > 0) Console.Write("{0,-36}", CueNames.Where(row => row.Index == waveId).First().Name); + //else Console.Write(waveId); + + //Console.WriteLine(subfileOffset); + } + + cueNames = new List(); + } + + public ushort Subkey => subkey; + + public bool IsEmbedded { get; } + + public List Waves => waves; + + public Stream GetWaveSubfileStream(Wave wave) + { + return new SpliceStream(binaryReader.BaseStream, wave.Offset, wave.Length); + } + + private static void Fail() + { + throw new Exception("Failure reading AWB file."); + } + + public void Dispose() + { + binaryReader.Dispose(); + } + } +} \ No newline at end of file diff --git a/Assets/Scripts/Audio/CriWareFormats/AwbReader.cs.meta b/Assets/Scripts/Audio/CriWareFormats/AwbReader.cs.meta new file mode 100644 index 0000000..c08d940 --- /dev/null +++ b/Assets/Scripts/Audio/CriWareFormats/AwbReader.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0e1fffc1a1dfe27459a35520448ccaf0 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Audio/CriWareFormats/Common.meta b/Assets/Scripts/Audio/CriWareFormats/Common.meta new file mode 100644 index 0000000..a74cd00 --- /dev/null +++ b/Assets/Scripts/Audio/CriWareFormats/Common.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 13c5ca40b071c634bb7e480a0479ad81 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Audio/CriWareFormats/Common/BinaryPrimitives.cs b/Assets/Scripts/Audio/CriWareFormats/Common/BinaryPrimitives.cs new file mode 100644 index 0000000..8079b17 --- /dev/null +++ b/Assets/Scripts/Audio/CriWareFormats/Common/BinaryPrimitives.cs @@ -0,0 +1,51 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Assets.Scripts.Audio.CriWareFormats.Common +{ + public class BinaryPrimitives + { + internal static ushort ReverseEndianness(ushort le) + { + byte[] tmp = BitConverter.GetBytes(le); + Array.Reverse(tmp); + return BitConverter.ToUInt16(tmp,0); + } + + internal static int ReverseEndianness(int le) + { + byte[] tmp = BitConverter.GetBytes(le); + Array.Reverse(tmp); + return BitConverter.ToInt32(tmp, 0); + } + + internal static uint ReverseEndianness(uint le) + { + byte[] tmp = BitConverter.GetBytes(le); + Array.Reverse(tmp); + return BitConverter.ToUInt32(tmp, 0); + } + + internal static long ReverseEndianness(long le) + { + byte[] tmp = BitConverter.GetBytes(le); + Array.Reverse(tmp); + return BitConverter.ToInt64(tmp, 0); + } + + internal static ulong ReverseEndianness(ulong le) + { + byte[] tmp = BitConverter.GetBytes(le); + Array.Reverse(tmp); + return BitConverter.ToUInt64(tmp, 0); + } + + public static float Int32BitsToSingle(int m) + { + return BitConverter.ToSingle(BitConverter.GetBytes(m), 0); + } + } +} diff --git a/Assets/Scripts/Audio/CriWareFormats/Common/BinaryPrimitives.cs.meta b/Assets/Scripts/Audio/CriWareFormats/Common/BinaryPrimitives.cs.meta new file mode 100644 index 0000000..4cad7fd --- /dev/null +++ b/Assets/Scripts/Audio/CriWareFormats/Common/BinaryPrimitives.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 35c4bac6c1dd0664b975a22cf7ea445a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Audio/CriWareFormats/Common/BinaryReaderEndian.cs b/Assets/Scripts/Audio/CriWareFormats/Common/BinaryReaderEndian.cs new file mode 100644 index 0000000..b9f08f4 --- /dev/null +++ b/Assets/Scripts/Audio/CriWareFormats/Common/BinaryReaderEndian.cs @@ -0,0 +1,69 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Runtime; +using Assets.Scripts.Audio.CriWareFormats.Common; + +namespace CriWareFormats.Common +{ + public class BinaryReaderEndian : BinaryReader + + { + public BinaryReaderEndian(Stream input) : base(input) + { + } + + public short ReadInt16BE() + { + ushort le = base.ReadUInt16(); + return (short)BinaryPrimitives.ReverseEndianness(le); + } + + public ushort ReadUInt16BE() + { + ushort le = base.ReadUInt16(); + return BinaryPrimitives.ReverseEndianness(le); + } + + public int ReadInt32BE() + { + uint le = base.ReadUInt32(); + return (int)BinaryPrimitives.ReverseEndianness(le); + } + + public uint ReadUInt32BE() + { + uint le = base.ReadUInt32(); + return BinaryPrimitives.ReverseEndianness(le); + } + + public long ReadInt64BE() + { + ulong le = base.ReadUInt64(); + return (long)BinaryPrimitives.ReverseEndianness(le); + } + + public ulong ReadUInt64BE() + { + ulong le = base.ReadUInt64(); + return BinaryPrimitives.ReverseEndianness(le); + } + + public float ReadSingleBE() + { + float le = base.ReadSingle(); + byte[] floatBytes = BitConverter.GetBytes(le); + byte[] reversed = new byte[4]; + for (int i = 0; i < 4; i++) + { + reversed[i] = floatBytes[3 - i]; + } + return BitConverter.ToSingle(reversed, 0); + } + + + } +} diff --git a/Assets/Scripts/Audio/CriWareFormats/Common/BinaryReaderEndian.cs.meta b/Assets/Scripts/Audio/CriWareFormats/Common/BinaryReaderEndian.cs.meta new file mode 100644 index 0000000..ea14afa --- /dev/null +++ b/Assets/Scripts/Audio/CriWareFormats/Common/BinaryReaderEndian.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f17047d6b7698144588e1d5181473cf9 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Audio/CriWareFormats/Common/Endian.cs b/Assets/Scripts/Audio/CriWareFormats/Common/Endian.cs new file mode 100644 index 0000000..6f7bc0a --- /dev/null +++ b/Assets/Scripts/Audio/CriWareFormats/Common/Endian.cs @@ -0,0 +1,27 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace CriWareFormats.Common +{ + public static class Endian + { + public static ushort Reverse(ushort value) + { + return (ushort)(value << 8 | value >> 8); + } + + public static uint Reverse(uint value) + { + value = (value & 0x00FF00FFu) << 8 | (value & 0xFF00FF00u) >> 8; + return (value & 0x0000FFFFu) << 16 | (value & 0xFFFF0000u) >> 16; + } + + public static ulong Reverse(ulong value) + { + value = (value & 0x00FF00FF00FF00FFu) << 8 | (value & 0xFF00FF00FF00FF00u) >> 8; + value = (value & 0x0000FFFF0000FFFFu) << 16 | (value & 0xFFFF0000FFFF0000u) >> 16; + return value << 32 | value >> 32; + } + } +} diff --git a/Assets/Scripts/Audio/CriWareFormats/Common/Endian.cs.meta b/Assets/Scripts/Audio/CriWareFormats/Common/Endian.cs.meta new file mode 100644 index 0000000..8403b84 --- /dev/null +++ b/Assets/Scripts/Audio/CriWareFormats/Common/Endian.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: dfc4d0df7cc8c294ead855ed1ccc762d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Audio/CriWareFormats/SpliceStream.cs b/Assets/Scripts/Audio/CriWareFormats/SpliceStream.cs new file mode 100644 index 0000000..9965fad --- /dev/null +++ b/Assets/Scripts/Audio/CriWareFormats/SpliceStream.cs @@ -0,0 +1,116 @@ +using System; +using System.IO; + +namespace CriWareFormats +{ + public class SpliceStream : Stream + { + private readonly Stream innerStream; + private readonly long realPosition; + + private long internalPosition; + + private readonly object positionLock = new object(); + + public SpliceStream(Stream sourceStream, long offset, long length) + { + innerStream = sourceStream; + realPosition = offset; + internalPosition = 0; + + Length = length; + } + + public override bool CanRead => true; + + public override bool CanSeek => true; + + public override bool CanWrite => false; + + public override long Length { get; } + + public override long Position + { + get + { + lock (positionLock) + { + return internalPosition; + } + } + set + { + lock (positionLock) + { + long checkValue = value + realPosition; + if (value < 0 || value >= Length) throw new ArgumentOutOfRangeException(nameof(value)); + internalPosition = value; + + if (innerStream.CanSeek) innerStream.Position = checkValue; + } + } + } + + public override void Flush() + { + throw new NotImplementedException(); + } + + public override int Read(byte[] buffer, int offset, int count) + { + lock (positionLock) + { + if (innerStream.CanRead) + { + long restore = innerStream.Position; + innerStream.Position = realPosition + internalPosition; + int read = innerStream.Read(buffer, offset, count); + internalPosition += read; + innerStream.Position = restore; + return read; + } + else return 0; + } + } + + public override long Seek(long offset, SeekOrigin origin) + { + lock (positionLock) + { + switch (origin) + { + case SeekOrigin.Begin: + if (offset >= Length) throw new ArgumentOutOfRangeException(nameof(offset)); + internalPosition = offset; + break; + + case SeekOrigin.Current: + if (internalPosition + offset >= Length) throw new ArgumentOutOfRangeException(nameof(offset)); + internalPosition += offset; + break; + + case SeekOrigin.End: + if (internalPosition - offset < 0) throw new ArgumentOutOfRangeException(nameof(offset)); + internalPosition = Length; + internalPosition -= offset; + break; + + default: + break; + } + + return internalPosition; + } + } + + public override void SetLength(long value) + { + throw new NotImplementedException(); + } + + public override void Write(byte[] buffer, int offset, int count) + { + throw new NotImplementedException(); + } + } +} diff --git a/Assets/Scripts/Audio/CriWareFormats/SpliceStream.cs.meta b/Assets/Scripts/Audio/CriWareFormats/SpliceStream.cs.meta new file mode 100644 index 0000000..0af8e81 --- /dev/null +++ b/Assets/Scripts/Audio/CriWareFormats/SpliceStream.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 5e2b71da36bdac14fae41451686dac14 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Audio/CriWareFormats/UtfTable.cs b/Assets/Scripts/Audio/CriWareFormats/UtfTable.cs new file mode 100644 index 0000000..087e4c6 --- /dev/null +++ b/Assets/Scripts/Audio/CriWareFormats/UtfTable.cs @@ -0,0 +1,435 @@ +using CriWareFormats.Common; +using System; +using System.IO; +using System.Linq; +using System.Text; + +namespace CriWareFormats +{ + [Flags] + public enum ColumnFlag : byte + { + Name = 0x10, + Default = 0x20, + Row = 0x40, + Undefined = 0x80 + } + + public enum ColumnType : byte + { + Byte = 0x00, + SByte = 0x01, + UInt16 = 0x02, + Int16 = 0x03, + UInt32 = 0x04, + Int32 = 0x05, + UInt64 = 0x06, + Int64 = 0x07, + Float = 0x08, + Double = 0x09, + String = 0x0A, + VLData = 0x0B, + UInt128 = 0x0C, + Undefined = 0xFF + } + + public struct Column + { + public ColumnFlag Flag; + public ColumnType Type; + public string Name; + public uint Offset; + + public override string ToString() + { + return Name; + } + } + + public struct VLData + { + public uint Offset; + public uint Size; + + public override string ToString() + { + return $"Offset: {Offset}, Length: {Size}"; + } + } + + public struct Result + { + public ColumnType Type; + public object Value; + } + + public sealed class UtfTable + { + private readonly BinaryReaderEndian binaryReader; + private readonly uint tableOffset; + + private readonly uint tableSize; + private readonly ushort version; + private readonly ushort rowsOffset; + private readonly uint stringsOffset; + private readonly uint dataOffset; + private readonly uint nameOffset; + + private readonly ushort columns; + private readonly ushort rowWidth; + private readonly uint rows; + + private readonly byte[] schemaBuffer; + private readonly Column[] schema; + + private readonly uint schemaOffset; + private readonly uint schemaSize; + private readonly uint rowsSize; + private readonly uint dataSize; + private readonly uint stringsSize; + + private readonly byte[] stringTable; + private readonly string tableName; + + public UtfTable(Stream utfTableStream, out int utfTableRows, out string utfTableRowName) : + this(utfTableStream, 0, out utfTableRows, out utfTableRowName) + { } + + public UtfTable(Stream utfTableStream, uint offset) : + this(utfTableStream, offset, out int _, out string _) + { } + + public UtfTable(Stream utfTableStream, uint offset, out int utfTableRows, out string rowName) + { + binaryReader = new BinaryReaderEndian(utfTableStream); + tableOffset = offset; + + binaryReader.BaseStream.Position = offset; + + if (!binaryReader.ReadChars(4).SequenceEqual("@UTF".ToCharArray())) + throw new InvalidDataException("Incorrect magic."); + tableSize = binaryReader.ReadUInt32BE() + 0x08; + version = binaryReader.ReadUInt16BE(); + rowsOffset = (ushort)(binaryReader.ReadUInt16BE() + 0x08); + stringsOffset = binaryReader.ReadUInt32BE() + 0x08; + dataOffset = binaryReader.ReadUInt32BE() + 0x08; + nameOffset = binaryReader.ReadUInt32BE(); + columns = binaryReader.ReadUInt16BE(); + rowWidth = binaryReader.ReadUInt16BE(); + rows = binaryReader.ReadUInt32BE(); + + schemaOffset = 0x20; + schemaSize = rowsOffset - schemaOffset; + rowsSize = stringsOffset - rowsOffset; + stringsSize = dataOffset - stringsOffset; + dataSize = tableSize - dataOffset; + + if (version != 0x00 && version != 0x01) + throw new InvalidDataException("Unknown @UTF version."); + if (tableOffset + tableSize > utfTableStream.Length) + throw new InvalidDataException("Table size exceeds bounds of file."); + if (rowsOffset > tableSize || stringsOffset > tableSize || dataOffset > tableSize) + throw new InvalidDataException("Offsets out of bounds."); + if (stringsSize <= 0 || nameOffset > stringsSize) + throw new InvalidDataException("Invalid string table size."); + if (Columns <= 0) + throw new InvalidDataException("Table has no columns."); + + schemaBuffer = new byte[schemaSize]; + binaryReader.BaseStream.Position = tableOffset + schemaOffset; + if (binaryReader.Read(schemaBuffer, 0, (int)schemaSize) != schemaSize) + throw new InvalidDataException("Failed to read schema."); + + stringTable = new byte[stringsSize]; + binaryReader.BaseStream.Position = tableOffset + stringsOffset; + if (binaryReader.Read(stringTable, 0, (int)stringsSize) != stringsSize) + throw new InvalidDataException("Failed to read string table."); + + uint columnOffset = 0; + uint schemaPos = 0; + + tableName = GetStringFromTable(nameOffset); + + schema = new Column[columns]; + + BinaryReaderEndian bytesReader = new BinaryReaderEndian(new MemoryStream(schemaBuffer) { Position = 0 }); + for (int i = 0; i < columns; i++) + { + bytesReader.BaseStream.Position = schemaPos; + + byte info = bytesReader.ReadByte(); + uint nameOffset = bytesReader.ReadUInt32BE(); + + if (nameOffset > stringsSize) + throw new InvalidDataException("String offset out of bounds."); + schemaPos += 0x1 + 0x4; + + bytesReader.BaseStream.Position = schemaPos; + + schema[i] = new Column() + { + Flag = (ColumnFlag)(info & 0xF0), + Type = (ColumnType)(info & 0x0F), + Name = "", + Offset = 0 + }; + + if (schema[i].Flag == 0 || + !schema[i].Flag.HasFlag(ColumnFlag.Name) || + schema[i].Flag.HasFlag(ColumnFlag.Default) && schema[i].Flag.HasFlag(ColumnFlag.Row) || + schema[i].Flag.HasFlag(ColumnFlag.Undefined)) + throw new InvalidDataException("Unknown column flag combo found."); + + uint valueSize; + switch (schema[i].Type) + { + case ColumnType.Byte: + case ColumnType.SByte: + valueSize = 0x1; + break; + case ColumnType.UInt16: + case ColumnType.Int16: + valueSize = 0x2; + break; + case ColumnType.UInt32: + case ColumnType.Int32: + case ColumnType.Float: + case ColumnType.String: + valueSize = 0x4; + break; + case ColumnType.UInt64: + case ColumnType.Int64: + case ColumnType.VLData: + valueSize = 0x8; + break; + default: + throw new InvalidDataException("Invalid column type."); + }; + + if (schema[i].Flag.HasFlag(ColumnFlag.Name)) + schema[i].Name = GetStringFromTable(nameOffset); + + if (schema[i].Flag.HasFlag(ColumnFlag.Default)) + { + schema[i].Offset = schemaPos; + schemaPos += valueSize; + + bytesReader.BaseStream.Position = schemaPos; + + } + + if (schema[i].Flag.HasFlag(ColumnFlag.Row)) + { + schema[i].Offset = columnOffset; + columnOffset += valueSize; + } + } + + utfTableRows = (int)rows; + rowName = GetStringFromTable(nameOffset); + + bytesReader.Dispose(); + } + + public ushort Columns => columns; + + public uint Rows => rows; + + public Column[] Schema => schema; + + public string TableName => tableName; + + public int GetColumn(string columnName) + { + for (int i = 0; i < columns; i++) + { + Column column = schema[i]; + + if (column.Name is null || !column.Name.Equals(columnName)) + continue; + + return i; + } + + return -1; + } + + private bool Query(int row, int column, out Result result) + { + result = new Result(); + + if (row >= rows || row < 0) + //throw new ArgumentOutOfRangeException(nameof(row)); + return false; + if (column >= columns || column < 0) + //throw new ArgumentOutOfRangeException(nameof(column)); + return false; + + Column col = schema[column]; + uint dataOffset = 0; + BinaryReaderEndian bytesReader = null; + + result.Type = col.Type; + + if (col.Flag.HasFlag(ColumnFlag.Default)) + { + if (schemaBuffer != null) + { + bytesReader = new BinaryReaderEndian(new MemoryStream(schemaBuffer)); + bytesReader.BaseStream.Position = col.Offset; + } + else + { + dataOffset = tableOffset + schemaOffset + col.Offset; + } + } + else if (col.Flag.HasFlag(ColumnFlag.Row)) + { + dataOffset = (uint)(tableOffset + rowsOffset + row * rowWidth + col.Offset); + } + else + throw new InvalidDataException("Invalid flag."); + + binaryReader.BaseStream.Position = dataOffset; + + switch (col.Type) + { + case ColumnType.Byte: + result.Value = (bytesReader != null) ? bytesReader.ReadByte() : binaryReader.ReadByte(); + break; + case ColumnType.SByte: + result.Value = (bytesReader != null) ? bytesReader.ReadSByte() : binaryReader.ReadSByte(); + break; + case ColumnType.UInt16: + result.Value = (bytesReader != null) ? bytesReader.ReadUInt16BE() : binaryReader.ReadUInt16BE(); + break; + case ColumnType.Int16: + result.Value = (bytesReader != null) ? bytesReader.ReadInt16BE() : binaryReader.ReadInt16BE(); + break; + case ColumnType.UInt32: + result.Value = (bytesReader != null) ? bytesReader.ReadUInt32BE() : binaryReader.ReadUInt32BE(); + break; + case ColumnType.Int32: + result.Value = (bytesReader != null) ? bytesReader.ReadInt32BE() : binaryReader.ReadInt32BE(); + break; + case ColumnType.UInt64: + result.Value = (bytesReader != null) ? bytesReader.ReadUInt64BE() : binaryReader.ReadUInt64BE(); + break; + case ColumnType.Int64: + result.Value = (bytesReader != null) ? bytesReader.ReadInt64BE() : binaryReader.ReadInt64BE(); + break; + case ColumnType.Float: + result.Value = (bytesReader != null) ? bytesReader.ReadSingleBE() : binaryReader.ReadSingleBE(); + break; + //case ColumnType.Double: + // break; + case ColumnType.String: + uint nameOffset = (bytesReader != null) ? bytesReader.ReadUInt32BE() : binaryReader.ReadUInt32BE(); + if (nameOffset > stringsSize) + throw new InvalidDataException("Name offset out of bounds."); + result.Value = GetStringFromTable(nameOffset); + break; + case ColumnType.VLData: + if ((bytesReader != null)) + { + result.Value = new VLData() + { + Offset = bytesReader.ReadUInt32BE(), + Size = bytesReader.ReadUInt32BE() + }; + } + else + { + result.Value = new VLData() + { + Offset = binaryReader.ReadUInt32BE(), + Size = binaryReader.ReadUInt32BE() + }; + } + break; + //case ColumnType.UInt128: + // break; + default: + return false; + } + + return true; + } + + public bool Query(int row, int column, out T value) + { + bool valid = Query(row, column, out Result result); + + bool enumParseResult = Enum.TryParse(typeof(T).Name, out ColumnType type); + + if (!valid || !enumParseResult || result.Type != type) + { + value = default; + return false; + } + + value = (T)result.Value; + + if (value is VLData vlData) + { + vlData.Offset += tableOffset + dataOffset; + value = (T)(object)vlData; + } + + return true; + } + + public bool Query(int row, string columnName, out T value) => + Query(row, GetColumn(columnName), out value); + + public bool Query(int row, int column, out uint offset, out uint size) + { + if (!Query(row, column, out VLData data)) + { + offset = 0; + size = 0; + + return false; + } + + offset = data.Offset; + size = data.Size; + + return true; + } + + public bool Query(int row, string columnName, out uint offset, out uint size) + => Query(row, GetColumn(columnName), out offset, out size); + + private string GetStringFromTable(uint offset) + { + if (offset > stringsSize) + throw new InvalidDataException("Invalid string offset."); + + StringBuilder stringBuilder = new StringBuilder(); + + int i = 0; + while (i < stringsSize) + { + stringBuilder.Append((char)stringTable[offset + i++]); + if (stringTable[offset + i] == '\0') break; + } + + return stringBuilder.ToString(); + } + + public UtfTable OpenSubtable(string tableName) + { + if (!Query(0, tableName, out VLData tableValueData)) + throw new ArgumentException("Subtable does not exist."); + + binaryReader.BaseStream.Position = tableValueData.Offset; + + return new UtfTable( + binaryReader.BaseStream, + tableValueData.Offset, + out int _, + out string _); + } + } +} \ No newline at end of file diff --git a/Assets/Scripts/Audio/CriWareFormats/UtfTable.cs.meta b/Assets/Scripts/Audio/CriWareFormats/UtfTable.cs.meta new file mode 100644 index 0000000..eb7d199 --- /dev/null +++ b/Assets/Scripts/Audio/CriWareFormats/UtfTable.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d662e0678754d5945b5223b3ab889993 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Audio/HcaWaveStream.cs b/Assets/Scripts/Audio/HcaWaveStream.cs new file mode 100644 index 0000000..b8280cd --- /dev/null +++ b/Assets/Scripts/Audio/HcaWaveStream.cs @@ -0,0 +1,172 @@ +using ClHcaSharp; +using NAudio.Wave; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace UmaMusumeAudio +{ + public class HcaWaveStream : WaveStream + { + private readonly Stream hcaFileStream; + private readonly BinaryReader hcaFileReader; + private readonly HcaDecoder decoder; + private readonly HcaInfo info; + private readonly long dataStart; + private readonly object positionLock = new object(); + + private readonly short[][] sampleBuffer; + + private long samplePosition; + + public HcaWaveStream(Stream hcaFile, ulong key) + { + hcaFileStream = hcaFile; + hcaFileReader = new BinaryReader(hcaFile); + decoder = new HcaDecoder(hcaFile, key); + info = decoder.GetInfo(); + dataStart = hcaFile.Position; + + sampleBuffer = new short[info.ChannelCount][]; + for (int i = 0; i < info.ChannelCount; i++) + { + sampleBuffer[i] = new short[info.SamplesPerBlock]; + } + + Loop = info.LoopEnabled; + LoopStartSample = info.LoopStartSample; + LoopEndSample = info.LoopEndSample; + + WaveFormat = new WaveFormat(info.SamplingRate, info.ChannelCount); + + samplePosition = info.EncoderDelay; + FillBuffer(samplePosition); + } + + public HcaInfo Info => Info1; + + public bool Loop { get; set; } + + public long LoopStartSample { get; set; } + + public long LoopEndSample { get; set; } + + public override WaveFormat WaveFormat { get; } + + public override long Length => Info1.SampleCount * Info1.ChannelCount * sizeof(short); + + public override long Position + { + get + { + lock (positionLock) + { + return (samplePosition - Info1.EncoderDelay) * Info1.ChannelCount * sizeof(short); + } + } + set + { + lock (positionLock) + { + samplePosition = value / Info1.ChannelCount / sizeof(short); + samplePosition += Info1.EncoderDelay; + + if (Position < Length) FillBuffer(samplePosition); + } + } + } + + public HcaInfo Info1 => info; + + public short[][] SampleBuffer => sampleBuffer; + + public HcaDecoder Decoder => decoder; + + public override int Read(byte[] buffer, int offset, int count) + { + lock (positionLock) + { + int read = 0; + + for (int i = 0; i < count / Info1.ChannelCount / sizeof(short); i++) + { + if (samplePosition - Info1.EncoderDelay >= LoopEndSample && Loop) + { + samplePosition = LoopStartSample + Info1.EncoderDelay; + FillBuffer(samplePosition); + } + else if (Position >= Length) break; + + if (samplePosition % Info1.SamplesPerBlock == 0) FillBuffer(samplePosition); + + for (int j = 0; j < Info1.ChannelCount; j++) + { + int bufferOffset = (i * Info1.ChannelCount + j) * sizeof(short); + buffer[offset + bufferOffset] = (byte)SampleBuffer[j][samplePosition % Info1.SamplesPerBlock]; + buffer[offset + bufferOffset + 1] = (byte)(SampleBuffer[j][samplePosition % Info1.SamplesPerBlock] >> 8); + + read += sizeof(short); + } + + samplePosition++; + } + + return read; + } + } + + public void ResetLoop() + { + Loop = Info1.LoopEnabled; + LoopStartSample = Info1.LoopStartSample; + LoopEndSample = Info1.LoopEndSample; + } + + private void FillBuffer(long sample) + { + int block = (int)(sample / Info1.SamplesPerBlock); + FillBuffer(block); + } + + private void FillBuffer(int block) + { + if (block >= 0) hcaFileStream.Position = dataStart + block * Info1.BlockSize; + + if (hcaFileStream.Position < hcaFileStream.Length) + { + byte[] blockBytes = hcaFileReader.ReadBytes(Info1.BlockSize); + if (blockBytes.Length > 0) + { + Decoder.DecodeBlock(blockBytes); + Decoder.ReadSamples16(SampleBuffer); + } + } + } + + //private void FillBuffer() + //{ + // if (hcaFileStream.Position >= hcaFileStream.Length) + // hcaFileStream.Position = dataStart; + + // byte[] blockBytes = hcaFileReader.ReadBytes(info.BlockSize); + // if (blockBytes.Length > 0) + // { + // decoder.DecodeBlock(blockBytes); + // decoder.ReadSamples16(sampleBuffer); + // } + // else + // { + // for (int i = 0; i < sampleBuffer.Length; i++) + // { + // for (int j = 0; j < sampleBuffer[i].Length; j++) + // { + // sampleBuffer[i][j] = 0; + // } + // } + // } + //} + } +} diff --git a/Assets/Scripts/Audio/HcaWaveStream.cs.meta b/Assets/Scripts/Audio/HcaWaveStream.cs.meta new file mode 100644 index 0000000..31393b7 --- /dev/null +++ b/Assets/Scripts/Audio/HcaWaveStream.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9d2df19f53207594cbf031ad1620c2ea +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Audio/UmaWaveStream.cs b/Assets/Scripts/Audio/UmaWaveStream.cs new file mode 100644 index 0000000..e402246 --- /dev/null +++ b/Assets/Scripts/Audio/UmaWaveStream.cs @@ -0,0 +1,54 @@ +using NAudio.Wave; +using System; +using UnityEngine; +using System.IO; +using CriWareFormats; +using ClHcaSharp; + +namespace UmaMusumeAudio +{ + public class UmaWaveStream : WaveStream + { + /* + * Open Umamusume > umamusume_Data > resources.assets with a hex editor. + * Check the results when finding the string "StreamingAssets". + * The key should be near a string named "cri_auth". + */ + private const ulong umaMusumeKey = 75923756697503; + + private readonly HcaWaveStream hcaWaveStream; + + public UmaWaveStream(AwbReader awbReader, int waveId) + { + Stream awbSubfile = awbReader.GetWaveSubfileStream(awbReader.Waves.Find((wave) => wave.WaveId == waveId)); + hcaWaveStream = new HcaWaveStream(awbSubfile, MixKey(umaMusumeKey, awbReader.Subkey)); + } + + public override WaveFormat WaveFormat => hcaWaveStream.WaveFormat; + + public bool Loop { get => hcaWaveStream.Loop; set { hcaWaveStream.Loop = value; } } + + public long LoopStartSample { get => hcaWaveStream.LoopStartSample; set { hcaWaveStream.LoopStartSample = value; } } + + public long LoopEndSample { get => hcaWaveStream.LoopEndSample; set { hcaWaveStream.LoopEndSample = value; } } + + public override long Length => hcaWaveStream.Length; + + public override long Position { get => hcaWaveStream.Position; set => hcaWaveStream.Position = value; } + + public short[][] SampleBuffer => hcaWaveStream.SampleBuffer; + + public HcaDecoder Decoder => hcaWaveStream.Decoder; + public HcaInfo Info => hcaWaveStream.Info; + + public override int Read(byte[] buffer, int offset, int count) + { + return hcaWaveStream.Read(buffer, offset, count); + } + + public void ResetLoop() => hcaWaveStream.ResetLoop(); + + private static ulong MixKey(ulong key, ushort subkey) => + key * (((ulong)subkey << 16) | ((ushort)~subkey + 2u)); + } +} diff --git a/Assets/Scripts/Audio/UmaWaveStream.cs.meta b/Assets/Scripts/Audio/UmaWaveStream.cs.meta new file mode 100644 index 0000000..adf3202 --- /dev/null +++ b/Assets/Scripts/Audio/UmaWaveStream.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d159c340b0cc08c47bfafb5e5641a630 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Audio/WAV.cs b/Assets/Scripts/Audio/WAV.cs new file mode 100644 index 0000000..f35f700 --- /dev/null +++ b/Assets/Scripts/Audio/WAV.cs @@ -0,0 +1,118 @@ +public class WAV +{ + + // convert two bytes to one float in the range -1 to 1 + static float bytesToFloat(byte firstByte, byte secondByte) + { + // convert two bytes to one short (little endian) + short s = (short)((secondByte << 8) | firstByte); + // convert to range from -1 to (just below) 1 + return s / 32768.0F; + } + + static int bytesToInt(byte[] bytes, int offset = 0) + { + int value = 0; + for (int i = 0; i < 4; i++) + { + value |= ((int)bytes[offset + i]) << (i * 8); + } + return value; + } + // properties + public float[] LeftChannel { get; internal set; } + public float[] RightChannel { get; internal set; } + public float[] StereoChannel { get; internal set; } + public int ChannelCount { get; internal set; } + public int SampleCount { get; internal set; } + public int Frequency { get; internal set; } + + public WAV(byte[] wav) + { + + // Determine if mono or stereo + ChannelCount = wav[22]; // Forget byte 23 as 99.999% of WAVs are 1 or 2 channels + + // Get the frequency + Frequency = bytesToInt(wav, 24); + + // Get past all the other sub chunks to get to the data subchunk: + int pos = 12; // First Subchunk ID from 12 to 16 + + // Keep iterating until we find the data chunk (i.e. 64 61 74 61 ...... (i.e. 100 97 116 97 in decimal)) + while (!(wav[pos] == 100 && wav[pos + 1] == 97 && wav[pos + 2] == 116 && wav[pos + 3] == 97)) + { + pos += 4; + int chunkSize = wav[pos] + wav[pos + 1] * 256 + wav[pos + 2] * 65536 + wav[pos + 3] * 16777216; + pos += 4 + chunkSize; + } + pos += 8; + + // Pos is now positioned to start of actual sound data. + SampleCount = (wav.Length - pos) / 2; // 2 bytes per sample (16 bit sound mono) + if (ChannelCount == 2) SampleCount /= 2; // 4 bytes per sample (16 bit stereo) + + // Allocate memory (right will be null if only mono sound) + LeftChannel = new float[SampleCount]; + if (ChannelCount == 2) RightChannel = new float[SampleCount]; + else RightChannel = null; + + // Write to double array/s: + int i = 0; + while (pos < wav.Length) + { + LeftChannel[i] = bytesToFloat(wav[pos], wav[pos + 1]); + pos += 2; + if (ChannelCount == 2) + { + RightChannel[i] = bytesToFloat(wav[pos], wav[pos + 1]); + pos += 2; + } + i++; + } + + //Merge left and right channels for stereo sound + if (ChannelCount == 2) + { + StereoChannel = new float[SampleCount * 2]; + //Current position in our left and right channels + int channelPos = 0; + //After we've changed two values for our Stereochannel, we want to increase our channelPos + short posChange = 0; + + for (int index = 0; index < (SampleCount * 2); index++) + { + + if (index % 2 == 0) + { + StereoChannel[index] = LeftChannel[channelPos]; + posChange++; + } + else + { + StereoChannel[index] = RightChannel[channelPos]; + posChange++; + } + //Two values have been changed, so update our channelPos + if (posChange % 2 == 0) + { + if (channelPos < SampleCount) + { + channelPos++; + //Reset the counter for next iterations + posChange = 0; + } + } + } + } + else + { + StereoChannel = null; + } + } + + public override string ToString() + { + return string.Format("[WAV: LeftChannel={0}, RightChannel={1}, ChannelCount={2}, SampleCount={3}, Frequency={4}]", LeftChannel, RightChannel, ChannelCount, SampleCount, Frequency); + } +} \ No newline at end of file diff --git a/Assets/Scripts/Audio/WAV.cs.meta b/Assets/Scripts/Audio/WAV.cs.meta new file mode 100644 index 0000000..fb63974 --- /dev/null +++ b/Assets/Scripts/Audio/WAV.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f0f51605a8223f8489a6c386d8d06198 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/UmaViewerBuilder.cs b/Assets/Scripts/UmaViewerBuilder.cs index 9cbd1b6..ada8b15 100644 --- a/Assets/Scripts/UmaViewerBuilder.cs +++ b/Assets/Scripts/UmaViewerBuilder.cs @@ -1,10 +1,15 @@ -using Gallop; +using CriWareFormats; +using Gallop; +using NAudio.Wave; +using NAudio.Wave.SampleProviders; using Newtonsoft.Json.Linq; using System; using System.Collections; using System.Collections.Generic; using System.IO; using System.Linq; +using System.Text; +using UmaMusumeAudio; using UnityEditor; using UnityEngine; @@ -21,7 +26,7 @@ public class UmaViewerBuilder : MonoBehaviour public UmaContainer CurrentUMAContainer; public UmaContainer CurrentLiveContainer; public UmaContainer CurrentOtherContainer; - + public AudioSource CurrentAudioSource; public AnimatorOverrideController OverrideController; @@ -337,10 +342,10 @@ public class UmaViewerBuilder : MonoBehaviour public void LoadLive(int id) { - var asset = UmaViewerMain.Instance.AbList.FirstOrDefault(a => a.Name.EndsWith("cutt_son"+id)); + var asset = UmaViewerMain.Instance.AbList.FirstOrDefault(a => a.Name.EndsWith("cutt_son" + id)); if (CurrentLiveContainer != null) { - Destroy(CurrentLiveContainer); + Destroy(CurrentLiveContainer.gameObject); } UnloadAllBundle(); CurrentLiveContainer = new GameObject(Path.GetFileName(asset.Name)).AddComponent(); @@ -348,6 +353,47 @@ public class UmaViewerBuilder : MonoBehaviour } + public void LoadLiveSound(int songid, UmaDatabaseEntry SongAwb) + { + if (CurrentAudioSource) + { + Destroy(CurrentAudioSource.gameObject); + } + AudioClip clip = LoadAudio(SongAwb); + if (clip != null) + { + CurrentAudioSource = new GameObject("SoundController").AddComponent(); + CurrentAudioSource.clip = clip; + CurrentAudioSource.Play(); + } + } + + public AudioClip LoadAudio(UmaDatabaseEntry awb) + { + UmaViewerUI.Instance.LoadedAssetsAdd(awb); + + string awbPath = $"{Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + "Low"}\\Cygames\\umamusume\\dat\\{awb.Url.Substring(0, 2)}\\{awb.Url}"; + if (!File.Exists(awbPath)) return null; + + FileStream awbFile = File.OpenRead(awbPath); + AwbReader awbReader = new AwbReader(awbFile); + + + var stream = new UmaWaveStream(awbReader, 0); + MemoryStream outputStream = new MemoryStream(); + WaveFileWriter.WriteWavFileToStream(outputStream, stream); + + WAV wav = new WAV(outputStream.ToArray()); + AudioClip clip = AudioClip.Create(Path.GetFileName(awb.Name).Replace(".awb", ""),wav.SampleCount,wav.ChannelCount,wav.Frequency,false); + clip.SetData(wav.ChannelCount > 1 ? wav.StereoChannel : wav.LeftChannel, 0); + + awbReader.Dispose(); + awbFile.Dispose(); + outputStream.Dispose(); + + return clip; + } + private void RecursiveLoadAsset(UmaDatabaseEntry entry, bool IsSubAsset = false) { if (!string.IsNullOrEmpty(entry.Prerequisites)) @@ -397,17 +443,17 @@ public class UmaViewerBuilder : MonoBehaviour Type aType = asset.GetType(); if (aType == typeof(AnimationClip)) { - if (CurrentUMAContainer&&CurrentUMAContainer.Body) + if (CurrentUMAContainer && CurrentUMAContainer.Body) { AnimationClip bbb = asset as AnimationClip; bbb.wrapMode = WrapMode.Loop; CurrentUMAContainer.OverrideController["clip"] = bbb; CurrentUMAContainer.UmaAnimator.Play("clip", 0, 0); - + } - if(!CurrentLiveContainer) - UnloadBundle(bundle, false); + if (!CurrentLiveContainer) + UnloadBundle(bundle, false); } else if (aType == typeof(GameObject)) { @@ -678,7 +724,7 @@ public class UmaViewerBuilder : MonoBehaviour private void LoadProp(GameObject go) { - var prop = Instantiate(go, (go.name.Contains("Cutt_son")?CurrentLiveContainer:CurrentOtherContainer).transform); + var prop = Instantiate(go, (go.name.Contains("Cutt_son") ? CurrentLiveContainer : CurrentOtherContainer).transform); foreach (Renderer r in prop.GetComponentsInChildren()) { foreach (Material m in r.sharedMaterials) diff --git a/Assets/Scripts/UmaViewerUI.cs b/Assets/Scripts/UmaViewerUI.cs index ddf9808..775c275 100644 --- a/Assets/Scripts/UmaViewerUI.cs +++ b/Assets/Scripts/UmaViewerUI.cs @@ -30,6 +30,8 @@ public class UmaViewerUI : MonoBehaviour,FaceLoadCallBack public ScrollRect FacialList; public ScrollRect LiveList; + public ScrollRect LiveSoundList; + public ScrollRect LiveCharaSoundList; //settings public TMPro.TMP_InputField SSWidth, SSHeight; @@ -117,7 +119,11 @@ public class UmaViewerUI : MonoBehaviour,FaceLoadCallBack { Destroy(ui.gameObject); } - foreach (FacialMorph morph in target.EyeBrowMorphs) + List tempMorph = new List(); + tempMorph.AddRange(target.EyeBrowMorphs); + tempMorph.AddRange(target.EyeMorphs); + tempMorph.AddRange(target.MouthMorphs); + foreach (FacialMorph morph in tempMorph) { var container = Instantiate(UmaContainerSliderPrefab, FacialList.content).GetComponent(); container.Name.text = morph.name; @@ -126,24 +132,6 @@ public class UmaViewerUI : MonoBehaviour,FaceLoadCallBack container.Slider.minValue = 0; container.Slider.onValueChanged.AddListener((a) => { morph.Weight = a;}); } - foreach (FacialMorph morph in target.EyeMorphs) - { - var container = Instantiate(UmaContainerSliderPrefab, FacialList.content).GetComponent(); - container.Name.text = morph.name; - container.Slider.value = morph.Weight; - container.Slider.maxValue = 1; - container.Slider.minValue = 0; - container.Slider.onValueChanged.AddListener((a) => { morph.Weight = a; }); - } - foreach (FacialMorph morph in target.MouthMorphs) - { - var container = Instantiate(UmaContainerSliderPrefab, FacialList.content).GetComponent(); - container.Name.text = morph.name; - container.Slider.value = morph.Weight; - container.Slider.maxValue = 1; - container.Slider.minValue = 0; - container.Slider.onValueChanged.AddListener((a) => { morph.Weight = a; }); - } } public void LoadLivePanels() @@ -159,7 +147,17 @@ public class UmaViewerUI : MonoBehaviour,FaceLoadCallBack Builder.LoadLive(live.MusicId); }); + var CharaContainer = Instantiate(UmaContainerNoTMPPrefab, LiveSoundList.content).GetComponent(); + CharaContainer.GetComponentInChildren().text = " " + live.MusicId + " " + live.songName; + var CharaimageInstance1 = container.GetComponent(); + CharaContainer.Button.onClick.AddListener(() => { + HighlightChildImage(LiveList.content, imageInstance1); + ListLiveSounds(live.MusicId); + }); + } + + } public void LoadMiniModelPanels() @@ -263,6 +261,32 @@ public class UmaViewerUI : MonoBehaviour,FaceLoadCallBack } } + void ListLiveSounds(int songid) + { + for (int i = LiveCharaSoundList.content.childCount - 1; i >= 0; i--) + { + Destroy(LiveCharaSoundList.content.GetChild(i).gameObject); + } + string nameVar = $"snd_bgm_live_{songid}_chara"; + foreach (var entry in Main.AbList.Where(a => a.Name.Contains(nameVar) && a.Name.EndsWith("awb"))) + { + var container = Instantiate(UmaContainerPrefab, LiveCharaSoundList.content).GetComponent(); + string[] split = entry.Name.Split('_'); + string name = split[split.Length - 2] + getCharaName(split[split.Length - 2]) + " " + split[split.Length - 1].Replace(".awb",""); + container.Name.text = name; + container.Button.onClick.AddListener(() => { + HighlightChildImage(LiveCharaSoundList.content, container.GetComponent()); + Builder.LoadLiveSound(songid, entry); + }); + } + } + + string getCharaName(string id) + { + var entry = Main.Characters.FirstOrDefault(a => a.Id.ToString().Equals(id)); + return (entry == null) ? id.ToString() : entry.Name; + } + public static string GetCostumeName(string costumeId) { switch (costumeId) diff --git a/ProjectSettings/ProjectSettings.asset b/ProjectSettings/ProjectSettings.asset index 4086f3f..37bbbeb 100644 --- a/ProjectSettings/ProjectSettings.asset +++ b/ProjectSettings/ProjectSettings.asset @@ -161,7 +161,6 @@ PlayerSettings: m_ColorGamuts: 00000000 targetPixelDensity: 30 resolutionScalingMode: 0 - resetResolutionOnWindowResize: 0 androidSupportedAspectRatio: 1 androidMaxAspectRatio: 2.1 applicationIdentifier: @@ -514,9 +513,7 @@ PlayerSettings: switchPlayerConnectionEnabled: 1 switchUseNewStyleFilepaths: 0 switchUseMicroSleepForYield: 1 - switchEnableRamDiskSupport: 0 switchMicroSleepForYieldTime: 25 - switchRamDiskSpaceSize: 12 ps4NPAgeRating: 12 ps4NPTitleSecret: ps4NPTrophyPackPath: @@ -631,7 +628,8 @@ PlayerSettings: gcIncremental: 0 assemblyVersionValidation: 1 gcWBarrierValidation: 0 - apiCompatibilityLevelPerPlatform: {} + apiCompatibilityLevelPerPlatform: + Standalone: 6 m_RenderingPath: 1 m_MobileRenderingPath: 1 metroPackageName: Template_3D @@ -661,7 +659,6 @@ PlayerSettings: metroFTAName: metroFTAFileTypes: [] metroProtocolName: - vcxProjDefaultLanguage: XboxOneProductId: XboxOneUpdateKey: XboxOneSandboxId: diff --git a/app.config b/app.config new file mode 100644 index 0000000..d4ff09b --- /dev/null +++ b/app.config @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file