H-Sound Engine: Difference between revisions
KungFuFurby (talk | contribs) |
KungFuFurby (talk | contribs) (All command names added on (but not further documentation yet)) |
||
Line 26: | Line 26: | ||
==Communication with the SNES== | ==Communication with the SNES== | ||
Each command is triggered by sending the command ID to $2140/$F4. The same command can't be executed twice in a row unless the register is zeroed out manually first. | |||
===Output to the SNES=== | |||
''TODO document this'' | |||
===Command IDs=== | |||
{| class="wikitable sortable" | |||
|- | |||
! Command ID !! Description !! Register Values & Arguments | |||
|- | |||
|<tt>$00</tt> || NOP || <tt>$00 ?? ?? ??</tt> | |||
|- | |||
|<tt>$01</tt> || Play Music/SFX || <tt>$01 xx ?? ??</tt> | |||
|- | |||
|<tt>$02</tt> || Stop All Sound || <tt>$02 ?? ?? ??</tt> | |||
|- | |||
|<tt>$03</tt> || Mute Channels || <tt>$03 %xxxxxxxx ?? ??</tt> | |||
|- | |||
|<tt>$04</tt> || Echo Volume || <tt>$04 xx ?? ??</tt> | |||
|- | |||
|<tt>$05</tt> || Master Volume || <tt>$05 xx yy ??</tt> | |||
|- | |||
|<tt>$06</tt> || FLG DSP Register Set || <tt>$06 xx ?? ??</tt> | |||
|- | |||
|<tt>$07</tt> || Acknowledge || <tt>$07 ?? ?? ??</tt> | |||
|- | |||
|<tt>$08</tt> || Echo Feedback || <tt>$08 xx ?? ??</tt> | |||
|- | |||
|<tt>$09</tt> || Global Transposition || <tt>$09 xx ?? ??</tt> | |||
|- | |||
|<tt>$0A</tt> || Tempo Offset || <tt>$0A xx ?? ??</tt> | |||
|- | |||
|<tt>$0B</tt> || Echo Enable Bits || <tt>$0B %xxxxxxxx ?? ??</tt> | |||
|- | |||
|<tt>$0C</tt> || FIR Coefficient Table ID || <tt>$0C xx ?? ??</tt> | |||
|- | |||
|<tt>$0D</tt> || Stop All Sound + Load New Data || <tt>$0D ?? ?? ??</tt> | |||
|- | |||
|<tt>$0E</tt> || Acknowledge + Load New Data || <tt>$0E ?? ?? ??</tt> | |||
|- | |||
|<tt>$0F</tt> || Stop All Sound + Load New Data + Play Music ID $00 || <tt>$0F ?? ?? ??</tt> | |||
|- | |||
|<tt>$10</tt> || Set Instrument ID For Channel || <tt>$10 xx yy ??</tt> | |||
|- | |||
|<tt>$11</tt> || Set Instrument ADSR For Channel || <tt>$11 xx yy zz</tt> | |||
|- | |||
|<tt>$12</tt> || Inverted Relative Master & Echo Volume || <tt>$12 xx yy ??</tt> | |||
|- | |||
|<tt>$13</tt> || Relative Master & Echo Volume || <tt>$13 xx yy ??</tt> | |||
|- | |||
|<tt>$14</tt> || Inverted Relative Song Tempo Offset || <tt>$14 xx ?? ??</tt> | |||
|- | |||
|<tt>$15</tt> || Relative Song Tempo Offset || <tt>$15 xx ?? ??</tt> | |||
|- | |||
|<tt>$16</tt> || Pitch Offset for Channel || <tt>$16 xx yy zz</tt> | |||
|- | |||
|<tt>$17</tt> || Set Stereo Mode || <tt>$17 ?? ?? ??</tt> | |||
|- | |||
|<tt>$18</tt> || Redefine FIR Coefficient in Table || <tt>$18 xx yy zz</tt> | |||
|- | |||
|<tt>$19</tt> || Instrument Pitch Base Offset For Channel || <tt>$19 xx ?? ??</tt> | |||
|- | |||
|<tt>$1A</tt> || Restart || <tt>$1A ?? ?? ??</tt> | |||
|- | |||
|<tt>$1B</tt> || Set Mono Mode || <tt>$1B ?? ?? ??</tt> | |||
|- | |||
|<tt>$1C-$1D</tt> || Stop All SFX || <tt>$1C-$1D ?? ?? ??</tt> | |||
|- | |||
|<tt>$1E</tt> || Fade Out || <tt>$1E ?? ?? ??</tt> | |||
|- | |||
|<tt>$1F</tt> || Stop All SFX || <tt>$1F ?? ?? ??</tt> | |||
|- | |||
|<tt>$20</tt> || Redefine Attack For Channel || <tt>$20 %????xxxx ?? ??</tt> | |||
|- | |||
|<tt>$21</tt> || Redefine Decay For Channel || <tt>$21 %?????xxx ?? ??</tt> | |||
|- | |||
|<tt>$22</tt> || Redefine Sustain Level For Channel || <tt>$22 %?????xxx ?? ??</tt> | |||
|- | |||
|<tt>$23</tt> || Redefine Sustain Rate For Channel || <tt>$23 %???xxxxx ?? ??</tt> | |||
|- | |||
|<tt>$24-$FF</tt> || Acknowledge || <tt>$24-$FF ?? ?? ??</tt> | |||
|} | |||
''TODO document this'' | ''TODO document this'' | ||
Line 75: | Line 158: | ||
|<tt>$E2</tt> || Note Volume || <tt>xx</tt> | |<tt>$E2</tt> || Note Volume || <tt>xx</tt> | ||
|- | |- | ||
|<tt>$E3</tt> || NOP || | |<tt>$E3</tt> || NOP || | ||
|- | |- | ||
|<tt>$E4</tt> || Pitch Offset || <tt>xx</tt> | |<tt>$E4</tt> || Pitch Offset || <tt>xx</tt> |
Revision as of 02:33, 23 March 2021
H-Sound is a sound engine created by Tsutomu Hagiwara of Sol for the SPC700 [1] [2]. The sound driver was used in five games.
Only one version, 0.5, was ever used. However, there are technically three different builds, each with very minor differences:
- Yuujin no Furi Furi Girls, compared to Kamen Rider SD, has extra valid percussion note slots and a single extra opcode that overwrites the timer value to use at the start, thus almost not even qualifying as a build variant.
- The other three games, compared to Kamen Rider SD, are missing an optional inversion operation for the echo volume. This is not controlled by a VCMD within the song.
Game Name | Build ID | VCMD Table Location ($E0 and up) | ROM Offset |
---|---|---|---|
Kamen Rider SD | 1 | 0x0C3D | 0x0C9B91 |
Yuujin no Furi Furi Girls | 2 | 0x0C45 | 0x888000 |
Hisshou Pachi-Slot Fun | 3 | 0x0C69 | 0x088000 |
Honkakuha Igo - Gosei | 3 | 0x0C69 | 0x0C8000 |
Janyuuki Gokuu Randa | 3 | 0x0C69 | 0x1D8000 |
The raw build sorting notes can be found here.
Communication with the SNES
Each command is triggered by sending the command ID to $2140/$F4. The same command can't be executed twice in a row unless the register is zeroed out manually first.
Output to the SNES
TODO document this
Command IDs
Command ID | Description | Register Values & Arguments |
---|---|---|
$00 | NOP | $00 ?? ?? ?? |
$01 | Play Music/SFX | $01 xx ?? ?? |
$02 | Stop All Sound | $02 ?? ?? ?? |
$03 | Mute Channels | $03 %xxxxxxxx ?? ?? |
$04 | Echo Volume | $04 xx ?? ?? |
$05 | Master Volume | $05 xx yy ?? |
$06 | FLG DSP Register Set | $06 xx ?? ?? |
$07 | Acknowledge | $07 ?? ?? ?? |
$08 | Echo Feedback | $08 xx ?? ?? |
$09 | Global Transposition | $09 xx ?? ?? |
$0A | Tempo Offset | $0A xx ?? ?? |
$0B | Echo Enable Bits | $0B %xxxxxxxx ?? ?? |
$0C | FIR Coefficient Table ID | $0C xx ?? ?? |
$0D | Stop All Sound + Load New Data | $0D ?? ?? ?? |
$0E | Acknowledge + Load New Data | $0E ?? ?? ?? |
$0F | Stop All Sound + Load New Data + Play Music ID $00 | $0F ?? ?? ?? |
$10 | Set Instrument ID For Channel | $10 xx yy ?? |
$11 | Set Instrument ADSR For Channel | $11 xx yy zz |
$12 | Inverted Relative Master & Echo Volume | $12 xx yy ?? |
$13 | Relative Master & Echo Volume | $13 xx yy ?? |
$14 | Inverted Relative Song Tempo Offset | $14 xx ?? ?? |
$15 | Relative Song Tempo Offset | $15 xx ?? ?? |
$16 | Pitch Offset for Channel | $16 xx yy zz |
$17 | Set Stereo Mode | $17 ?? ?? ?? |
$18 | Redefine FIR Coefficient in Table | $18 xx yy zz |
$19 | Instrument Pitch Base Offset For Channel | $19 xx ?? ?? |
$1A | Restart | $1A ?? ?? ?? |
$1B | Set Mono Mode | $1B ?? ?? ?? |
$1C-$1D | Stop All SFX | $1C-$1D ?? ?? ?? |
$1E | Fade Out | $1E ?? ?? ?? |
$1F | Stop All SFX | $1F ?? ?? ?? |
$20 | Redefine Attack For Channel | $20 %????xxxx ?? ?? |
$21 | Redefine Decay For Channel | $21 %?????xxx ?? ?? |
$22 | Redefine Sustain Level For Channel | $22 %?????xxx ?? ?? |
$23 | Redefine Sustain Rate For Channel | $23 %???xxxxx ?? ?? |
$24-$FF | Acknowledge | $24-$FF ?? ?? ?? |
TODO document this
Instrument Format
The instrument format is N-SPC/Kankichi-kun compatible minus noise support for SRCN values above 127.
The instrument format is defined as the following bytes...
xx yy zz aa bb cc
- xx is a direct write to the VxSRCN DSP register.
- yy is a direct write to the VxADSR1 DSP register.
- zz is a direct write to the VxADSR2 DSP register.
- aa is a direct write to the VxGAIN DSP register.
- bb is a pitch base multiplier.
- cc is a fractional pitch base multiplier, defined in 256ths.
Header Format
Each song's header is a series of eight four-byte entries, one per channel. Thus, they show up like this in the data...
xx xx yy ?? xx xx yy ?? xx xx yy ?? xx xx yy ?? xx xx yy ?? xx xx yy ?? xx xx yy ?? xx xx yy ??
Each entry (consisting of one track) contains the following bytes...
xx xx yy ??
- xx xx is a little endian track pointer.
- yy is a master track ID. For the music, this is zero. For SFX, this is a non-zero value.
Voice Command Format
VCMD ID | Description | Arguments |
---|---|---|
$00-$60 | Note Length | |
$61-$71 | Invalid Velocity | |
$72-$79 | Velocity | |
$7A-$7F | Quantization | |
$80-$C7 | Note | |
$C8 | Instant Slide To Note | |
$C9 | Tie | |
$CA-$DF | Percussion | |
$E0 | Instrument | xx |
$E1 | Panning | xx |
$E2 | Note Volume | xx |
$E3 | NOP | |
$E4 | Pitch Offset | xx |
$E5 | Absolute Transposition | xx |
$E6 | Global Absolute Transposition | xx |
$E7 | Loop Section Start | |
$E8 | Loop Section End | xx |
$E9 | Tempo | xx |
$EA | NOP | |
$EB | Activate Percussion Mode | |
$EC | Echo On | |
$ED | Echo Off | |
$EE | ADSR | xx yy |
$EF | GAIN | xx |
$F0-$F1 | NOP | |
$F2 | Jump | xx xx |
$F3 | Noise Clock | %???xxxxx |
$F4 | Noise On | |
$F5 | Noise Off | |
$F6 | Key Off On Quantization Elapse Enable | |
$F7 | Key Off On Quantization Elapse Disable | |
$F8 | FIR Coefficient Table ID | xx |
$F9 | Echo Volume | xx |
$FA | Echo Feedback | xx |
$FB-$FD | NOP | |
$FE | End of Track | |
$FF | NOP |
NOP (VCMD $E3, $EA, $F0-$F1, $FB-$FD, $FF)
Does absolutely nothing.
Note Length (VCMD $00-$60)
Defines a note length in tempo ticks plus one.
Invalid Velocity (VCMD $61-$71)
These are invalid VCMD IDs. They technically work, just that they read invalid velocity parameters as a side effect.
Velocity (VCMD $72-$79)
Refers to an array that contains a value to multiply by when combined with other volume parameters.
Quantization (VCMD $7A-$7F)
Refers to an array that contains a percentage in 256ths for how far along the note to play before keying it off in tempo ticks.
NOTE: This affects all channels due to a bug in its implementation (specifically, there's no indexed loading when calculating the number of ticks before keying off), and it only works when the first channel defines the quantization.
Note (VCMD $80-$C7)
Plays a note and delays the channel for one note length before reading another VCMD.
Instant Slide To Note (VCMD $C8)
Sets up the next note to not be keyed on and instead merely changes the pitch to the next note indicated. Other VCMDs can be processed first prior to the note being defined.
Tie (VCMD $C9)
Continues playing the previous note and delays the channel for one note length before reading another VCMD.
Percussion (VCMD $CA-$DF)
Plays a percussion note. Each percussion note takes up an instrument slot starting at a hardcoded fixed offset, and has a dedicated fixed pitch to play at referred to via a separate table.
Instrument (VCMD $E0)
$E0 xx
- xx is an instrument ID to an array of instruments. See Instrument Format above for the format.
Panning (VCMD $E1)
$E1 xx
- xx is the panning value. $00 is left, and $FF is right.
Note Volume (VCMD $E2)
$E2 xx
- xx is the volume of the note.
Pitch Offset (VCMD $E4)
$E4 xx
- xx defines the offset in units used for the VxPITCHH DSP registers. This is applied after multiplying out all of the other pitches.
Absolute Transposition (VCMD $E5)
$E5 xx
- xx is a signed value defining the number of semitones to transpose subsequent notes.
Global Absolute Transposition (VCMD $E6)
$E6 xx
- xx is a signed value defining the number of semitones to transpose subsequent notes. Note that this affects all channels, not just one channel.
Loop Section Start (VCMD $E7)
Defines a starting point for a loop section. No nesting is allowed.
Loop Section End (VCMD $E8)
$E8 xx
- xx defines the number of times to go back to the loop section start marker.
Tempo (VCMD $E9)
$E9 xx
- xx defines the tempo. One tempo is equal to one timer 0 tick multiplied by .
Activate Percussion Mode (VCMD $EB)
Causes standard notes to be invalid and percussion notes to be valid. Without using this VCMD, percussion notes are a NOP instead.
Echo On (VCMD $EC)
Activates echo for the channel.
Echo Off (VCMD $ED)
Disables echo for the channel.
ADSR (VCMD $EE)
$EE xx yy
- xx is a direct write to the VxADSR1 register. The highest bit is automatically set to force ADSR mode.
- yy is a direct write to the VxADSR2 register.
GAIN (VCMD $EF)
$EF xx
The highest bit in the VxADSR1 register is automatically cleared to force GAIN mode.
- xx is a direct write to the VxGAIN register.
Jump (VCMD $F2)
$F2 xx xx
- xx xx is a little endian pointer indicating where to jump to.
Noise Clock (VCMD $F3)
$F3 %???xxxxx
- %xxxxx defines the speed of the noise clock in five bits.
Noise On (VCMD $F4)
Activates noise for the channel.
Noise Off (VCMD $F5)
Disables noise for the channel.
Key Off On Quantization Elapse Enable (VCMD $F6)
This enables an automatic key off when a percentage of the note length defined by the quantization value has elapsed.
Key Off On Quantization Elapse Disable (VCMD $F7)
This disables an automatic key off when a percentage of the note length defined by the quantization value has elapsed.
FIR Coefficient Table ID (VCMD $F8)
$F8 xx
- xx is an ID for a table of FIR coefficient IDs.
Echo Volume (VCMD $F9)
$F9 xx
- xx defines the volume used for the EVOLL and EVOLR DSP registers.
Echo Feedback (VCMD $FA)
$FA xx
- xx defines the value used for the EFB DSP register.
End of Track (VCMD $FE)
Stops the track from playing.