diff options
Diffstat (limited to 'src/factories/oot/OoTAudioFontWriter.h')
| -rw-r--r-- | src/factories/oot/OoTAudioFontWriter.h | 78 |
1 files changed, 78 insertions, 0 deletions
diff --git a/src/factories/oot/OoTAudioFontWriter.h b/src/factories/oot/OoTAudioFontWriter.h new file mode 100644 index 0000000..615ea7f --- /dev/null +++ b/src/factories/oot/OoTAudioFontWriter.h @@ -0,0 +1,78 @@ +#pragma once + +#include "OoTAudioTypes.h" + +namespace OoT { + +struct DrumEntry { + uint8_t releaseRate, pan, loaded; + float tuning; + std::vector<std::pair<int16_t, int16_t>> env; + std::string sampleRef; +}; + +struct InstEntry { + bool isValid; + uint8_t loaded, normalRangeLo, normalRangeHi, releaseRate; + std::vector<std::pair<int16_t, int16_t>> env; + uint32_t lowAddr, normalAddr, highAddr; +}; + +// Cross-font stack residue. ZAPDTR reuses the same stack frame across fonts, +// so invalid instruments inherit field values from the previous font's last +// valid instrument. See docs/oot-audio-font-residue-analysis.md +class FontResidue { +public: + void Reset(); + void SeedFromDrums(const std::vector<DrumEntry>& drums); + void ApplyToInstrument(InstEntry& inst) const; + void UpdateFromInstrument(const InstEntry& inst); +private: + uint8_t mLoaded = 0, mRangeLo = 0, mRangeHi = 0, mRelease = 0; +}; + +struct SFXEntry { + bool exists; + std::string sampleRef; + float tuning; +}; + +struct FontWriteContext { + SafeAudioBankReader& audioBank; + const std::vector<AudioTableEntry>& sampleBankTable; + std::map<uint32_t, SampleInfo>& sampleMap; +}; + +class AudioFontWriter { +public: + void Extract(YAML::Node& node, + SafeAudioBankReader& audioBank, + const std::vector<AudioTableEntry>& fontTable, + const std::vector<AudioTableEntry>& sampleBankTable, + std::map<uint32_t, SampleInfo>& sampleMap); + +private: + std::string GetSampleRef(int bankIndex, uint32_t sampleAddr, uint32_t baseOffset, FontWriteContext& ctx); + std::vector<std::pair<int16_t, int16_t>> ParseEnvelope(uint32_t envOffset, FontWriteContext& ctx); + void WriteSFE(LUS::BinaryWriter& w, uint32_t sfeOffset, uint32_t baseOffset, + int bankIndex, FontWriteContext& ctx); + void WriteFontCompanion(uint32_t fontIndex, const AudioTableEntry& fontEntry, + const std::vector<DrumEntry>& drums, + const std::vector<InstEntry>& instruments, + const std::vector<SFXEntry>& sfxEntries, + uint32_t ptr, int sampleBankId, + FontWriteContext& ctx, + const std::map<int, std::string>& fontNames); + void WriteDrums(LUS::BinaryWriter& w, const std::vector<DrumEntry>& drums); + void WriteInstruments(LUS::BinaryWriter& w, const std::vector<InstEntry>& instruments, + uint32_t ptr, int sampleBankId, FontWriteContext& ctx); + void WriteSFXEntries(LUS::BinaryWriter& w, const std::vector<SFXEntry>& sfxEntries); + void WriteEnvData(LUS::BinaryWriter& w, const std::vector<std::pair<int16_t, int16_t>>& envs); + std::vector<InstEntry> ParseInstruments(int numInstruments, uint32_t ptr, FontWriteContext& ctx); + std::vector<SFXEntry> ParseSFX(int numSfx, uint32_t ptr, int sampleBankId, FontWriteContext& ctx); + std::vector<DrumEntry> ParseDrums(int numDrums, uint32_t ptr, int sampleBankId, FontWriteContext& ctx); + + FontResidue mResidue; +}; + +} // namespace OoT |
