ADX (file format): Difference between revisions

Content deleted Content added
AndreR908 (talk | contribs)
Minor correction
AndreR908 (talk | contribs)
Touchups
Line 9:
}}
 
ADX is a lossy [[proprietary]] audio storage and compression format developed by [[CRI Middleware]] specifically for use in [[video games]]. The format is similar in principal to [[ADPCM]] but offers smaller storage sizes., Thethe sound quality is quite impressive given the extremely small sample size used by the format. The format also provides a looping feature that has proved useful for background music in various games that have adopted the format, such as the [[Dreamcast]] and later generation [[Sonic the Hedgehog]] games from [[SEGA]].
 
== File Format ==
The ADX format's specification is not freely available, however the internal structure of the most significant elements that make up the format have been described in various places on the internet. The information given here may be incomplete but is sufficient to build a working [[codec]] or [[transcoder]].
 
The format is inherently [[big-endian]] even when used on [[little-endian]] architectures such as the [[Xbox | original Xbox]] or [[x86]] computer. The standard [[byte]] size is an [[Octet (computing) | octet]]. The basic structure is outlined below:
{| class="wikitable" <!-- File layout outline -->
!
Line 101:
 
=== Decoding Samples ===
As noted above, each sample consists of 4bits, the high 4bits of aeach [[byte]] (more specifically, [[octet_(computing) | octet]]) are the first sample with the low 4bits being the second.
{| class="wikitable"
!7
Line 119:
int_fast32_t sample;
uint_least8_t sample_4bit;
uint_fast16_t block_scale;
/* ... Get 4 bit sample ... */
data_index = audio_data_start + (sample_index / 32) * num_channels * 18 + (current_channel - 1) * 18 + 2 + sample_index % 32 / 2;
block_scale = ntohs( *(uint16_t*)&raw_data[data_index] );
data_index += 2 + sample_index % 32 / 2;
sample_4bit = raw_data[data_index];
if (sample_index % 2) /* If the sample index [starting at 0] is odd then we are decoding a secondsecondary sample */
sample_4bit &= 0x0F;
else /* Otherwise it is a primary sample */
Line 135 ⟶ 138:
sample += previous_sample * 0x7298; /* Incorporate previous sample data */
sample -= second_previous_sample * 0x3350; /* Incorporate previous previous sample data */
sample &gt;&gt;= 14; /* DownshiftDivide the sample by 14 bits16384 */
if (sample > 32767) /* Round-off the sample within the valid range for a 16bit signed sample */
sample = 32767;
Line 144 ⟶ 147:
previous_sample = sample;
 
The accquistion of the desired byte seems more complex then it really is, the long calculation can actually be more easily performed using a byte counter that is incremented every 'audio frame' processed but for complete clarity, the entire calculation is shown. It is assumed the entire file has been either [[mmap]]-ed or else read into memory, however progressive reading [(ie. [[Streaming media | streaming]]]) of the file is entirely possible as well. We start at the begining of the audio section of the ADX then move the pointer to the 'audio frame' currently being processed, the calculation finds the number of frames already processed then, of course, there is a block for each channel in each frame with each being 18 bytes that must be skipped over until we reach the frame we want. Once that is done it is then necessary to move to the block that belongs to the channel that is currently being processed in the frame (ie. if we are reading the right channel, we must skip over the left channel block),. We need the block's scale value to decode the sample so we thencollect skipthat overusing [[ntohs]] to convert from big to little endian if necessary. Finally, to get the sample we move past the 2 byte scale value at the start of the block before proceeding to the byte we want within it. The last division by 2 in the last calculation is done becauseas it is assumed that the array contains 8bit [unsigned] bytes, with each holding 2 samples.
 
The highest bit of the 4bit sample is the [[sign bit]] (negative when set, [[Two's complement]]) so the number has to be converted into an 8bit or larger signed integer for proper arithmetic handling as few processors can handle 4bit numbers natively. The next stage is to multiply the sample by the scale which gives it a rational amplitude, then amplify by a volume, values between 0-20004000<sub>16</sub> tend to work best fordepending on the volumeaudio butfile in question, you can go higher but distortion effects may be noticeable (this is caused by [[truncation]] of the higher frequencies by the 16bit roundoff). The next 2 steps include information from the previous two samples to bring the sample in line with the others, be aware that the previous samples progress across block boundaries, but separate sample sets must be kept for each channel, [NOTE: Thethe values start at 0 onin the first audio frame]. Lastly, it'sthe sample is divided by 16384 using a downshift then rounded off inside of the 16bit signed sample range (-32768 to 32767).
 
The decoded samples from each channel willmay still need to be interleaved together if to form rawa [[PCM]]standard interleaved audio datastream suitable for outputuse intowith amost sound cardcards.
 
== Sources ==