Difference between revisions of "HERAD"
(→MIDI notation: Added some notes about the MIDI data) |
Binarymaster (talk | contribs) (→Speed / Tempo: update frequency info) |
||
(85 intermediate revisions by 4 users not shown) | |||
Line 11: | Line 11: | ||
| OutputPSG = No | | OutputPSG = No | ||
| Released = 1992-??-?? | | Released = 1992-??-?? | ||
− | | FirstGame = | + | | FirstGame = [[Dune (DOS)]] |
− | | Extension01 = *. | + | | Extension01 = *.agd |
− | | Extension02 = *. | + | | Extension02 = *.sdb |
− | | Extension03 = *. | + | | Extension03 = *.m32 |
− | | Extension04 = *. | + | | Extension04 = *.hsq |
− | | Extension05 = *. | + | | Extension05 = *.sqx |
+ | | Extension06 = *.sqz | ||
}} | }} | ||
− | '''Herbulot AdLib (HERAD) System''' was created by [[Rémi Herbulot]], one of [[Cryo Interactive Entertainment]] co-founders and lead programmers. [[Stéphane Picq]], Cryo's first music composer also helped design HERAD with Herbulot. | + | '''Herbulot AdLib (HERAD) System''' was created by [[Rémi Herbulot]], one of [[Cryo Interactive Entertainment]] co-founders and lead programmers. [[Stéphane Picq]], Cryo's first music composer also helped design HERAD with Herbulot. There are two versions of HERAD that are known to exist. |
+ | |||
+ | Stéphane Picq had this to say about HERAD: | ||
+ | {{quote|I designed HERAD because the existing softwares [sic] didn't take advantages of all sound parameters, and were very poor in expressiveness, the only dynamic being volume of notes. Basically, in HERAD several individual parameters of the soundpatches (like volume of operators) can be modulated individually, by velocity, modulation wheel, or aftertouch, like a real synth. Also, we used some "hidden" parameters not documented by Adlib, but mentioned in the Yamaha technical notice of the chip FM YM3812.}} | ||
+ | |||
+ | [[Dune (DOS)|Dune]] (the first game to utilize HERAD) lists in the credit roll a special thanks to "[[Henri Chalifour]] and [[Grant Hamilton]] from [[Ad Lib|the Ad Lib Company]]", who also were involved in the development of the music format. | ||
+ | |||
+ | Henri Chalifour said this in regards to HERAD development on Dune: | ||
+ | |||
+ | {{quote|Regarding my involvement with Cryo Interactive, as far as I remember I shared with Mr. Picq some tricks, recipes and advices [sic] concerning sound designing. Being quite comfortable within the Ad Lib environment, It was however a modest contribution that I brought.}} | ||
+ | |||
+ | HERAD was used in only three games: Dune, [[KGB (DOS)|KGB aka Conspiracy]], and [[MegaRace (DOS)|MegaRace]]. All three games have been arguably rated as some of the best DOS game soundtracks ever written for OPL2. | ||
==Players== | ==Players== | ||
Line 30: | Line 42: | ||
===HERAD to ?=== | ===HERAD to ?=== | ||
+ | * [[MIDIPLEX]] - Windows - [[MIDI]] | ||
===? to HERAD=== | ===? to HERAD=== | ||
Line 47: | Line 60: | ||
| 1992-??-?? | | 1992-??-?? | ||
| [[KGB (DOS)]] | | [[KGB (DOS)]] | ||
− | | | + | | {{Song-Box|02 - KGB - DOS - Gorbachev.ogg}} |
|- | |- | ||
| 1993-??-?? | | 1993-??-?? | ||
| [[MegaRace (DOS)]] | | [[MegaRace (DOS)]] | ||
− | | | + | | {{Song-Box|01_-_MegaRace_-_DOS_-_NewSan.ogg}} |
|} | |} | ||
− | ==Technical== | + | ==Technical Specifiations== |
− | + | ||
− | ** ''' | + | ===File Formats=== |
− | ** '''AGD''' - [[AdLib Gold]] ([[OPL3]]) | + | |
+ | HERAD comes in several different file formats. The data is usually packed inside '''HSQ''' or '''SQX''' files. | ||
+ | |||
+ | * '''HSQ''' are compressed files with the Herbulot Sequencer algorithm, which is similar to LZ** dictionary algorithms. HSQ files can be found in Dune and MegaRace. | ||
+ | * '''SQX''' is another compression format, that seems to be similar to HSQ, but decompression is currently not possible except for playback in RDOSPlay. | ||
+ | * In the non-interactive demo for [[Dune (DOS)|Dune]], the music files are compressed in a format called '''SQZ''', however, these files are identical to HSQ files. | ||
+ | |||
+ | Once the data is decompressed, there are several different file extensions that are used. Since HSQ doesn't keep the original data's filename or extention, it is assumed that these file extentions are retronyms and were given to the raw data after they were decompressed. | ||
+ | |||
+ | * The file extensions stand for different sound devices: | ||
+ | ** '''SDB''' - [[AdLib]]/[[Sound Blaster]] ([[OPL2]]) | ||
+ | ** '''AGD''' - [[AdLib Gold 1000]] ([[OPL3]]) | ||
** '''M32''' - [[Roland]] [[MT-32]] ([[LA32]]) | ** '''M32''' - [[Roland]] [[MT-32]] ([[LA32]]) | ||
− | |||
− | |||
− | |||
− | ===File structure=== | + | ===Musical Notation=== |
− | All values | + | |
+ | * The internal music notation is very similar to [[MIDI]], however Pitch Bend and Meta events do differ. | ||
+ | * M32 files usually contain one multi-channel track, while SDB/AGD files may contain multiple tracks. | ||
+ | * Despite all MIDI tracks use channel 1, any channel number can be used as this number is simply ignored. | ||
+ | |||
+ | ===Speech Synthesis=== | ||
+ | As heard in the KGB song, "Gorbi", the word "[[wikipedia:Mikhail_Gorbachev|Gorbachev]]" is played around 1:00. It was assumed that speech synthesis or perhaps PCM audio was possible with HERAD; however, after analyzing the uncompressed music file, it turns out the speech synthesis is just very clever MIDI sequencing and OPL2 programming done by Stéphane Picq to produce pseudo-speech synthesis. | ||
+ | |||
+ | ===Version Compatibility=== | ||
+ | The format has two known versions, which have several differences; however, neither version has any FourCC or header data denoting which version it is. In order to detect the proper version, each music file needs to be inspected. | ||
+ | |||
+ | The first version was used in [[Dune (DOS)|Dune]] and [[KGB (DOS)|KGB]], and the second version was used in [[MegaRace (DOS)|MegaRace]]. | ||
+ | |||
+ | ==File structure== | ||
+ | |||
+ | There are three chunks to HERAD files: the header, the MIDI data, and the AdLib Instrument chunk. Note that the Instrument chunk is absent in M32 files. | ||
+ | |||
+ | ===Header=== | ||
+ | All values in the header are in little endian format. For M32 files, the <tt>wFileSize</tt> value represents the total file size, while AGD and SDB files, it represents the file size without the instrument data block. | ||
{| class="wikitable" | {| class="wikitable" | ||
Line 71: | Line 110: | ||
! Description | ! Description | ||
|- | |- | ||
− | | <tt>UINT16</tt> || <tt>wFileSize</tt> || Size of uncompressed file | + | | <tt>UINT16</tt> || <tt>wFileSize</tt> || Size of uncompressed file / Instrument Chunk offset |
|- | |- | ||
| <tt>UINT16[21]</tt> || <tt>wOffsets</tt> || Array of relative offsets to the MIDI tracks (0 = track doesn't exist) | | <tt>UINT16[21]</tt> || <tt>wOffsets</tt> || Array of relative offsets to the MIDI tracks (0 = track doesn't exist) | ||
Line 81: | Line 120: | ||
| <tt>UINT16</tt> || <tt>wLoopCount</tt> || Number of times the selected measures will play (0 = loop forever; >0 - play N times) | | <tt>UINT16</tt> || <tt>wLoopCount</tt> || Number of times the selected measures will play (0 = loop forever; >0 - play N times) | ||
|- | |- | ||
− | | <tt>UINT16</tt> || <tt>wSpeed</tt> || | + | | <tt>UINT16</tt> || <tt>wSpeed</tt> || Fixed point value that controls music speed. Value range is 0x0100 - 0x8100 |
+ | |- | ||
+ | | <tt>UINT8[32]</tt> || <tt>bGoldRegs</tt> || Register values for AdLib Gold 1000 surround module. Only found in '''AGD''' files<br>Modifying these values produces no changes to regular OPL3 playback | ||
+ | |} | ||
+ | |||
+ | ====Looping==== | ||
+ | Looping a song works by specifying the start and end points with the <tt>wLoopStart</tt> and <tt>wLoopEnd</tt> bytes, and denoting how many times the loop should play with the <tt>wLoopCount</tt> byte. This can be used to either play a song forever, or to play a song that doesn't repeat but has a short segment that loops instead (like a repeating melody or phrase). For example, to loop the first two measures of the song, the <tt>wLoopStart</tt> byte will be <tt>01</tt> and the <tt>wLoopEnd</tt> byte will be <tt>03</tt>. A measure is 96 MIDI ticks in duration. | ||
+ | |||
+ | For version 1 songs, in order for music to repeat, this loop data must be in place. Version 2 songs that are being played back in MegaRace's sound engine will automatically repeat forever even if the <tt>wLoopCount</tt> field specifies that the song should only be played once. If there are no loop points in the file, the version 2 song will automatically repeat from beginning to end. As a result, several tracks in MegaRace (NewSan, Maeva and Terminal City) have short loops that are only a few measures long. Because those loop points are being used, the music continues to loop the song from beginning to end due to the sound engine. The other remaining tracks from MegaRace (Factory Land, Skyholder and Fractalian Space) have intros to them that are not repeated so their loop points start at the end of the intro and finish when the song is over. | ||
+ | |||
+ | ====Speed / Tempo==== | ||
+ | The default tempo is 500 BPM with the MIDI data at 24 ticks per quarter note. Obviously, this default value is way too fast so to slow down the music, a fixed-point value must be entered into the <tt>wSpeed</tt> field. To calculate the tempo of the song, take 500 and divide it by the value. Since this is a fixed-point number, some BPM will be at odd values. HERAD driver refresh rate is around 200.299 Hz. You can calculate ticks per second frequency by dividing refresh rate by the speed value. | ||
+ | |||
+ | Some of these values were taken from MegaRace and Dune files. | ||
+ | |||
+ | {| class="wikitable" | | ||
+ | ! Speed value | ||
+ | ! Fixed-Point value | ||
+ | ! Approximate BPM | ||
+ | ! Frequency (Hz) | ||
+ | |- | ||
+ | | 0x0100 | ||
+ | | 1.0 | ||
+ | | 500 | ||
+ | | = 200.299 | ||
+ | |- | ||
+ | | 0x03E0 | ||
+ | | 3.875 | ||
+ | | 129.032 | ||
+ | | ≈ 51.69 | ||
+ | |- | ||
+ | | 0x0400 | ||
+ | | 4.0 | ||
+ | | 125 | ||
+ | | ≈ 50.07 | ||
|- | |- | ||
− | | | + | | 0x042B |
+ | | 4.168 | ||
+ | | 119.961 | ||
+ | | ≈ 48.06 | ||
|- | |- | ||
− | | | + | | 0x04B8 |
+ | | 4.71875 | ||
+ | | 105.960 | ||
+ | | ≈ 42.45 | ||
|- | |- | ||
− | | | + | | 0x0500 |
+ | | 5 | ||
+ | | 100 | ||
+ | | ≈ 40.06 | ||
|} | |} | ||
− | === | + | ====AdLib Gold Settings==== |
− | + | In '''AGD''' files, there's an additional chunk of 32 bytes in the header before the MIDI notation begins. These bytes are register values for various settings on the rare [[AdLib Gold 1000]] sound card. | |
− | + | {| class="wikitable" | | |
+ | ! Offset | ||
+ | ! Description | ||
+ | ! Notes | ||
+ | |- | ||
+ | | 0x0 | ||
+ | | <center>'''[[TDA8425]] register value (Gold control register 8)'''</center> | ||
+ | | 0xD6 = pseudo stereo; 0xDE = spatial stereo.<br>Since this seems to be the register value for the TDA8425 chip, other values should be valid (in theory).<br>Dune only uses 0xD6 or 0xDE. According to the TDA8425 datasheet, spatial stereo is for handling stereo sound and<br>pseudo stereo is for mono sound. | ||
+ | |- | ||
+ | | 0x1-0x1F | ||
+ | | <center>'''[[YM7128]] (Surround Module) register values'''</center> | ||
+ | | These are the raw register values for the YM7128 chip that is found on the Surround Module of the AdLib Gold 1000.<br>The YM7128 creates the reverb and delay signal processing that the AdLib Gold 1000 is known for. | ||
+ | |} | ||
− | + | Only two songs (MORNING and WORMSUIT) use the spatial stereo setting for the TDA8425. | |
===MIDI notation=== | ===MIDI notation=== | ||
− | * | + | * Most of the status bytes are compatible with the MIDI standard. |
− | * It looks like | + | * It looks like running status is not supported as all known songs programmed in HERAD never use it. |
+ | * All MIDI data for Cryo's games uses 24 ticks per quarter note. | ||
{| class="wikitable" | | {| class="wikitable" | | ||
Line 122: | Line 217: | ||
| Unknown | | Unknown | ||
|- | |- | ||
− | | B# | + | | B# xx xx |
− | | Control Change ( | + | | Control Change ('''M32''') |
− | | | + | | Yes |
|- | |- | ||
| C# xx | | C# xx | ||
Line 131: | Line 226: | ||
|- | |- | ||
| D# xx | | D# xx | ||
− | | Channel Aftertouch | + | | Channel Aftertouch (only version 1) |
| Yes | | Yes | ||
|- | |- | ||
| E# xx | | E# xx | ||
− | | Pitch Bend | + | | Pitch Bend ('''AGD''' and '''SDB''') |
| No | | No | ||
+ | |- | ||
+ | | E# xx xx | ||
+ | | Pitch Bend ('''M32''') | ||
+ | | Yes | ||
|- | |- | ||
| FF | | FF | ||
Line 143: | Line 242: | ||
|} | |} | ||
− | For the Note Off command in version 2 songs, the velocity byte has been removed. | + | ====Note Off==== |
+ | For the Note Off command in version 2 songs, the velocity byte has been removed. Some older MIDI sequencers back in the '80s and early '90s did this to stop sending redundant data. | ||
+ | |||
+ | ====Pitch Bend==== | ||
+ | In the '''AGD''' and '''SDB''' files Pitch Bend command has only the MSB byte available. Like the MIDI Standard dictates, 0x40 is the "center" of the pitch bend range. Sending this 0x40 data byte after the Pitch Bend status byte will result in no change to the pitch. This event does differ from it's MIDI counterpart since the value range for Pitch Bend is 0x00 to 0x80, which surpasses MIDI's 7-bit value range. 0x00 equals to 2 semitones down and 0x80 equals to 2 semitones up. | ||
+ | |||
+ | The frequency number range for pitch bends is 325 to 685. For example, if the sequencer were to play a 2 semitone pitch bend downwards from C to A#, it would start at FNum 343, go down to 325 and then decrease the block number and continue the pitch bend at 650 (B, which is 1 semitone down from C) and finally stopping at 614 aka A sharp. If a 2 semitone pitch bend upwards were to happen at B, the FNum will start at 650, continue to increment the FNum until it reaches 685. Once there, it goes to the next block number and resumes increasing the FNum starting at 343 (which is C) before finishing the pitch bend 2 semitones up at 364 (which is C sharp). | ||
+ | |||
+ | Because the pitch bend event has a full 8-bit value instead of MIDI's standard 7-bit value, it is possible to go up higher above 0x80. For example, a pitch bend value of 0xFF when played on a C note will bend the pitch all the way up to F#, a 6 semitone difference. | ||
+ | |||
+ | ====Channel Aftertouch==== | ||
+ | Dune uses Aftertouch events to control the velocity of sustaining notes, as heard in the song, "Morning". However, HERAD 2 drops support of Aftertouch completely. Songs that have Aftertouch events will still play but the aftertouch events will be ignored. In the MegaRace music files, Channel Aftertouch only occurs one time in one song (Fractalian Space). | ||
+ | |||
+ | ====Note Pitch / Frequency Number Table==== | ||
+ | |||
+ | HERAD uses MIDI Notes C1 to B8 (0x18 to 0x77). If any MIDI notes are out of range, the sequencer will play note C1. The Block number corresponds with the MIDI octave (Block number 0 = MIDI octave 1, Block number 1 = MIDI octave 2, etc). | ||
+ | |||
+ | {| class="wikitable" | | ||
+ | ! MIDI Note | ||
+ | ! F-Num | ||
+ | |- | ||
+ | | C | ||
+ | | 343 | ||
+ | |- | ||
+ | | C# | ||
+ | | 364 | ||
+ | |- | ||
+ | | D | ||
+ | | 385 | ||
+ | |- | ||
+ | | D# | ||
+ | | 408 | ||
+ | |- | ||
+ | | E | ||
+ | | 433 | ||
+ | |- | ||
+ | | F | ||
+ | | 459 | ||
+ | |- | ||
+ | | F# | ||
+ | | 486 | ||
+ | |- | ||
+ | | G | ||
+ | | 515 | ||
+ | |- | ||
+ | | G# | ||
+ | | 546 | ||
+ | |- | ||
+ | | A | ||
+ | | 579 | ||
+ | |- | ||
+ | | A# | ||
+ | | 614 | ||
+ | |- | ||
+ | | B | ||
+ | | 650 | ||
+ | |} | ||
===Instrument Data=== | ===Instrument Data=== | ||
− | The instrument chunk contains all the OPL register values needed for each instrument, along with some macros that control various parameters of the instrument during playback. Each instrument is 0x28 bytes long. | + | The instrument chunk contains all the OPL register values needed for each instrument, along with some macros that control various parameters of the instrument during playback. Each instrument is 0x28 bytes long. Version 2 of HERAD introduced a keymap instrument that can be used for linking several instruments into one; this allows for some very complex drum sequencing. |
+ | |||
+ | To use an instrument, the MIDI notation must use the "Program Change" message and specify a number for the instrument to be used. All instruments are listed sequentially and the first instrument is always number #0. Let's say we want to play the 13th instrument in the chunk. We tell the MIDI data to Program Change to instrument number #12 (<tt>C0 0C</tt>) and the notation after that will play using that instrument until the end of the track or another Program Change message is sent. | ||
It seems that the OPL register values are almost in the exact same layout as the [[BNK]] format ([http://www.shikadi.net/moddingwiki/AdLib_Instrument_Bank_Format technical]). Thanks to [[User:Malvineous|Malvineous]] for his documentation on the BNK file format. | It seems that the OPL register values are almost in the exact same layout as the [[BNK]] format ([http://www.shikadi.net/moddingwiki/AdLib_Instrument_Bank_Format technical]). Thanks to [[User:Malvineous|Malvineous]] for his documentation on the BNK file format. | ||
Line 158: | Line 315: | ||
! Description | ! Description | ||
! OPL base register | ! OPL base register | ||
− | ! | + | ! Notes |
|- | |- | ||
− | | 0x0 || 1 || || <center> | + | | 0x0 || 1 || || <center>'''Mode'''</center> || || Denotes if this is an instrument or a version 2 keymap. <br>Normally 0x0 in version 1 songs; either 0x1 or 0xFF in version 2 songs<br>As long as this value is not set to 0xFF in a version 2 song, this can be set to any number. |
|- | |- | ||
− | | 0x1 || 1 || || <center> | + | | 0x1 || 1 || || <center>'''Voice number'''</center> || || Most likely a meta identifier (changing this value has no effect in any song) |
|- | |- | ||
| 0x2 || 1 || ksl || <center>'''Modulator Key scaling level'''</center> || 0x40 (bits 6-7) || | | 0x2 || 1 || ksl || <center>'''Modulator Key scaling level'''</center> || 0x40 (bits 6-7) || | ||
Line 176: | Line 333: | ||
| 0x7 || 1 || eg || <center>'''Modulator Envelope gain'''</center> || 0x20 (bit 5) || nonzero value is on | | 0x7 || 1 || eg || <center>'''Modulator Envelope gain'''</center> || 0x20 (bit 5) || nonzero value is on | ||
|- | |- | ||
− | | 0x8 || 1 || decay || <center>'''Modulator | + | | 0x8 || 1 || decay || <center>'''Modulator Decay'''</center> || 0x60 (lower four bits) || |
|- | |- | ||
| 0x9 || 1 || releaseRate || <center>'''Modulator Release'''</center> || 0x80 (lower four bits) || | | 0x9 || 1 || releaseRate || <center>'''Modulator Release'''</center> || 0x80 (lower four bits) || | ||
|- | |- | ||
− | | 0xA || 1 || totalLevel || <center>'''Modulator Output Level'''</center> || 0x40 (bit 0-5) || | + | | 0xA || 1 || totalLevel || <center>'''Modulator Output Level'''</center> || 0x40 (bit 0-5) || Output level is NOT affected by MIDI Velocity. To enable velocity, see offset 0x1E |
|- | |- | ||
| 0xB || 1 || am ||<center>'''Modulator Amplitude modulation (Tremolo)'''</center> || 0x20 (bit 7) || | | 0xB || 1 || am ||<center>'''Modulator Amplitude modulation (Tremolo)'''</center> || 0x20 (bit 7) || | ||
Line 190: | Line 347: | ||
| 0xE || 1 || con || <center>'''Connector'''</center> || 0xC0 (bit 0, inverted) || 0: OPL bit set to 1<br>other: OPL bit set to 0 | | 0xE || 1 || con || <center>'''Connector'''</center> || 0xC0 (bit 0, inverted) || 0: OPL bit set to 1<br>other: OPL bit set to 0 | ||
|- | |- | ||
− | | 0xF || 1 || | + | | 0xF || 1 || ksl || <center>'''Carrier Key scaling level'''</center> || 0x40 (bits 6-7) || |
|- | |- | ||
| 0x10 || 1 || multiple || <center>'''Carrier Frequency multiplier'''</center> || 0x20 (bits 0-3) || | | 0x10 || 1 || multiple || <center>'''Carrier Frequency multiplier'''</center> || 0x20 (bits 0-3) || | ||
|- | |- | ||
− | | 0x11 || 1 || | + | | 0x11 || 1 || || <center>'''Panning (OPL3)'''</center> || 0xC0 (upper four bits) || This controls the upper bits of the 0xC0 register to control panning in OPL3. <br>3 = both speakers; 2 = right speaker; 1 = left speaker<br>MegaRace uses 3 as the default value. Dune's OPL2 driver ignores this byte and sets it to 0.<br>Dune's OPL3 driver defaults any invaild value to both speakers. |
|- | |- | ||
| 0x12 || 1 || attack || <center>'''Carrier Attack'''</center> || 0x60 (upper four bits) || | | 0x12 || 1 || attack || <center>'''Carrier Attack'''</center> || 0x60 (upper four bits) || | ||
Line 202: | Line 359: | ||
| 0x14 || 1 || eg || <center>'''Carrier Envelope gain'''</center> || 0x20 (bit 5) || nonzero value is on | | 0x14 || 1 || eg || <center>'''Carrier Envelope gain'''</center> || 0x20 (bit 5) || nonzero value is on | ||
|- | |- | ||
− | | 0x15 || 1 || decay || <center>'''Carrier | + | | 0x15 || 1 || decay || <center>'''Carrier Decay'''</center> || 0x60 (lower four bits) || |
|- | |- | ||
| 0x16 || 1 || releaseRate || <center>'''Carrier Release'''</center> || 0x80 (lower four bits) || | | 0x16 || 1 || releaseRate || <center>'''Carrier Release'''</center> || 0x80 (lower four bits) || | ||
|- | |- | ||
− | | 0x17 || 1 || totalLevel || <center>'''Carrier Output Level'''</center> || 0x40 (bit 0-5) || | + | | 0x17 || 1 || totalLevel || <center>'''Carrier Output Level'''</center> || 0x40 (bit 0-5) || Output level is NOT affected by MIDI Velocity. To enable velocity, see offset 0x1F |
|- | |- | ||
| 0x18 || 1 || am ||<center>'''Carrier Amplitude modulation (Tremolo)'''</center> || 0x20 (bit 7) || | | 0x18 || 1 || am ||<center>'''Carrier Amplitude modulation (Tremolo)'''</center> || 0x20 (bit 7) || | ||
Line 214: | Line 371: | ||
| 0x1A || 1 || ksr || <center>'''Carrier Key scaling/envelope rate'''</center> || 0x20 (bit 4) || | | 0x1A || 1 || ksr || <center>'''Carrier Key scaling/envelope rate'''</center> || 0x20 (bit 4) || | ||
|- | |- | ||
− | | 0x1B || 1 || | + | | 0x1B || 1 || HERAD Macro || <center>'''Feedback Scaling - Aftertouch'''</center> || 0xC0 (bits 1-3) || This modifies feedback based off of MIDI Aftertouch events. <br>Value range goes from 1-6 and FF-FA; 0 turns the scaling off.<BR> If Feedback (0x4) has already been assigned, that value will be added to the scaling. |
+ | |- | ||
+ | | 0x1C || 1 || || <center>'''Modulator Waveform Select'''</center> || 0xE0 (bits 0-1) || Bits 0-2 for '''AGD''' | ||
|- | |- | ||
− | | | + | | 0x1D || 1 || || <center>'''Carrier Waveform Select'''</center> || 0xE0 (bits 0-1) || Bits 0-2 for '''AGD''' |
|- | |- | ||
− | | | + | | 0x1E || 1 || HERAD Macro || <center>'''Modulator Output Level Scaling'''</center> || 0x40 (bit 0-5) || This uses the MIDI NoteOn velocity to control the Modulator Output level <br>Value range goes from 1-4 and FF-FC; 0 turns the scaling off.<BR>Due to the design of the OPL2 chip, the higher values will decrease the volume and vice versa.<br> |
|- | |- | ||
− | | | + | | 0x1F || 1 || HERAD Macro || <center>'''Carrier Output Level Scaling'''</center> || 0x40 (bit 0-5) || Same as previous macro, only this affects the Carrier operator. <br>Seems to multiply the velocity value; as a result some notes that are too loud<br>or quiet will not be affected since the sum will be out of range for the OPL chip. |
|- | |- | ||
− | | | + | | 0x20 || 1 || HERAD Macro || <center>'''Feedback Scaling - Velocity'''</center> || 0xC0 (bits 1-3) || Same concept as the previous two macros, however this modifies feedback based off of MIDI NoteOn velocity. <br>Value range goes from 1-6 and FF-FA; 0 turns the scaling off.<BR> If Feedback (0x4) has already been assigned, that value will be added to the scaling. |
|- | |- | ||
− | | | + | | 0x21 || 1 || HERAD Macro || <center>'''Pitch Slide Range Flag'''</center> || || Increases pitch bend range (Fine tune = 0, Coarse tune = 1) |
|- | |- | ||
− | | | + | | 0x22 || 1 || HERAD Macro || <center>'''Root Note Transpose'''</center> || || Normally set at 0x0 and accepts signed integers, for example, 0xC = an octave higher; 0xF4 = an octave lower<br>This macro functions very differently in HERAD version 2, see [[HERAD#Root Note Macro|Root Note Macro]] |
|- | |- | ||
− | | | + | | 0x23 || 1 || HERAD Macro ||<center>'''Pitch Slide Duration'''</center> || || Duration of the pitch bend in ticks |
|- | |- | ||
− | | | + | | 0x24 || 1 || HERAD Macro || <center>'''Pitch Slide Range'''</center> || || Signed integer value. <br>For each MIDI tick, increase or decrease the FNUM by 1 when fine tune is on. <br>When coarse tune is on, a 60-note scale is used (see [[HERAD#Coarse Pitch Slide Frequency Table|Coarse Pitch Slide Frequency Table]]). |
|- | |- | ||
− | | | + | | 0x25 || 1 || Unknown || <center>''Unused''</center> || || While this byte is used in some instruments for Dune, KGB, and MegaRace, <br>extensive testing shows that this byte doesn't change any OPL registers or affect playback at all.<br>This byte is considered unused. |
|- | |- | ||
− | | 0x27 || 1 || || <center> | + | | 0x26 || 1 || HERAD Macro || <center>'''Modulator Output Level Aftertouch Scaling'''</center> || || This uses the MIDI Channel Aftertouch events to modify the modulator output level. <br>Just like in 0x1E, the value range goes from 1-4 and FF-FC; 0 turns the scaling off.<BR>For some reason, in version 2 instruments, this is always set to 0x1 |
+ | |- | ||
+ | | 0x27 || 1 || HERAD Macro || <center>'''Carrier Output Level Aftertouch Scaling'''</center> || || This uses the MIDI Channel Aftertouch events to modify the carrier output level. <br>Just like in 0x1F, the value range goes from 1-4 and FF-FC; 0 turns the scaling off.<BR>In MegaRace, this is always set to zero.<BR>In order for this macro to function, the 0x1F byte MUST be enabled. | ||
|} | |} | ||
+ | |||
+ | ====Coarse Pitch Slide Frequency Table==== | ||
+ | |||
+ | When the Pitch Slide Range Flag (0x21) is set to the coarse tune setting, 4 additional F-Nums are added to each note of the standard 12-note scale, resulting in a 60-note scale. The sequencer will cycle through all the F-Nums until the next Note Off or the pitch slide exceeds the MIDI Note Range or until the end of the Pitch Slide Duration (0x23). | ||
+ | |||
+ | {| class="wikitable" style="text-align: center; width: 200px; height: 200px;" | ||
+ | |- | ||
+ | ! colspan="2" style="text-align: center;" | MIDI Note and Corresponding F-Num | ||
+ | ! colspan="4" style="text-align: center;" | Additional F-Nums added to 12 note scale | ||
+ | |- | ||
+ | ! C | ||
+ | | 343 || 348 || 353 || 358 || 363 | ||
+ | |- | ||
+ | ! C# | ||
+ | | 364 || 369 || 374 || 379 || 384 | ||
+ | |- | ||
+ | ! D | ||
+ | | 385 || 390 || 395 || 400 || 405 | ||
+ | |- | ||
+ | ! D# | ||
+ | | 408 || 413 || 418 || 423 || 428 | ||
+ | |- | ||
+ | ! E | ||
+ | | 433 || 438 || 443 || 448 || 453 | ||
+ | |- | ||
+ | ! F | ||
+ | | 459 || 464 || 469 || 474 || 479 | ||
+ | |- | ||
+ | ! F# | ||
+ | | 486 || 492 || 498 || 504 || 510 | ||
+ | |- | ||
+ | ! G | ||
+ | | 515 || 521 || 527 || 533 || 539 | ||
+ | |- | ||
+ | ! G# | ||
+ | | 546 || 552 || 558 || 564 || 570 | ||
+ | |- | ||
+ | ! A | ||
+ | | 579 || 585 || 591 || 597 || 603 | ||
+ | |- | ||
+ | ! A# | ||
+ | | 614 || 620 || 626 || 632 || 638 | ||
+ | |- | ||
+ | ! B | ||
+ | | 650 || 656 || 662 || 668 || 674 | ||
+ | |- | ||
+ | |} | ||
+ | ====Output Level Scaling Table==== | ||
+ | |||
+ | The following is the lookup table for the output level scaling macros. 3F is the quietest output level whereas 00 is the loudest. If any of the output level values (0xA and 0x17) have already been assigned, that value will be added to the scaling. | ||
+ | |||
+ | {| class="wikitable" | ||
+ | ! MIDI Velocity || 4 || 3 || 2 || 1 || FF || FE || FD || FC | ||
+ | |- | ||
+ | | 0 || 3F || 3F || 20 || 10 || 0 || 0 || 0 || 0 | ||
+ | |- | ||
+ | | 1 || 3F || 3F || 1F || 0F || 0 || 0 || 0 || 1 | ||
+ | |- | ||
+ | | 2 || 3F || 3F || 1F || 0F || 0 || 0 || 1 || 2 | ||
+ | |- | ||
+ | | 3 || 3F || 3E || 1F || 0F || 0 || 0 || 1 || 3 | ||
+ | |- | ||
+ | | 4 || 3F || 3E || 1F || 0F || 0 || 1 || 2 || 4 | ||
+ | |- | ||
+ | | 5 || 3F || 3D || 1E || 0F || 0 || 1 || 2 || 5 | ||
+ | |- | ||
+ | | 6 || 3F || 3D || 1E || 0F || 0 || 1 || 3 || 6 | ||
+ | |- | ||
+ | | 7 || 3F || 3C || 1E || 0F || 0 || 1 || 3 || 7 | ||
+ | |- | ||
+ | | 8 || 3F || 3C || 1E || 0E || 1 || 2 || 4 || 8 | ||
+ | |- | ||
+ | | 9 || 3F || 3B || 1D || 0E || 1 || 2 || 4 || 9 | ||
+ | |- | ||
+ | | 0A || 3F || 3B || 1D || 0E || 1 || 2 || 5 || 0A | ||
+ | |- | ||
+ | | 0B || 3F || 3A || 1D || 0E || 1 || 2 || 5 || 0B | ||
+ | |- | ||
+ | | 0C || 3F || 3A || 1D || 0E || 1 || 3 || 6 || 0C | ||
+ | |- | ||
+ | | 0D || 3F || 39 || 1C || 0E || 1 || 3 || 6 || 0D | ||
+ | |- | ||
+ | | 0E || 3F || 39 || 1C || 0E || 1 || 3 || 7 || 0E | ||
+ | |- | ||
+ | | 0F || 3F || 38 || 1C || 0E || 1 || 3 || 7 || 0F | ||
+ | |- | ||
+ | | 10 || 3F || 38 || 1C || 0D || 2 || 4 || 8 || 10 | ||
+ | |- | ||
+ | | 11 || 3F || 37 || 1B || 0D || 2 || 4 || 8 || 11 | ||
+ | |- | ||
+ | | 12 || 3F || 37 || 1B || 0D || 2 || 4 || 9 || 12 | ||
+ | |- | ||
+ | | 13 || 3F || 36 || 1B || 0D || 2 || 4 || 9 || 13 | ||
+ | |- | ||
+ | | 14 || 3F || 36 || 1B || 0D || 2 || 5 || 0A || 14 | ||
+ | |- | ||
+ | | 15 || 3F || 35 || 1A || 0D || 2 || 5 || 0A || 15 | ||
+ | |- | ||
+ | | 16 || 3F || 35 || 1A || 0D || 2 || 5 || 0B || 16 | ||
+ | |- | ||
+ | | 17 || 3F || 34 || 1A || 0D || 2 || 5 || 0B || 17 | ||
+ | |- | ||
+ | | 18 || 3F || 34 || 1A || 0C || 3 || 6 || 0C || 18 | ||
+ | |- | ||
+ | | 19 || 3F || 33 || 19 || 0C || 3 || 6 || 0C || 19 | ||
+ | |- | ||
+ | | 1A || 3F || 33 || 19 || 0C || 3 || 6 || 0D || 1A | ||
+ | |- | ||
+ | | 1B || 3F || 32 || 19 || 0C || 3 || 6 || 0D || 1B | ||
+ | |- | ||
+ | | 1C || 3F || 32 || 19 || 0C || 3 || 7 || 0E || 1C | ||
+ | |- | ||
+ | | 1D || 3F || 31 || 18 || 0C || 3 || 7 || 0E || 1D | ||
+ | |- | ||
+ | | 1E || 3F || 31 || 18 || 0C || 3 || 7 || 0F || 1E | ||
+ | |- | ||
+ | | 1F || 3F || 30 || 18 || 0C || 3 || 7 || 0F || 1F | ||
+ | |- | ||
+ | | 20 || 3F || 30 || 18 || 0B || 4 || 8 || 10 || 20 | ||
+ | |- | ||
+ | | 21 || 3F || 2F || 17 || 0B || 4 || 8 || 10 || 21 | ||
+ | |- | ||
+ | | 22 || 3F || 2F || 17 || 0B || 4 || 8 || 11 || 22 | ||
+ | |- | ||
+ | | 23 || 3F || 2E || 17 || 0B || 4 || 8 || 11 || 23 | ||
+ | |- | ||
+ | | 24 || 3F || 2E || 17 || 0B || 4 || 9 || 12 || 24 | ||
+ | |- | ||
+ | | 25 || 3F || 2D || 16 || 0B || 4 || 9 || 12 || 25 | ||
+ | |- | ||
+ | | 26 || 3F || 2D || 16 || 0B || 4 || 9 || 13 || 26 | ||
+ | |- | ||
+ | | 27 || 3F || 2C || 16 || 0B || 4 || 9 || 13 || 27 | ||
+ | |- | ||
+ | | 28 || 3F || 2C || 16 || 0A || 5 || 0A || 14 || 28 | ||
+ | |- | ||
+ | | 29 || 3F || 2B || 15 || 0A || 5 || 0A || 14 || 29 | ||
+ | |- | ||
+ | | 2A || 3F || 2B || 15 || 0A || 5 || 0A || 15 || 2A | ||
+ | |- | ||
+ | | 2B || 3F || 2A || 15 || 0A || 5 || 0A || 15 || 2B | ||
+ | |- | ||
+ | | 2C || 3F || 2A || 15 || 0A || 5 || 0B || 16 || 2C | ||
+ | |- | ||
+ | | 2D || 3F || 29 || 14 || 0A || 5 || 0B || 16 || 2D | ||
+ | |- | ||
+ | | 2E || 3F || 29 || 14 || 0A || 5 || 0B || 17 || 2E | ||
+ | |- | ||
+ | | 2F || 3F || 28 || 14 || 0A || 5 || 0B || 17 || 2F | ||
+ | |- | ||
+ | | 30 || 3F || 28 || 14 || 9 || 6 || 0C || 18 || 30 | ||
+ | |- | ||
+ | | 31 || 3F || 27 || 13 || 9 || 6 || 0C || 18 || 31 | ||
+ | |- | ||
+ | | 32 || 3F || 27 || 13 || 9 || 6 || 0C || 19 || 32 | ||
+ | |- | ||
+ | | 33 || 3F || 26 || 13 || 9 || 6 || 0C || 19 || 33 | ||
+ | |- | ||
+ | | 34 || 3F || 26 || 13 || 9 || 6 || 0D || 1A || 34 | ||
+ | |- | ||
+ | | 35 || 3F || 25 || 12 || 9 || 6 || 0D || 1A || 35 | ||
+ | |- | ||
+ | | 36 || 3F || 25 || 12 || 9 || 6 || 0D || 1B || 36 | ||
+ | |- | ||
+ | | 37 || 3F || 24 || 12 || 9 || 6 || 0D || 1B || 37 | ||
+ | |- | ||
+ | | 38 || 3F || 24 || 12 || 8 || 7 || 0E || 1C || 38 | ||
+ | |- | ||
+ | | 39 || 3F || 23 || 11 || 8 || 7 || 0E || 1C || 39 | ||
+ | |- | ||
+ | | 3A || 3F || 23 || 11 || 8 || 7 || 0E || 1D || 3A | ||
+ | |- | ||
+ | | 3B || 3F || 22 || 11 || 8 || 7 || 0E || 1D || 3B | ||
+ | |- | ||
+ | | 3C || 3F || 22 || 11 || 8 || 7 || 0F || 1E || 3C | ||
+ | |- | ||
+ | | 3D || 3F || 21 || 10 || 8 || 7 || 0F || 1E || 3D | ||
+ | |- | ||
+ | | 3E || 3F || 21 || 10 || 8 || 7 || 0F || 1F || 3E | ||
+ | |- | ||
+ | | 3F || 3F || 20 || 10 || 8 || 7 || 0F || 1F || 3F | ||
+ | |- | ||
+ | | 40 || 3F || 20 || 10 || 7 || 7 || 10 || 20 || 3F | ||
+ | |- | ||
+ | | 41 || 3F || 1F || 0F || 7 || 8 || 10 || 20 || 3F | ||
+ | |- | ||
+ | | 42 || 3E || 1F || 0F || 7 || 8 || 10 || 21 || 3F | ||
+ | |- | ||
+ | | 43 || 3D || 1E || 0F || 7 || 8 || 10 || 21 || 3F | ||
+ | |- | ||
+ | | 44 || 3C || 1E || 0F || 7 || 8 || 11 || 22 || 3F | ||
+ | |- | ||
+ | | 45 || 3B || 1D || 0E || 7 || 8 || 11 || 22 || 3F | ||
+ | |- | ||
+ | | 46 || 3A || 1D || 0E || 7 || 8 || 11 || 23 || 3F | ||
+ | |- | ||
+ | | 47 || 39 || 1C || 0E || 7 || 8 || 11 || 23 || 3F | ||
+ | |- | ||
+ | | 48 || 38 || 1C || 0E || 7 || 8 || 12 || 24 || 3F | ||
+ | |- | ||
+ | | 49 || 37 || 1B || 0D || 6 || 9 || 12 || 24 || 3F | ||
+ | |- | ||
+ | | 4A || 36 || 1B || 0D || 6 || 9 || 12 || 25 || 3F | ||
+ | |- | ||
+ | | 4B || 35 || 1A || 0D || 6 || 9 || 12 || 25 || 3F | ||
+ | |- | ||
+ | | 4C || 34 || 1A || 0D || 6 || 9 || 13 || 26 || 3F | ||
+ | |- | ||
+ | | 4D || 33 || 19 || 0C || 6 || 9 || 13 || 26 || 3F | ||
+ | |- | ||
+ | | 4E || 32 || 19 || 0C || 6 || 9 || 13 || 27 || 3F | ||
+ | |- | ||
+ | | 4F || 31 || 18 || 0C || 6 || 9 || 13 || 27 || 3F | ||
+ | |- | ||
+ | | 50 || 30 || 18 || 0C || 6 || 9 || 14 || 28 || 3F | ||
+ | |- | ||
+ | | 51 || 2F || 17 || 0B || 5 || 0A || 14 || 28 || 3F | ||
+ | |- | ||
+ | | 52 || 2E || 17 || 0B || 5 || 0A || 14 || 29 || 3F | ||
+ | |- | ||
+ | | 53 || 2D || 16 || 0B || 5 || 0A || 14 || 29 || 3F | ||
+ | |- | ||
+ | | 54 || 2C || 16 || 0B || 5 || 0A || 15 || 2A || 3F | ||
+ | |- | ||
+ | | 55 || 2B || 15 || 0A || 5 || 0A || 15 || 2A || 3F | ||
+ | |- | ||
+ | | 56 || 2A || 15 || 0A || 5 || 0A || 15 || 2B || 3F | ||
+ | |- | ||
+ | | 57 || 29 || 14 || 0A || 5 || 0A || 15 || 2B || 3F | ||
+ | |- | ||
+ | | 58 || 28 || 14 || 0A || 5 || 0A || 16 || 2C || 3F | ||
+ | |- | ||
+ | | 59 || 27 || 13 || 9 || 4 || 0B || 16 || 2C || 3F | ||
+ | |- | ||
+ | | 5A || 26 || 13 || 9 || 4 || 0B || 16 || 2D || 3F | ||
+ | |- | ||
+ | | 5B || 25 || 12 || 9 || 4 || 0B || 16 || 2D || 3F | ||
+ | |- | ||
+ | | 5C || 24 || 12 || 9 || 4 || 0B || 17 || 2E || 3F | ||
+ | |- | ||
+ | | 5D || 23 || 11 || 8 || 4 || 0B || 17 || 2E || 3F | ||
+ | |- | ||
+ | | 5E || 22 || 11 || 8 || 4 || 0B || 17 || 2F || 3F | ||
+ | |- | ||
+ | | 5F || 21 || 10 || 8 || 4 || 0B || 17 || 2F || 3F | ||
+ | |- | ||
+ | | 60 || 20 || 10 || 8 || 4 || 0B || 18 || 30 || 3F | ||
+ | |- | ||
+ | | 61 || 1F || 0F || 7 || 3 || 0C || 18 || 30 || 3F | ||
+ | |- | ||
+ | | 62 || 1E || 0F || 7 || 3 || 0C || 18 || 31 || 3F | ||
+ | |- | ||
+ | | 63 || 1D || 0E || 7 || 3 || 0C || 18 || 31 || 3F | ||
+ | |- | ||
+ | | 64 || 1C || 0E || 7 || 3 || 0C || 19 || 32 || 3F | ||
+ | |- | ||
+ | | 65 || 1B || 0D || 6 || 3 || 0C || 19 || 32 || 3F | ||
+ | |- | ||
+ | | 66 || 1A || 0D || 6 || 3 || 0C || 19 || 33 || 3F | ||
+ | |- | ||
+ | | 67 || 19 || 0C || 6 || 3 || 0C || 19 || 33 || 3F | ||
+ | |- | ||
+ | | 68 || 18 || 0C || 6 || 3 || 0C || 1A || 34 || 3F | ||
+ | |- | ||
+ | | 69 || 17 || 0B || 5 || 2 || 0D || 1A || 34 || 3F | ||
+ | |- | ||
+ | | 6A || 16 || 0B || 5 || 2 || 0D || 1A || 35 || 3F | ||
+ | |- | ||
+ | | 6B || 15 || 0A || 5 || 2 || 0D || 1A || 35 || 3F | ||
+ | |- | ||
+ | | 6C || 14 || 0A || 5 || 2 || 0D || 1B || 36 || 3F | ||
+ | |- | ||
+ | | 6D || 13 || 9 || 4 || 2 || 0D || 1B || 36 || 3F | ||
+ | |- | ||
+ | | 6E || 12 || 9 || 4 || 2 || 0D || 1B || 37 || 3F | ||
+ | |- | ||
+ | | 6F || 11 || 8 || 4 || 2 || 0D || 1B || 37 || 3F | ||
+ | |- | ||
+ | | 70 || 10 || 8 || 4 || 2 || 0D || 1C || 38 || 3F | ||
+ | |- | ||
+ | | 71 || 0F || 7 || 3 || 1 || 0E || 1C || 38 || 3F | ||
+ | |- | ||
+ | | 72 || 0E || 7 || 3 || 1 || 0E || 1C || 39 || 3F | ||
+ | |- | ||
+ | | 73 || 0D || 6 || 3 || 1 || 0E || 1C || 39 || 3F | ||
+ | |- | ||
+ | | 74 || 0C || 6 || 3 || 1 || 0E || 1D || 3A || 3F | ||
+ | |- | ||
+ | | 75 || 0B || 5 || 2 || 1 || 0E || 1D || 3A || 3F | ||
+ | |- | ||
+ | | 76 || 0A || 5 || 2 || 1 || 0E || 1D || 3B || 3F | ||
+ | |- | ||
+ | | 77 || 9 || 4 || 2 || 1 || 0E || 1D || 3B || 3F | ||
+ | |- | ||
+ | | 78 || 8 || 4 || 2 || 1 || 0E || 1E || 3C || 3F | ||
+ | |- | ||
+ | | 79 || 7 || 3 || 1 || 0 || 0F || 1E || 3C || 3F | ||
+ | |- | ||
+ | | 7A || 6 || 3 || 1 || 0 || 0F || 1E || 3D || 3F | ||
+ | |- | ||
+ | | 7B || 5 || 2 || 1 || 0 || 0F || 1E || 3D || 3F | ||
+ | |- | ||
+ | | 7C || 4 || 2 || 1 || 0 || 0F || 1F || 3E || 3F | ||
+ | |- | ||
+ | | 7D || 3 || 1 || 0 || 0 || 0F || 1F || 3E || 3F | ||
+ | |- | ||
+ | | 7E || 2 || 1 || 0 || 0 || 0F || 1F || 3F || 3F | ||
+ | |- | ||
+ | | 7F || 1 || 0 || 0 || 0 || 0F || 1F || 3F || 3F | ||
+ | |} | ||
+ | |||
+ | ====Feedback Scaling Table==== | ||
+ | |||
+ | The following is the lookup table for the feedback scaling macros. If the feedback value (0x4) has already been assigned, that value will be added to the scaling. The feedback value ranges from 0-7. | ||
+ | |||
+ | {| class="wikitable" | ||
+ | ! MIDI Velocity || 6 || 5 || 4 || 3 || 2 || 1 || FF || FE || FD || FC || FB || FA | ||
+ | |- | ||
+ | | 0 || 7 || 7 || 7 || 7 || 4 || 2 || 0 || 0 || 0 || 0 || 0 || 0 | ||
+ | |- | ||
+ | | 1 || 7 || 7 || 7 || 7 || 3 || 1 || 0 || 0 || 0 || 0 || 0 || 0 | ||
+ | |- | ||
+ | | 2 || 7 || 7 || 7 || 7 || 3 || 1 || 0 || 0 || 0 || 0 || 0 || 1 | ||
+ | |- | ||
+ | | 3 || 7 || 7 || 7 || 7 || 3 || 1 || 0 || 0 || 0 || 0 || 0 || 1 | ||
+ | |- | ||
+ | | 4 || 7 || 7 || 7 || 7 || 3 || 1 || 0 || 0 || 0 || 0 || 1 || 2 | ||
+ | |- | ||
+ | | 5 || 7 || 7 || 7 || 7 || 3 || 1 || 0 || 0 || 0 || 0 || 1 || 2 | ||
+ | |- | ||
+ | | 6 || 7 || 7 || 7 || 7 || 3 || 1 || 0 || 0 || 0 || 0 || 1 || 3 | ||
+ | |- | ||
+ | | 7 || 7 || 7 || 7 || 7 || 3 || 1 || 0 || 0 || 0 || 0 || 1 || 3 | ||
+ | |- | ||
+ | | 8 || 7 || 7 || 7 || 7 || 3 || 1 || 0 || 0 || 0 || 1 || 2 || 4 | ||
+ | |- | ||
+ | | 9 || 7 || 7 || 7 || 7 || 3 || 1 || 0 || 0 || 0 || 1 || 2 || 4 | ||
+ | |- | ||
+ | | 0A || 7 || 7 || 7 || 7 || 3 || 1 || 0 || 0 || 0 || 1 || 2 || 5 | ||
+ | |- | ||
+ | | 0B || 7 || 7 || 7 || 7 || 3 || 1 || 0 || 0 || 0 || 1 || 2 || 5 | ||
+ | |- | ||
+ | | 0C || 7 || 7 || 7 || 7 || 3 || 1 || 0 || 0 || 0 || 1 || 3 || 6 | ||
+ | |- | ||
+ | | 0D || 7 || 7 || 7 || 7 || 3 || 1 || 0 || 0 || 0 || 1 || 3 || 6 | ||
+ | |- | ||
+ | | 0E || 7 || 7 || 7 || 7 || 3 || 1 || 0 || 0 || 0 || 1 || 3 || 7 | ||
+ | |- | ||
+ | | 0F || 7 || 7 || 7 || 7 || 3 || 1 || 0 || 0 || 0 || 1 || 3 || 7 | ||
+ | |- | ||
+ | | 10 || 7 || 7 || 7 || 7 || 3 || 1 || 0 || 0 || 1 || 2 || 4 || 7 | ||
+ | |- | ||
+ | | 11 || 7 || 7 || 7 || 6 || 3 || 1 || 0 || 0 || 1 || 2 || 4 || 7 | ||
+ | |- | ||
+ | | 12 || 7 || 7 || 7 || 6 || 3 || 1 || 0 || 0 || 1 || 2 || 4 || 7 | ||
+ | |- | ||
+ | | 13 || 7 || 7 || 7 || 6 || 3 || 1 || 0 || 0 || 1 || 2 || 4 || 7 | ||
+ | |- | ||
+ | | 14 || 7 || 7 || 7 || 6 || 3 || 1 || 0 || 0 || 1 || 2 || 5 || 7 | ||
+ | |- | ||
+ | | 15 || 7 || 7 || 7 || 6 || 3 || 1 || 0 || 0 || 1 || 2 || 5 || 7 | ||
+ | |- | ||
+ | | 16 || 7 || 7 || 7 || 6 || 3 || 1 || 0 || 0 || 1 || 2 || 5 || 7 | ||
+ | |- | ||
+ | | 17 || 7 || 7 || 7 || 6 || 3 || 1 || 0 || 0 || 1 || 2 || 5 || 7 | ||
+ | |- | ||
+ | | 18 || 7 || 7 || 7 || 6 || 3 || 1 || 0 || 0 || 1 || 3 || 6 || 7 | ||
+ | |- | ||
+ | | 19 || 7 || 7 || 7 || 6 || 3 || 1 || 0 || 0 || 1 || 3 || 6 || 7 | ||
+ | |- | ||
+ | | 1A || 7 || 7 || 7 || 6 || 3 || 1 || 0 || 0 || 1 || 3 || 6 || 7 | ||
+ | |- | ||
+ | | 1B || 7 || 7 || 7 || 6 || 3 || 1 || 0 || 0 || 1 || 3 || 6 || 7 | ||
+ | |- | ||
+ | | 1C || 7 || 7 || 7 || 6 || 3 || 1 || 0 || 0 || 1 || 3 || 7 || 7 | ||
+ | |- | ||
+ | | 1D || 7 || 7 || 7 || 6 || 3 || 1 || 0 || 0 || 1 || 3 || 7 || 7 | ||
+ | |- | ||
+ | | 1E || 7 || 7 || 7 || 6 || 3 || 1 || 0 || 0 || 1 || 3 || 7 || 7 | ||
+ | |- | ||
+ | | 1F || 7 || 7 || 7 || 6 || 3 || 1 || 0 || 0 || 1 || 3 || 7 || 7 | ||
+ | |- | ||
+ | | 20 || 7 || 7 || 7 || 6 || 3 || 1 || 0 || 1 || 2 || 4 || 7 || 7 | ||
+ | |- | ||
+ | | 21 || 7 || 7 || 7 || 5 || 2 || 1 || 0 || 1 || 2 || 4 || 7 || 7 | ||
+ | |- | ||
+ | | 22 || 7 || 7 || 7 || 5 || 2 || 1 || 0 || 1 || 2 || 4 || 7 || 7 | ||
+ | |- | ||
+ | | 23 || 7 || 7 || 7 || 5 || 2 || 1 || 0 || 1 || 2 || 4 || 7 || 7 | ||
+ | |- | ||
+ | | 24 || 7 || 7 || 7 || 5 || 2 || 1 || 0 || 1 || 2 || 4 || 7 || 7 | ||
+ | |- | ||
+ | | 25 || 7 || 7 || 7 || 5 || 2 || 1 || 0 || 1 || 2 || 4 || 7 || 7 | ||
+ | |- | ||
+ | | 26 || 7 || 7 || 7 || 5 || 2 || 1 || 0 || 1 || 2 || 4 || 7 || 7 | ||
+ | |- | ||
+ | | 27 || 7 || 7 || 7 || 5 || 2 || 1 || 0 || 1 || 2 || 4 || 7 || 7 | ||
+ | |- | ||
+ | | 28 || 7 || 7 || 7 || 5 || 2 || 1 || 0 || 1 || 2 || 5 || 7 || 7 | ||
+ | |- | ||
+ | | 29 || 7 || 7 || 7 || 5 || 2 || 1 || 0 || 1 || 2 || 5 || 7 || 7 | ||
+ | |- | ||
+ | | 2A || 7 || 7 || 7 || 5 || 2 || 1 || 0 || 1 || 2 || 5 || 7 || 7 | ||
+ | |- | ||
+ | | 2B || 7 || 7 || 7 || 5 || 2 || 1 || 0 || 1 || 2 || 5 || 7 || 7 | ||
+ | |- | ||
+ | | 2C || 7 || 7 || 7 || 5 || 2 || 1 || 0 || 1 || 2 || 5 || 7 || 7 | ||
+ | |- | ||
+ | | 2D || 7 || 7 || 7 || 5 || 2 || 1 || 0 || 1 || 2 || 5 || 7 || 7 | ||
+ | |- | ||
+ | | 2E || 7 || 7 || 7 || 5 || 2 || 1 || 0 || 1 || 2 || 5 || 7 || 7 | ||
+ | |- | ||
+ | | 2F || 7 || 7 || 7 || 5 || 2 || 1 || 0 || 1 || 2 || 5 || 7 || 7 | ||
+ | |- | ||
+ | | 30 || 7 || 7 || 7 || 5 || 2 || 1 || 0 || 1 || 3 || 6 || 7 || 7 | ||
+ | |- | ||
+ | | 31 || 7 || 7 || 7 || 4 || 2 || 1 || 0 || 1 || 3 || 6 || 7 || 7 | ||
+ | |- | ||
+ | | 32 || 7 || 7 || 7 || 4 || 2 || 1 || 0 || 1 || 3 || 6 || 7 || 7 | ||
+ | |- | ||
+ | | 33 || 7 || 7 || 7 || 4 || 2 || 1 || 0 || 1 || 3 || 6 || 7 || 7 | ||
+ | |- | ||
+ | | 34 || 7 || 7 || 7 || 4 || 2 || 1 || 0 || 1 || 3 || 6 || 7 || 7 | ||
+ | |- | ||
+ | | 35 || 7 || 7 || 7 || 4 || 2 || 1 || 0 || 1 || 3 || 6 || 7 || 7 | ||
+ | |- | ||
+ | | 36 || 7 || 7 || 7 || 4 || 2 || 1 || 0 || 1 || 3 || 6 || 7 || 7 | ||
+ | |- | ||
+ | | 37 || 7 || 7 || 7 || 4 || 2 || 1 || 0 || 1 || 3 || 6 || 7 || 7 | ||
+ | |- | ||
+ | | 38 || 7 || 7 || 7 || 4 || 2 || 1 || 0 || 1 || 3 || 7 || 7 || 7 | ||
+ | |- | ||
+ | | 39 || 7 || 7 || 7 || 4 || 2 || 1 || 0 || 1 || 3 || 7 || 7 || 7 | ||
+ | |- | ||
+ | | 3A || 7 || 7 || 7 || 4 || 2 || 1 || 0 || 1 || 3 || 7 || 7 || 7 | ||
+ | |- | ||
+ | | 3B || 7 || 7 || 7 || 4 || 2 || 1 || 0 || 1 || 3 || 7 || 7 || 7 | ||
+ | |- | ||
+ | | 3C || 7 || 7 || 7 || 4 || 2 || 1 || 0 || 1 || 3 || 7 || 7 || 7 | ||
+ | |- | ||
+ | | 3D || 7 || 7 || 7 || 4 || 2 || 1 || 0 || 1 || 3 || 7 || 7 || 7 | ||
+ | |- | ||
+ | | 3E || 7 || 7 || 7 || 4 || 2 || 1 || 0 || 1 || 3 || 7 || 7 || 7 | ||
+ | |- | ||
+ | | 3F || 7 || 7 || 7 || 4 || 2 || 1 || 0 || 1 || 3 || 7 || 7 || 7 | ||
+ | |- | ||
+ | | 40 || 7 || 7 || 7 || 4 || 2 || 1 || 1 || 2 || 4 || 7 || 7 || 7 | ||
+ | |- | ||
+ | | 41 || 7 || 7 || 7 || 3 || 1 || 0 || 1 || 2 || 4 || 7 || 7 || 7 | ||
+ | |- | ||
+ | | 42 || 7 || 7 || 7 || 3 || 1 || 0 || 1 || 2 || 4 || 7 || 7 || 7 | ||
+ | |- | ||
+ | | 43 || 7 || 7 || 7 || 3 || 1 || 0 || 1 || 2 || 4 || 7 || 7 || 7 | ||
+ | |- | ||
+ | | 44 || 7 || 7 || 7 || 3 || 1 || 0 || 1 || 2 || 4 || 7 || 7 || 7 | ||
+ | |- | ||
+ | | 45 || 7 || 7 || 7 || 3 || 1 || 0 || 1 || 2 || 4 || 7 || 7 || 7 | ||
+ | |- | ||
+ | | 46 || 7 || 7 || 7 || 3 || 1 || 0 || 1 || 2 || 4 || 7 || 7 || 7 | ||
+ | |- | ||
+ | | 47 || 7 || 7 || 7 || 3 || 1 || 0 || 1 || 2 || 4 || 7 || 7 || 7 | ||
+ | |- | ||
+ | | 48 || 7 || 7 || 7 || 3 || 1 || 0 || 1 || 2 || 4 || 7 || 7 || 7 | ||
+ | |- | ||
+ | | 49 || 7 || 7 || 7 || 3 || 1 || 0 || 1 || 2 || 4 || 7 || 7 || 7 | ||
+ | |- | ||
+ | | 4A || 7 || 7 || 6 || 3 || 1 || 0 || 1 || 2 || 4 || 7 || 7 || 7 | ||
+ | |- | ||
+ | | 4B || 7 || 7 || 6 || 3 || 1 || 0 || 1 || 2 || 4 || 7 || 7 || 7 | ||
+ | |- | ||
+ | | 4C || 7 || 7 || 6 || 3 || 1 || 0 || 1 || 2 || 4 || 7 || 7 || 7 | ||
+ | |- | ||
+ | | 4D || 7 || 7 || 6 || 3 || 1 || 0 || 1 || 2 || 4 || 7 || 7 || 7 | ||
+ | |- | ||
+ | | 4E || 7 || 7 || 6 || 3 || 1 || 0 || 1 || 2 || 4 || 7 || 7 || 7 | ||
+ | |- | ||
+ | | 4F || 7 || 7 || 6 || 3 || 1 || 0 || 1 || 2 || 4 || 7 || 7 || 7 | ||
+ | |- | ||
+ | | 50 || 7 || 7 || 6 || 3 || 1 || 0 || 1 || 2 || 5 || 7 || 7 || 7 | ||
+ | |- | ||
+ | | 51 || 7 || 7 || 6 || 2 || 1 || 0 || 1 || 2 || 5 || 7 || 7 || 7 | ||
+ | |- | ||
+ | | 52 || 7 || 7 || 5 || 2 || 1 || 0 || 1 || 2 || 5 || 7 || 7 || 7 | ||
+ | |- | ||
+ | | 53 || 7 || 7 || 5 || 2 || 1 || 0 || 1 || 2 || 5 || 7 || 7 || 7 | ||
+ | |- | ||
+ | | 54 || 7 || 7 || 5 || 2 || 1 || 0 || 1 || 2 || 5 || 7 || 7 || 7 | ||
+ | |- | ||
+ | | 55 || 7 || 7 || 5 || 2 || 1 || 0 || 1 || 2 || 5 || 7 || 7 || 7 | ||
+ | |- | ||
+ | | 56 || 7 || 7 || 5 || 2 || 1 || 0 || 1 || 2 || 5 || 7 || 7 || 7 | ||
+ | |- | ||
+ | | 57 || 7 || 7 || 5 || 2 || 1 || 0 || 1 || 2 || 5 || 7 || 7 || 7 | ||
+ | |- | ||
+ | | 58 || 7 || 7 || 5 || 2 || 1 || 0 || 1 || 2 || 5 || 7 || 7 || 7 | ||
+ | |- | ||
+ | | 59 || 7 || 7 || 5 || 2 || 1 || 0 || 1 || 2 || 5 || 7 || 7 || 7 | ||
+ | |- | ||
+ | | 5A || 7 || 7 || 4 || 2 || 1 || 0 || 1 || 2 || 5 || 7 || 7 || 7 | ||
+ | |- | ||
+ | | 5B || 7 || 7 || 4 || 2 || 1 || 0 || 1 || 2 || 5 || 7 || 7 || 7 | ||
+ | |- | ||
+ | | 5C || 7 || 7 || 4 || 2 || 1 || 0 || 1 || 2 || 5 || 7 || 7 || 7 | ||
+ | |- | ||
+ | | 5D || 7 || 7 || 4 || 2 || 1 || 0 || 1 || 2 || 5 || 7 || 7 || 7 | ||
+ | |- | ||
+ | | 5E || 7 || 7 || 4 || 2 || 1 || 0 || 1 || 2 || 5 || 7 || 7 || 7 | ||
+ | |- | ||
+ | | 5F || 7 || 7 || 4 || 2 || 1 || 0 || 1 || 2 || 5 || 7 || 7 || 7 | ||
+ | |- | ||
+ | | 60 || 7 || 7 || 4 || 2 || 1 || 0 || 1 || 3 || 6 || 7 || 7 || 7 | ||
+ | |- | ||
+ | | 61 || 7 || 7 || 4 || 1 || 0 || 0 || 1 || 3 || 6 || 7 || 7 || 7 | ||
+ | |- | ||
+ | | 62 || 7 || 7 || 3 || 1 || 0 || 0 || 1 || 3 || 6 || 7 || 7 || 7 | ||
+ | |- | ||
+ | | 63 || 7 || 7 || 3 || 1 || 0 || 0 || 1 || 3 || 6 || 7 || 7 || 7 | ||
+ | |- | ||
+ | | 64 || 7 || 7 || 3 || 1 || 0 || 0 || 1 || 3 || 6 || 7 || 7 || 7 | ||
+ | |- | ||
+ | | 65 || 7 || 6 || 3 || 1 || 0 || 0 || 1 || 3 || 6 || 7 || 7 || 7 | ||
+ | |- | ||
+ | | 66 || 7 || 6 || 3 || 1 || 0 || 0 || 1 || 3 || 6 || 7 || 7 || 7 | ||
+ | |- | ||
+ | | 67 || 7 || 6 || 3 || 1 || 0 || 0 || 1 || 3 || 6 || 7 || 7 || 7 | ||
+ | |- | ||
+ | | 68 || 7 || 6 || 3 || 1 || 0 || 0 || 1 || 3 || 6 || 7 || 7 || 7 | ||
+ | |- | ||
+ | | 69 || 7 || 5 || 3 || 1 || 0 || 0 || 1 || 3 || 6 || 7 || 7 || 7 | ||
+ | |- | ||
+ | | 6A || 7 || 5 || 2 || 1 || 0 || 0 || 1 || 3 || 6 || 7 || 7 || 7 | ||
+ | |- | ||
+ | | 6B || 7 || 5 || 2 || 1 || 0 || 0 || 1 || 3 || 6 || 7 || 7 || 7 | ||
+ | |- | ||
+ | | 6C || 7 || 5 || 2 || 1 || 0 || 0 || 1 || 3 || 6 || 7 || 7 || 7 | ||
+ | |- | ||
+ | | 6D || 7 || 4 || 2 || 1 || 0 || 0 || 1 || 3 || 6 || 7 || 7 || 7 | ||
+ | |- | ||
+ | | 6E || 7 || 4 || 2 || 1 || 0 || 0 || 1 || 3 || 6 || 7 || 7 || 7 | ||
+ | |- | ||
+ | | 6F || 7 || 4 || 2 || 1 || 0 || 0 || 1 || 3 || 6 || 7 || 7 || 7 | ||
+ | |- | ||
+ | | 70 || 7 || 4 || 2 || 1 || 0 || 0 || 1 || 3 || 7 || 7 || 7 || 7 | ||
+ | |- | ||
+ | | 71 || 7 || 3 || 2 || 0 || 0 || 0 || 1 || 3 || 7 || 7 || 7 || 7 | ||
+ | |- | ||
+ | | 72 || 7 || 3 || 1 || 0 || 0 || 0 || 1 || 3 || 7 || 7 || 7 || 7 | ||
+ | |- | ||
+ | | 73 || 6 || 3 || 1 || 0 || 0 || 0 || 1 || 3 || 7 || 7 || 7 || 7 | ||
+ | |- | ||
+ | | 74 || 6 || 3 || 1 || 0 || 0 || 0 || 1 || 3 || 7 || 7 || 7 || 7 | ||
+ | |- | ||
+ | | 75 || 5 || 2 || 1 || 0 || 0 || 0 || 1 || 3 || 7 || 7 || 7 || 7 | ||
+ | |- | ||
+ | | 76 || 5 || 2 || 1 || 0 || 0 || 0 || 1 || 3 || 7 || 7 || 7 || 7 | ||
+ | |- | ||
+ | | 77 || 4 || 2 || 1 || 0 || 0 || 0 || 1 || 3 || 7 || 7 || 7 || 7 | ||
+ | |- | ||
+ | | 78 || 4 || 2 || 1 || 0 || 0 || 0 || 1 || 3 || 7 || 7 || 7 || 7 | ||
+ | |- | ||
+ | | 79 || 3 || 1 || 1 || 0 || 0 || 0 || 1 || 3 || 7 || 7 || 7 || 7 | ||
+ | |- | ||
+ | | 7A || 3 || 1 || 0 || 0 || 0 || 0 || 1 || 3 || 7 || 7 || 7 || 7 | ||
+ | |- | ||
+ | | 7B || 2 || 1 || 0 || 0 || 0 || 0 || 1 || 3 || 7 || 7 || 7 || 7 | ||
+ | |- | ||
+ | | 7C || 2 || 1 || 0 || 0 || 0 || 0 || 1 || 3 || 7 || 7 || 7 || 7 | ||
+ | |- | ||
+ | | 7D || 1 || 0 || 0 || 0 || 0 || 0 || 1 || 3 || 7 || 7 || 7 || 7 | ||
+ | |- | ||
+ | | 7E || 1 || 0 || 0 || 0 || 0 || 0 || 1 || 3 || 7 || 7 || 7 || 7 | ||
+ | |- | ||
+ | | 7F || 0 || 0 || 0 || 0 || 0 || 0 || 1 || 3 || 7 || 7 || 7 || 7 | ||
+ | |} | ||
+ | |||
+ | ====Root Note Macro==== | ||
+ | In the instrument chunk, offset 0x22 controls the root note of an instrument relative to a MIDI note's pitch, so for example, if you have a drum sound that you want to play at a particular pitch or you need your bass to be played an octave lower, you can set this byte to the pitch you want and the sequencer will play the instrument accordingly. | ||
+ | |||
+ | In HERAD version 1, the MIDI sequencer will take any note that's thrown at it and change the pitch, so if the value is 1 and the MIDI note that's being played is C4, then the sequencer will play C#4. If the note that needs to be changed is out of range on the MIDI keyboard (C1 to B8), HERAD will just play note C1 instead. | ||
+ | |||
+ | HERAD version 2 introduces some very different functionality when it comes to handling the root note. From value ranges D1-FF to 01-30, the root note works exactly the same as version 1. However, from D0 to B9 and 31 to 90, the pitches cycle through again but this time, MIDI Note pitches are ignored, so any note that is triggered in the sequencer has it's pitch overridden by the root note value. | ||
+ | |||
+ | The value range 91-B8 produces the same functionality, except if a MIDI Control Change event occurs, no notes after it will be played until the song repeats. No known HERAD instruments use this value range so it's most likely that this behavior is a glitch and is not used. | ||
+ | |||
+ | {| class="wikitable" | ||
+ | ! Root Note Macro Value Range | ||
+ | ! Function | ||
+ | |- | ||
+ | | 31 - 90 || MIDI NoteOn Pitch is ignored, all notes that are triggered will play the root note's pitch.<br>Note that 30 and 31 share the same pitch, the only difference is that 30 can still be affected by MIDI pitch and 31 has it's pitch locked. | ||
+ | |- | ||
+ | | 01 - 30 || Root note goes upward. | ||
+ | |- | ||
+ | | 00 || No change | ||
+ | |- | ||
+ | | FF - D1 || Signed integer; Root note goes downward. | ||
+ | |- | ||
+ | | D0 - B9 || Signed integer; MIDI NoteOn Pitch is ignored, all notes that are triggered will play the root note's pitch.<br>Note that D0 and D1 share the same pitch, the only difference is that D0 can still be affected by MIDI pitch and D1 has it's pitch locked. | ||
+ | |- | ||
+ | | B8 - 91 || Unused; does the same thing as the previous value range, except any MIDI Control Change events will cause no further notes to play until the song repeats. | ||
+ | |} | ||
+ | |||
+ | ====Keymap==== | ||
+ | |||
+ | Introduced in version 2 songs, a keymap control was added into the instrument chunk. All 6 songs in MegaRace use this keymapping for their drum sequencing. Like the other separate instruments in this chunk, it is also 0x28 bytes long, but differs greatly from the other instruments since it doesn't contain any OPL register values. | ||
+ | |||
+ | It is essentially an array of instruments that are mapped to different MIDI notes. Instead of having to send a Program Change MIDI message every time a different drum instrument is used, this keymap greatly reduces the amount of MIDI messages being sent since all the drum sounds are located in one instrument. | ||
+ | |||
+ | {| class="wikitable" | | ||
+ | ! Offset | ||
+ | ! Description | ||
+ | ! Notes | ||
+ | |- | ||
+ | | 0x0 | ||
+ | | <center>'''Mode'''</center> | ||
+ | | Must always be 0xFF; this denotes that this is a keymap | ||
+ | |- | ||
+ | | 0x1 | ||
+ | | <center>'''Voice Number'''</center> | ||
+ | | Most likely a meta identifier (so far, changing this value results in no effect) | ||
+ | |- | ||
+ | | 0x2 | ||
+ | | <center>'''Keymap Offset'''</center> | ||
+ | | Must always be 0x18; changing this will offset the instruments sounds. <br>Leaving this at 0x18 will have the keymap start at MIDI pitch #48 (aka C4). <br>Decreasing the value will start the keymap at a lower pitch.<br>For example, if you change the value to 0x11, the keymap will start at MIDI pitch #41 (aka F3) | ||
+ | |- | ||
+ | | 0x3 | ||
+ | | <center>Unknown</center> | ||
+ | | So far, changing this value results in no effect to any instruments inside the keymap range. <br>Some instruments outside the keymap range may be affected, but these aren't suppose to be heard anyway. | ||
+ | |- | ||
+ | | 0x4-0x27 | ||
+ | | <center>'''Instrument Array'''</center> | ||
+ | | List of instruments | ||
+ | |} | ||
+ | |||
+ | The keymap starts at MIDI pitch #48 (aka C4) and continues with each consecutive pitch (48, 49, 50, ..., etc). | ||
+ | |||
+ | Sometimes in the instrument array, there will be an instrument that covers several MIDI pitches, instead of just a single instance (for example, a tom-tom drum that requires different pitches). This is done by specifying the instrument's number (i.e. 0x10) and then for every repeating instrument, the keymap instrument's number itself is referenced. For example, let's say our keymap instrument is number "0xC" and we want to repeat the instrument "0x10" 8 times. We do this like so: <tt>10 0C 0C 0C 0C 0C 0C 0C</tt>. Sometimes, this doesn't work due to an unknown glitch (possibly to do with drums that are played very quickly - like the grace note between the kick and snare in MegaRace's "Skyholder"). Instead of referencing the keymap's instrument number, repeating the drum instrument number itself will also work and is a work around for this glitch. | ||
+ | |||
+ | Again, all instruments in the instrument chunk must be 0x28 bytes long, so when all the instruments in the array are specified, the remaining bytes are to be padded out by the keymap instrument number. | ||
==Links== | ==Links== | ||
* [[:File:MegaRace - DOS - Credits.png]] - HERAD system is mentioned in the credits of [[MegaRace (DOS)]]. | * [[:File:MegaRace - DOS - Credits.png]] - HERAD system is mentioned in the credits of [[MegaRace (DOS)]]. | ||
* [https://www.mobygames.com/developer/sheet/view/developerId,1760/ mobygames.com/developer/sheet/view/developerId,1760/] - HERAD System mentioned on MobyGames. | * [https://www.mobygames.com/developer/sheet/view/developerId,1760/ mobygames.com/developer/sheet/view/developerId,1760/] - HERAD System mentioned on MobyGames. | ||
− | * [http://sourceforge.net/p/adplug/feature-requests/18/ sourceforge.net/p/adplug/feature-requests/18/] - Format support request | + | * [http://www.vogons.org/viewtopic.php?f=7&t=49813 vogons.org/viewtopic.php?f=7&t=49813] - Discussion on VOGONS. |
+ | * [https://github.com/adplug/adplug/issues/39 github.com/adplug/adplug/issues/39] - Format support request in AdPlug repository. | ||
+ | * [http://sourceforge.net/p/adplug/feature-requests/18/ sourceforge.net/p/adplug/feature-requests/18/] - Format support request in old AdPlug repository. | ||
[[Category: MIDI]] | [[Category: MIDI]] |
Revision as of 11:33, 9 May 2017
HERAD System | |||||
Developer: | Rémi Herbulot | ||||
Header: | Custom | ||||
Content: | Notational | ||||
Instruments: | Optional | ||||
Target Output
| |||||
Released: | 1992-??-?? | ||||
First Game: | Dune (DOS) | ||||
Extensions |
|
Herbulot AdLib (HERAD) System was created by Rémi Herbulot, one of Cryo Interactive Entertainment co-founders and lead programmers. Stéphane Picq, Cryo's first music composer also helped design HERAD with Herbulot. There are two versions of HERAD that are known to exist.
Stéphane Picq had this to say about HERAD:
Dune (the first game to utilize HERAD) lists in the credit roll a special thanks to "Henri Chalifour and Grant Hamilton from the Ad Lib Company", who also were involved in the development of the music format.
Henri Chalifour said this in regards to HERAD development on Dune:
HERAD was used in only three games: Dune, KGB aka Conspiracy, and MegaRace. All three games have been arguably rated as some of the best DOS game soundtracks ever written for OPL2.
Contents
Players
- RdosPlay - DOS - only version 1 (OPL2/OPL3 music)
Converters
HERAD to ?
? to HERAD
Games
Released | Title | Sample |
---|---|---|
1992-??-?? | Dune (DOS) | |
1992-??-?? | KGB (DOS) | |
1993-??-?? | MegaRace (DOS) | |
Technical Specifiations
File Formats
HERAD comes in several different file formats. The data is usually packed inside HSQ or SQX files.
- HSQ are compressed files with the Herbulot Sequencer algorithm, which is similar to LZ** dictionary algorithms. HSQ files can be found in Dune and MegaRace.
- SQX is another compression format, that seems to be similar to HSQ, but decompression is currently not possible except for playback in RDOSPlay.
- In the non-interactive demo for Dune, the music files are compressed in a format called SQZ, however, these files are identical to HSQ files.
Once the data is decompressed, there are several different file extensions that are used. Since HSQ doesn't keep the original data's filename or extention, it is assumed that these file extentions are retronyms and were given to the raw data after they were decompressed.
- The file extensions stand for different sound devices:
- SDB - AdLib/Sound Blaster (OPL2)
- AGD - AdLib Gold 1000 (OPL3)
- M32 - Roland MT-32 (LA32)
Musical Notation
- The internal music notation is very similar to MIDI, however Pitch Bend and Meta events do differ.
- M32 files usually contain one multi-channel track, while SDB/AGD files may contain multiple tracks.
- Despite all MIDI tracks use channel 1, any channel number can be used as this number is simply ignored.
Speech Synthesis
As heard in the KGB song, "Gorbi", the word "Gorbachev" is played around 1:00. It was assumed that speech synthesis or perhaps PCM audio was possible with HERAD; however, after analyzing the uncompressed music file, it turns out the speech synthesis is just very clever MIDI sequencing and OPL2 programming done by Stéphane Picq to produce pseudo-speech synthesis.
Version Compatibility
The format has two known versions, which have several differences; however, neither version has any FourCC or header data denoting which version it is. In order to detect the proper version, each music file needs to be inspected.
The first version was used in Dune and KGB, and the second version was used in MegaRace.
File structure
There are three chunks to HERAD files: the header, the MIDI data, and the AdLib Instrument chunk. Note that the Instrument chunk is absent in M32 files.
Header
All values in the header are in little endian format. For M32 files, the wFileSize value represents the total file size, while AGD and SDB files, it represents the file size without the instrument data block.
Data type | Name | Description |
---|---|---|
UINT16 | wFileSize | Size of uncompressed file / Instrument Chunk offset |
UINT16[21] | wOffsets | Array of relative offsets to the MIDI tracks (0 = track doesn't exist) |
UINT16 | wLoopStart | Loop starts at this measure (0 = don't loop) |
UINT16 | wLoopEnd | Loop ends at this measure (0 = don't loop) |
UINT16 | wLoopCount | Number of times the selected measures will play (0 = loop forever; >0 - play N times) |
UINT16 | wSpeed | Fixed point value that controls music speed. Value range is 0x0100 - 0x8100 |
UINT8[32] | bGoldRegs | Register values for AdLib Gold 1000 surround module. Only found in AGD files Modifying these values produces no changes to regular OPL3 playback |
Looping
Looping a song works by specifying the start and end points with the wLoopStart and wLoopEnd bytes, and denoting how many times the loop should play with the wLoopCount byte. This can be used to either play a song forever, or to play a song that doesn't repeat but has a short segment that loops instead (like a repeating melody or phrase). For example, to loop the first two measures of the song, the wLoopStart byte will be 01 and the wLoopEnd byte will be 03. A measure is 96 MIDI ticks in duration.
For version 1 songs, in order for music to repeat, this loop data must be in place. Version 2 songs that are being played back in MegaRace's sound engine will automatically repeat forever even if the wLoopCount field specifies that the song should only be played once. If there are no loop points in the file, the version 2 song will automatically repeat from beginning to end. As a result, several tracks in MegaRace (NewSan, Maeva and Terminal City) have short loops that are only a few measures long. Because those loop points are being used, the music continues to loop the song from beginning to end due to the sound engine. The other remaining tracks from MegaRace (Factory Land, Skyholder and Fractalian Space) have intros to them that are not repeated so their loop points start at the end of the intro and finish when the song is over.
Speed / Tempo
The default tempo is 500 BPM with the MIDI data at 24 ticks per quarter note. Obviously, this default value is way too fast so to slow down the music, a fixed-point value must be entered into the wSpeed field. To calculate the tempo of the song, take 500 and divide it by the value. Since this is a fixed-point number, some BPM will be at odd values. HERAD driver refresh rate is around 200.299 Hz. You can calculate ticks per second frequency by dividing refresh rate by the speed value.
Some of these values were taken from MegaRace and Dune files.
Speed value | Fixed-Point value | Approximate BPM | Frequency (Hz) |
---|---|---|---|
0x0100 | 1.0 | 500 | = 200.299 |
0x03E0 | 3.875 | 129.032 | ≈ 51.69 |
0x0400 | 4.0 | 125 | ≈ 50.07 |
0x042B | 4.168 | 119.961 | ≈ 48.06 |
0x04B8 | 4.71875 | 105.960 | ≈ 42.45 |
0x0500 | 5 | 100 | ≈ 40.06 |
AdLib Gold Settings
In AGD files, there's an additional chunk of 32 bytes in the header before the MIDI notation begins. These bytes are register values for various settings on the rare AdLib Gold 1000 sound card.
Offset | Description | Notes |
---|---|---|
0x0 | |
0xD6 = pseudo stereo; 0xDE = spatial stereo. Since this seems to be the register value for the TDA8425 chip, other values should be valid (in theory). Dune only uses 0xD6 or 0xDE. According to the TDA8425 datasheet, spatial stereo is for handling stereo sound and pseudo stereo is for mono sound. |
0x1-0x1F | |
These are the raw register values for the YM7128 chip that is found on the Surround Module of the AdLib Gold 1000. The YM7128 creates the reverb and delay signal processing that the AdLib Gold 1000 is known for. |
Only two songs (MORNING and WORMSUIT) use the spatial stereo setting for the TDA8425.
MIDI notation
- Most of the status bytes are compatible with the MIDI standard.
- It looks like running status is not supported as all known songs programmed in HERAD never use it.
- All MIDI data for Cryo's games uses 24 ticks per quarter note.
MIDI message | Description | MIDI compatible |
---|---|---|
8# xx xx | Note Off (version 1) | Yes |
8# xx | Note Off (version 2) | No |
9# xx xx | Note On | Yes |
A# ?? ?? | Poly Aftertouch (unused) | Unknown |
B# xx xx | Control Change (M32) | Yes |
C# xx | Program Change (uses internal instruments for AGD and SDB) | Yes |
D# xx | Channel Aftertouch (only version 1) | Yes |
E# xx | Pitch Bend (AGD and SDB) | No |
E# xx xx | Pitch Bend (M32) | Yes |
FF | Track End |
Note Off
For the Note Off command in version 2 songs, the velocity byte has been removed. Some older MIDI sequencers back in the '80s and early '90s did this to stop sending redundant data.
Pitch Bend
In the AGD and SDB files Pitch Bend command has only the MSB byte available. Like the MIDI Standard dictates, 0x40 is the "center" of the pitch bend range. Sending this 0x40 data byte after the Pitch Bend status byte will result in no change to the pitch. This event does differ from it's MIDI counterpart since the value range for Pitch Bend is 0x00 to 0x80, which surpasses MIDI's 7-bit value range. 0x00 equals to 2 semitones down and 0x80 equals to 2 semitones up.
The frequency number range for pitch bends is 325 to 685. For example, if the sequencer were to play a 2 semitone pitch bend downwards from C to A#, it would start at FNum 343, go down to 325 and then decrease the block number and continue the pitch bend at 650 (B, which is 1 semitone down from C) and finally stopping at 614 aka A sharp. If a 2 semitone pitch bend upwards were to happen at B, the FNum will start at 650, continue to increment the FNum until it reaches 685. Once there, it goes to the next block number and resumes increasing the FNum starting at 343 (which is C) before finishing the pitch bend 2 semitones up at 364 (which is C sharp).
Because the pitch bend event has a full 8-bit value instead of MIDI's standard 7-bit value, it is possible to go up higher above 0x80. For example, a pitch bend value of 0xFF when played on a C note will bend the pitch all the way up to F#, a 6 semitone difference.
Channel Aftertouch
Dune uses Aftertouch events to control the velocity of sustaining notes, as heard in the song, "Morning". However, HERAD 2 drops support of Aftertouch completely. Songs that have Aftertouch events will still play but the aftertouch events will be ignored. In the MegaRace music files, Channel Aftertouch only occurs one time in one song (Fractalian Space).
Note Pitch / Frequency Number Table
HERAD uses MIDI Notes C1 to B8 (0x18 to 0x77). If any MIDI notes are out of range, the sequencer will play note C1. The Block number corresponds with the MIDI octave (Block number 0 = MIDI octave 1, Block number 1 = MIDI octave 2, etc).
MIDI Note | F-Num |
---|---|
C | 343 |
C# | 364 |
D | 385 |
D# | 408 |
E | 433 |
F | 459 |
F# | 486 |
G | 515 |
G# | 546 |
A | 579 |
A# | 614 |
B | 650 |
Instrument Data
The instrument chunk contains all the OPL register values needed for each instrument, along with some macros that control various parameters of the instrument during playback. Each instrument is 0x28 bytes long. Version 2 of HERAD introduced a keymap instrument that can be used for linking several instruments into one; this allows for some very complex drum sequencing.
To use an instrument, the MIDI notation must use the "Program Change" message and specify a number for the instrument to be used. All instruments are listed sequentially and the first instrument is always number #0. Let's say we want to play the 13th instrument in the chunk. We tell the MIDI data to Program Change to instrument number #12 (C0 0C) and the notation after that will play using that instrument until the end of the track or another Program Change message is sent.
It seems that the OPL register values are almost in the exact same layout as the BNK format (technical). Thanks to Malvineous for his documentation on the BNK file format.
These offsets are still a work in progress and need more research.
Offset | Size | Name | Description | OPL base register | Notes |
---|---|---|---|---|---|
0x0 | 1 | |
Denotes if this is an instrument or a version 2 keymap. Normally 0x0 in version 1 songs; either 0x1 or 0xFF in version 2 songs As long as this value is not set to 0xFF in a version 2 song, this can be set to any number. | ||
0x1 | 1 | |
Most likely a meta identifier (changing this value has no effect in any song) | ||
0x2 | 1 | ksl | |
0x40 (bits 6-7) | |
0x3 | 1 | multiple | |
0x20 (bits 0-3) | |
0x4 | 1 | feedback | |
0xC0 (bits 1-3) | |
0x5 | 1 | attack | |
0x60 (upper four bits) | |
0x6 | 1 | sustain | |
0x80 (upper four bits) | |
0x7 | 1 | eg | |
0x20 (bit 5) | nonzero value is on |
0x8 | 1 | decay | |
0x60 (lower four bits) | |
0x9 | 1 | releaseRate | |
0x80 (lower four bits) | |
0xA | 1 | totalLevel | |
0x40 (bit 0-5) | Output level is NOT affected by MIDI Velocity. To enable velocity, see offset 0x1E |
0xB | 1 | am | 0x20 (bit 7) | ||
0xC | 1 | vib | 0x20 (bit 6) | ||
0xD | 1 | ksr | |
0x20 (bit 4) | |
0xE | 1 | con | |
0xC0 (bit 0, inverted) | 0: OPL bit set to 1 other: OPL bit set to 0 |
0xF | 1 | ksl | |
0x40 (bits 6-7) | |
0x10 | 1 | multiple | |
0x20 (bits 0-3) | |
0x11 | 1 | |
0xC0 (upper four bits) | This controls the upper bits of the 0xC0 register to control panning in OPL3. 3 = both speakers; 2 = right speaker; 1 = left speaker MegaRace uses 3 as the default value. Dune's OPL2 driver ignores this byte and sets it to 0. Dune's OPL3 driver defaults any invaild value to both speakers. | |
0x12 | 1 | attack | |
0x60 (upper four bits) | |
0x13 | 1 | sustain | |
0x80 (upper four bits) | |
0x14 | 1 | eg | |
0x20 (bit 5) | nonzero value is on |
0x15 | 1 | decay | |
0x60 (lower four bits) | |
0x16 | 1 | releaseRate | |
0x80 (lower four bits) | |
0x17 | 1 | totalLevel | |
0x40 (bit 0-5) | Output level is NOT affected by MIDI Velocity. To enable velocity, see offset 0x1F |
0x18 | 1 | am | 0x20 (bit 7) | ||
0x19 | 1 | vib | 0x20 (bit 6) | ||
0x1A | 1 | ksr | |
0x20 (bit 4) | |
0x1B | 1 | HERAD Macro | |
0xC0 (bits 1-3) | This modifies feedback based off of MIDI Aftertouch events. Value range goes from 1-6 and FF-FA; 0 turns the scaling off. If Feedback (0x4) has already been assigned, that value will be added to the scaling. |
0x1C | 1 | |
0xE0 (bits 0-1) | Bits 0-2 for AGD | |
0x1D | 1 | |
0xE0 (bits 0-1) | Bits 0-2 for AGD | |
0x1E | 1 | HERAD Macro | |
0x40 (bit 0-5) | This uses the MIDI NoteOn velocity to control the Modulator Output level Value range goes from 1-4 and FF-FC; 0 turns the scaling off. Due to the design of the OPL2 chip, the higher values will decrease the volume and vice versa. |
0x1F | 1 | HERAD Macro | |
0x40 (bit 0-5) | Same as previous macro, only this affects the Carrier operator. Seems to multiply the velocity value; as a result some notes that are too loud or quiet will not be affected since the sum will be out of range for the OPL chip. |
0x20 | 1 | HERAD Macro | |
0xC0 (bits 1-3) | Same concept as the previous two macros, however this modifies feedback based off of MIDI NoteOn velocity. Value range goes from 1-6 and FF-FA; 0 turns the scaling off. If Feedback (0x4) has already been assigned, that value will be added to the scaling. |
0x21 | 1 | HERAD Macro | |
Increases pitch bend range (Fine tune = 0, Coarse tune = 1) | |
0x22 | 1 | HERAD Macro | |
Normally set at 0x0 and accepts signed integers, for example, 0xC = an octave higher; 0xF4 = an octave lower This macro functions very differently in HERAD version 2, see Root Note Macro | |
0x23 | 1 | HERAD Macro | Duration of the pitch bend in ticks | ||
0x24 | 1 | HERAD Macro | |
Signed integer value. For each MIDI tick, increase or decrease the FNUM by 1 when fine tune is on. When coarse tune is on, a 60-note scale is used (see Coarse Pitch Slide Frequency Table). | |
0x25 | 1 | Unknown | |
While this byte is used in some instruments for Dune, KGB, and MegaRace, extensive testing shows that this byte doesn't change any OPL registers or affect playback at all. This byte is considered unused. | |
0x26 | 1 | HERAD Macro | |
This uses the MIDI Channel Aftertouch events to modify the modulator output level. Just like in 0x1E, the value range goes from 1-4 and FF-FC; 0 turns the scaling off. For some reason, in version 2 instruments, this is always set to 0x1 | |
0x27 | 1 | HERAD Macro | |
This uses the MIDI Channel Aftertouch events to modify the carrier output level. Just like in 0x1F, the value range goes from 1-4 and FF-FC; 0 turns the scaling off. In MegaRace, this is always set to zero. In order for this macro to function, the 0x1F byte MUST be enabled. |
Coarse Pitch Slide Frequency Table
When the Pitch Slide Range Flag (0x21) is set to the coarse tune setting, 4 additional F-Nums are added to each note of the standard 12-note scale, resulting in a 60-note scale. The sequencer will cycle through all the F-Nums until the next Note Off or the pitch slide exceeds the MIDI Note Range or until the end of the Pitch Slide Duration (0x23).
MIDI Note and Corresponding F-Num | Additional F-Nums added to 12 note scale | ||||
---|---|---|---|---|---|
C | 343 | 348 | 353 | 358 | 363 |
C# | 364 | 369 | 374 | 379 | 384 |
D | 385 | 390 | 395 | 400 | 405 |
D# | 408 | 413 | 418 | 423 | 428 |
E | 433 | 438 | 443 | 448 | 453 |
F | 459 | 464 | 469 | 474 | 479 |
F# | 486 | 492 | 498 | 504 | 510 |
G | 515 | 521 | 527 | 533 | 539 |
G# | 546 | 552 | 558 | 564 | 570 |
A | 579 | 585 | 591 | 597 | 603 |
A# | 614 | 620 | 626 | 632 | 638 |
B | 650 | 656 | 662 | 668 | 674 |
Output Level Scaling Table
The following is the lookup table for the output level scaling macros. 3F is the quietest output level whereas 00 is the loudest. If any of the output level values (0xA and 0x17) have already been assigned, that value will be added to the scaling.
MIDI Velocity | 4 | 3 | 2 | 1 | FF | FE | FD | FC |
---|---|---|---|---|---|---|---|---|
0 | 3F | 3F | 20 | 10 | 0 | 0 | 0 | 0 |
1 | 3F | 3F | 1F | 0F | 0 | 0 | 0 | 1 |
2 | 3F | 3F | 1F | 0F | 0 | 0 | 1 | 2 |
3 | 3F | 3E | 1F | 0F | 0 | 0 | 1 | 3 |
4 | 3F | 3E | 1F | 0F | 0 | 1 | 2 | 4 |
5 | 3F | 3D | 1E | 0F | 0 | 1 | 2 | 5 |
6 | 3F | 3D | 1E | 0F | 0 | 1 | 3 | 6 |
7 | 3F | 3C | 1E | 0F | 0 | 1 | 3 | 7 |
8 | 3F | 3C | 1E | 0E | 1 | 2 | 4 | 8 |
9 | 3F | 3B | 1D | 0E | 1 | 2 | 4 | 9 |
0A | 3F | 3B | 1D | 0E | 1 | 2 | 5 | 0A |
0B | 3F | 3A | 1D | 0E | 1 | 2 | 5 | 0B |
0C | 3F | 3A | 1D | 0E | 1 | 3 | 6 | 0C |
0D | 3F | 39 | 1C | 0E | 1 | 3 | 6 | 0D |
0E | 3F | 39 | 1C | 0E | 1 | 3 | 7 | 0E |
0F | 3F | 38 | 1C | 0E | 1 | 3 | 7 | 0F |
10 | 3F | 38 | 1C | 0D | 2 | 4 | 8 | 10 |
11 | 3F | 37 | 1B | 0D | 2 | 4 | 8 | 11 |
12 | 3F | 37 | 1B | 0D | 2 | 4 | 9 | 12 |
13 | 3F | 36 | 1B | 0D | 2 | 4 | 9 | 13 |
14 | 3F | 36 | 1B | 0D | 2 | 5 | 0A | 14 |
15 | 3F | 35 | 1A | 0D | 2 | 5 | 0A | 15 |
16 | 3F | 35 | 1A | 0D | 2 | 5 | 0B | 16 |
17 | 3F | 34 | 1A | 0D | 2 | 5 | 0B | 17 |
18 | 3F | 34 | 1A | 0C | 3 | 6 | 0C | 18 |
19 | 3F | 33 | 19 | 0C | 3 | 6 | 0C | 19 |
1A | 3F | 33 | 19 | 0C | 3 | 6 | 0D | 1A |
1B | 3F | 32 | 19 | 0C | 3 | 6 | 0D | 1B |
1C | 3F | 32 | 19 | 0C | 3 | 7 | 0E | 1C |
1D | 3F | 31 | 18 | 0C | 3 | 7 | 0E | 1D |
1E | 3F | 31 | 18 | 0C | 3 | 7 | 0F | 1E |
1F | 3F | 30 | 18 | 0C | 3 | 7 | 0F | 1F |
20 | 3F | 30 | 18 | 0B | 4 | 8 | 10 | 20 |
21 | 3F | 2F | 17 | 0B | 4 | 8 | 10 | 21 |
22 | 3F | 2F | 17 | 0B | 4 | 8 | 11 | 22 |
23 | 3F | 2E | 17 | 0B | 4 | 8 | 11 | 23 |
24 | 3F | 2E | 17 | 0B | 4 | 9 | 12 | 24 |
25 | 3F | 2D | 16 | 0B | 4 | 9 | 12 | 25 |
26 | 3F | 2D | 16 | 0B | 4 | 9 | 13 | 26 |
27 | 3F | 2C | 16 | 0B | 4 | 9 | 13 | 27 |
28 | 3F | 2C | 16 | 0A | 5 | 0A | 14 | 28 |
29 | 3F | 2B | 15 | 0A | 5 | 0A | 14 | 29 |
2A | 3F | 2B | 15 | 0A | 5 | 0A | 15 | 2A |
2B | 3F | 2A | 15 | 0A | 5 | 0A | 15 | 2B |
2C | 3F | 2A | 15 | 0A | 5 | 0B | 16 | 2C |
2D | 3F | 29 | 14 | 0A | 5 | 0B | 16 | 2D |
2E | 3F | 29 | 14 | 0A | 5 | 0B | 17 | 2E |
2F | 3F | 28 | 14 | 0A | 5 | 0B | 17 | 2F |
30 | 3F | 28 | 14 | 9 | 6 | 0C | 18 | 30 |
31 | 3F | 27 | 13 | 9 | 6 | 0C | 18 | 31 |
32 | 3F | 27 | 13 | 9 | 6 | 0C | 19 | 32 |
33 | 3F | 26 | 13 | 9 | 6 | 0C | 19 | 33 |
34 | 3F | 26 | 13 | 9 | 6 | 0D | 1A | 34 |
35 | 3F | 25 | 12 | 9 | 6 | 0D | 1A | 35 |
36 | 3F | 25 | 12 | 9 | 6 | 0D | 1B | 36 |
37 | 3F | 24 | 12 | 9 | 6 | 0D | 1B | 37 |
38 | 3F | 24 | 12 | 8 | 7 | 0E | 1C | 38 |
39 | 3F | 23 | 11 | 8 | 7 | 0E | 1C | 39 |
3A | 3F | 23 | 11 | 8 | 7 | 0E | 1D | 3A |
3B | 3F | 22 | 11 | 8 | 7 | 0E | 1D | 3B |
3C | 3F | 22 | 11 | 8 | 7 | 0F | 1E | 3C |
3D | 3F | 21 | 10 | 8 | 7 | 0F | 1E | 3D |
3E | 3F | 21 | 10 | 8 | 7 | 0F | 1F | 3E |
3F | 3F | 20 | 10 | 8 | 7 | 0F | 1F | 3F |
40 | 3F | 20 | 10 | 7 | 7 | 10 | 20 | 3F |
41 | 3F | 1F | 0F | 7 | 8 | 10 | 20 | 3F |
42 | 3E | 1F | 0F | 7 | 8 | 10 | 21 | 3F |
43 | 3D | 1E | 0F | 7 | 8 | 10 | 21 | 3F |
44 | 3C | 1E | 0F | 7 | 8 | 11 | 22 | 3F |
45 | 3B | 1D | 0E | 7 | 8 | 11 | 22 | 3F |
46 | 3A | 1D | 0E | 7 | 8 | 11 | 23 | 3F |
47 | 39 | 1C | 0E | 7 | 8 | 11 | 23 | 3F |
48 | 38 | 1C | 0E | 7 | 8 | 12 | 24 | 3F |
49 | 37 | 1B | 0D | 6 | 9 | 12 | 24 | 3F |
4A | 36 | 1B | 0D | 6 | 9 | 12 | 25 | 3F |
4B | 35 | 1A | 0D | 6 | 9 | 12 | 25 | 3F |
4C | 34 | 1A | 0D | 6 | 9 | 13 | 26 | 3F |
4D | 33 | 19 | 0C | 6 | 9 | 13 | 26 | 3F |
4E | 32 | 19 | 0C | 6 | 9 | 13 | 27 | 3F |
4F | 31 | 18 | 0C | 6 | 9 | 13 | 27 | 3F |
50 | 30 | 18 | 0C | 6 | 9 | 14 | 28 | 3F |
51 | 2F | 17 | 0B | 5 | 0A | 14 | 28 | 3F |
52 | 2E | 17 | 0B | 5 | 0A | 14 | 29 | 3F |
53 | 2D | 16 | 0B | 5 | 0A | 14 | 29 | 3F |
54 | 2C | 16 | 0B | 5 | 0A | 15 | 2A | 3F |
55 | 2B | 15 | 0A | 5 | 0A | 15 | 2A | 3F |
56 | 2A | 15 | 0A | 5 | 0A | 15 | 2B | 3F |
57 | 29 | 14 | 0A | 5 | 0A | 15 | 2B | 3F |
58 | 28 | 14 | 0A | 5 | 0A | 16 | 2C | 3F |
59 | 27 | 13 | 9 | 4 | 0B | 16 | 2C | 3F |
5A | 26 | 13 | 9 | 4 | 0B | 16 | 2D | 3F |
5B | 25 | 12 | 9 | 4 | 0B | 16 | 2D | 3F |
5C | 24 | 12 | 9 | 4 | 0B | 17 | 2E | 3F |
5D | 23 | 11 | 8 | 4 | 0B | 17 | 2E | 3F |
5E | 22 | 11 | 8 | 4 | 0B | 17 | 2F | 3F |
5F | 21 | 10 | 8 | 4 | 0B | 17 | 2F | 3F |
60 | 20 | 10 | 8 | 4 | 0B | 18 | 30 | 3F |
61 | 1F | 0F | 7 | 3 | 0C | 18 | 30 | 3F |
62 | 1E | 0F | 7 | 3 | 0C | 18 | 31 | 3F |
63 | 1D | 0E | 7 | 3 | 0C | 18 | 31 | 3F |
64 | 1C | 0E | 7 | 3 | 0C | 19 | 32 | 3F |
65 | 1B | 0D | 6 | 3 | 0C | 19 | 32 | 3F |
66 | 1A | 0D | 6 | 3 | 0C | 19 | 33 | 3F |
67 | 19 | 0C | 6 | 3 | 0C | 19 | 33 | 3F |
68 | 18 | 0C | 6 | 3 | 0C | 1A | 34 | 3F |
69 | 17 | 0B | 5 | 2 | 0D | 1A | 34 | 3F |
6A | 16 | 0B | 5 | 2 | 0D | 1A | 35 | 3F |
6B | 15 | 0A | 5 | 2 | 0D | 1A | 35 | 3F |
6C | 14 | 0A | 5 | 2 | 0D | 1B | 36 | 3F |
6D | 13 | 9 | 4 | 2 | 0D | 1B | 36 | 3F |
6E | 12 | 9 | 4 | 2 | 0D | 1B | 37 | 3F |
6F | 11 | 8 | 4 | 2 | 0D | 1B | 37 | 3F |
70 | 10 | 8 | 4 | 2 | 0D | 1C | 38 | 3F |
71 | 0F | 7 | 3 | 1 | 0E | 1C | 38 | 3F |
72 | 0E | 7 | 3 | 1 | 0E | 1C | 39 | 3F |
73 | 0D | 6 | 3 | 1 | 0E | 1C | 39 | 3F |
74 | 0C | 6 | 3 | 1 | 0E | 1D | 3A | 3F |
75 | 0B | 5 | 2 | 1 | 0E | 1D | 3A | 3F |
76 | 0A | 5 | 2 | 1 | 0E | 1D | 3B | 3F |
77 | 9 | 4 | 2 | 1 | 0E | 1D | 3B | 3F |
78 | 8 | 4 | 2 | 1 | 0E | 1E | 3C | 3F |
79 | 7 | 3 | 1 | 0 | 0F | 1E | 3C | 3F |
7A | 6 | 3 | 1 | 0 | 0F | 1E | 3D | 3F |
7B | 5 | 2 | 1 | 0 | 0F | 1E | 3D | 3F |
7C | 4 | 2 | 1 | 0 | 0F | 1F | 3E | 3F |
7D | 3 | 1 | 0 | 0 | 0F | 1F | 3E | 3F |
7E | 2 | 1 | 0 | 0 | 0F | 1F | 3F | 3F |
7F | 1 | 0 | 0 | 0 | 0F | 1F | 3F | 3F |
Feedback Scaling Table
The following is the lookup table for the feedback scaling macros. If the feedback value (0x4) has already been assigned, that value will be added to the scaling. The feedback value ranges from 0-7.
MIDI Velocity | 6 | 5 | 4 | 3 | 2 | 1 | FF | FE | FD | FC | FB | FA |
---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 7 | 7 | 7 | 7 | 4 | 2 | 0 | 0 | 0 | 0 | 0 | 0 |
1 | 7 | 7 | 7 | 7 | 3 | 1 | 0 | 0 | 0 | 0 | 0 | 0 |
2 | 7 | 7 | 7 | 7 | 3 | 1 | 0 | 0 | 0 | 0 | 0 | 1 |
3 | 7 | 7 | 7 | 7 | 3 | 1 | 0 | 0 | 0 | 0 | 0 | 1 |
4 | 7 | 7 | 7 | 7 | 3 | 1 | 0 | 0 | 0 | 0 | 1 | 2 |
5 | 7 | 7 | 7 | 7 | 3 | 1 | 0 | 0 | 0 | 0 | 1 | 2 |
6 | 7 | 7 | 7 | 7 | 3 | 1 | 0 | 0 | 0 | 0 | 1 | 3 |
7 | 7 | 7 | 7 | 7 | 3 | 1 | 0 | 0 | 0 | 0 | 1 | 3 |
8 | 7 | 7 | 7 | 7 | 3 | 1 | 0 | 0 | 0 | 1 | 2 | 4 |
9 | 7 | 7 | 7 | 7 | 3 | 1 | 0 | 0 | 0 | 1 | 2 | 4 |
0A | 7 | 7 | 7 | 7 | 3 | 1 | 0 | 0 | 0 | 1 | 2 | 5 |
0B | 7 | 7 | 7 | 7 | 3 | 1 | 0 | 0 | 0 | 1 | 2 | 5 |
0C | 7 | 7 | 7 | 7 | 3 | 1 | 0 | 0 | 0 | 1 | 3 | 6 |
0D | 7 | 7 | 7 | 7 | 3 | 1 | 0 | 0 | 0 | 1 | 3 | 6 |
0E | 7 | 7 | 7 | 7 | 3 | 1 | 0 | 0 | 0 | 1 | 3 | 7 |
0F | 7 | 7 | 7 | 7 | 3 | 1 | 0 | 0 | 0 | 1 | 3 | 7 |
10 | 7 | 7 | 7 | 7 | 3 | 1 | 0 | 0 | 1 | 2 | 4 | 7 |
11 | 7 | 7 | 7 | 6 | 3 | 1 | 0 | 0 | 1 | 2 | 4 | 7 |
12 | 7 | 7 | 7 | 6 | 3 | 1 | 0 | 0 | 1 | 2 | 4 | 7 |
13 | 7 | 7 | 7 | 6 | 3 | 1 | 0 | 0 | 1 | 2 | 4 | 7 |
14 | 7 | 7 | 7 | 6 | 3 | 1 | 0 | 0 | 1 | 2 | 5 | 7 |
15 | 7 | 7 | 7 | 6 | 3 | 1 | 0 | 0 | 1 | 2 | 5 | 7 |
16 | 7 | 7 | 7 | 6 | 3 | 1 | 0 | 0 | 1 | 2 | 5 | 7 |
17 | 7 | 7 | 7 | 6 | 3 | 1 | 0 | 0 | 1 | 2 | 5 | 7 |
18 | 7 | 7 | 7 | 6 | 3 | 1 | 0 | 0 | 1 | 3 | 6 | 7 |
19 | 7 | 7 | 7 | 6 | 3 | 1 | 0 | 0 | 1 | 3 | 6 | 7 |
1A | 7 | 7 | 7 | 6 | 3 | 1 | 0 | 0 | 1 | 3 | 6 | 7 |
1B | 7 | 7 | 7 | 6 | 3 | 1 | 0 | 0 | 1 | 3 | 6 | 7 |
1C | 7 | 7 | 7 | 6 | 3 | 1 | 0 | 0 | 1 | 3 | 7 | 7 |
1D | 7 | 7 | 7 | 6 | 3 | 1 | 0 | 0 | 1 | 3 | 7 | 7 |
1E | 7 | 7 | 7 | 6 | 3 | 1 | 0 | 0 | 1 | 3 | 7 | 7 |
1F | 7 | 7 | 7 | 6 | 3 | 1 | 0 | 0 | 1 | 3 | 7 | 7 |
20 | 7 | 7 | 7 | 6 | 3 | 1 | 0 | 1 | 2 | 4 | 7 | 7 |
21 | 7 | 7 | 7 | 5 | 2 | 1 | 0 | 1 | 2 | 4 | 7 | 7 |
22 | 7 | 7 | 7 | 5 | 2 | 1 | 0 | 1 | 2 | 4 | 7 | 7 |
23 | 7 | 7 | 7 | 5 | 2 | 1 | 0 | 1 | 2 | 4 | 7 | 7 |
24 | 7 | 7 | 7 | 5 | 2 | 1 | 0 | 1 | 2 | 4 | 7 | 7 |
25 | 7 | 7 | 7 | 5 | 2 | 1 | 0 | 1 | 2 | 4 | 7 | 7 |
26 | 7 | 7 | 7 | 5 | 2 | 1 | 0 | 1 | 2 | 4 | 7 | 7 |
27 | 7 | 7 | 7 | 5 | 2 | 1 | 0 | 1 | 2 | 4 | 7 | 7 |
28 | 7 | 7 | 7 | 5 | 2 | 1 | 0 | 1 | 2 | 5 | 7 | 7 |
29 | 7 | 7 | 7 | 5 | 2 | 1 | 0 | 1 | 2 | 5 | 7 | 7 |
2A | 7 | 7 | 7 | 5 | 2 | 1 | 0 | 1 | 2 | 5 | 7 | 7 |
2B | 7 | 7 | 7 | 5 | 2 | 1 | 0 | 1 | 2 | 5 | 7 | 7 |
2C | 7 | 7 | 7 | 5 | 2 | 1 | 0 | 1 | 2 | 5 | 7 | 7 |
2D | 7 | 7 | 7 | 5 | 2 | 1 | 0 | 1 | 2 | 5 | 7 | 7 |
2E | 7 | 7 | 7 | 5 | 2 | 1 | 0 | 1 | 2 | 5 | 7 | 7 |
2F | 7 | 7 | 7 | 5 | 2 | 1 | 0 | 1 | 2 | 5 | 7 | 7 |
30 | 7 | 7 | 7 | 5 | 2 | 1 | 0 | 1 | 3 | 6 | 7 | 7 |
31 | 7 | 7 | 7 | 4 | 2 | 1 | 0 | 1 | 3 | 6 | 7 | 7 |
32 | 7 | 7 | 7 | 4 | 2 | 1 | 0 | 1 | 3 | 6 | 7 | 7 |
33 | 7 | 7 | 7 | 4 | 2 | 1 | 0 | 1 | 3 | 6 | 7 | 7 |
34 | 7 | 7 | 7 | 4 | 2 | 1 | 0 | 1 | 3 | 6 | 7 | 7 |
35 | 7 | 7 | 7 | 4 | 2 | 1 | 0 | 1 | 3 | 6 | 7 | 7 |
36 | 7 | 7 | 7 | 4 | 2 | 1 | 0 | 1 | 3 | 6 | 7 | 7 |
37 | 7 | 7 | 7 | 4 | 2 | 1 | 0 | 1 | 3 | 6 | 7 | 7 |
38 | 7 | 7 | 7 | 4 | 2 | 1 | 0 | 1 | 3 | 7 | 7 | 7 |
39 | 7 | 7 | 7 | 4 | 2 | 1 | 0 | 1 | 3 | 7 | 7 | 7 |
3A | 7 | 7 | 7 | 4 | 2 | 1 | 0 | 1 | 3 | 7 | 7 | 7 |
3B | 7 | 7 | 7 | 4 | 2 | 1 | 0 | 1 | 3 | 7 | 7 | 7 |
3C | 7 | 7 | 7 | 4 | 2 | 1 | 0 | 1 | 3 | 7 | 7 | 7 |
3D | 7 | 7 | 7 | 4 | 2 | 1 | 0 | 1 | 3 | 7 | 7 | 7 |
3E | 7 | 7 | 7 | 4 | 2 | 1 | 0 | 1 | 3 | 7 | 7 | 7 |
3F | 7 | 7 | 7 | 4 | 2 | 1 | 0 | 1 | 3 | 7 | 7 | 7 |
40 | 7 | 7 | 7 | 4 | 2 | 1 | 1 | 2 | 4 | 7 | 7 | 7 |
41 | 7 | 7 | 7 | 3 | 1 | 0 | 1 | 2 | 4 | 7 | 7 | 7 |
42 | 7 | 7 | 7 | 3 | 1 | 0 | 1 | 2 | 4 | 7 | 7 | 7 |
43 | 7 | 7 | 7 | 3 | 1 | 0 | 1 | 2 | 4 | 7 | 7 | 7 |
44 | 7 | 7 | 7 | 3 | 1 | 0 | 1 | 2 | 4 | 7 | 7 | 7 |
45 | 7 | 7 | 7 | 3 | 1 | 0 | 1 | 2 | 4 | 7 | 7 | 7 |
46 | 7 | 7 | 7 | 3 | 1 | 0 | 1 | 2 | 4 | 7 | 7 | 7 |
47 | 7 | 7 | 7 | 3 | 1 | 0 | 1 | 2 | 4 | 7 | 7 | 7 |
48 | 7 | 7 | 7 | 3 | 1 | 0 | 1 | 2 | 4 | 7 | 7 | 7 |
49 | 7 | 7 | 7 | 3 | 1 | 0 | 1 | 2 | 4 | 7 | 7 | 7 |
4A | 7 | 7 | 6 | 3 | 1 | 0 | 1 | 2 | 4 | 7 | 7 | 7 |
4B | 7 | 7 | 6 | 3 | 1 | 0 | 1 | 2 | 4 | 7 | 7 | 7 |
4C | 7 | 7 | 6 | 3 | 1 | 0 | 1 | 2 | 4 | 7 | 7 | 7 |
4D | 7 | 7 | 6 | 3 | 1 | 0 | 1 | 2 | 4 | 7 | 7 | 7 |
4E | 7 | 7 | 6 | 3 | 1 | 0 | 1 | 2 | 4 | 7 | 7 | 7 |
4F | 7 | 7 | 6 | 3 | 1 | 0 | 1 | 2 | 4 | 7 | 7 | 7 |
50 | 7 | 7 | 6 | 3 | 1 | 0 | 1 | 2 | 5 | 7 | 7 | 7 |
51 | 7 | 7 | 6 | 2 | 1 | 0 | 1 | 2 | 5 | 7 | 7 | 7 |
52 | 7 | 7 | 5 | 2 | 1 | 0 | 1 | 2 | 5 | 7 | 7 | 7 |
53 | 7 | 7 | 5 | 2 | 1 | 0 | 1 | 2 | 5 | 7 | 7 | 7 |
54 | 7 | 7 | 5 | 2 | 1 | 0 | 1 | 2 | 5 | 7 | 7 | 7 |
55 | 7 | 7 | 5 | 2 | 1 | 0 | 1 | 2 | 5 | 7 | 7 | 7 |
56 | 7 | 7 | 5 | 2 | 1 | 0 | 1 | 2 | 5 | 7 | 7 | 7 |
57 | 7 | 7 | 5 | 2 | 1 | 0 | 1 | 2 | 5 | 7 | 7 | 7 |
58 | 7 | 7 | 5 | 2 | 1 | 0 | 1 | 2 | 5 | 7 | 7 | 7 |
59 | 7 | 7 | 5 | 2 | 1 | 0 | 1 | 2 | 5 | 7 | 7 | 7 |
5A | 7 | 7 | 4 | 2 | 1 | 0 | 1 | 2 | 5 | 7 | 7 | 7 |
5B | 7 | 7 | 4 | 2 | 1 | 0 | 1 | 2 | 5 | 7 | 7 | 7 |
5C | 7 | 7 | 4 | 2 | 1 | 0 | 1 | 2 | 5 | 7 | 7 | 7 |
5D | 7 | 7 | 4 | 2 | 1 | 0 | 1 | 2 | 5 | 7 | 7 | 7 |
5E | 7 | 7 | 4 | 2 | 1 | 0 | 1 | 2 | 5 | 7 | 7 | 7 |
5F | 7 | 7 | 4 | 2 | 1 | 0 | 1 | 2 | 5 | 7 | 7 | 7 |
60 | 7 | 7 | 4 | 2 | 1 | 0 | 1 | 3 | 6 | 7 | 7 | 7 |
61 | 7 | 7 | 4 | 1 | 0 | 0 | 1 | 3 | 6 | 7 | 7 | 7 |
62 | 7 | 7 | 3 | 1 | 0 | 0 | 1 | 3 | 6 | 7 | 7 | 7 |
63 | 7 | 7 | 3 | 1 | 0 | 0 | 1 | 3 | 6 | 7 | 7 | 7 |
64 | 7 | 7 | 3 | 1 | 0 | 0 | 1 | 3 | 6 | 7 | 7 | 7 |
65 | 7 | 6 | 3 | 1 | 0 | 0 | 1 | 3 | 6 | 7 | 7 | 7 |
66 | 7 | 6 | 3 | 1 | 0 | 0 | 1 | 3 | 6 | 7 | 7 | 7 |
67 | 7 | 6 | 3 | 1 | 0 | 0 | 1 | 3 | 6 | 7 | 7 | 7 |
68 | 7 | 6 | 3 | 1 | 0 | 0 | 1 | 3 | 6 | 7 | 7 | 7 |
69 | 7 | 5 | 3 | 1 | 0 | 0 | 1 | 3 | 6 | 7 | 7 | 7 |
6A | 7 | 5 | 2 | 1 | 0 | 0 | 1 | 3 | 6 | 7 | 7 | 7 |
6B | 7 | 5 | 2 | 1 | 0 | 0 | 1 | 3 | 6 | 7 | 7 | 7 |
6C | 7 | 5 | 2 | 1 | 0 | 0 | 1 | 3 | 6 | 7 | 7 | 7 |
6D | 7 | 4 | 2 | 1 | 0 | 0 | 1 | 3 | 6 | 7 | 7 | 7 |
6E | 7 | 4 | 2 | 1 | 0 | 0 | 1 | 3 | 6 | 7 | 7 | 7 |
6F | 7 | 4 | 2 | 1 | 0 | 0 | 1 | 3 | 6 | 7 | 7 | 7 |
70 | 7 | 4 | 2 | 1 | 0 | 0 | 1 | 3 | 7 | 7 | 7 | 7 |
71 | 7 | 3 | 2 | 0 | 0 | 0 | 1 | 3 | 7 | 7 | 7 | 7 |
72 | 7 | 3 | 1 | 0 | 0 | 0 | 1 | 3 | 7 | 7 | 7 | 7 |
73 | 6 | 3 | 1 | 0 | 0 | 0 | 1 | 3 | 7 | 7 | 7 | 7 |
74 | 6 | 3 | 1 | 0 | 0 | 0 | 1 | 3 | 7 | 7 | 7 | 7 |
75 | 5 | 2 | 1 | 0 | 0 | 0 | 1 | 3 | 7 | 7 | 7 | 7 |
76 | 5 | 2 | 1 | 0 | 0 | 0 | 1 | 3 | 7 | 7 | 7 | 7 |
77 | 4 | 2 | 1 | 0 | 0 | 0 | 1 | 3 | 7 | 7 | 7 | 7 |
78 | 4 | 2 | 1 | 0 | 0 | 0 | 1 | 3 | 7 | 7 | 7 | 7 |
79 | 3 | 1 | 1 | 0 | 0 | 0 | 1 | 3 | 7 | 7 | 7 | 7 |
7A | 3 | 1 | 0 | 0 | 0 | 0 | 1 | 3 | 7 | 7 | 7 | 7 |
7B | 2 | 1 | 0 | 0 | 0 | 0 | 1 | 3 | 7 | 7 | 7 | 7 |
7C | 2 | 1 | 0 | 0 | 0 | 0 | 1 | 3 | 7 | 7 | 7 | 7 |
7D | 1 | 0 | 0 | 0 | 0 | 0 | 1 | 3 | 7 | 7 | 7 | 7 |
7E | 1 | 0 | 0 | 0 | 0 | 0 | 1 | 3 | 7 | 7 | 7 | 7 |
7F | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 3 | 7 | 7 | 7 | 7 |
Root Note Macro
In the instrument chunk, offset 0x22 controls the root note of an instrument relative to a MIDI note's pitch, so for example, if you have a drum sound that you want to play at a particular pitch or you need your bass to be played an octave lower, you can set this byte to the pitch you want and the sequencer will play the instrument accordingly.
In HERAD version 1, the MIDI sequencer will take any note that's thrown at it and change the pitch, so if the value is 1 and the MIDI note that's being played is C4, then the sequencer will play C#4. If the note that needs to be changed is out of range on the MIDI keyboard (C1 to B8), HERAD will just play note C1 instead.
HERAD version 2 introduces some very different functionality when it comes to handling the root note. From value ranges D1-FF to 01-30, the root note works exactly the same as version 1. However, from D0 to B9 and 31 to 90, the pitches cycle through again but this time, MIDI Note pitches are ignored, so any note that is triggered in the sequencer has it's pitch overridden by the root note value.
The value range 91-B8 produces the same functionality, except if a MIDI Control Change event occurs, no notes after it will be played until the song repeats. No known HERAD instruments use this value range so it's most likely that this behavior is a glitch and is not used.
Root Note Macro Value Range | Function |
---|---|
31 - 90 | MIDI NoteOn Pitch is ignored, all notes that are triggered will play the root note's pitch. Note that 30 and 31 share the same pitch, the only difference is that 30 can still be affected by MIDI pitch and 31 has it's pitch locked. |
01 - 30 | Root note goes upward. |
00 | No change |
FF - D1 | Signed integer; Root note goes downward. |
D0 - B9 | Signed integer; MIDI NoteOn Pitch is ignored, all notes that are triggered will play the root note's pitch. Note that D0 and D1 share the same pitch, the only difference is that D0 can still be affected by MIDI pitch and D1 has it's pitch locked. |
B8 - 91 | Unused; does the same thing as the previous value range, except any MIDI Control Change events will cause no further notes to play until the song repeats. |
Keymap
Introduced in version 2 songs, a keymap control was added into the instrument chunk. All 6 songs in MegaRace use this keymapping for their drum sequencing. Like the other separate instruments in this chunk, it is also 0x28 bytes long, but differs greatly from the other instruments since it doesn't contain any OPL register values.
It is essentially an array of instruments that are mapped to different MIDI notes. Instead of having to send a Program Change MIDI message every time a different drum instrument is used, this keymap greatly reduces the amount of MIDI messages being sent since all the drum sounds are located in one instrument.
Offset | Description | Notes |
---|---|---|
0x0 | |
Must always be 0xFF; this denotes that this is a keymap |
0x1 | |
Most likely a meta identifier (so far, changing this value results in no effect) |
0x2 | |
Must always be 0x18; changing this will offset the instruments sounds. Leaving this at 0x18 will have the keymap start at MIDI pitch #48 (aka C4). Decreasing the value will start the keymap at a lower pitch. For example, if you change the value to 0x11, the keymap will start at MIDI pitch #41 (aka F3) |
0x3 | |
So far, changing this value results in no effect to any instruments inside the keymap range. Some instruments outside the keymap range may be affected, but these aren't suppose to be heard anyway. |
0x4-0x27 | |
List of instruments |
The keymap starts at MIDI pitch #48 (aka C4) and continues with each consecutive pitch (48, 49, 50, ..., etc).
Sometimes in the instrument array, there will be an instrument that covers several MIDI pitches, instead of just a single instance (for example, a tom-tom drum that requires different pitches). This is done by specifying the instrument's number (i.e. 0x10) and then for every repeating instrument, the keymap instrument's number itself is referenced. For example, let's say our keymap instrument is number "0xC" and we want to repeat the instrument "0x10" 8 times. We do this like so: 10 0C 0C 0C 0C 0C 0C 0C. Sometimes, this doesn't work due to an unknown glitch (possibly to do with drums that are played very quickly - like the grace note between the kick and snare in MegaRace's "Skyholder"). Instead of referencing the keymap's instrument number, repeating the drum instrument number itself will also work and is a work around for this glitch.
Again, all instruments in the instrument chunk must be 0x28 bytes long, so when all the instruments in the array are specified, the remaining bytes are to be padded out by the keymap instrument number.
Links
- File:MegaRace - DOS - Credits.png - HERAD system is mentioned in the credits of MegaRace (DOS).
- mobygames.com/developer/sheet/view/developerId,1760/ - HERAD System mentioned on MobyGames.
- vogons.org/viewtopic.php?f=7&t=49813 - Discussion on VOGONS.
- github.com/adplug/adplug/issues/39 - Format support request in AdPlug repository.
- sourceforge.net/p/adplug/feature-requests/18/ - Format support request in old AdPlug repository.