# How the SharpEmu Atrac9 Decoder Processes Superframes: A Complete Technical Guide

> Discover how the SharpEmu Atrac9 decoder processes superframes. Learn about spectral de-quantization, intensity stereo, and IMDCT transformation for PCM audio.

- Repository: [Berk/sharpemu](https://github.com/par274/sharpemu)
- Tags: deep-dive
- Published: 2026-07-13

---

**The Atrac9 decoder in SharpEmu processes superframes by iterating through individual frames, applying spectral de-quantization, intensity stereo reconstruction, and IMDCT transformation to convert encoded bitstreams into 16-bit PCM audio buffers.**

SharpEmu implements a comprehensive Atrac9 decoder to handle ATRAC9-encoded audio streams found in PlayStation game formats. The decoder operates on **superframes**, which are aggregate units containing multiple individual frames, to reconstruct high-fidelity PCM output. Understanding how the `Atrac9Decoder` class processes these superframes reveals the intricate DSP pipeline that transforms compressed spectral data into playable audio.

## What Is an Atrac9 Superframe?

A superframe in the Atrac9 format consists of a configurable number of regular frames, specifically `1 << SuperframeIndex` as defined in the stream configuration. According to the SharpEmu source code, each superframe contains `Config.FramesPerSuperframe` individual frames, with buffer sizes determined by `Config.SuperframeBytes` for input and `Config.ChannelCount × Config.SuperframeSamples` for output. This aggregation allows efficient batch processing of audio data while maintaining synchronization between channels.

## The Superframe Decoding Pipeline

The decoding process follows a strict pipeline from bitstream validation to PCM output.

### Initialization and Configuration

The `Atrac9Decoder.Initialize(byte[] configData)` method, located at `Atrac9Decoder.cs:21-31`, parses the 4-byte configuration header to build an `Atrac9Config` object. This initialization creates a reusable `Frame` object and prepares a `BitReader` instance for bit-level stream parsing. The configuration establishes critical parameters including sample rates, channel counts, and the superframe size metrics that govern the decoding loop.

### Buffer Validation and Bitstream Setup

Before processing, the `Decode` method validates that the input buffer meets the minimum size requirement of `Config.SuperframeBytes` and that the output array can accommodate `Config.ChannelCount × Config.SuperframeSamples` 16-bit samples, as implemented in `Atrac9Decoder.cs:50-72`. The decoder then positions the `BitReader` at the start of the superframe data (`Atrac9Decoder.cs:46-47`), preparing for sequential frame extraction.

### Frame Iteration and Parsing

The core processing occurs in `DecodeSuperFrame`, which iterates exactly `Config.FramesPerSuperframe` times according to the implementation at `Atrac9Decoder.cs:74-83`. For each iteration, the decoder:

1. Sets the `Frame.FrameIndex` to track position
2. Invokes `DecodeFrame` to process the current frame
3. Aligns the bit-reader to the next byte boundary after frame completion

Within each frame, `Unpack.UnpackFrame` (defined in [`Unpack.cs`](https://github.com/par274/sharpemu/blob/main/Unpack.cs)) parses the raw bitstream into a `Frame` structure containing one or more `Block` objects, each representing sub-streams such as stereo pairs or LFE channels.

### Spectral Processing and Channel Reconstruction

Each block undergoes a multi-stage DSP pipeline as orchestrated in `Atrac9Decoder.cs:10-16`:

1. **De-quantization**: `Quantization.DequantizeSpectra` reconstructs spectral coefficients from compressed values
2. **Intensity Stereo**: `Stereo.ApplyIntensityStereo` reconstructs stereo imaging from encoded parameters
3. **Scaling**: `Quantization.ScaleSpectrum` applies scale factors to normalize spectral data
4. **Band Extension**: `BandExtension.ApplyBandExtension` reconstructs high-frequency content
5. **IMDCT**: `ImdctBlock` calls `Mdct.RunImdct` to convert frequency-domain spectra into time-domain samples

The `Mdct` object within each `Channel` (see `Channel.cs:12-15`) writes the resulting floating-point PCM data into the channel's `Pcm` buffer.

### Float-to-Short Conversion and Output

Following the IMDCT stage, the `PcmFloatToShort` method (implemented at `Atrac9Decoder.cs:85-101`) walks through each channel's floating-point buffer. It rounds each sample and clamps values to the signed 16-bit range using `Helpers.Clamp16`, writing the final results into the caller's `short[][] pcmOut` array. Upon completion of the loop, the output buffer contains fully decoded 16-bit PCM audio for the entire superframe duration.

## Practical Implementation Example

The following C# example demonstrates decoding a single superframe using the SharpEmu Atrac9 decoder:

```csharp
// Example: decode a single superframe
byte[] configData = File.ReadAllBytes("audio.atrac9.cfg");   // 4‑byte config
byte[] superframe   = File.ReadAllBytes("audio.atrac9.sf");   // ≥ Config.SuperframeBytes

var decoder = new LibAtrac9.Atrac9Decoder();
decoder.Initialize(configData);

// Allocate PCM output buffer: [channels][samples]
short[][] pcm = new short[decoder.Config.ChannelCount][];
for (int c = 0; c < pcm.Length; c++)
    pcm[c] = new short[decoder.Config.SuperframeSamples];

decoder.Decode(superframe, pcm);

// `pcm` now holds the decoded 16‑bit audio for the whole superframe.

```

For streaming applications, process superframes sequentially in a loop:

```csharp
// Example: decoding a stream of superframes in a loop
var decoder = new LibAtrac9.Atrac9Decoder();
decoder.Initialize(configData);

while (stream.Position < stream.Length)
{
    // Read exactly one superframe (size known from the config)
    byte[] sf = new byte[decoder.Config.SuperframeBytes];
    stream.Read(sf, 0, sf.Length);

    short[][] outBuffer = new short[decoder.Config.ChannelCount][];
    for (int i = 0; i < outBuffer.Length; i++)
        outBuffer[i] = new short[decoder.Config.SuperframeSamples];

    decoder.Decode(sf, outBuffer);
    // …process or play `outBuffer`…
}

```

## Summary

- **Superframe Structure**: Atrac9 superframes aggregate multiple frames (`1 << SuperframeIndex`) into single processing units with sizes defined by `Config.SuperframeBytes` and `Config.SuperframeSamples`.
- **Validation Pipeline**: The decoder validates input buffer lengths and output array capacities before processing, ensuring memory safety during bitstream operations.
- **Frame Iteration**: `DecodeSuperFrame` iterates through `Config.FramesPerSuperframe` individual frames, parsing each via `Unpack.UnpackFrame` and processing through discrete `Block` objects.
- **DSP Chain**: Each block undergoes de-quantization, intensity stereo reconstruction, scaling, band extension, and IMDCT transformation to produce floating-point PCM.
- **Output Conversion**: The `PcmFloatToShort` method converts floating-point samples to 16-bit integers using `Helpers.Clamp16`, delivering the final audio output.

## Frequently Asked Questions

### What is the difference between a frame and a superframe in Atrac9?

A frame represents a single unit of compressed audio data, while a superframe is an aggregate container holding multiple frames—specifically `1 << SuperframeIndex` frames according to the stream configuration. The decoder processes superframes as atomic units, extracting individual frames sequentially to reconstruct continuous audio output.

### How does the decoder handle buffer size validation?

The `Decode` method in `Atrac9Decoder.cs:50-72` explicitly verifies that the input byte array length meets or exceeds `Config.SuperframeBytes` and that the output PCM array dimensions match `Config.ChannelCount × Config.SuperframeSamples`. This validation prevents buffer overruns and ensures sufficient space for decoded audio before bitstream processing begins.

### What specific DSP operations are applied during frame decoding?

For each frame block, the decoder applies `Quantization.DequantizeSpectra` for spectral reconstruction, `Stereo.ApplyIntensityStereo` for stereo image restoration, `Quantization.ScaleSpectrum` for amplitude normalization, `BandExtension.ApplyBandExtension` for high-frequency synthesis, and `Mdct.RunImdct` for time-domain conversion. These operations transform encoded spectral data into raw floating-point PCM samples.

### How does the decoder convert floating-point audio to 16-bit PCM?

After IMDCT processing, the `PcmFloatToShort` method (located at `Atrac9Decoder.cs:85-101`) iterates through each channel's floating-point buffer, rounds the samples, and clamps them to the signed 16-bit integer range using `Helpers.Clamp16`. This produces the final `short[][]` output array containing the decoded audio suitable for standard audio playback APIs.