@carbonenginejs/runtime-resource 0.1.0 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/FORMAT-PROVENANCE.md +14 -5
- package/README.md +537 -241
- package/dist/CjsMotherLode.js +1244 -29
- package/dist/CjsMotherLode.js.map +1 -1
- package/dist/CjsResMan.js +2537 -272
- package/dist/CjsResMan.js.map +1 -1
- package/dist/CjsResource.js +218 -18
- package/dist/CjsResource.js.map +1 -1
- package/dist/format/CjsBlueReader.js +269 -0
- package/dist/format/CjsBlueReader.js.map +1 -0
- package/dist/format/CjsFormat.js +44 -30
- package/dist/format/CjsFormat.js.map +1 -1
- package/dist/format/CjsReader.js +18 -0
- package/dist/format/CjsReader.js.map +1 -0
- package/dist/format/CjsResourceProbe.js +12 -4
- package/dist/format/CjsResourceProbe.js.map +1 -1
- package/dist/formats/black/CjsBlackFormat.js +12 -6
- package/dist/formats/black/CjsBlackFormat.js.map +1 -1
- package/dist/formats/black/core/CjsBlackReader.js +27 -148
- package/dist/formats/black/core/CjsBlackReader.js.map +1 -1
- package/dist/formats/bnk/CjsBnkFormat.js +140 -147
- package/dist/formats/bnk/CjsBnkFormat.js.map +1 -1
- package/dist/formats/bnk/core/graph.js +140 -0
- package/dist/formats/bnk/core/graph.js.map +1 -0
- package/dist/formats/bnk/core/helpers.js +58 -3
- package/dist/formats/bnk/core/helpers.js.map +1 -1
- package/dist/formats/bnk/core/musicNodes.js +521 -0
- package/dist/formats/bnk/core/musicNodes.js.map +1 -0
- package/dist/formats/bnk/index.js +0 -1
- package/dist/formats/bnk/index.js.map +1 -1
- package/dist/formats/cmf/CjsCmfFormat.js +14 -8
- package/dist/formats/cmf/CjsCmfFormat.js.map +1 -1
- package/dist/formats/dds/CjsDdsFormat.js +12 -6
- package/dist/formats/dds/CjsDdsFormat.js.map +1 -1
- package/dist/formats/fbx/CjsFbxFormat.js +12 -6
- package/dist/formats/fbx/CjsFbxFormat.js.map +1 -1
- package/dist/formats/flac/CjsFlacFormat.js +10 -4
- package/dist/formats/flac/CjsFlacFormat.js.map +1 -1
- package/dist/formats/gif/CjsGifFormat.js +11 -5
- package/dist/formats/gif/CjsGifFormat.js.map +1 -1
- package/dist/formats/gltf/CjsGltfFormat.js +12 -6
- package/dist/formats/gltf/CjsGltfFormat.js.map +1 -1
- package/dist/formats/jpeg/CjsJpegFormat.js +11 -5
- package/dist/formats/jpeg/CjsJpegFormat.js.map +1 -1
- package/dist/formats/mp3/CjsMp3Format.js +11 -5
- package/dist/formats/mp3/CjsMp3Format.js.map +1 -1
- package/dist/formats/mp4/CjsMp4Format.js +10 -4
- package/dist/formats/mp4/CjsMp4Format.js.map +1 -1
- package/dist/formats/obj/CjsObjFormat.js +12 -6
- package/dist/formats/obj/CjsObjFormat.js.map +1 -1
- package/dist/formats/ogg/CjsOggFormat.js +9 -3
- package/dist/formats/ogg/CjsOggFormat.js.map +1 -1
- package/dist/formats/png/CjsPngFormat.js +11 -5
- package/dist/formats/png/CjsPngFormat.js.map +1 -1
- package/dist/formats/red/CjsRedFormat.js +19 -5
- package/dist/formats/red/CjsRedFormat.js.map +1 -1
- package/dist/formats/red/core/CjsRedReader.js +63 -70
- package/dist/formats/red/core/CjsRedReader.js.map +1 -1
- package/dist/formats/red/core/helpers.js +3 -0
- package/dist/formats/red/core/helpers.js.map +1 -1
- package/dist/formats/stl/CjsStlFormat.js +77 -16
- package/dist/formats/stl/CjsStlFormat.js.map +1 -1
- package/dist/formats/stl/core/helpers.js +4 -0
- package/dist/formats/stl/core/helpers.js.map +1 -1
- package/dist/formats/stl/core/stl.js +100 -15
- package/dist/formats/stl/core/stl.js.map +1 -1
- package/dist/formats/tga/CjsTgaFormat.js +11 -5
- package/dist/formats/tga/CjsTgaFormat.js.map +1 -1
- package/dist/formats/wav/CjsWavFormat.js +11 -5
- package/dist/formats/wav/CjsWavFormat.js.map +1 -1
- package/dist/formats/webm/CjsWebmFormat.js +10 -4
- package/dist/formats/webm/CjsWebmFormat.js.map +1 -1
- package/dist/formats/webp/CjsWebpFormat.js +9 -3
- package/dist/formats/webp/CjsWebpFormat.js.map +1 -1
- package/dist/formats/wem/CjsWemFormat.js +50 -6
- package/dist/formats/wem/CjsWemFormat.js.map +1 -1
- package/dist/formats/wem/core/helpers.js +84 -3
- package/dist/formats/wem/core/helpers.js.map +1 -1
- package/dist/formats/wem/core/ptadpcm.js +77 -0
- package/dist/formats/wem/core/ptadpcm.js.map +1 -0
- package/dist/formats/wem/core/resolve.js +121 -0
- package/dist/formats/wem/core/resolve.js.map +1 -0
- package/dist/formats/yaml/CjsYamlFormat.js +11 -5
- package/dist/formats/yaml/CjsYamlFormat.js.map +1 -1
- package/dist/formats/yaml/core/CjsYamlReader.js +3 -2
- package/dist/formats/yaml/core/CjsYamlReader.js.map +1 -1
- package/dist/index.js +28 -32
- package/dist/index.js.map +1 -1
- package/dist/{generated/resources → resources}/AudioGeometryResData.js +2 -2
- package/dist/resources/AudioGeometryResData.js.map +1 -0
- package/dist/{generated/resources → resources}/GStateBindingCallbackData.js +2 -2
- package/dist/resources/GStateBindingCallbackData.js.map +1 -0
- package/dist/{generated/resources → resources}/MeshDecalData.js +2 -2
- package/dist/resources/MeshDecalData.js.map +1 -0
- package/dist/{generated/resources → resources}/MeshDecalLodData.js +2 -2
- package/dist/resources/MeshDecalLodData.js.map +1 -0
- package/dist/resources/Tr2GrannyIntersectionResult.js +60 -0
- package/dist/resources/Tr2GrannyIntersectionResult.js.map +1 -0
- package/dist/{generated/resources → resources}/Tr2MaterialArea.js +2 -2
- package/dist/resources/Tr2MaterialArea.js.map +1 -0
- package/dist/{generated/resources → resources}/Tr2MaterialMesh.js +2 -2
- package/dist/resources/Tr2MaterialMesh.js.map +1 -0
- package/dist/{generated/resources → resources}/Tr2MaterialRes.js +2 -2
- package/dist/resources/Tr2MaterialRes.js.map +1 -0
- package/dist/{generated/resources → resources}/Tr2ShaderPermutation.js +2 -2
- package/dist/resources/Tr2ShaderPermutation.js.map +1 -0
- package/dist/{generated/resources → resources}/Tr2TextureLodManager.js +50 -10
- package/dist/resources/Tr2TextureLodManager.js.map +1 -0
- package/dist/{generated/resources → resources}/Tr2TextureLodUpdateRequest.js +2 -2
- package/dist/resources/Tr2TextureLodUpdateRequest.js.map +1 -0
- package/dist/{generated/resources → resources}/Tr2TexturePackChannel.js +2 -2
- package/dist/resources/Tr2TexturePackChannel.js.map +1 -0
- package/dist/resources/Tr2TexturePipeline.js +68 -0
- package/dist/resources/Tr2TexturePipeline.js.map +1 -0
- package/dist/{generated/resources → resources}/Tr2TexturePipelineParams.js +2 -2
- package/dist/resources/Tr2TexturePipelineParams.js.map +1 -0
- package/dist/{generated/resources → resources}/Tr2TexturePipelineStepCompress.js +3 -3
- package/dist/resources/Tr2TexturePipelineStepCompress.js.map +1 -0
- package/dist/{generated/resources → resources}/Tr2TexturePipelineStepLimitSize.js +2 -2
- package/dist/resources/Tr2TexturePipelineStepLimitSize.js.map +1 -0
- package/dist/{generated/resources → resources}/Tr2TexturePipelineStepLoad.js +2 -2
- package/dist/resources/Tr2TexturePipelineStepLoad.js.map +1 -0
- package/dist/{generated/resources → resources}/Tr2TexturePipelineStepPack.js +3 -3
- package/dist/resources/Tr2TexturePipelineStepPack.js.map +1 -0
- package/dist/{generated/resources → resources}/TriGeometryResAreaData.js +2 -2
- package/dist/resources/TriGeometryResAreaData.js.map +1 -0
- package/dist/{generated/resources → resources}/TriGeometryResJointData.js +2 -2
- package/dist/resources/TriGeometryResJointData.js.map +1 -0
- package/dist/{generated/resources → resources}/TriGeometryResLodData.js +2 -2
- package/dist/resources/TriGeometryResLodData.js.map +1 -0
- package/dist/{generated/resources → resources}/TriGeometryResMeshData.js +2 -2
- package/dist/resources/TriGeometryResMeshData.js.map +1 -0
- package/dist/{generated/resources → resources}/TriGeometryResSkeletonData.js +2 -2
- package/dist/resources/TriGeometryResSkeletonData.js.map +1 -0
- package/dist/{generated/resources → resources}/TriJointBinding.js +2 -2
- package/dist/resources/TriJointBinding.js.map +1 -0
- package/dist/{generated/resources → resources}/TriMorphTargetGeometryConstants.js +2 -2
- package/dist/resources/TriMorphTargetGeometryConstants.js.map +1 -0
- package/dist/{generated/resources → resources}/TriRtGeometryConstants.js +2 -2
- package/dist/resources/TriRtGeometryConstants.js.map +1 -0
- package/dist/resources/enums.js.map +1 -0
- package/dist/resources/texturePipelineBehavior.js +320 -0
- package/dist/resources/texturePipelineBehavior.js.map +1 -0
- package/format-notices/bnk/NOTICE +7 -4
- package/package.json +51 -51
- package/resource-lifecycle.md +262 -70
- package/dist/generated/resources/AudioGeometryResData.js.map +0 -1
- package/dist/generated/resources/CmfVertexReader.js +0 -46
- package/dist/generated/resources/CmfVertexReader.js.map +0 -1
- package/dist/generated/resources/GStateBindingCallbackData.js.map +0 -1
- package/dist/generated/resources/MeshDecalData.js.map +0 -1
- package/dist/generated/resources/MeshDecalLodData.js.map +0 -1
- package/dist/generated/resources/Tr2AsyncSave.js +0 -46
- package/dist/generated/resources/Tr2AsyncSave.js.map +0 -1
- package/dist/generated/resources/Tr2CmfContents.js +0 -37
- package/dist/generated/resources/Tr2CmfContents.js.map +0 -1
- package/dist/generated/resources/Tr2GrannyIntersectionResult.js +0 -58
- package/dist/generated/resources/Tr2GrannyIntersectionResult.js.map +0 -1
- package/dist/generated/resources/Tr2LoadPrepareFence.js +0 -37
- package/dist/generated/resources/Tr2LoadPrepareFence.js.map +0 -1
- package/dist/generated/resources/Tr2MaterialArea.js.map +0 -1
- package/dist/generated/resources/Tr2MaterialMesh.js.map +0 -1
- package/dist/generated/resources/Tr2MaterialRes.js.map +0 -1
- package/dist/generated/resources/Tr2ShaderPermutation.js.map +0 -1
- package/dist/generated/resources/Tr2TextureLodManager.js.map +0 -1
- package/dist/generated/resources/Tr2TextureLodUpdateRequest.js.map +0 -1
- package/dist/generated/resources/Tr2TexturePackChannel.js.map +0 -1
- package/dist/generated/resources/Tr2TexturePipeline.js +0 -44
- package/dist/generated/resources/Tr2TexturePipeline.js.map +0 -1
- package/dist/generated/resources/Tr2TexturePipelineParams.js.map +0 -1
- package/dist/generated/resources/Tr2TexturePipelineStepCompress.js.map +0 -1
- package/dist/generated/resources/Tr2TexturePipelineStepLimitSize.js.map +0 -1
- package/dist/generated/resources/Tr2TexturePipelineStepLoad.js.map +0 -1
- package/dist/generated/resources/Tr2TexturePipelineStepPack.js.map +0 -1
- package/dist/generated/resources/TriGeometryResAreaData.js.map +0 -1
- package/dist/generated/resources/TriGeometryResJointData.js.map +0 -1
- package/dist/generated/resources/TriGeometryResLodData.js.map +0 -1
- package/dist/generated/resources/TriGeometryResMeshData.js.map +0 -1
- package/dist/generated/resources/TriGeometryResSkeletonData.js.map +0 -1
- package/dist/generated/resources/TriJointBinding.js.map +0 -1
- package/dist/generated/resources/TriMorphTargetGeometryConstants.js.map +0 -1
- package/dist/generated/resources/TriRtGeometryConstants.js.map +0 -1
- package/dist/generated/resources/enums.js.map +0 -1
- package/dist/generated/resources/index.js +0 -32
- package/dist/generated/resources/index.js.map +0 -1
- /package/dist/{generated/resources → resources}/enums.js +0 -0
|
@@ -1,153 +1,157 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { DEFAULT_VALUES, normalizeValues, readWithValues, inspectWithValues, isSupportedWithValues, toJsonValue, toBytes, extractMedia, isBNK,
|
|
1
|
+
import { wwiseIdFromName, joinSoundbanksInfo, buildSoundbanksCatalog, parseSoundbanksInfo, isSoundbanksInfo } from './core/soundbanksInfo.js';
|
|
2
|
+
import { DEFAULT_VALUES, normalizeValues, readWithValues, inspectWithValues, isSupportedWithValues, toJsonValue, toBytes, extractMedia, isBNK, OUTPUT_MEDIA, OUTPUT_BNK_JSON, OUTPUT_JSON, OUTPUT_RAW, HIRC_TYPE_NAMES } from './core/helpers.js';
|
|
3
|
+
import { eventMediaFromBanks } from './core/graph.js';
|
|
4
|
+
import { parseMusicSwitch, parseMusicPlaylist, parseMusicTrack, parseMusicSegment, musicNodesFromBanks } from './core/musicNodes.js';
|
|
3
5
|
|
|
4
6
|
const FORMAT_NAME = "CjsBnkFormat";
|
|
5
7
|
|
|
6
|
-
/**
|
|
7
|
-
* Reader for Audiokinetic Wwise soundbank (.bnk) containers.
|
|
8
|
-
*
|
|
9
|
-
* Inspection decodes the bank header, embedded media index, object hierarchy
|
|
10
|
-
* listing, and referenced bank names
|
|
11
|
-
* the raw bank, debug JSON, or the
|
|
12
|
-
*
|
|
8
|
+
/**
|
|
9
|
+
* Reader for Audiokinetic Wwise soundbank (.bnk) containers.
|
|
10
|
+
*
|
|
11
|
+
* Inspection decodes the bank header, embedded media index, object hierarchy
|
|
12
|
+
* listing (with version-stable typed fields), and referenced bank names
|
|
13
|
+
* without copying payloads. Read can emit the raw bank, debug JSON, or the
|
|
14
|
+
* embedded media items undecoded. The read path stays a pure container
|
|
15
|
+
* reader; the Wwise-domain toolkit (SoundbanksInfo catalog helpers, id hash,
|
|
16
|
+
* event -> media graph resolution) is grouped under the `wwise` static.
|
|
13
17
|
*/
|
|
14
18
|
class CjsBnkFormat {
|
|
15
19
|
#values = DEFAULT_VALUES;
|
|
16
20
|
|
|
17
|
-
/**
|
|
18
|
-
* Create a reusable bnk format profile.
|
|
19
|
-
*
|
|
20
|
-
* @param {object} [options] Default read/inspect options.
|
|
21
|
+
/**
|
|
22
|
+
* Create a reusable bnk format profile.
|
|
23
|
+
*
|
|
24
|
+
* @param {object} [options] Default read/inspect options.
|
|
21
25
|
*/
|
|
22
26
|
constructor(options = {}) {
|
|
23
27
|
this.SetValues(options);
|
|
24
28
|
}
|
|
25
29
|
|
|
26
|
-
/**
|
|
27
|
-
* Merge options into this profile.
|
|
28
|
-
*
|
|
29
|
-
* @param {object} [options] Values to merge.
|
|
30
|
-
* @returns {CjsBnkFormat} This format profile.
|
|
30
|
+
/**
|
|
31
|
+
* Merge options into this profile.
|
|
32
|
+
*
|
|
33
|
+
* @param {object} [options] Values to merge.
|
|
34
|
+
* @returns {CjsBnkFormat} This format profile.
|
|
31
35
|
*/
|
|
32
36
|
SetValues(options = {}) {
|
|
33
37
|
this.#values = normalizeValues(this.#values, options, FORMAT_NAME);
|
|
34
38
|
return this;
|
|
35
39
|
}
|
|
36
40
|
|
|
37
|
-
/**
|
|
38
|
-
* Get normalized profile values with optional per-call overrides.
|
|
39
|
-
*
|
|
40
|
-
* @param {object} [options] Per-call values.
|
|
41
|
-
* @returns {object} Normalized read values.
|
|
41
|
+
/**
|
|
42
|
+
* Get normalized profile values with optional per-call overrides.
|
|
43
|
+
*
|
|
44
|
+
* @param {object} [options] Per-call values.
|
|
45
|
+
* @returns {object} Normalized read values.
|
|
42
46
|
*/
|
|
43
47
|
GetValues(options = {}) {
|
|
44
48
|
return normalizeValues(this.#values, options, FORMAT_NAME);
|
|
45
49
|
}
|
|
46
50
|
|
|
47
|
-
/**
|
|
48
|
-
* Read soundbank bytes with this profile.
|
|
49
|
-
*
|
|
50
|
-
* @param {Uint8Array|ArrayBuffer|DataView} input Soundbank bytes.
|
|
51
|
-
* @param {object} [options] Per-call values.
|
|
52
|
-
* @returns {object} GPU-free raw/debug/media payload for the selected emit target.
|
|
51
|
+
/**
|
|
52
|
+
* Read soundbank bytes with this profile.
|
|
53
|
+
*
|
|
54
|
+
* @param {Uint8Array|ArrayBuffer|DataView} input Soundbank bytes.
|
|
55
|
+
* @param {object} [options] Per-call values.
|
|
56
|
+
* @returns {object} GPU-free raw/debug/media payload for the selected emit target.
|
|
53
57
|
*/
|
|
54
58
|
Read(input, options = {}) {
|
|
55
59
|
return readWithValues(input, this.GetValues(options));
|
|
56
60
|
}
|
|
57
61
|
|
|
58
|
-
/**
|
|
59
|
-
* Read soundbank bytes asynchronously with this profile.
|
|
60
|
-
*
|
|
61
|
-
* @param {Uint8Array|ArrayBuffer|DataView} input Soundbank bytes.
|
|
62
|
-
* @param {object} [options] Per-call values.
|
|
63
|
-
* @returns {Promise<object>} GPU-free raw/debug/media payload for the selected emit target.
|
|
62
|
+
/**
|
|
63
|
+
* Read soundbank bytes asynchronously with this profile.
|
|
64
|
+
*
|
|
65
|
+
* @param {Uint8Array|ArrayBuffer|DataView} input Soundbank bytes.
|
|
66
|
+
* @param {object} [options] Per-call values.
|
|
67
|
+
* @returns {Promise<object>} GPU-free raw/debug/media payload for the selected emit target.
|
|
64
68
|
*/
|
|
65
69
|
async ReadAsync(input, options = {}) {
|
|
66
70
|
return this.Read(input, options);
|
|
67
71
|
}
|
|
68
72
|
|
|
69
|
-
/**
|
|
70
|
-
* Inspect soundbank bytes without copying media payloads.
|
|
71
|
-
*
|
|
72
|
-
* @param {Uint8Array|ArrayBuffer|DataView} input Soundbank bytes.
|
|
73
|
-
* @param {object} [options] Per-call values.
|
|
74
|
-
* @returns {object} Soundbank metadata.
|
|
73
|
+
/**
|
|
74
|
+
* Inspect soundbank bytes without copying media payloads.
|
|
75
|
+
*
|
|
76
|
+
* @param {Uint8Array|ArrayBuffer|DataView} input Soundbank bytes.
|
|
77
|
+
* @param {object} [options] Per-call values.
|
|
78
|
+
* @returns {object} Soundbank metadata.
|
|
75
79
|
*/
|
|
76
80
|
Inspect(input, options = {}) {
|
|
77
81
|
return inspectWithValues(input, this.GetValues(options));
|
|
78
82
|
}
|
|
79
83
|
|
|
80
|
-
/**
|
|
81
|
-
* Report whether soundbank input and requested output variants are supported.
|
|
82
|
-
*
|
|
83
|
-
* @param {Uint8Array|ArrayBuffer|DataView} input Soundbank bytes.
|
|
84
|
-
* @param {object} [options] Per-call values.
|
|
85
|
-
* @returns {object} Support/probe report.
|
|
84
|
+
/**
|
|
85
|
+
* Report whether soundbank input and requested output variants are supported.
|
|
86
|
+
*
|
|
87
|
+
* @param {Uint8Array|ArrayBuffer|DataView} input Soundbank bytes.
|
|
88
|
+
* @param {object} [options] Per-call values.
|
|
89
|
+
* @returns {object} Support/probe report.
|
|
86
90
|
*/
|
|
87
91
|
IsSupported(input, options = {}) {
|
|
88
92
|
return isSupportedWithValues(input, this.GetValues(options));
|
|
89
93
|
}
|
|
90
94
|
|
|
91
|
-
/**
|
|
92
|
-
* Convert format output into JSON-compatible debug data.
|
|
93
|
-
*
|
|
94
|
-
* @param {any} value Format output.
|
|
95
|
-
* @returns {any} JSON-compatible value.
|
|
95
|
+
/**
|
|
96
|
+
* Convert format output into JSON-compatible debug data.
|
|
97
|
+
*
|
|
98
|
+
* @param {any} value Format output.
|
|
99
|
+
* @returns {any} JSON-compatible value.
|
|
96
100
|
*/
|
|
97
101
|
ToJSON(value) {
|
|
98
102
|
return toJsonValue(value);
|
|
99
103
|
}
|
|
100
104
|
|
|
101
|
-
/**
|
|
102
|
-
* One-shot soundbank read.
|
|
103
|
-
*
|
|
104
|
-
* @param {Uint8Array|ArrayBuffer|DataView} input Soundbank bytes.
|
|
105
|
-
* @param {object} [options] Read options.
|
|
106
|
-
* @returns {object} GPU-free raw/debug/media payload for the selected emit target.
|
|
105
|
+
/**
|
|
106
|
+
* One-shot soundbank read.
|
|
107
|
+
*
|
|
108
|
+
* @param {Uint8Array|ArrayBuffer|DataView} input Soundbank bytes.
|
|
109
|
+
* @param {object} [options] Read options.
|
|
110
|
+
* @returns {object} GPU-free raw/debug/media payload for the selected emit target.
|
|
107
111
|
*/
|
|
108
112
|
static read(input, options = {}) {
|
|
109
113
|
return readWithValues(input, normalizeValues(DEFAULT_VALUES, options, FORMAT_NAME));
|
|
110
114
|
}
|
|
111
115
|
|
|
112
|
-
/**
|
|
113
|
-
* One-shot asynchronous soundbank read.
|
|
114
|
-
*
|
|
115
|
-
* @param {Uint8Array|ArrayBuffer|DataView} input Soundbank bytes.
|
|
116
|
-
* @param {object} [options] Read options.
|
|
117
|
-
* @returns {Promise<object>} GPU-free raw/debug/media payload for the selected emit target.
|
|
116
|
+
/**
|
|
117
|
+
* One-shot asynchronous soundbank read.
|
|
118
|
+
*
|
|
119
|
+
* @param {Uint8Array|ArrayBuffer|DataView} input Soundbank bytes.
|
|
120
|
+
* @param {object} [options] Read options.
|
|
121
|
+
* @returns {Promise<object>} GPU-free raw/debug/media payload for the selected emit target.
|
|
118
122
|
*/
|
|
119
123
|
static async readAsync(input, options = {}) {
|
|
120
124
|
return CjsBnkFormat.read(input, options);
|
|
121
125
|
}
|
|
122
126
|
|
|
123
|
-
/**
|
|
124
|
-
* One-shot soundbank inspection.
|
|
125
|
-
*
|
|
126
|
-
* @param {Uint8Array|ArrayBuffer|DataView} input Soundbank bytes.
|
|
127
|
-
* @param {object} [options] Inspect options.
|
|
128
|
-
* @returns {object} Soundbank metadata.
|
|
127
|
+
/**
|
|
128
|
+
* One-shot soundbank inspection.
|
|
129
|
+
*
|
|
130
|
+
* @param {Uint8Array|ArrayBuffer|DataView} input Soundbank bytes.
|
|
131
|
+
* @param {object} [options] Inspect options.
|
|
132
|
+
* @returns {object} Soundbank metadata.
|
|
129
133
|
*/
|
|
130
134
|
static inspect(input, options = {}) {
|
|
131
135
|
return inspectWithValues(input, normalizeValues(DEFAULT_VALUES, options, FORMAT_NAME));
|
|
132
136
|
}
|
|
133
137
|
|
|
134
|
-
/**
|
|
135
|
-
* One-shot soundbank support probe.
|
|
136
|
-
*
|
|
137
|
-
* @param {Uint8Array|ArrayBuffer|DataView} input Soundbank bytes.
|
|
138
|
-
* @param {object} [options] Probe options.
|
|
139
|
-
* @returns {object} Support/probe report.
|
|
138
|
+
/**
|
|
139
|
+
* One-shot soundbank support probe.
|
|
140
|
+
*
|
|
141
|
+
* @param {Uint8Array|ArrayBuffer|DataView} input Soundbank bytes.
|
|
142
|
+
* @param {object} [options] Probe options.
|
|
143
|
+
* @returns {object} Support/probe report.
|
|
140
144
|
*/
|
|
141
145
|
static isSupported(input, options = {}) {
|
|
142
146
|
return isSupportedWithValues(input, normalizeValues(DEFAULT_VALUES, options, FORMAT_NAME));
|
|
143
147
|
}
|
|
144
148
|
|
|
145
|
-
/**
|
|
146
|
-
* Extract embedded media payloads as views over the soundbank bytes.
|
|
147
|
-
*
|
|
148
|
-
* @param {Uint8Array|ArrayBuffer|DataView} input Soundbank bytes.
|
|
149
|
-
* @param {number} [mediaId] Optional single media id filter.
|
|
150
|
-
* @returns {Array<object>} Extracted media items with undecoded bytes.
|
|
149
|
+
/**
|
|
150
|
+
* Extract embedded media payloads as views over the soundbank bytes.
|
|
151
|
+
*
|
|
152
|
+
* @param {Uint8Array|ArrayBuffer|DataView} input Soundbank bytes.
|
|
153
|
+
* @param {number} [mediaId] Optional single media id filter.
|
|
154
|
+
* @returns {Array<object>} Extracted media items with undecoded bytes.
|
|
151
155
|
*/
|
|
152
156
|
static extractMedia(input, mediaId) {
|
|
153
157
|
const bytes = toBytes(input);
|
|
@@ -155,72 +159,21 @@ class CjsBnkFormat {
|
|
|
155
159
|
return extractMedia(bytes, metadata, mediaId);
|
|
156
160
|
}
|
|
157
161
|
|
|
158
|
-
/**
|
|
159
|
-
* Convert format output into JSON-compatible debug data.
|
|
160
|
-
*
|
|
161
|
-
* @param {any} value Format output.
|
|
162
|
-
* @returns {any} JSON-compatible value.
|
|
162
|
+
/**
|
|
163
|
+
* Convert format output into JSON-compatible debug data.
|
|
164
|
+
*
|
|
165
|
+
* @param {any} value Format output.
|
|
166
|
+
* @returns {any} JSON-compatible value.
|
|
163
167
|
*/
|
|
164
168
|
static toJSON(value) {
|
|
165
169
|
return toJsonValue(value);
|
|
166
170
|
}
|
|
167
171
|
|
|
168
|
-
/**
|
|
169
|
-
* Test whether
|
|
170
|
-
*
|
|
171
|
-
* @param {Uint8Array|ArrayBuffer|DataView
|
|
172
|
-
* @returns {boolean} True when
|
|
173
|
-
*/
|
|
174
|
-
static isSoundbanksInfo(input) {
|
|
175
|
-
return isSoundbanksInfo(input);
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
/**
|
|
179
|
-
* Parse a SoundbanksInfo document into a normalized summary.
|
|
180
|
-
*
|
|
181
|
-
* @param {Uint8Array|ArrayBuffer|DataView|string|object} input SoundbanksInfo JSON bytes, text, or object.
|
|
182
|
-
* @returns {object} Normalized document summary with per-bank details.
|
|
183
|
-
*/
|
|
184
|
-
static parseSoundbanksInfo(input) {
|
|
185
|
-
return parseSoundbanksInfo(input);
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
/**
|
|
189
|
-
* Build id-keyed lookup tables from a SoundbanksInfo document.
|
|
190
|
-
*
|
|
191
|
-
* @param {Uint8Array|ArrayBuffer|DataView|string|object} input SoundbanksInfo JSON bytes, text, or object.
|
|
192
|
-
* @returns {object} Catalog with banksById, mediaById, eventsById, and eventsByName.
|
|
193
|
-
*/
|
|
194
|
-
static buildSoundbanksCatalog(input) {
|
|
195
|
-
return buildSoundbanksCatalog(input);
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
/**
|
|
199
|
-
* Join a bank inspection result with a SoundbanksInfo catalog.
|
|
200
|
-
*
|
|
201
|
-
* @param {object} bankInfo Inspect output for a soundbank.
|
|
202
|
-
* @param {object} catalog `buildSoundbanksCatalog` output.
|
|
203
|
-
* @returns {object} Bank/media/event annotations for the inspected bank.
|
|
204
|
-
*/
|
|
205
|
-
static joinSoundbanksInfo(bankInfo, catalog) {
|
|
206
|
-
return joinSoundbanksInfo(bankInfo, catalog);
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
/**
|
|
210
|
-
* Compute the Wwise 32-bit id for a bank, event, switch, or language name.
|
|
211
|
-
*
|
|
212
|
-
* @param {string} name Wwise object name.
|
|
213
|
-
* @returns {number} Unsigned 32-bit Wwise id (FNV-1 of the lowercased name).
|
|
214
|
-
*/
|
|
215
|
-
static wwiseIdFromName(name) {
|
|
216
|
-
return wwiseIdFromName(name);
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
/**
|
|
220
|
-
* Test whether bytes look like a Wwise soundbank.
|
|
221
|
-
*
|
|
222
|
-
* @param {Uint8Array|ArrayBuffer|DataView} input Candidate soundbank bytes.
|
|
223
|
-
* @returns {boolean} True when the BKHD header chunk is present.
|
|
172
|
+
/**
|
|
173
|
+
* Test whether bytes look like a Wwise soundbank.
|
|
174
|
+
*
|
|
175
|
+
* @param {Uint8Array|ArrayBuffer|DataView} input Candidate soundbank bytes.
|
|
176
|
+
* @returns {boolean} True when the BKHD header chunk is present.
|
|
224
177
|
*/
|
|
225
178
|
static isBNK(input) {
|
|
226
179
|
try {
|
|
@@ -229,10 +182,50 @@ class CjsBnkFormat {
|
|
|
229
182
|
return false;
|
|
230
183
|
}
|
|
231
184
|
}
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* Wwise-domain toolkit, grouped apart from the container-reading statics -
|
|
188
|
+
* the single home for the SoundbanksInfo catalog helpers
|
|
189
|
+
* (`isSoundbanksInfo`, `parseSoundbanksInfo`, `buildSoundbanksCatalog`,
|
|
190
|
+
* `joinSoundbanksInfo`), the id hash (`wwiseIdFromName`, FNV-1 of the
|
|
191
|
+
* lowercased name), and event-graph resolution.
|
|
192
|
+
*
|
|
193
|
+
* `eventMediaFromBanks(inspections, options)` is graph interpretation over
|
|
194
|
+
* `inspect()` results, not a read path: banks may split events from their
|
|
195
|
+
* target objects (EVE keeps all events in one bank and their sounds in
|
|
196
|
+
* others), so always pass every related bank to one call. Returns
|
|
197
|
+
* `{ eventMedia: Map<eventObjectId, Set<wemId>>, diagnostics }`. See
|
|
198
|
+
* core/graph.js for the walk policy.
|
|
199
|
+
*
|
|
200
|
+
* The interactive-music decoders (`musicNodesFromBanks` and the per-type
|
|
201
|
+
* `parseMusicSegment/Track/Playlist/Switch`) turn the music-hierarchy
|
|
202
|
+
* entries (HIRC 10-13) into typed nodes - children, meter, cue markers,
|
|
203
|
+
* clips, playlist trees, decision trees, and transition rules. See
|
|
204
|
+
* core/musicNodes.js for the anchored, exact-end-validated parse.
|
|
205
|
+
*/
|
|
206
|
+
static wwise = Object.freeze({
|
|
207
|
+
isSoundbanksInfo,
|
|
208
|
+
parseSoundbanksInfo,
|
|
209
|
+
buildSoundbanksCatalog,
|
|
210
|
+
joinSoundbanksInfo,
|
|
211
|
+
wwiseIdFromName,
|
|
212
|
+
eventMediaFromBanks,
|
|
213
|
+
musicNodesFromBanks,
|
|
214
|
+
parseMusicSegment,
|
|
215
|
+
parseMusicTrack,
|
|
216
|
+
parseMusicPlaylist,
|
|
217
|
+
parseMusicSwitch
|
|
218
|
+
});
|
|
219
|
+
|
|
220
|
+
/**
|
|
221
|
+
* Emit targets for this format (canonical frozen enum).
|
|
222
|
+
*/
|
|
223
|
+
static Output = Object.freeze({
|
|
224
|
+
RAW: OUTPUT_RAW,
|
|
225
|
+
JSON: OUTPUT_JSON,
|
|
226
|
+
BNK_JSON: OUTPUT_BNK_JSON,
|
|
227
|
+
MEDIA: OUTPUT_MEDIA
|
|
228
|
+
});
|
|
236
229
|
static HIRC_TYPE_NAMES = HIRC_TYPE_NAMES;
|
|
237
230
|
static type = Object.freeze(["audio"]);
|
|
238
231
|
static mediaTypes = Object.freeze(["audio"]);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CjsBnkFormat.js","sources":["../../../../src/formats/bnk/CjsBnkFormat.js"],"sourcesContent":["import {\n buildSoundbanksCatalog,\n isSoundbanksInfo,\n joinSoundbanksInfo,\n parseSoundbanksInfo,\n wwiseIdFromName\n} from \"./core/soundbanksInfo.js\";\nimport {\n DEFAULT_VALUES,\n HIRC_TYPE_NAMES,\n OUTPUT_BNK_JSON,\n OUTPUT_JSON,\n OUTPUT_MEDIA,\n OUTPUT_RAW,\n extractMedia,\n inspectWithValues,\n isBNK,\n isSupportedWithValues,\n normalizeValues,\n readWithValues,\n toBytes,\n toJsonValue\n} from \"./core/helpers.js\";\n\nconst FORMAT_NAME = \"CjsBnkFormat\";\n\n/**\n * Reader for Audiokinetic Wwise soundbank (.bnk) containers.\n *\n * Inspection decodes the bank header, embedded media index, object hierarchy\n * listing, and referenced bank names without copying payloads. Read can emit\n * the raw bank, debug JSON, or the embedded media items undecoded; Wwise\n * event/graph semantics are deliberately out of scope for this reader.\n */\nexport class CjsBnkFormat\n{\n #values = DEFAULT_VALUES;\n\n /**\n * Create a reusable bnk format profile.\n *\n * @param {object} [options] Default read/inspect options.\n */\n constructor(options = {})\n {\n this.SetValues(options);\n }\n\n /**\n * Merge options into this profile.\n *\n * @param {object} [options] Values to merge.\n * @returns {CjsBnkFormat} This format profile.\n */\n SetValues(options = {})\n {\n this.#values = normalizeValues(this.#values, options, FORMAT_NAME);\n return this;\n }\n\n /**\n * Get normalized profile values with optional per-call overrides.\n *\n * @param {object} [options] Per-call values.\n * @returns {object} Normalized read values.\n */\n GetValues(options = {})\n {\n return normalizeValues(this.#values, options, FORMAT_NAME);\n }\n\n /**\n * Read soundbank bytes with this profile.\n *\n * @param {Uint8Array|ArrayBuffer|DataView} input Soundbank bytes.\n * @param {object} [options] Per-call values.\n * @returns {object} GPU-free raw/debug/media payload for the selected emit target.\n */\n Read(input, options = {})\n {\n return readWithValues(input, this.GetValues(options));\n }\n\n /**\n * Read soundbank bytes asynchronously with this profile.\n *\n * @param {Uint8Array|ArrayBuffer|DataView} input Soundbank bytes.\n * @param {object} [options] Per-call values.\n * @returns {Promise<object>} GPU-free raw/debug/media payload for the selected emit target.\n */\n async ReadAsync(input, options = {})\n {\n return this.Read(input, options);\n }\n\n /**\n * Inspect soundbank bytes without copying media payloads.\n *\n * @param {Uint8Array|ArrayBuffer|DataView} input Soundbank bytes.\n * @param {object} [options] Per-call values.\n * @returns {object} Soundbank metadata.\n */\n Inspect(input, options = {})\n {\n return inspectWithValues(input, this.GetValues(options));\n }\n\n /**\n * Report whether soundbank input and requested output variants are supported.\n *\n * @param {Uint8Array|ArrayBuffer|DataView} input Soundbank bytes.\n * @param {object} [options] Per-call values.\n * @returns {object} Support/probe report.\n */\n IsSupported(input, options = {})\n {\n return isSupportedWithValues(input, this.GetValues(options));\n }\n\n /**\n * Convert format output into JSON-compatible debug data.\n *\n * @param {any} value Format output.\n * @returns {any} JSON-compatible value.\n */\n ToJSON(value)\n {\n return toJsonValue(value);\n }\n\n /**\n * One-shot soundbank read.\n *\n * @param {Uint8Array|ArrayBuffer|DataView} input Soundbank bytes.\n * @param {object} [options] Read options.\n * @returns {object} GPU-free raw/debug/media payload for the selected emit target.\n */\n static read(input, options = {})\n {\n return readWithValues(input, normalizeValues(DEFAULT_VALUES, options, FORMAT_NAME));\n }\n\n /**\n * One-shot asynchronous soundbank read.\n *\n * @param {Uint8Array|ArrayBuffer|DataView} input Soundbank bytes.\n * @param {object} [options] Read options.\n * @returns {Promise<object>} GPU-free raw/debug/media payload for the selected emit target.\n */\n static async readAsync(input, options = {})\n {\n return CjsBnkFormat.read(input, options);\n }\n\n /**\n * One-shot soundbank inspection.\n *\n * @param {Uint8Array|ArrayBuffer|DataView} input Soundbank bytes.\n * @param {object} [options] Inspect options.\n * @returns {object} Soundbank metadata.\n */\n static inspect(input, options = {})\n {\n return inspectWithValues(input, normalizeValues(DEFAULT_VALUES, options, FORMAT_NAME));\n }\n\n /**\n * One-shot soundbank support probe.\n *\n * @param {Uint8Array|ArrayBuffer|DataView} input Soundbank bytes.\n * @param {object} [options] Probe options.\n * @returns {object} Support/probe report.\n */\n static isSupported(input, options = {})\n {\n return isSupportedWithValues(input, normalizeValues(DEFAULT_VALUES, options, FORMAT_NAME));\n }\n\n /**\n * Extract embedded media payloads as views over the soundbank bytes.\n *\n * @param {Uint8Array|ArrayBuffer|DataView} input Soundbank bytes.\n * @param {number} [mediaId] Optional single media id filter.\n * @returns {Array<object>} Extracted media items with undecoded bytes.\n */\n static extractMedia(input, mediaId)\n {\n const bytes = toBytes(input);\n const metadata = inspectWithValues(bytes, DEFAULT_VALUES);\n return extractMedia(bytes, metadata, mediaId);\n }\n\n /**\n * Convert format output into JSON-compatible debug data.\n *\n * @param {any} value Format output.\n * @returns {any} JSON-compatible value.\n */\n static toJSON(value)\n {\n return toJsonValue(value);\n }\n\n /**\n * Test whether input looks like a Wwise SoundbanksInfo document.\n *\n * @param {Uint8Array|ArrayBuffer|DataView|string|object} input Candidate document.\n * @returns {boolean} True when a SoundBanksInfo bank list is present.\n */\n static isSoundbanksInfo(input)\n {\n return isSoundbanksInfo(input);\n }\n\n /**\n * Parse a SoundbanksInfo document into a normalized summary.\n *\n * @param {Uint8Array|ArrayBuffer|DataView|string|object} input SoundbanksInfo JSON bytes, text, or object.\n * @returns {object} Normalized document summary with per-bank details.\n */\n static parseSoundbanksInfo(input)\n {\n return parseSoundbanksInfo(input);\n }\n\n /**\n * Build id-keyed lookup tables from a SoundbanksInfo document.\n *\n * @param {Uint8Array|ArrayBuffer|DataView|string|object} input SoundbanksInfo JSON bytes, text, or object.\n * @returns {object} Catalog with banksById, mediaById, eventsById, and eventsByName.\n */\n static buildSoundbanksCatalog(input)\n {\n return buildSoundbanksCatalog(input);\n }\n\n /**\n * Join a bank inspection result with a SoundbanksInfo catalog.\n *\n * @param {object} bankInfo Inspect output for a soundbank.\n * @param {object} catalog `buildSoundbanksCatalog` output.\n * @returns {object} Bank/media/event annotations for the inspected bank.\n */\n static joinSoundbanksInfo(bankInfo, catalog)\n {\n return joinSoundbanksInfo(bankInfo, catalog);\n }\n\n /**\n * Compute the Wwise 32-bit id for a bank, event, switch, or language name.\n *\n * @param {string} name Wwise object name.\n * @returns {number} Unsigned 32-bit Wwise id (FNV-1 of the lowercased name).\n */\n static wwiseIdFromName(name)\n {\n return wwiseIdFromName(name);\n }\n\n /**\n * Test whether bytes look like a Wwise soundbank.\n *\n * @param {Uint8Array|ArrayBuffer|DataView} input Candidate soundbank bytes.\n * @returns {boolean} True when the BKHD header chunk is present.\n */\n static isBNK(input)\n {\n try\n {\n return isBNK(toBytes(input));\n }\n catch\n {\n return false;\n }\n }\n\n static OUTPUT_RAW = OUTPUT_RAW;\n static OUTPUT_JSON = OUTPUT_JSON;\n static OUTPUT_BNK_JSON = OUTPUT_BNK_JSON;\n static OUTPUT_MEDIA = OUTPUT_MEDIA;\n static HIRC_TYPE_NAMES = HIRC_TYPE_NAMES;\n static type = Object.freeze([ \"audio\" ]);\n static mediaTypes = Object.freeze([ \"audio\" ]);\n static inputTypes = Object.freeze([ \"bnk\" ]);\n static outputTypes = Object.freeze([ OUTPUT_RAW, OUTPUT_MEDIA ]);\n static debugOutputTypes = Object.freeze([ OUTPUT_BNK_JSON, OUTPUT_RAW ]);\n}\n\nexport default CjsBnkFormat;\n"],"names":["FORMAT_NAME","CjsBnkFormat","DEFAULT_VALUES","constructor","options","SetValues","normalizeValues","GetValues","Read","input","readWithValues","ReadAsync","Inspect","inspectWithValues","IsSupported","isSupportedWithValues","ToJSON","value","toJsonValue","read","readAsync","inspect","isSupported","extractMedia","mediaId","bytes","toBytes","metadata","toJSON","isSoundbanksInfo","parseSoundbanksInfo","buildSoundbanksCatalog","joinSoundbanksInfo","bankInfo","catalog","wwiseIdFromName","name","isBNK","OUTPUT_RAW","OUTPUT_JSON","OUTPUT_BNK_JSON","OUTPUT_MEDIA","HIRC_TYPE_NAMES","type","Object","freeze","mediaTypes","inputTypes","outputTypes","debugOutputTypes"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"CjsBnkFormat.js","sources":["../../../../src/formats/bnk/CjsBnkFormat.js"],"sourcesContent":["import {\r\n buildSoundbanksCatalog,\r\n isSoundbanksInfo,\r\n joinSoundbanksInfo,\r\n parseSoundbanksInfo,\r\n wwiseIdFromName\r\n} from \"./core/soundbanksInfo.js\";\r\nimport {\r\n DEFAULT_VALUES,\r\n HIRC_TYPE_NAMES,\r\n OUTPUT_BNK_JSON,\r\n OUTPUT_JSON,\r\n OUTPUT_MEDIA,\r\n OUTPUT_RAW,\r\n extractMedia,\r\n inspectWithValues,\r\n isBNK,\r\n isSupportedWithValues,\r\n normalizeValues,\r\n readWithValues,\r\n toBytes,\r\n toJsonValue\r\n} from \"./core/helpers.js\";\r\nimport { eventMediaFromBanks } from \"./core/graph.js\";\r\nimport {\r\n musicNodesFromBanks,\r\n parseMusicPlaylist,\r\n parseMusicSegment,\r\n parseMusicSwitch,\r\n parseMusicTrack\r\n} from \"./core/musicNodes.js\";\r\n\r\nconst FORMAT_NAME = \"CjsBnkFormat\";\r\n\r\n/**\r\n * Reader for Audiokinetic Wwise soundbank (.bnk) containers.\r\n *\r\n * Inspection decodes the bank header, embedded media index, object hierarchy\r\n * listing (with version-stable typed fields), and referenced bank names\r\n * without copying payloads. Read can emit the raw bank, debug JSON, or the\r\n * embedded media items undecoded. The read path stays a pure container\r\n * reader; the Wwise-domain toolkit (SoundbanksInfo catalog helpers, id hash,\r\n * event -> media graph resolution) is grouped under the `wwise` static.\r\n */\r\nexport class CjsBnkFormat\r\n{\r\n #values = DEFAULT_VALUES;\r\n\r\n /**\r\n * Create a reusable bnk format profile.\r\n *\r\n * @param {object} [options] Default read/inspect options.\r\n */\r\n constructor(options = {})\r\n {\r\n this.SetValues(options);\r\n }\r\n\r\n /**\r\n * Merge options into this profile.\r\n *\r\n * @param {object} [options] Values to merge.\r\n * @returns {CjsBnkFormat} This format profile.\r\n */\r\n SetValues(options = {})\r\n {\r\n this.#values = normalizeValues(this.#values, options, FORMAT_NAME);\r\n return this;\r\n }\r\n\r\n /**\r\n * Get normalized profile values with optional per-call overrides.\r\n *\r\n * @param {object} [options] Per-call values.\r\n * @returns {object} Normalized read values.\r\n */\r\n GetValues(options = {})\r\n {\r\n return normalizeValues(this.#values, options, FORMAT_NAME);\r\n }\r\n\r\n /**\r\n * Read soundbank bytes with this profile.\r\n *\r\n * @param {Uint8Array|ArrayBuffer|DataView} input Soundbank bytes.\r\n * @param {object} [options] Per-call values.\r\n * @returns {object} GPU-free raw/debug/media payload for the selected emit target.\r\n */\r\n Read(input, options = {})\r\n {\r\n return readWithValues(input, this.GetValues(options));\r\n }\r\n\r\n /**\r\n * Read soundbank bytes asynchronously with this profile.\r\n *\r\n * @param {Uint8Array|ArrayBuffer|DataView} input Soundbank bytes.\r\n * @param {object} [options] Per-call values.\r\n * @returns {Promise<object>} GPU-free raw/debug/media payload for the selected emit target.\r\n */\r\n async ReadAsync(input, options = {})\r\n {\r\n return this.Read(input, options);\r\n }\r\n\r\n /**\r\n * Inspect soundbank bytes without copying media payloads.\r\n *\r\n * @param {Uint8Array|ArrayBuffer|DataView} input Soundbank bytes.\r\n * @param {object} [options] Per-call values.\r\n * @returns {object} Soundbank metadata.\r\n */\r\n Inspect(input, options = {})\r\n {\r\n return inspectWithValues(input, this.GetValues(options));\r\n }\r\n\r\n /**\r\n * Report whether soundbank input and requested output variants are supported.\r\n *\r\n * @param {Uint8Array|ArrayBuffer|DataView} input Soundbank bytes.\r\n * @param {object} [options] Per-call values.\r\n * @returns {object} Support/probe report.\r\n */\r\n IsSupported(input, options = {})\r\n {\r\n return isSupportedWithValues(input, this.GetValues(options));\r\n }\r\n\r\n /**\r\n * Convert format output into JSON-compatible debug data.\r\n *\r\n * @param {any} value Format output.\r\n * @returns {any} JSON-compatible value.\r\n */\r\n ToJSON(value)\r\n {\r\n return toJsonValue(value);\r\n }\r\n\r\n /**\r\n * One-shot soundbank read.\r\n *\r\n * @param {Uint8Array|ArrayBuffer|DataView} input Soundbank bytes.\r\n * @param {object} [options] Read options.\r\n * @returns {object} GPU-free raw/debug/media payload for the selected emit target.\r\n */\r\n static read(input, options = {})\r\n {\r\n return readWithValues(input, normalizeValues(DEFAULT_VALUES, options, FORMAT_NAME));\r\n }\r\n\r\n /**\r\n * One-shot asynchronous soundbank read.\r\n *\r\n * @param {Uint8Array|ArrayBuffer|DataView} input Soundbank bytes.\r\n * @param {object} [options] Read options.\r\n * @returns {Promise<object>} GPU-free raw/debug/media payload for the selected emit target.\r\n */\r\n static async readAsync(input, options = {})\r\n {\r\n return CjsBnkFormat.read(input, options);\r\n }\r\n\r\n /**\r\n * One-shot soundbank inspection.\r\n *\r\n * @param {Uint8Array|ArrayBuffer|DataView} input Soundbank bytes.\r\n * @param {object} [options] Inspect options.\r\n * @returns {object} Soundbank metadata.\r\n */\r\n static inspect(input, options = {})\r\n {\r\n return inspectWithValues(input, normalizeValues(DEFAULT_VALUES, options, FORMAT_NAME));\r\n }\r\n\r\n /**\r\n * One-shot soundbank support probe.\r\n *\r\n * @param {Uint8Array|ArrayBuffer|DataView} input Soundbank bytes.\r\n * @param {object} [options] Probe options.\r\n * @returns {object} Support/probe report.\r\n */\r\n static isSupported(input, options = {})\r\n {\r\n return isSupportedWithValues(input, normalizeValues(DEFAULT_VALUES, options, FORMAT_NAME));\r\n }\r\n\r\n /**\r\n * Extract embedded media payloads as views over the soundbank bytes.\r\n *\r\n * @param {Uint8Array|ArrayBuffer|DataView} input Soundbank bytes.\r\n * @param {number} [mediaId] Optional single media id filter.\r\n * @returns {Array<object>} Extracted media items with undecoded bytes.\r\n */\r\n static extractMedia(input, mediaId)\r\n {\r\n const bytes = toBytes(input);\r\n const metadata = inspectWithValues(bytes, DEFAULT_VALUES);\r\n return extractMedia(bytes, metadata, mediaId);\r\n }\r\n\r\n /**\r\n * Convert format output into JSON-compatible debug data.\r\n *\r\n * @param {any} value Format output.\r\n * @returns {any} JSON-compatible value.\r\n */\r\n static toJSON(value)\r\n {\r\n return toJsonValue(value);\r\n }\r\n\r\n /**\r\n * Test whether bytes look like a Wwise soundbank.\r\n *\r\n * @param {Uint8Array|ArrayBuffer|DataView} input Candidate soundbank bytes.\r\n * @returns {boolean} True when the BKHD header chunk is present.\r\n */\r\n static isBNK(input)\r\n {\r\n try\r\n {\r\n return isBNK(toBytes(input));\r\n }\r\n catch\r\n {\r\n return false;\r\n }\r\n }\r\n\r\n /**\r\n * Wwise-domain toolkit, grouped apart from the container-reading statics -\r\n * the single home for the SoundbanksInfo catalog helpers\r\n * (`isSoundbanksInfo`, `parseSoundbanksInfo`, `buildSoundbanksCatalog`,\r\n * `joinSoundbanksInfo`), the id hash (`wwiseIdFromName`, FNV-1 of the\r\n * lowercased name), and event-graph resolution.\r\n *\r\n * `eventMediaFromBanks(inspections, options)` is graph interpretation over\r\n * `inspect()` results, not a read path: banks may split events from their\r\n * target objects (EVE keeps all events in one bank and their sounds in\r\n * others), so always pass every related bank to one call. Returns\r\n * `{ eventMedia: Map<eventObjectId, Set<wemId>>, diagnostics }`. See\r\n * core/graph.js for the walk policy.\r\n *\r\n * The interactive-music decoders (`musicNodesFromBanks` and the per-type\r\n * `parseMusicSegment/Track/Playlist/Switch`) turn the music-hierarchy\r\n * entries (HIRC 10-13) into typed nodes - children, meter, cue markers,\r\n * clips, playlist trees, decision trees, and transition rules. See\r\n * core/musicNodes.js for the anchored, exact-end-validated parse.\r\n */\r\n static wwise = Object.freeze({\r\n isSoundbanksInfo,\r\n parseSoundbanksInfo,\r\n buildSoundbanksCatalog,\r\n joinSoundbanksInfo,\r\n wwiseIdFromName,\r\n eventMediaFromBanks,\r\n musicNodesFromBanks,\r\n parseMusicSegment,\r\n parseMusicTrack,\r\n parseMusicPlaylist,\r\n parseMusicSwitch\r\n });\r\n\r\n /**\r\n * Emit targets for this format (canonical frozen enum).\r\n */\r\n static Output = Object.freeze({\r\n RAW: OUTPUT_RAW,\r\n JSON: OUTPUT_JSON,\r\n BNK_JSON: OUTPUT_BNK_JSON,\r\n MEDIA: OUTPUT_MEDIA\r\n });\r\n\r\n static HIRC_TYPE_NAMES = HIRC_TYPE_NAMES;\r\n\r\n static type = Object.freeze([ \"audio\" ]);\r\n\r\n static mediaTypes = Object.freeze([ \"audio\" ]);\r\n\r\n static inputTypes = Object.freeze([ \"bnk\" ]);\r\n\r\n static outputTypes = Object.freeze([ OUTPUT_RAW, OUTPUT_MEDIA ]);\r\n\r\n static debugOutputTypes = Object.freeze([ OUTPUT_BNK_JSON, OUTPUT_RAW ]);\r\n}\r\n\r\nexport default CjsBnkFormat;\r\n"],"names":["FORMAT_NAME","CjsBnkFormat","DEFAULT_VALUES","constructor","options","SetValues","normalizeValues","GetValues","Read","input","readWithValues","ReadAsync","Inspect","inspectWithValues","IsSupported","isSupportedWithValues","ToJSON","value","toJsonValue","read","readAsync","inspect","isSupported","extractMedia","mediaId","bytes","toBytes","metadata","toJSON","isBNK","wwise","Object","freeze","isSoundbanksInfo","parseSoundbanksInfo","buildSoundbanksCatalog","joinSoundbanksInfo","wwiseIdFromName","eventMediaFromBanks","musicNodesFromBanks","parseMusicSegment","parseMusicTrack","parseMusicPlaylist","parseMusicSwitch","Output","RAW","OUTPUT_RAW","JSON","OUTPUT_JSON","BNK_JSON","OUTPUT_BNK_JSON","MEDIA","OUTPUT_MEDIA","HIRC_TYPE_NAMES","type","mediaTypes","inputTypes","outputTypes","debugOutputTypes"],"mappings":";;;;;AAgCA,MAAMA,WAAW,GAAG,cAAc;;AAElC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,MAAMC,YAAY,CACzB;EACI,OAAO,GAAGC,cAAc;;AAExB;AACJ;AACA;AACA;AACA;AACIC,EAAAA,WAAWA,CAACC,OAAO,GAAG,EAAE,EACxB;AACI,IAAA,IAAI,CAACC,SAAS,CAACD,OAAO,CAAC;AAC3B,EAAA;;AAEA;AACJ;AACA;AACA;AACA;AACA;AACIC,EAAAA,SAASA,CAACD,OAAO,GAAG,EAAE,EACtB;AACI,IAAA,IAAI,CAAC,OAAO,GAAGE,eAAe,CAAC,IAAI,CAAC,OAAO,EAAEF,OAAO,EAAEJ,WAAW,CAAC;AAClE,IAAA,OAAO,IAAI;AACf,EAAA;;AAEA;AACJ;AACA;AACA;AACA;AACA;AACIO,EAAAA,SAASA,CAACH,OAAO,GAAG,EAAE,EACtB;IACI,OAAOE,eAAe,CAAC,IAAI,CAAC,OAAO,EAAEF,OAAO,EAAEJ,WAAW,CAAC;AAC9D,EAAA;;AAEA;AACJ;AACA;AACA;AACA;AACA;AACA;AACIQ,EAAAA,IAAIA,CAACC,KAAK,EAAEL,OAAO,GAAG,EAAE,EACxB;IACI,OAAOM,cAAc,CAACD,KAAK,EAAE,IAAI,CAACF,SAAS,CAACH,OAAO,CAAC,CAAC;AACzD,EAAA;;AAEA;AACJ;AACA;AACA;AACA;AACA;AACA;EACI,MAAMO,SAASA,CAACF,KAAK,EAAEL,OAAO,GAAG,EAAE,EACnC;AACI,IAAA,OAAO,IAAI,CAACI,IAAI,CAACC,KAAK,EAAEL,OAAO,CAAC;AACpC,EAAA;;AAEA;AACJ;AACA;AACA;AACA;AACA;AACA;AACIQ,EAAAA,OAAOA,CAACH,KAAK,EAAEL,OAAO,GAAG,EAAE,EAC3B;IACI,OAAOS,iBAAiB,CAACJ,KAAK,EAAE,IAAI,CAACF,SAAS,CAACH,OAAO,CAAC,CAAC;AAC5D,EAAA;;AAEA;AACJ;AACA;AACA;AACA;AACA;AACA;AACIU,EAAAA,WAAWA,CAACL,KAAK,EAAEL,OAAO,GAAG,EAAE,EAC/B;IACI,OAAOW,qBAAqB,CAACN,KAAK,EAAE,IAAI,CAACF,SAAS,CAACH,OAAO,CAAC,CAAC;AAChE,EAAA;;AAEA;AACJ;AACA;AACA;AACA;AACA;EACIY,MAAMA,CAACC,KAAK,EACZ;IACI,OAAOC,WAAW,CAACD,KAAK,CAAC;AAC7B,EAAA;;AAEA;AACJ;AACA;AACA;AACA;AACA;AACA;EACI,OAAOE,IAAIA,CAACV,KAAK,EAAEL,OAAO,GAAG,EAAE,EAC/B;AACI,IAAA,OAAOM,cAAc,CAACD,KAAK,EAAEH,eAAe,CAACJ,cAAc,EAAEE,OAAO,EAAEJ,WAAW,CAAC,CAAC;AACvF,EAAA;;AAEA;AACJ;AACA;AACA;AACA;AACA;AACA;EACI,aAAaoB,SAASA,CAACX,KAAK,EAAEL,OAAO,GAAG,EAAE,EAC1C;AACI,IAAA,OAAOH,YAAY,CAACkB,IAAI,CAACV,KAAK,EAAEL,OAAO,CAAC;AAC5C,EAAA;;AAEA;AACJ;AACA;AACA;AACA;AACA;AACA;EACI,OAAOiB,OAAOA,CAACZ,KAAK,EAAEL,OAAO,GAAG,EAAE,EAClC;AACI,IAAA,OAAOS,iBAAiB,CAACJ,KAAK,EAAEH,eAAe,CAACJ,cAAc,EAAEE,OAAO,EAAEJ,WAAW,CAAC,CAAC;AAC1F,EAAA;;AAEA;AACJ;AACA;AACA;AACA;AACA;AACA;EACI,OAAOsB,WAAWA,CAACb,KAAK,EAAEL,OAAO,GAAG,EAAE,EACtC;AACI,IAAA,OAAOW,qBAAqB,CAACN,KAAK,EAAEH,eAAe,CAACJ,cAAc,EAAEE,OAAO,EAAEJ,WAAW,CAAC,CAAC;AAC9F,EAAA;;AAEA;AACJ;AACA;AACA;AACA;AACA;AACA;AACI,EAAA,OAAOuB,YAAYA,CAACd,KAAK,EAAEe,OAAO,EAClC;AACI,IAAA,MAAMC,KAAK,GAAGC,OAAO,CAACjB,KAAK,CAAC;AAC5B,IAAA,MAAMkB,QAAQ,GAAGd,iBAAiB,CAACY,KAAK,EAAEvB,cAAc,CAAC;AACzD,IAAA,OAAOqB,YAAY,CAACE,KAAK,EAAEE,QAAQ,EAAEH,OAAO,CAAC;AACjD,EAAA;;AAEA;AACJ;AACA;AACA;AACA;AACA;EACI,OAAOI,MAAMA,CAACX,KAAK,EACnB;IACI,OAAOC,WAAW,CAACD,KAAK,CAAC;AAC7B,EAAA;;AAEA;AACJ;AACA;AACA;AACA;AACA;EACI,OAAOY,KAAKA,CAACpB,KAAK,EAClB;IACI,IACA;AACI,MAAA,OAAOoB,KAAK,CAACH,OAAO,CAACjB,KAAK,CAAC,CAAC;AAChC,IAAA,CAAC,CACD,MACA;AACI,MAAA,OAAO,KAAK;AAChB,IAAA;AACJ,EAAA;;AAEA;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACI,EAAA,OAAOqB,KAAK,GAAGC,MAAM,CAACC,MAAM,CAAC;IACzBC,gBAAgB;IAChBC,mBAAmB;IACnBC,sBAAsB;IACtBC,kBAAkB;IAClBC,eAAe;IACfC,mBAAmB;IACnBC,mBAAmB;IACnBC,iBAAiB;IACjBC,eAAe;IACfC,kBAAkB;AAClBC,IAAAA;AACJ,GAAC,CAAC;;AAEF;AACJ;AACA;AACI,EAAA,OAAOC,MAAM,GAAGb,MAAM,CAACC,MAAM,CAAC;AAC1Ba,IAAAA,GAAG,EAAEC,UAAU;AACfC,IAAAA,IAAI,EAAEC,WAAW;AACjBC,IAAAA,QAAQ,EAAEC,eAAe;AACzBC,IAAAA,KAAK,EAAEC;AACX,GAAC,CAAC;EAEF,OAAOC,eAAe,GAAGA,eAAe;EAExC,OAAOC,IAAI,GAAGvB,MAAM,CAACC,MAAM,CAAC,CAAE,OAAO,CAAE,CAAC;EAExC,OAAOuB,UAAU,GAAGxB,MAAM,CAACC,MAAM,CAAC,CAAE,OAAO,CAAE,CAAC;EAE9C,OAAOwB,UAAU,GAAGzB,MAAM,CAACC,MAAM,CAAC,CAAE,KAAK,CAAE,CAAC;EAE5C,OAAOyB,WAAW,GAAG1B,MAAM,CAACC,MAAM,CAAC,CAAEc,UAAU,EAAEM,YAAY,CAAE,CAAC;EAEhE,OAAOM,gBAAgB,GAAG3B,MAAM,CAACC,MAAM,CAAC,CAAEkB,eAAe,EAAEJ,UAAU,CAAE,CAAC;AAC5E;;;;"}
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
// Wwise soundbank object-graph interpretation: event -> media resolution over
|
|
2
|
+
// one or more inspected banks. Exposed as `CjsBnkFormat.eventMediaFromBanks`.
|
|
3
|
+
// This is NOT part of the format read path and is never used by the resource
|
|
4
|
+
// lifecycle - it exists so consumers can go from `inspect()` output to "what
|
|
5
|
+
// does event X play?" without writing their own graph walk.
|
|
6
|
+
//
|
|
7
|
+
// Inputs are plain inspect() results (formats/bnk): the typed HIRC fields
|
|
8
|
+
// (event actionIds, action actionType/targetId, sound/track sourceIds) plus
|
|
9
|
+
// per-object raw payload views for the structures that stay undecoded
|
|
10
|
+
// (container children, positioning, RTPC data).
|
|
11
|
+
//
|
|
12
|
+
// Verified against EVE soundbanks (bank generator version 150 / Wwise 2022.1):
|
|
13
|
+
// - Banks may split responsibilities: EVE keeps every event/action in one
|
|
14
|
+
// bank (common.bnk) and the sounds/containers they target in the media
|
|
15
|
+
// banks, so edges only resolve over the MERGED graph - always pass every
|
|
16
|
+
// related bank to one call.
|
|
17
|
+
// - Walk policy: only play-family actions (actionType high byte 0x04) are
|
|
18
|
+
// followed; sounds and music tracks are terminals (their typed sourceIds
|
|
19
|
+
// are the media); actor-mixers and buses are never entered, because node
|
|
20
|
+
// payloads carry parent/bus back-pointers that would otherwise drag every
|
|
21
|
+
// sibling sound into the result.
|
|
22
|
+
// - Container children lists are undecoded, so references are recovered with
|
|
23
|
+
// a validated id-scan: a u32 at ANY byte offset of a container payload
|
|
24
|
+
// counts only when it matches a traversable object id or a known wem id.
|
|
25
|
+
// Wwise ids are 32-bit hashes, making in-bank collisions vanishingly rare.
|
|
26
|
+
|
|
27
|
+
const HIRC_SOUND = 2;
|
|
28
|
+
const HIRC_ACTION = 3;
|
|
29
|
+
const HIRC_EVENT = 4;
|
|
30
|
+
const HIRC_MUSIC_TRACK = 11;
|
|
31
|
+
|
|
32
|
+
// Types the walk may traverse INTO from a play action or container:
|
|
33
|
+
// sound (2), random-sequence (5), switch (6), blend/layer (9),
|
|
34
|
+
// music segment/track/switch/playlist (10-13).
|
|
35
|
+
const TRAVERSABLE_TYPES = new Set([2, 5, 6, 9, 10, 11, 12, 13]);
|
|
36
|
+
|
|
37
|
+
// Media-bearing terminals: typed sourceIds are collected, no traversal out.
|
|
38
|
+
const TERMINAL_TYPES = new Set([HIRC_SOUND, HIRC_MUSIC_TRACK]);
|
|
39
|
+
|
|
40
|
+
// actionType high byte for the play family (for example 0x0403 = play; the
|
|
41
|
+
// low byte is scope). Stop is 0x01xx, pause 0x02xx, resume 0x03xx.
|
|
42
|
+
const PLAY_ACTION_FAMILY = 0x0400;
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Resolve event -> wem media edges over one or more inspected soundbanks.
|
|
46
|
+
*
|
|
47
|
+
* @param {Array<object>} inspections `CjsBnkFormat.inspect()` results for every related bank.
|
|
48
|
+
* @param {object} [options] Optional settings.
|
|
49
|
+
* @param {Iterable<number|string>} [options.knownWemIds] Streamed wem ids to validate media references against; every bank's embedded media ids are always included.
|
|
50
|
+
* @returns {{eventMedia: Map<number, Set<number>>, diagnostics: object}} Event object id -> wem id set, plus walk diagnostics.
|
|
51
|
+
*/
|
|
52
|
+
function eventMediaFromBanks(inspections, {
|
|
53
|
+
knownWemIds = []
|
|
54
|
+
} = {}) {
|
|
55
|
+
const objects = new Map();
|
|
56
|
+
const diagnostics = {
|
|
57
|
+
objectCount: 0,
|
|
58
|
+
eventCount: 0
|
|
59
|
+
};
|
|
60
|
+
for (const inspection of inspections) {
|
|
61
|
+
for (const entry of inspection.hirc || []) {
|
|
62
|
+
objects.set(entry.id, entry);
|
|
63
|
+
diagnostics.objectCount++;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
const wemIdSet = new Set();
|
|
67
|
+
for (const id of knownWemIds) wemIdSet.add(Number(id) >>> 0);
|
|
68
|
+
for (const inspection of inspections) {
|
|
69
|
+
for (const record of inspection.media || []) wemIdSet.add(record.id);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// Validated id-scan over a container payload, cached per object id -
|
|
73
|
+
// containers are shared between many events.
|
|
74
|
+
const scanCache = new Map();
|
|
75
|
+
const scanObject = entry => {
|
|
76
|
+
let cached = scanCache.get(entry.id);
|
|
77
|
+
if (cached) return cached;
|
|
78
|
+
const nodeRefs = new Set();
|
|
79
|
+
const mediaRefs = new Set();
|
|
80
|
+
cached = {
|
|
81
|
+
nodeRefs,
|
|
82
|
+
mediaRefs
|
|
83
|
+
};
|
|
84
|
+
scanCache.set(entry.id, cached);
|
|
85
|
+
const body = entry.payload;
|
|
86
|
+
if (!body) return cached;
|
|
87
|
+
for (let at = 0; at + 4 <= body.byteLength; at++) {
|
|
88
|
+
const value = (body[at] | body[at + 1] << 8 | body[at + 2] << 16 | body[at + 3] * 0x1000000) >>> 0;
|
|
89
|
+
if (value === entry.id) continue;
|
|
90
|
+
if (wemIdSet.has(value)) mediaRefs.add(value);
|
|
91
|
+
const target = objects.get(value);
|
|
92
|
+
if (target && TRAVERSABLE_TYPES.has(target.type)) nodeRefs.add(value);
|
|
93
|
+
}
|
|
94
|
+
return cached;
|
|
95
|
+
};
|
|
96
|
+
const eventMedia = new Map();
|
|
97
|
+
for (const entry of objects.values()) {
|
|
98
|
+
if (entry.type !== HIRC_EVENT) continue;
|
|
99
|
+
diagnostics.eventCount++;
|
|
100
|
+
const media = new Set();
|
|
101
|
+
const visited = new Set();
|
|
102
|
+
const stack = [];
|
|
103
|
+
for (const actionId of entry.actionIds || []) {
|
|
104
|
+
const action = objects.get(actionId);
|
|
105
|
+
if (!action || action.type !== HIRC_ACTION) continue;
|
|
106
|
+
if (((action.actionType ?? 0) & 0xff00) !== PLAY_ACTION_FAMILY) continue;
|
|
107
|
+
const target = objects.get(action.targetId);
|
|
108
|
+
if (target && TRAVERSABLE_TYPES.has(target.type)) stack.push(target.id);
|
|
109
|
+
}
|
|
110
|
+
while (stack.length) {
|
|
111
|
+
const node = objects.get(stack.pop());
|
|
112
|
+
if (!node || visited.has(node.id)) continue;
|
|
113
|
+
visited.add(node.id);
|
|
114
|
+
const {
|
|
115
|
+
nodeRefs,
|
|
116
|
+
mediaRefs
|
|
117
|
+
} = scanObject(node);
|
|
118
|
+
for (const wemId of mediaRefs) media.add(wemId);
|
|
119
|
+
if (node.type === HIRC_SOUND && node.sourceId !== undefined && wemIdSet.has(node.sourceId)) {
|
|
120
|
+
media.add(node.sourceId);
|
|
121
|
+
}
|
|
122
|
+
if (node.type === HIRC_MUSIC_TRACK) {
|
|
123
|
+
for (const source of node.sources || []) {
|
|
124
|
+
if (wemIdSet.has(source.sourceId)) media.add(source.sourceId);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
if (!TERMINAL_TYPES.has(node.type)) {
|
|
128
|
+
for (const next of nodeRefs) stack.push(next);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
if (media.size) eventMedia.set(entry.id, media);
|
|
132
|
+
}
|
|
133
|
+
return {
|
|
134
|
+
eventMedia,
|
|
135
|
+
diagnostics
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
export { eventMediaFromBanks };
|
|
140
|
+
//# sourceMappingURL=graph.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"graph.js","sources":["../../../../../src/formats/bnk/core/graph.js"],"sourcesContent":["// Wwise soundbank object-graph interpretation: event -> media resolution over\n// one or more inspected banks. Exposed as `CjsBnkFormat.eventMediaFromBanks`.\n// This is NOT part of the format read path and is never used by the resource\n// lifecycle - it exists so consumers can go from `inspect()` output to \"what\n// does event X play?\" without writing their own graph walk.\n//\n// Inputs are plain inspect() results (formats/bnk): the typed HIRC fields\n// (event actionIds, action actionType/targetId, sound/track sourceIds) plus\n// per-object raw payload views for the structures that stay undecoded\n// (container children, positioning, RTPC data).\n//\n// Verified against EVE soundbanks (bank generator version 150 / Wwise 2022.1):\n// - Banks may split responsibilities: EVE keeps every event/action in one\n// bank (common.bnk) and the sounds/containers they target in the media\n// banks, so edges only resolve over the MERGED graph - always pass every\n// related bank to one call.\n// - Walk policy: only play-family actions (actionType high byte 0x04) are\n// followed; sounds and music tracks are terminals (their typed sourceIds\n// are the media); actor-mixers and buses are never entered, because node\n// payloads carry parent/bus back-pointers that would otherwise drag every\n// sibling sound into the result.\n// - Container children lists are undecoded, so references are recovered with\n// a validated id-scan: a u32 at ANY byte offset of a container payload\n// counts only when it matches a traversable object id or a known wem id.\n// Wwise ids are 32-bit hashes, making in-bank collisions vanishingly rare.\n\nconst HIRC_SOUND = 2;\nconst HIRC_ACTION = 3;\nconst HIRC_EVENT = 4;\nconst HIRC_MUSIC_TRACK = 11;\n\n// Types the walk may traverse INTO from a play action or container:\n// sound (2), random-sequence (5), switch (6), blend/layer (9),\n// music segment/track/switch/playlist (10-13).\nconst TRAVERSABLE_TYPES = new Set([ 2, 5, 6, 9, 10, 11, 12, 13 ]);\n\n// Media-bearing terminals: typed sourceIds are collected, no traversal out.\nconst TERMINAL_TYPES = new Set([ HIRC_SOUND, HIRC_MUSIC_TRACK ]);\n\n// actionType high byte for the play family (for example 0x0403 = play; the\n// low byte is scope). Stop is 0x01xx, pause 0x02xx, resume 0x03xx.\nconst PLAY_ACTION_FAMILY = 0x0400;\n\n/**\n * Resolve event -> wem media edges over one or more inspected soundbanks.\n *\n * @param {Array<object>} inspections `CjsBnkFormat.inspect()` results for every related bank.\n * @param {object} [options] Optional settings.\n * @param {Iterable<number|string>} [options.knownWemIds] Streamed wem ids to validate media references against; every bank's embedded media ids are always included.\n * @returns {{eventMedia: Map<number, Set<number>>, diagnostics: object}} Event object id -> wem id set, plus walk diagnostics.\n */\nexport function eventMediaFromBanks(inspections, { knownWemIds = [] } = {})\n{\n const objects = new Map();\n const diagnostics = { objectCount: 0, eventCount: 0 };\n\n for (const inspection of inspections)\n {\n for (const entry of inspection.hirc || [])\n {\n objects.set(entry.id, entry);\n diagnostics.objectCount++;\n }\n }\n\n const wemIdSet = new Set();\n for (const id of knownWemIds) wemIdSet.add(Number(id) >>> 0);\n for (const inspection of inspections)\n {\n for (const record of inspection.media || []) wemIdSet.add(record.id);\n }\n\n // Validated id-scan over a container payload, cached per object id -\n // containers are shared between many events.\n const scanCache = new Map();\n const scanObject = (entry) =>\n {\n let cached = scanCache.get(entry.id);\n if (cached) return cached;\n const nodeRefs = new Set();\n const mediaRefs = new Set();\n cached = { nodeRefs, mediaRefs };\n scanCache.set(entry.id, cached);\n const body = entry.payload;\n if (!body) return cached;\n for (let at = 0; at + 4 <= body.byteLength; at++)\n {\n const value = (body[at] | (body[at + 1] << 8) | (body[at + 2] << 16) | (body[at + 3] * 0x1000000)) >>> 0;\n if (value === entry.id) continue;\n if (wemIdSet.has(value)) mediaRefs.add(value);\n const target = objects.get(value);\n if (target && TRAVERSABLE_TYPES.has(target.type)) nodeRefs.add(value);\n }\n return cached;\n };\n\n const eventMedia = new Map();\n for (const entry of objects.values())\n {\n if (entry.type !== HIRC_EVENT) continue;\n diagnostics.eventCount++;\n const media = new Set();\n const visited = new Set();\n const stack = [];\n\n for (const actionId of entry.actionIds || [])\n {\n const action = objects.get(actionId);\n if (!action || action.type !== HIRC_ACTION) continue;\n if (((action.actionType ?? 0) & 0xff00) !== PLAY_ACTION_FAMILY) continue;\n const target = objects.get(action.targetId);\n if (target && TRAVERSABLE_TYPES.has(target.type)) stack.push(target.id);\n }\n\n while (stack.length)\n {\n const node = objects.get(stack.pop());\n if (!node || visited.has(node.id)) continue;\n visited.add(node.id);\n\n const { nodeRefs, mediaRefs } = scanObject(node);\n for (const wemId of mediaRefs) media.add(wemId);\n if (node.type === HIRC_SOUND && node.sourceId !== undefined && wemIdSet.has(node.sourceId))\n {\n media.add(node.sourceId);\n }\n if (node.type === HIRC_MUSIC_TRACK)\n {\n for (const source of node.sources || [])\n {\n if (wemIdSet.has(source.sourceId)) media.add(source.sourceId);\n }\n }\n if (!TERMINAL_TYPES.has(node.type))\n {\n for (const next of nodeRefs) stack.push(next);\n }\n }\n\n if (media.size) eventMedia.set(entry.id, media);\n }\n\n return { eventMedia, diagnostics };\n}\n"],"names":["HIRC_SOUND","HIRC_ACTION","HIRC_EVENT","HIRC_MUSIC_TRACK","TRAVERSABLE_TYPES","Set","TERMINAL_TYPES","PLAY_ACTION_FAMILY","eventMediaFromBanks","inspections","knownWemIds","objects","Map","diagnostics","objectCount","eventCount","inspection","entry","hirc","set","id","wemIdSet","add","Number","record","media","scanCache","scanObject","cached","get","nodeRefs","mediaRefs","body","payload","at","byteLength","value","has","target","type","eventMedia","values","visited","stack","actionId","actionIds","action","actionType","targetId","push","length","node","pop","wemId","sourceId","undefined","source","sources","next","size"],"mappings":"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"}
|