Music/SMD

From Final Fantasy Hacktics Wiki
Jump to navigation Jump to search

SMD files are Final Fantasy Tactics's music files. Each SMD file holds one song.

List of Songs: Songs

Header

The header consists of the following:

Header
Offset Type Purpose
0x00 string SMD identifier (literal "smds")
0x04 ? Unknown
0x8 uint File size (in bytes)
0xc ? Unknown
0x14 uint Number of channels
0x13 ? Unknown
0x1a char Reverb Mode
0x1b char Volume Depth
0x1c char Reverb Delay
0x1d char Reverb Feedback
0x1e uint Offset of filename
0x20 uint Offset of data chunk
0x22 uint[number of channels] Offset of channel N. The number of these will equal the number of channels read earlier.
Varies uint End of offsets. (Should equal 0)
Varies string Filename. This is a zero-terminated string. always 12 bytes long though. music ##.mid


Channels

SMD files contain a number of channels. Each channel contains a sequence of notes and instructions, and they're all played simultaneously. To play a 3-note chord, for example, you need to have 3 channels, and each channel plays one note of the chord. Typically, channel 0 doesn't contain notes, only special instructions like tempo settings. There is some evidence that notes placed in channel 0 will not play, so notes should probably go in channels 1 and higher.


Instructions

Each instruction begins with an identifier byte and is followed by zero to 3 parameter bytes. The number of parameter bytes depends on the instruction.

Instructions
Value (hex) Name Parameters (bytes) Purpose
0x00-0x7F Note 1 or 2 Play a note. 0x00 is the quietest and 0x7F is the loudest. The 1st parameter is the note's pitch and duration. (See the table below.) If the first parameter is divisible by 0x13 (19), then there will be a second parameter.
0x80 Rest 1 The parameter is the length of the rest, in 192nds of a note. A duration of 0xc0 (192) is equal to a whole note, 0x60 (96) is a half note, etc.
0x81 Fermata 1 Extend previous note. The parameter is the length of the extension, in 192nds of a note.
0x90 End Bar 0 End channel. Stops any more instructions from being read in this channel.
0x91 Loop 0 Loop remainder of channel indefinitely.
0x94 Octave 1 Set octave. The parameter is the octave. 0x03 is the 4th octave (the one with middle C).
0x95 Raise Octave 0 Increment octave
0x96 Lower Octave 0 Decrement octave
0x97 Time Signature 2 Set time signature, apparently. Not sure if this affects playback or is just informational. The 1st parameter is the top number, the 2nd is the bottom.
0x98 Repeat 1 Begin loop. The parameter is the number of times to loop
0x99 Coda 0 End loop. (sets a loop point?)
0x9a To Coda 0 Goes to set point?
0x9c Sound Effect 3 Play a sound effect. first argument is the sound effect ID.
0xa0 Tempo 1 Set tempo. 0x66 (102) is the most commonly-used tempo across all files, and it appears to be 120 bpm.
0xa1 Accelerando 1 Raises the tempo by the argument's value.
0xac Instrument 1 Set instrument. The parameter is the instrument number. For a full list, see: Instruments.
0xb2 Enable LFO 0 enables oscillation based on the sound wave of the previous instrument. !! Only works if the current instrument is in an Odd (not even) channel.
0xb3 Disable LFO 0 turns off oscillation.
0xb4 Enable Noise 1 Sets the current instrument to Noise. Argument is the noise clock.
0xb5 Increase Noise 1 increases the Noise clock by the argument.
0xb6 Turn on Noise 0 Sets the current instrument to Noise. Does not calculate the noise clock.
0xb7 Disable Noise 0 Turns off noise for this instrument.
0xb8 Acoustics 3 Sets the reverb delay, reverb feedback, and volume depth of the current song. probably intended to only be used via channel 0.
0xba Enable Reverb 0 Turns reverb on for this instrument.
0xbf Disable Reverb 0 Turns off reverb for this instrument.
0xc0 Naturale 0 Resets the current instruments parameters (based off of its WAVESET soundfont data!)
0xc1 Envelope Shape 3 Sets the attack mode, sustain mode, and release mode of the current instrument, in that order. [1]
0xc2 Attack time 1 Set attack time. First parameter is the length of the attack. Higher values mean the note takes longer to fade in.
0xc3 Decay Time 1 Sets Decay Time. First parameter is the length of the decay.
0xc4 Sustain 1 Sets the sustain. first parameter is the length of the sustain.
0xc5 Release 1 Sets the release. first parameter is the length of the release.
0xc6 Sustain level 1 Set sustain level. first parameter is the sustain level. higher values hold the note louder.
0xc7 Envelope Tail 2 Sets both the Decay time and the sustain level, in that order.
0xc8 Attack Mode 1 Sets the attack gradient. if the attack mode is 5, set the attack mode to exponential. Otherwise, it's linear.
0xc9 Sustain Mode 1 Sets the sustain gradient. if the sustain mode is 1, set linear increase. if the sustain mode is 5, set exponential increase. if the sustain mode is 7, set exponential decrease. otherwuse, linear decrease.
0xca Release Mode 1 Sets the release gradient. if the release mode is 7, set exponential gradient. Otherwise, it's linear.
0xd2 ? 1 ?
0xd7 ? 1 ?
0xd8 Pitch Shift 3 The 1st parameter is the speed, 2nd is the intensity (amount of pitch change), and 3rd is delay before pitch shift happens in each note.
0xda ? 0 ?
0xdb ? 0 ?
0xe0 Dynamics 1 Set volume. 0x00 is the quietest, 0x7f is the loudest.
0xe1 Crescendo 1 Increases volume.
0xe2 Fermata Ramp 2 Sets a fermata with the length of argument 1. sets the target volume to reach by the end of the fermata as argument 2.
0xe3 ? 1 ?
0xe4 ? 3 ?
0xe6 ? 0 ?
0xe8 Balance 1 Set balance. 0x00 is left speaker, 0x7f is right speaker.
0xe9 Shift Balance 1 Adjust the balance towards either the left or right speaker.
0xfd Scale tempo 1 Multiply the tempo by the argument.
0xfe Select Sound Font 1 Tries to find a soundfont with the ID given as a parameter. as only one soundfont in FFT exists that can be played with suzuki's music library, this does nothing.

Notes

To play a note, use a note-playing instruction (00-7f) followed by a byte from the table below. If you use a custom note length (0x00, 0x13, 0x26, etc.), then you will need a second parameter specifying the note's length, in 192nds of a note (see explanation of Rests, above). This gives you more control over exactly how long the note lasts.

Note types (all values in hex)
C C# D D# E F F# G G# A A# B
Custom 00 13 26 39 4c 5f 72 85 98 ab be d1
whole 01 14 27 3a 4d 60 73 86 99 ac bf d2
dotted half 02 15 28 3b 4e 61 74 87 9a ad c0 d3
half 03 16 29 3c 4f 62 75 88 9b ae c1 d4
dotted quarter 04 17 2a 3d 50 63 76 89 9c af c2 d5
3rd 05 18 2b 3e 51 64 77 8a 9d b0 c3 d6
quarter 06 19 2c 3f 52 65 78 8b 9e b1 c4 d7
dotted 8th 07 1a 2d 40 53 66 79 8c 9f b2 c5 d8
6th 08 1b 2e 41 54 67 7a 8d a0 b3 c6 d9
8th 09 1c 2f 42 55 68 7b 8e a1 b4 c7 da
dotted 16th 0a 1d 30 43 56 69 7c 8f a2 b5 c8 db
12th 0b 1e 31 44 57 6a 7d 90 a3 b6 c9 dc
16th 0c 1f 32 45 58 6b 7e 91 a4 b7 ca dd
dotted 32nd 0d 20 33 46 59 6c 7f 92 a5 b8 cb de
24th 0e 21 34 47 5a 6d 80 93 a6 b9 cc df
32nd 0f 22 35 48 5b 6e 81 94 a7 ba cd e0
48th 10 23 36 49 5c 6f 82 95 a8 bb ce e1
64th 11 24 37 4a 5d 70 83 96 a9 bc cf e2
96th 12 25 38 4b 5e 71 84 97 aa bd d0 e3


Credit

Thanks to P.J. Barnes for figuring out the structure of the file and a few commands.