EAD SoundBank Missing Fine-Tuning (And Additional Debug Output Required)
L-Spiro opened this issue · 1 comments
I am trying to build the tools myself so that I can add this data to the debug output, but the tools are not possible to build thanks to the issue I reported (#45). If there is a way around that I should be able to add this feature myself, but until this I am reporting this as a separate bug.
In EAD games, fine-tuning is ignored—hard-coded to 0x0000—while the base key is determined via a call to ConvertEADGameValueToKeyBase(), which performs the following:
BaseKey = round( 60 - log2( x ) * 12 );
This causes the fine-tuning value to be truncated out, which causes many samples in EAD tracks to be off-key.
The Float Key and Key Prev/Key/Key Sec values are used to determine both the root key and the fine-tuning value.
Here is how to correctly decode these values using Super Mario 64 Bank 0x25 Percussion 0x29 (Float Key = 0.546910) as an example:
Frac = 0.546910;
RealBase = 60 - log2( Frac ) * 12; // 70.4474958423231640836092992685735225677490234375, IE base key = 70, fine-tuning = -44.75 cents.
RoundedBase = round( RealBase ); // 70. This is the final “Key Base” value.
Diff = RealBase - RoundedBase; // 0.4474958423231640836092992685735225677490234375
Cents = -round( (Diff * 100) * 16 ) / 16; // -44.75.
// Fine-tune negation is because increasing the base key lowers the final pitch (and vice-versa) while increasing the fine-tuning increases the final pitch.
Note that EAD games have a much more detailed fine-tuning range than just the standard [-100..100] range of cents so exporting the fine-tuning in cents loses precision, however it would still get the samples extremely close to correct for people who use the DLS files.
For the work I do, I need more accuracy than this, so I would like to just have the raw Float Key/Key Prev/Key/Key Sec values exported to the debug file (as "%.8e" so that all significant digits are printed).
For example, Super Mario 64 Bank 0x25 Instrument 0x0C would look like:
Attack 00000000 Decay 7FFFFFFF Sustain 03E80000 Release FB500000 - 0002 7FBC 0001 7FBC 7FBC 72F6 FFFF 0000 003C3CD0 - 0.2048596590757
…
Attack 00000000 Decay 7FFFFFFF Sustain 03E80000 Release FB500000 - 0002 7FBC 0001 7FBC 7FBC 72F6 FFFF 0000 003C3CD0 - 0.2170408964157
…
Attack 00000000 Decay 7FFFFFFF Sustain 03E80000 Release FB500000 - 0002 7FBC 0001 7FBC 7FBC 72F6 FFFF 0000 003C3CD0 - 0.2806159853935
And Super Mario 64 Bank 0x25 Percussion 0x29 would look like:
Attack 00000000 Decay 7FFFFFFF Sustain 03E80000 Release F06DAFB6 - 0002 7FBC 0001 7FBC 7FBC 72F6 FFFF 0000 - 0.546909570694
I included some extra digits in my examples but the idea should be clear: Print the floats with at least 8 significant digits so as to be lossless.
Seems like you have it building, feel free to submit a merge request to solve this.