ACB Audio Injection
In this tutorial you will learn the basics of injecting audio (HCA, ADX) into CRIWARE's ACB files. Helps to cut down the size of mods by not shipping the entire ACB+AWB.
The tutorial will be using cri_utf_tool
from KwasTools for ACB conversion to and from XML.
Additional software will be required, such as the HCA audio converter and a text editor. I will be using VGAudioCli and Notepad++.
I also recommend installing foobar2000 with vgmstream component for easy preview of audio. Will also help with pinpointing file indices in AWB archive.
For this tutorial, I will be replacing Cyber Space 1-1 music in Sonic Frontiers.
Converting the ACB to XML
Converting the ACB
is as easy as drag and dropping it on the cri_utf_tool
executable.
If conversion was successful, it'll create an XML file in the same directory as the ACB
. For me it created bgm_cyber.acb.xml
.

Creating an internal AWB file
Some ACB
s do not have an internal AWB
file, which is required to store audio we want to use. This is the case with bgm_cyber
, it lacks one and we need to create it.
The XML structure of AWB
file is the same as one from cri_awb_tool
. However, I will include a minimal example for Sonic Frontiers below to keep things straightforward.
<AWB version="2" offset_size="4" id_size="2" alignment="32" subkey="0">
<entry id="0" path="audio.hca"/>
</AWB>
Keep in mind that parameters need to match the external AWB's. Game will crash otherwise.
Inserting the internal AWB structure
Search for <record value="" name="AwbFile"/>
and you should find this:
<record value="" name="AutoModulationTable"/>
<record value="" name="StreamAwbTocWorkOld"/>
<record value="" name="AwbFile"/>
<record value=" ACB Format/PC Ver.1.37.0 Build: " name="VersionString"/>
<record value="" name="CueLimitWorkTable"/>
We need to replace the AwbFile
record with our own AWB
structure.
After changes you should get something like this:
<record value="" name="AutoModulationTable"/>
<record value="" name="StreamAwbTocWorkOld"/>
<AWB version="2" offset_size="4" id_size="2" alignment="32" subkey="0">
<entry id="0" path="my_audio.hca"/>
<entry id="1" path="my_audio_boost.hca"/>
</AWB>
<record value=" ACB Format/PC Ver.1.37.0 Build: " name="VersionString"/>
<record value="" name="CueLimitWorkTable"/>
ID starts at 0 and goes up. Paths are relative to XML's location.
Modifying Waveform data
Next, we need to change data in the Waveform
table for each track we want to replace.
In short, we have to change the MemoryAwbId
and Streaming
values.
Explanation of parameters
MemoryAwbId
is the index in the internal AWB
file. In our case, index 0
is the main track and index 1
is the boost version.
Streaming is more interesting, it has three available options:
Value | Description |
---|---|
0 | Audio is streamed from internal AWB file, which resides in RAM
|
1 | Audio is streamed from external AWB file
|
2 | Short snippet of audio in internal AWB file to initialize the decoder, rest of the audio is streamed from external AWB file
|
What we're looking for is the value of 0
- streaming from internal AWB
.
Getting AWB IDs we want to replace
Cyber Space 1-1 stage name is w6d01
. Opening bgm_cyber.awb
in foobar2000 reveals that first two tracks are what we're looking for. However, foobar2000 lists all item indexes starting from 1
, so we need to subtract 1
from desired index.

bgm_cyber.awb
playing in foobar2000, with Cyber Space 1-1 audio tracks selected.So our IDs are 0
for main track and 1
for boost. With that we can finally proceed.
Modifying the parameters
Quick and easy way of finding a correct Waveform is searching for a string <record value="0" name="StreamAwbId"/>
, where value
is the external AWB
track ID.
<row>
<record value="65535" name="MemoryAwbId"/>
<record value="2" name="EncodeType"/>
<record value="1" name="Streaming"/>
<record value="2" name="NumChannels"/>
<record value="2" name="LoopFlag"/>
<record value="48000" name="SamplingRate"/>
<record value="4999086" name="NumSamples"/>
<record value="8" name="ExtensionData"/>
<record value="0" name="StreamAwbPortNo"/>
<record value="0" name="StreamAwbId"/>
<record value="65535" name="LipMorthIndex"/>
</row>
Waveform data for track 0
. After modifications (that is, changing MemoryAwbId
and Streaming
value) we get the following:
<row>
<record value="0" name="MemoryAwbId"/>
<record value="2" name="EncodeType"/>
<record value="0" name="Streaming"/>
<record value="2" name="NumChannels"/>
<record value="2" name="LoopFlag"/>
<record value="48000" name="SamplingRate"/>
<record value="4999086" name="NumSamples"/>
<record value="8" name="ExtensionData"/>
<record value="0" name="StreamAwbPortNo"/>
<record value="0" name="StreamAwbId"/>
<record value="65535" name="LipMorthIndex"/>
</row>
After repeating the process for the boost track, we can now finally convert back to ACB
and check results ingame.
Converting the XML to ACB
Same as before, drag and drop the XML on the cri_utf_tool
. It should output a big ACB
file that's ready to be copied into a mod.
Created ACB
is playable in foobar2000 and will only show audio files we injected into it.

ACB
playing in foobar2000