#pragma once #include "factories/BaseFactory.h" #include "types/RawBuffer.h" #include #include #include #include namespace BK64 { struct SoundfontBook { int32_t order = 0; int32_t npredictors = 0; std::vector book; }; struct SoundfontLoop { uint32_t start = 0; uint32_t end = 0; uint32_t count = 0; std::vector state; }; struct SoundfontEnvelope { int32_t attackTime = 0; int32_t decayTime = 0; int32_t releaseTime = 0; uint8_t attackVolume = 0; uint8_t decayVolume = 0; }; struct SoundfontKeyMap { uint8_t velocityMin = 0; uint8_t velocityMax = 0; uint8_t keyMin = 0; uint8_t keyMax = 0; uint8_t keyBase = 0; int8_t detune = 0; }; struct SoundfontWave { uint32_t base = 0; int32_t len = 0; uint8_t type = 0; uint8_t flags = 0; uint32_t loopOffset = 0; uint32_t bookOffset = 0; }; struct SoundfontSound { uint32_t envelopeOffset = 0; uint32_t keyMapOffset = 0; uint32_t waveOffset = 0; uint8_t samplePan = 0; uint8_t sampleVolume = 0; uint8_t flags = 0; }; struct SoundfontInstrument { uint8_t volume = 0; uint8_t pan = 0; uint8_t priority = 0; uint8_t flags = 0; uint8_t tremType = 0; uint8_t tremRate = 0; uint8_t tremDepth = 0; uint8_t tremDelay = 0; uint8_t vibType = 0; uint8_t vibRate = 0; uint8_t vibDepth = 0; uint8_t vibDelay = 0; int16_t bendRange = 0; std::vector soundOffsets; }; struct SoundfontBank { uint8_t flags = 0; uint8_t pad = 0; int32_t sampleRate = 0; uint32_t percussionOffset = 0; std::vector instrumentOffsets; }; struct SoundfontImage { std::vector bytes; std::vector covered; }; class SoundfontData : public RawBuffer { public: int16_t mRevision = 0; std::vector mBankOffsets; std::map mBanks; std::map mInstruments; std::map mSounds; std::map mEnvelopes; std::map mKeyMaps; std::map mWaves; std::map mBooks; std::map mLoops; std::vector mSampleData; explicit SoundfontData(std::vector bytes) : RawBuffer(bytes) { } uint64_t SampleDataEnd() const; SoundfontImage Serialize() const; std::vector SampleBytes(const SoundfontWave& wave) const; }; struct SoundfontModFile { std::string yaml; std::vector raw; std::vector wav; }; SoundfontData ParseSoundfont(const uint8_t* ctl, size_t ctlSize); class SoundfontBinaryExporter : public BaseExporter { ExportResult Export(std::ostream& write, std::shared_ptr data, std::string& entryName, YAML::Node& node, std::string* replacement) override; }; class SoundfontModdingExporter : public BaseExporter { ExportResult Export(std::ostream& write, std::shared_ptr data, std::string& entryName, YAML::Node& node, std::string* replacement) override; }; class SoundfontFactory : public BaseFactory { public: std::optional> parse(std::vector& buffer, YAML::Node& data) override; std::optional> parse_modding(std::vector& buffer, YAML::Node& data) override; inline std::unordered_map> GetExporters() override { return { REGISTER(Binary, SoundfontBinaryExporter) REGISTER(Modding, SoundfontModdingExporter) }; } bool SupportModdedAssets() override { return true; } }; uint32_t LocateSoundfontCtl(const std::vector& rom, uint32_t ctlOffset, uint32_t ctlSize); } // namespace BK64