Shipwright/soh/soh/resource/importer/AudioSoundFontFactory.cpp
briaguya e0d502b696
resource refactory (#3926)
* animation

* playeranimation

* stop putting things in the LUS namespace from SoH

* get all the factories out of the namespace

* LUS::

* start on scene command stuff

* i think that's the rest of scene

* reduce copypasta

* collision header

* skeleton

* skeletonlimb

* fix

* path

* cutscene

* text

* audio sample

* sound font

* audiosequence

* background

* Revert "stop putting things in the LUS namespace from SoH"

This reverts commit 0ead6056e6.

* namespace shanans

* wrap all factories in namespace soh

* it's trying to link now

* lus

* scene command override etc

* fix audio loading

* slightly less logspam

* get past the cutscene problem

* in game!

* exporter cleanup

* more exporter cleanup

* clang formatted lus

* msvc

* itny lus change

* variant

* formatty

* fix of some sort i guess?

* use latest lus main

* fix name to enum/factory mapping

* otrexporter
2024-02-15 21:06:52 -06:00

174 lines
7.6 KiB
C++

#include "soh/resource/importer/AudioSoundFontFactory.h"
#include "soh/resource/type/AudioSoundFont.h"
#include "spdlog/spdlog.h"
#include "libultraship/libultraship.h"
namespace SOH {
std::shared_ptr<LUS::IResource> ResourceFactoryBinaryAudioSoundFontV2::ReadResource(std::shared_ptr<LUS::File> file) {
if (!FileHasValidFormatAndReader(file)) {
return nullptr;
}
auto audioSoundFont = std::make_shared<AudioSoundFont>(file->InitData);
auto reader = std::get<std::shared_ptr<LUS::BinaryReader>>(file->Reader);
audioSoundFont->soundFont.fntIndex = reader->ReadInt32();
audioSoundFont->medium = reader->ReadInt8();
audioSoundFont->cachePolicy = reader->ReadInt8();
audioSoundFont->data1 = reader->ReadUInt16();
audioSoundFont->soundFont.sampleBankId1 = audioSoundFont->data1 >> 8;
audioSoundFont->soundFont.sampleBankId2 = audioSoundFont->data1 & 0xFF;
audioSoundFont->data2 = reader->ReadUInt16();
audioSoundFont->data3 = reader->ReadUInt16();
uint32_t drumCount = reader->ReadUInt32();
audioSoundFont->soundFont.numDrums = drumCount;
uint32_t instrumentCount = reader->ReadUInt32();
audioSoundFont->soundFont.numInstruments = instrumentCount;
uint32_t soundEffectCount = reader->ReadUInt32();
audioSoundFont->soundFont.numSfx = soundEffectCount;
// 🥁 DRUMS 🥁
audioSoundFont->drums.reserve(audioSoundFont->soundFont.numDrums);
audioSoundFont->drumAddresses.reserve(audioSoundFont->soundFont.numDrums);
for (uint32_t i = 0; i < audioSoundFont->soundFont.numDrums; i++) {
Drum drum;
drum.releaseRate = reader->ReadUByte();
drum.pan = reader->ReadUByte();
drum.loaded = reader->ReadUByte();
drum.loaded = 0; // this was always getting set to zero in ResourceMgr_LoadAudioSoundFont
uint32_t envelopeCount = reader->ReadUInt32();
audioSoundFont->drumEnvelopeCounts.push_back(envelopeCount);
std::vector<AdsrEnvelope> drumEnvelopes;
drumEnvelopes.reserve(audioSoundFont->drumEnvelopeCounts[i]);
for (uint32_t j = 0; j < audioSoundFont->drumEnvelopeCounts.back(); j++) {
AdsrEnvelope env;
int16_t delay = reader->ReadInt16();
int16_t arg = reader->ReadInt16();
env.delay = BE16SWAP(delay);
env.arg = BE16SWAP(arg);
drumEnvelopes.push_back(env);
}
audioSoundFont->drumEnvelopeArrays.push_back(drumEnvelopes);
drum.envelope = audioSoundFont->drumEnvelopeArrays.back().data();
bool hasSample = reader->ReadInt8();
std::string sampleFileName = reader->ReadString();
drum.sound.tuning = reader->ReadFloat();
if (sampleFileName.empty()) {
drum.sound.sample = nullptr;
} else {
auto res = LUS::Context::GetInstance()->GetResourceManager()->LoadResourceProcess(sampleFileName.c_str());
drum.sound.sample = static_cast<Sample*>(res ? res->GetRawPointer() : nullptr);
}
audioSoundFont->drums.push_back(drum);
audioSoundFont->drumAddresses.push_back(&audioSoundFont->drums.back());
}
audioSoundFont->soundFont.drums = audioSoundFont->drumAddresses.data();
// 🎺🎻🎷🎸🎹 INSTRUMENTS 🎹🎸🎷🎻🎺
audioSoundFont->instruments.reserve(audioSoundFont->soundFont.numInstruments);
for (uint32_t i = 0; i < audioSoundFont->soundFont.numInstruments; i++) {
Instrument instrument;
uint8_t isValidEntry = reader->ReadUByte();
instrument.loaded = reader->ReadUByte();
instrument.loaded = 0; // this was always getting set to zero in ResourceMgr_LoadAudioSoundFont
instrument.normalRangeLo = reader->ReadUByte();
instrument.normalRangeHi = reader->ReadUByte();
instrument.releaseRate = reader->ReadUByte();
uint32_t envelopeCount = reader->ReadInt32();
audioSoundFont->instrumentEnvelopeCounts.push_back(envelopeCount);
std::vector<AdsrEnvelope> instrumentEnvelopes;
for (uint32_t j = 0; j < audioSoundFont->instrumentEnvelopeCounts.back(); j++) {
AdsrEnvelope env;
int16_t delay = reader->ReadInt16();
int16_t arg = reader->ReadInt16();
env.delay = BE16SWAP(delay);
env.arg = BE16SWAP(arg);
instrumentEnvelopes.push_back(env);
}
audioSoundFont->instrumentEnvelopeArrays.push_back(instrumentEnvelopes);
instrument.envelope = audioSoundFont->instrumentEnvelopeArrays.back().data();
bool hasLowNoteSoundFontEntry = reader->ReadInt8();
if (hasLowNoteSoundFontEntry) {
bool hasSampleRef = reader->ReadInt8();
std::string sampleFileName = reader->ReadString();
instrument.lowNotesSound.tuning = reader->ReadFloat();
auto res = LUS::Context::GetInstance()->GetResourceManager()->LoadResourceProcess(sampleFileName.c_str());
instrument.lowNotesSound.sample = static_cast<Sample*>(res ? res->GetRawPointer() : nullptr);
} else {
instrument.lowNotesSound.sample = nullptr;
instrument.lowNotesSound.tuning = 0;
}
bool hasNormalNoteSoundFontEntry = reader->ReadInt8();
if (hasNormalNoteSoundFontEntry) {
bool hasSampleRef = reader->ReadInt8();
std::string sampleFileName = reader->ReadString();
instrument.normalNotesSound.tuning = reader->ReadFloat();
auto res = LUS::Context::GetInstance()->GetResourceManager()->LoadResourceProcess(sampleFileName.c_str());
instrument.normalNotesSound.sample = static_cast<Sample*>(res ? res->GetRawPointer() : nullptr);
} else {
instrument.normalNotesSound.sample = nullptr;
instrument.normalNotesSound.tuning = 0;
}
bool hasHighNoteSoundFontEntry = reader->ReadInt8();
if (hasHighNoteSoundFontEntry) {
bool hasSampleRef = reader->ReadInt8();
std::string sampleFileName = reader->ReadString();
instrument.highNotesSound.tuning = reader->ReadFloat();
auto res = LUS::Context::GetInstance()->GetResourceManager()->LoadResourceProcess(sampleFileName.c_str());
instrument.highNotesSound.sample = static_cast<Sample*>(res ? res->GetRawPointer() : nullptr);
} else {
instrument.highNotesSound.sample = nullptr;
instrument.highNotesSound.tuning = 0;
}
audioSoundFont->instruments.push_back(instrument);
audioSoundFont->instrumentAddresses.push_back(isValidEntry ?
&audioSoundFont->instruments.back() :
nullptr);
}
audioSoundFont->soundFont.instruments = audioSoundFont->instrumentAddresses.data();
// 🔊 SOUND EFFECTS 🔊
audioSoundFont->soundEffects.reserve(audioSoundFont->soundFont.numSfx);
for (uint32_t i = 0; i < audioSoundFont->soundFont.numSfx; i++) {
SoundFontSound soundEffect;
bool hasSFEntry = reader->ReadInt8();
if (hasSFEntry) {
bool hasSampleRef = reader->ReadInt8();
std::string sampleFileName = reader->ReadString();
soundEffect.tuning = reader->ReadFloat();
auto res = LUS::Context::GetInstance()->GetResourceManager()->LoadResourceProcess(sampleFileName.c_str());
soundEffect.sample = static_cast<Sample*>(res ? res->GetRawPointer() : nullptr);
}
audioSoundFont->soundEffects.push_back(soundEffect);
}
audioSoundFont->soundFont.soundEffects = audioSoundFont->soundEffects.data();
return audioSoundFont;
}
} // namespace SOH