Skip to content
View in the app

A better way to browse. Learn more.

ResHax

A full-screen app on your home screen with push notifications, badges and more.

To install this app on iOS and iPadOS
  1. Tap the Share icon in Safari
  2. Scroll the menu and tap Add to Home Screen.
  3. Tap Add in the top-right corner.
To install this app on Android
  1. Tap the 3-dot menu (⋮) in the top-right corner of the browser.
  2. Tap Add to Home screen or Install app.
  3. Confirm by tapping Install.
Help us keep the site running.

Reverse Engineering Metal Gear Solid 2 Audio Formats (.SDT & .SDX)

Featured Replies

PS-ADPCM fully documented, AMWX/XWMA investigation ongoing

Context

This write-up documents the reverse engineering of the .sdt and .sdx audio formats used by Metal Gear Solid 2: Sons of Liberty – Master Collection (PC).

The original goal was to build tools capable of replacing in-game dialogue, music and sound effects while preserving complete compatibility with the original file formats. Achieving this required understanding the binary layouts, audio codecs, and engine constraints imposed by both formats.

The resulting implementation is available as MGS2 SDT Tool, an open-source (MIT) project written in Python/PyQt6.

Repository: romerojopro-web/SDT-Tool-for-MGS2MCBetterAudioMod


1. Two completely different formats behind the .sdt extension

The first—and probably most important—discovery is that two incompatible formats share the .sdt extension.

Vanilla Steam / Master Collection

  • Konami AMWX container.

  • Audio appears to be stored as WMAv2/XWMA.

Better Audio Mod

  • Uses audio originating from the HD Collection assets.

  • Encoded as PlayStation 4-bit ADPCM (PS-ADPCM) at 44.1 kHz.

A significant amount of the early investigation was spent assuming Better Audio Mod files matched the vanilla Steam format. Although both use the .sdt extension, their internal layouts are completely different.

If you're investigating this format yourself, the first thing to verify is which variant you're dealing with before making assumptions about the codec or container.


2. PS-ADPCM format (Better Audio Mod)

This variant has now been fully documented and implemented.

General structure

Audio is stored as a sequence of MG blocks.

+--------------------+
| 16-byte header     |
+--------------------+
| up to 0x4000 bytes |
| of PS-ADPCM data   |
+--------------------+

Channel count

The number of channels is stored at offset 0x98 of the file header.


Stereo interleaving

The most difficult aspect of the format was stereo decoding.

Unlike standard PCM stereo—or even many PS-ADPCM implementations—the left and right channels are not interleaved sample-by-sample or ADPCM block-by-block.

Instead, interleaving occurs in 0x800-byte chunks:

L 0x800
R 0x800
L 0x800
R 0x800
...

Pitfall #1

Treating the stream as mono causes the right channel to be decoded approximately 81 ms later than the left channel, producing a noticeable echo.

Pitfall #2

De-interleaving every 16-byte ADPCM block initially appears to work, but playback becomes approximately 2× faster ("chipmunk voice").

This happens because PS-ADPCM prediction depends on previous decoder state. Splitting the stream too frequently destroys predictor continuity for each channel.


Working solution

The correct decoding procedure is:

  1. Read the channel count from offset 0x98.

  2. If stereo, separate both channels using 0x800-byte chunks.

  3. Decode each channel independently while maintaining its own ADPCM predictor state.

  4. Recombine both decoded streams into a standard 16-bit PCM stereo WAV.

For dialogue replacement, the reverse operation is performed:

  • encode the replacement dialogue as PS-ADPCM,

  • duplicate the encoded stream,

  • re-interleave both channels using 0x800-byte chunks,

  • preserve the original file size exactly, as required by the game engine.


3. Vanilla Steam format (AMWX/XWMA)

The vanilla Steam files remain the only unresolved part of the .sdt format.

Current findings:

  • Konami AMWX container.

  • Audio stored as WMAv2/XWMA.

  • The AMWX structure itself has largely been mapped.

  • Extracted bitstreams are rejected by ffmpeg, likely because of container-specific framing or non-standard padding.

Current research directions include:

  • normalizing XWMA headers before decoding,

  • using Microsoft's xWMAEncode.exe instead of ffmpeg,

  • identifying how AMWX stores XWMA block information.

A Reddit contributor (u/SpaceCore0352) also shared Python code for XWMA header normalization, which appears to be a promising lead.

Anyone familiar with XWMA, WMAv2, or AMWX-like containers is welcome to contribute.


4. SDX format (Stage sound banks)

Alongside .sdt, MGS2 also uses .sdx files for stage-specific sound banks.

Unlike .sdt, these are not simple audio containers but complete sound banks containing audio samples, lookup tables and playback sequences.

File layout

Region

Description

0x0000 – 0x1000

Header

0x1000 – ~0x100000

PS-ADPCM sample data (22050 Hz), approximately 200+ sequential samples

~0x101800 – 0x102xxx

Sample table (16-byte records referencing sample addresses)

~0x110000 – end

Playback sequence (event → sample mapping)

Unlike .sdt, every stage contains its own complete .sdx bank.


Sample table

The sample table consists of multiple 16-byte record types (for example beginning with 50 01 01, 10 01 01 or 30 01 01).

These records reference sample locations using addresses expressed in 8-byte units.

Several record types appear to store multiple addresses, likely representing combinations of:

  • sample start,

  • loop point,

  • sample end.

Although not every field has been fully identified, the table structure is sufficiently understood for safe sample replacement.


Audio replacement without breaking pointers

One major constraint is that the table stores absolute sample addresses.

Changing the encoded size of one sample shifts every subsequent address and invalidates the entire bank.

The implemented solution is therefore:

  1. Encode the replacement audio using exactly the same number of ADPCM frames as the original.

  2. Pad with silence or truncate as necessary.

  3. Preserve every original PS-ADPCM frame flag (loop/end markers) instead of regenerating them.

As a result:

  • only the target sample's audio data changes,

  • every pointer remains valid,

  • the sample table is left completely untouched,

  • the playback sequence remains byte-identical.

This approach has been validated both through automated parsing and in-game testing.


Cross-bank sample identification

Many sound effects appear in multiple stage banks.

To identify identical sounds regardless of bank location, an audio fingerprinting method based on hashing the decoded sample data (after neutralizing ADPCM frame flags) was implemented.

This makes it possible to recognize identical sounds independently of:

  • bank file,

  • scan order,

  • sample index.

The resulting identifier provides a consistent way to tag and organize sound effects across the entire game.


5. Current findings

At this stage, the following aspects are understood:

  • Two incompatible .sdt variants exist.

  • Better Audio Mod uses PS-ADPCM.

  • Stereo interleaving occurs every 0x800 bytes.

  • Channel count is stored at offset 0x98.

  • PS-ADPCM decoding and encoding are fully implemented.

  • .sdx sound banks have been structurally mapped.

  • Sample replacement works while preserving original pointer tables.

  • Vanilla Steam .sdt files use an AMWX container wrapping XWMA/WMAv2 audio.


6. Still unresolved

Open questions remain regarding the vanilla format:

  • Exact meaning of several AMWX metadata fields.

  • Why ffmpeg rejects extracted XWMA streams.

  • Whether additional preprocessing is required before decoding.

  • Complete support for vanilla Steam .sdt files.


7. Source code

The complete implementation is open source and includes:

  • binary parsers,

  • PS-ADPCM decoder,

  • stereo de-interleaver,

  • PS-ADPCM encoder,

  • .sdt dialogue replacement,

  • .sdx sample replacement,

  • command-line interface,

  • PyQt6 graphical interface.

GitHub: romerojopro-web/SDT-Tool-for-MGS2MCBetterAudioMod

Nexus Mods: MGS2MC SDT Tool

The code is fully commented in English, and the command-line interface can be used independently of the GUI for scripting or batch processing.

Feedback, corrections, or contributions—particularly regarding the AMWX/XWMA variant—are very welcome.

Remaining unknowns:

  • Exact XWMA block padding format.

  • Possible purpose of some SDT metadata fields.

  • Any documentation or previous research on the Master Collection audio pipeline.

Edited by Paté

Create an account or sign in to comment

Account

Navigation

Search

Search

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.