AGSC (File Format): Difference between revisions

Jump to navigation Jump to search
imported>Jackoalan
imported>Jackoalan
 
(27 intermediate revisions by 3 users not shown)
Line 1: Line 1:
'''AGSC''' is the sound effect format for Metroid Prime and Metroid Prime 2: Echoes. Each AGSC file contains a group of sound effects. The first two Metroid Prime games utilize the MusyX audio engine created by Factor5 and as a result, AGSC files are essentially just embedded MusyX files.  
'''AGSC''' is the sound effect format for Metroid Prime and Metroid Prime 2: Echoes. Each AGSC file contains a group of sound effects. The first two Metroid Prime games utilize the MusyX audio engine created by Factor5 and as a result, AGSC files are essentially just embedded MusyX files.  


The audio codec used in AGSC is the standard GameCube DSP ADPCM codec.
The audio codec used in AGSC is the standard GameCube DSP-ADPCM codec, but MusyX itself also offers uncompressed PCM as an option.


{{todo|Better descriptions for how SoundMacros work and a description for what each command does.}}
{{todo|Better descriptions for how SoundMacros work and a description for what each command does.}}
Line 23: Line 23:
| 0x0
| 0x0
| '''D'''
| '''D'''
| '''Audio Directory'''. Always "Audio/." Zero-terminated.
| '''Audio Directory'''. Always "Audio/". Zero-terminated.
|-
|-
| 0x0 + D
| 0x0 + D
Line 50: Line 50:
| 0x4 + D
| 0x4 + D
| 2
| 2
| {{unknown|Copy of '''first project unknown'''; 0xffff if empty}}
| '''Group ID'''; 0xFFFF if unspecified
|-
|-
| 0x6 + D
| 0x6 + D
Line 103: Line 103:
==== ObjectID ====
==== ObjectID ====


After this are four tables of objects. Each object is identified with a 16-bit '''ObjectID''':
After this are four tables of objects. Each object is identified with a 16-bit '''ObjectID'''.


{| class="wikitable"
Factor5 designed ObjectIDs to used in a polymorphic manner. The top 2 bits of the ID are used
! Offset
to differentiate between SoundMacros, Keymaps, and Layers. If the ID passes a mask of 0x4000,
! Size
the object is a ''Keymap''. If the ID passes a mask of 0x8000, the object is a ''Layer''.
! Description
Otherwise, the object is assumed to be a ''SoundMacro''. ''Tables'' don't require this type of
|-
polymorphism due to the context in which they are accessed.
| 0x0
| 1
| '''Sound object type''' <ol start="0"><li>SoundMacro</li><li>Table</li><li value=4>Keymap</li><li value=8>Layer</li></ol>
|-
| 0x1
| 1
| '''Unique ID''' (per type namespacing)
|-
| 0x2
| colspan=2 {{unknown|End of ObjectID}}
|}


==== SoundMacros ====
==== SoundMacros ====
Line 503: Line 492:
| colspan="5" {{unknown|}}
| colspan="5" {{unknown|}}
|-
|-
| 0x34
| 0x36
| SETPRIORITY
| SETPRIORITY
| Prio
| Prio
| colspan="6" {{unknown|}}
| colspan="6" {{unknown|}}
|-
|-
| 0x35
| 0x37
| ADDPRIORITY
| ADDPRIORITY
| {{unknown|}}
| {{unknown|}}
Line 514: Line 503:
| colspan="4" {{unknown|}}
| colspan="4" {{unknown|}}
|-
|-
| 0x36
| 0x38
| AGECNTSPEED
| AGECNTSPEED
| colspan="3" {{unknown|}}
| colspan="3" {{unknown|}}
| colspan="4" | Time
| colspan="4" | Time
|-
|-
| 0x37
| 0x39
| AGECNTVEL
| AGECNTVEL
| {{unknown|}}
| {{unknown|}}
Line 733: Line 722:
| colspan="2" | Immediate
| colspan="2" | Immediate
| {{unknown|}}
| {{unknown|}}
|-
| 0x65
| SET_VAR
| Ctrl
| A =
| colspan="1" {{unknown|}}
| colspan="2" | Immediate
| colspan="2" {{unknown|}}
|-
|-
| 0x70
| 0x70
Line 789: Line 786:


When the size of the table data is exactly 8, it may represent ADSR envelopes with this structure:
When the size of the table data is exactly 8, it may represent ADSR envelopes with this structure:
'''Note:''' All fields of the envelope are ''little endian''.


{| class="wikitable"
{| class="wikitable"
Line 796: Line 795:
|-
|-
| 0x0
| 0x0
| 1
| 2
| '''Attack time (0-255 milliseconds)'''; no multiplication is done to the value
| '''Attack time'''; in milliseconds
|-
| 0x2
| 2
| '''Decay time'''; in milliseconds
|-
| 0x4
| 2
| '''Sustain'''; percentage mapped between [0x0,0x1000]
|-
|-
| 0x1
| 0x6
| 1
| 2
| '''Attack time (0-65280 milliseconds)'''; multiply value by 256
| '''Release time'''; in milliseconds
|-
|-
| 0x2
| 0x8
| 1
| colspan=2 {{unknown|End of ADSR}}
| '''Decay time (0-255 milliseconds)''';  no multiplication is done to the value
|}
 
===== DLS ADSR =====
 
MusyX can also express more advanced envelopes using a modified [[wikipedia:DLS format|DLS]] representation.
This representation includes scaling coefficients to respond to played note and velocity
(so slamming down a key harder plays longer).
 
The attack and decay members are expressed in ''time-cents''. This may be converted to seconds using:
<code>2<sup>timecents / (1200.0 * 65536.0)</sup></code>
 
The attack and decay scale members are expressed as 0.1% increments in 16.16 fixed-point.
This may be converted to a normalized factor using:
<code>scale / (1000.0 * 65536.0)</code>
 
'''Note:''' All fields of the envelope are ''little endian''.
 
{| class="wikitable"
! Offset
! Size
! Description
|-
|-
| 0x3
| 0x0
| 1
| 4
| '''Decay time (0-65280 milliseconds)'''; multiply value by 256
| '''Attack time'''; in time-cents
|-
|-
| 0x4
| 0x4
| 1
| 4
| '''Sustain (percentage)'''; multiply value by 0.0244
| '''Decay time'''; in time-cents
|-
| 0x8
| 2
| '''Sustain'''; percentage mapped between [0x0,0x1000]
|-
|-
| 0x5
| 0xA
| 1
| 2
| '''Sustain (percentage)'''; multiply value by 6.25
| '''Release'''; in milliseconds
|-
|-
| 0x6
| 0xC
| 1
| 4
| '''Release time (0-255 milliseconds)'''; no multiplication is done to the value
| '''Velocity to Attack Scale'''; 0.1% increments as 16.16 fixed-point
|-
|-
| 0x7
| 0x10
| 1
| 4
| '''Release time (0-65280 milliseconds)'''; multiply value by 256
| '''Key to Decay Scale'''; 0.1% increments as 16.16 fixed-point
|-
|-
| 0x8
| 0x14
| colspan=2 {{unknown|End of entry}}
| colspan=2 {{unknown|End of DLS ADSR}}
|}
|}


===== Curves =====
===== Curves =====


To express a volume curve, the table data is simply an arbitrarily-sized table of <code>uint8_t</code> values
To express a volume curve, the table data is simply an arbitrarily-sized table of <code>uint8_t</code> values (although typically in MIDI range [0,127])


==== Keymaps ====
==== Keymaps ====
Line 947: Line 978:
| 0x6
| 0x6
| 1
| 1
| '''Pan'''
| '''Priority Offset'''
|-
|-
| 0x7
| 0x7
| 1
| 1
| '''Priority Offset'''
| '''Surround Pan'''; (0: extreme forward, 64: center, 127: extreme rearward)
|-
|-
| 0x8
| 0x8
| 1
| 1
| '''Unknown'''; usually 0x40
| '''Pan'''; (0: extreme left, 64: center, 127: extreme right)
|-
|-
| 0xC
| 0xC
Line 1,000: Line 1,031:
| 0x14
| 0x14
| 4
| 4
| '''Keymaps table offset''' (SongGroup)
| '''Keymaps table offset'''
|-
|-
| 0x18
| 0x18
| 4
| 4
| '''Layers table offset''' (SongGroup)
| '''Layers table offset'''
|-
|-
| 0x1C
| 0x1C
Line 1,026: Line 1,057:
==== SoundMacro ID Table ====
==== SoundMacro ID Table ====


This is a table of shorts; there's no count value, so it's terminated with a value of 0xFFFF. It's a list of SoundMacro IDs present in the file. Occasionally there's gaps in the list; these gaps are signified by the top bit, 0x8000, being set on the size value preceding the gap.
This is a ranged-table of shorts; there's no count value, so it's terminated with a value of 0xFFFF. It's a list of SoundMacro IDs present in the file. Contiguous ranges are expressed by IDs with most-significant bit set (0x8000). The range begins on the marked ID and incrementally reaches the next ID in the list, including that ID. All other IDs are singular.


==== Sample ID / Keymap / Layer Tables ====
==== Sample ID / Table / Keymap / Layer Tables ====


These function the same way as the SoundMacro ID table, but indexes other types of entities instead.
These function the same way as the SoundMacro ID table, but indexes other types of entities instead.
'''Note:''' Keymap and Layer IDs in these tables have their top 2 bits (indicating their type) masked off.
Keymaps must be OR'd with 0x4000 and Layers must be OR'd with 0x8000 in order to reconstruct the actual IDs.


==== Normal / Drum Page Entry ====
==== Normal / Drum Page Entry ====
Line 1,062: Line 1,096:
| '''Padding'''
| '''Padding'''
|}
|}
'''Note:''' The drum table is accessed when the MIDI channel is 10, otherwise the normal table is accessed.


==== SFX Entry ====
==== SFX Entry ====
Line 1,099: Line 1,135:
|-
|-
| 0x8
| 0x8
| 2
| 1
| '''Definite Key'''; The default pitch (usually 0x3C00... the second byte may possibly be the MIDI channel)
| '''Definite Key'''; The default pitch - usually 0x3C (MIDI C4)
|-
| 0x9
| 1
| '''Padding'''
|}
|}


Line 1,111: Line 1,151:
banks of instruments.
banks of instruments.


Each MIDI Setup starts with a u32 '''MIDI-Setup-ID''', followed by 16 entries of the following structure (one for each channel):
Each MIDI Setup starts with a u16 '''MIDI-Setup-ID''', then 16-bits padding, then 16 entries of the following structure (one for each channel):


{|class="wikitable"
{|class="wikitable"
Line 1,176: Line 1,216:
| 0xC
| 0xC
| 1
| 1
| '''Pitch'''; usually 0x3C. 0x3C is note C4 "Middle C" on the MIDI Keyboard. The keyboard notes are inverted - i.e., 0x48 is for note C3 and 0x30 is for note C5.
| '''Base Note'''; Corresponds to the MIDI note played in the sample, at the native sample-rate (which MusyX obtains from the INST chunk of .aiff files or SMPL chunk of .wav files, along with looping info). To play at a specified pitch in [[wikipedia:Cent (music)|cents]], set the playback sample rate using this formula: <code>sampleRate * 2<sup>((pitch - baseNote * 100) / 1200.0)</sup></code>
|-
|-
| 0xD
| 0xD
Line 1,187: Line 1,227:
|-
|-
| 0x10
| 0x10
| 4
| 1
| '''Audio format''' <ol start="0"><li>DSP-ADPCM</li><li>DSP-ADPCM (Drum Sample)</li><li>PCM</li><li>N64-VADPCM (Legacy Format)</li></ol>
|-
| 0x11
| 3
| '''Number of samples'''
| '''Number of samples'''
|-
|-
Line 1,245: Line 1,289:
== Tools ==
== Tools ==


* [https://drive.google.com/file/d/0B9MLV21H7SDvemgwN1daYnliSjA/view?usp=sharing Prime Audio Decoder] by Parax will dump all sound effects contained in a given AGSC file.
* [https://drive.google.com/file/d/0B9MLV21H7SDvemgwN1daYnliSjA/view?usp=sharing Prime Audio Decoder] by Aruki will dump all sound effects contained in a given AGSC file.


[[Category:File Formats]]
[[Category:File Formats]]
Anonymous user

Navigation menu