We did partial success while loading this

This commit is contained in:
KiritoDv 2025-02-03 03:12:20 -06:00 committed by Lywx
parent 5f0bd6e9f0
commit 93199b4c02
6 changed files with 241 additions and 7 deletions

View File

@ -1042,7 +1042,7 @@ Acmd* AudioSynth_ProcessNote(s32 noteIndex, NoteSubEu* noteSub, NoteSynthesisSta
numSamplesProcessed += numSamplesToLoadAdj;
dmemUncompressedAddrOffset1 = numSamplesToLoadAdj;
if (((synthState->samplePosInt * 2) + (numSamplesToLoadAdj)*SAMPLE_SIZE) < bookSample->size) {
if (((synthState->samplePosInt * 2) + (numSamplesToLoadAdj) * SAMPLE_SIZE) < bookSample->size) {
bytesToRead = (numSamplesToLoadAdj) * SAMPLE_SIZE;
} else {
bytesToRead = bookSample->size - (synthState->samplePosInt * 2);

View File

@ -244,6 +244,9 @@ GameEngine::GameEngine() {
loader->RegisterResourceFactory(std::make_shared<SF64::ResourceFactoryBinarySoundFontV0>(), RESOURCE_FORMAT_BINARY,
"SoundFont", static_cast<uint32_t>(SF64::ResourceType::SoundFont), 0);
loader->RegisterResourceFactory(std::make_shared<SF64::ResourceFactoryXMLSoundFontV0>(), RESOURCE_FORMAT_XML,
"SoundFont", static_cast<uint32_t>(SF64::ResourceType::SoundFont), 0);
prevAltAssets = CVarGetInteger("gEnhancements.Mods.AlternateAssets", 0);
gEnableGammaBoost = CVarGetInteger("gGraphics.GammaMode", 0) == 0;
context->GetResourceManager()->SetAltAssetsEnabled(prevAltAssets);

View File

@ -101,12 +101,14 @@ static void Mp3DecoderWorker(std::shared_ptr<Sample> sample, std::shared_ptr<Shi
drmp3 mp3;
drwav_uint64 numFrames;
drmp3_bool32 ret =
drmp3_init_memory(&mp3, sampleFile->Buffer.get()->data(), sampleFile->Buffer.get()->size(), nullptr);
drmp3_init_memory(&mp3, sampleFile->Buffer->data(), sampleFile->Buffer->size(), nullptr);
numFrames = drmp3_get_pcm_frame_count(&mp3);
drwav_uint64 channels = mp3.channels;
drwav_uint64 sampleRate = mp3.sampleRate;
sample->mSample.sampleAddr = new uint8_t[numFrames * channels * 2];
sample->mSample.tuning = (float)(sampleRate * channels) / 32000.0f;
sample->mSample.size = numFrames * channels * 2;
sample->mSample.sampleAddr = new uint8_t[sample->mSample.size];
drmp3_read_pcm_frames_s16(&mp3, numFrames, (int16_t*)sample->mSample.sampleAddr);
}
@ -131,6 +133,7 @@ static void OggDecoderWorker(std::shared_ptr<Sample> sample, std::shared_ptr<Shi
int bitStream = 0;
size_t toRead = numFrames * numChannels * 2;
sample->mSample.sampleAddr = new uint8_t[toRead];
sample->mSample.tuning = (float)(sampleRate * numChannels) / 32000.0f;
do {
read = ov_read(&vf, dataBuff, 4096, 0, 2, 1, &bitStream);
memcpy(sample->mSample.sampleAddr + pos, dataBuff, read);
@ -199,12 +202,13 @@ std::shared_ptr<Ship::IResource> ResourceFactoryXMLSampleV0::ReadResource(std::s
drwav_uint64 numFrames;
drwav_bool32 ret =
drwav_init_memory(&wav, sampleFile->Buffer.get()->data(), sampleFile->Buffer.get()->size(), nullptr);
drwav_init_memory(&wav, sampleFile->Buffer->data(), sampleFile->Buffer->size(), nullptr);
drwav_get_length_in_pcm_frames(&wav, &numFrames);
sample->mSample.tuning = (wav.sampleRate * wav.channels) / 32000.0f;
sample->mSample.sampleAddr = new uint8_t[numFrames * wav.channels * 2];
sample->mSample.tuning = (float)(wav.sampleRate * wav.channels) / 32000.0f;
sample->mSample.size = numFrames * wav.channels * 2;
sample->mSample.sampleAddr = new uint8_t[sample->mSample.size];
drwav_read_pcm_frames_s16(&wav, numFrames, (int16_t*)sample->mSample.sampleAddr);
return sample;

View File

@ -1,5 +1,7 @@
#include "SoundFontFactory.h"
#include "../ResourceUtil.h"
#include "utils/StringHelper.h"
#include <sf64audio_provisional.h>
#include "port/resource/type/audio/SoundFont.h"
namespace SF64 {
@ -29,4 +31,214 @@ std::shared_ptr<Ship::IResource> ResourceFactoryBinarySoundFontV0::ReadResource(
return font;
}
int8_t ResourceFactoryXMLSoundFontV0::MediumStrToInt(const char* str) {
if (!strcmp("Ram", str)) {
return MEDIUM_RAM;
} else if (!strcmp("Unk", str)) {
return MEDIUM_UNK;
} else if (!strcmp("Cart", str)) {
return MEDIUM_CART;
} else if (!strcmp("Disk", str)) {
return MEDIUM_DISK_DRIVE;
// 4 is skipped
} else {
throw std::runtime_error(
StringHelper::Sprintf("Bad medium value. Got %s, expected Ram, Unk, Cart, or Disk.", str));
}
}
int8_t ResourceFactoryXMLSoundFontV0::CachePolicyToInt(const char* str) {
if (!strcmp("Temporary", str)) {
return CACHE_TEMPORARY;
} else if (!strcmp("Persistent", str)) {
return CACHE_PERSISTENT;
} else if (!strcmp("Either", str)) {
return CACHE_EITHER;
} else if (!strcmp("Permanent", str)) {
return CACHE_PERMANENT;
} else {
throw std::runtime_error(StringHelper::Sprintf(
"Bad cache policy value. Got %s, expected Temporary, Persistent, Either, or Permanent.", str));
}
}
void ResourceFactoryXMLSoundFontV0::ParseDrums(SoundFont* soundFont, tinyxml2::XMLElement* element) {
element = (tinyxml2::XMLElement*)element->FirstChildElement();
// No drums
if (element == nullptr) {
soundFont->mFont.drums = nullptr;
soundFont->mFont.numDrums = 0;
return;
}
do {
auto drum = new DrumData;
std::vector<EnvelopePointData> envelopes;
drum->adsrDecayIndex = element->IntAttribute("ReleaseRate");
drum->pan = element->IntAttribute("Pan");
drum->isRelocated = element->IntAttribute("Loaded");
drum->tunedSample.tuning = element->FloatAttribute("Tuning");
const char* sampleStr = element->Attribute("SampleRef");
if (sampleStr != nullptr && sampleStr[0] != 0) {
auto res = Ship::Context::GetInstance()->GetResourceManager()->LoadResourceProcess(sampleStr);
drum->tunedSample.sample = static_cast<SampleData*>(res ? res->GetRawPointer() : nullptr);
} else {
drum->tunedSample.sample = nullptr;
}
element = (tinyxml2::XMLElement*)element->FirstChildElement();
if (!strcmp(element->Name(), "Envelopes")) {
// element = (tinyxml2::XMLElement*)element->FirstChildElement();
unsigned int envCount = 0;
envelopes = ParseEnvelopes(soundFont, element, &envCount);
element = (tinyxml2::XMLElement*)element->Parent();
drum->envelope = new EnvelopePointData[envelopes.size()];
memcpy(drum->envelope, envelopes.data(), envelopes.size() * sizeof(EnvelopePointData));
} else {
drum->envelope = nullptr;
}
if (drum->tunedSample.sample == nullptr) {
soundFont->mDrums.push_back(nullptr);
} else {
soundFont->mDrums.push_back(drum);
}
element = element->NextSiblingElement();
} while (element != nullptr);
soundFont->mFont.numDrums = soundFont->mDrums.size();
soundFont->mFont.drums = soundFont->mDrums.data();
}
void ResourceFactoryXMLSoundFontV0::ParseInstruments(SoundFont* soundFont, tinyxml2::XMLElement* element) {
element = element->FirstChildElement();
do {
auto instrument = new InstrumentData;
unsigned int envCount = 0;
std::vector<EnvelopePointData> envelopes;
int isValid = element->BoolAttribute("IsValid");
instrument->isRelocated = element->IntAttribute("Loaded");
instrument->normalRangeLo = element->IntAttribute("NormalRangeLo");
instrument->normalRangeHi = element->IntAttribute("NormalRangeHi");
instrument->adsrDecayIndex = element->IntAttribute("ReleaseRate");
tinyxml2::XMLElement* instrumentElement = element->FirstChildElement();
tinyxml2::XMLElement* instrumentElementCopy = instrumentElement;
if (instrumentElement != nullptr && !strcmp(instrumentElement->Name(), "Envelopes")) {
envelopes = ParseEnvelopes(soundFont, instrumentElement, &envCount);
instrument->envelope = new EnvelopePointData[envelopes.size()];
memcpy(instrument->envelope, envelopes.data(), envelopes.size() * sizeof(EnvelopePointData));
instrumentElement = instrumentElement->NextSiblingElement();
}
if (instrumentElement != nullptr && !strcmp("LowNotesSound", instrumentElement->Name())) {
instrument->lowPitchTunedSample.tuning = instrumentElement->FloatAttribute("Tuning");
const char* sampleStr = instrumentElement->Attribute("SampleRef");
if (sampleStr != nullptr && sampleStr[0] != 0) {
auto res = static_pointer_cast<Sample>(
Ship::Context::GetInstance()->GetResourceManager()->LoadResourceProcess(sampleStr, true));
auto sample = static_cast<SampleData*>(res ? res->GetRawPointer() : nullptr);
instrument->lowPitchTunedSample.sample = sample;
if (sample != nullptr && sample->tuning != 0.0f) {
instrument->lowPitchTunedSample.tuning = sample->tuning;
}
}
instrumentElement = instrumentElement->NextSiblingElement();
}
if (instrumentElement != nullptr && !strcmp("NormalNotesSound", instrumentElement->Name())) {
instrument->normalPitchTunedSample.tuning = instrumentElement->FloatAttribute("Tuning");
const char* sampleStr = instrumentElement->Attribute("SampleRef");
if (sampleStr != nullptr && sampleStr[0] != 0) {
auto res = static_pointer_cast<Sample>(
Ship::Context::GetInstance()->GetResourceManager()->LoadResourceProcess(sampleStr, true));
auto sample = static_cast<SampleData*>(res ? res->GetRawPointer() : nullptr);
instrument->normalPitchTunedSample.sample = sample;
if (sample != nullptr && sample->tuning != 0.0f) {
instrument->normalPitchTunedSample.tuning = sample->tuning;
}
}
instrumentElement = instrumentElement->NextSiblingElement();
}
if (instrumentElement != nullptr && !strcmp("HighNotesSound", instrumentElement->Name())) {
instrument->highPitchTunedSample.tuning = instrumentElement->FloatAttribute("Tuning");
const char* sampleStr = instrumentElement->Attribute("SampleRef");
if (sampleStr != nullptr && sampleStr[0] != 0) {
auto res = static_pointer_cast<Sample>(
Ship::Context::GetInstance()->GetResourceManager()->LoadResourceProcess(sampleStr, true));
auto sample = static_cast<SampleData*>(res ? res->GetRawPointer() : nullptr);
instrument->highPitchTunedSample.sample = sample;
if (sample != nullptr && sample->tuning != 0.0f) {
instrument->highPitchTunedSample.tuning = sample->tuning;
}
}
instrumentElement = instrumentElement->NextSiblingElement();
}
soundFont->mInstruments.push_back(instrument);
element = instrumentElementCopy;
element = (tinyxml2::XMLElement*)element->Parent();
element = element->NextSiblingElement();
} while (element != nullptr);
soundFont->mFont.instruments = soundFont->mInstruments.data();
soundFont->mFont.numInstruments = soundFont->mInstruments.size();
}
std::vector<EnvelopePointData> ResourceFactoryXMLSoundFontV0::ParseEnvelopes(SoundFont* soundFont,
tinyxml2::XMLElement* element,
unsigned int* count) {
std::vector<EnvelopePointData> envelopes;
unsigned int total = 0;
element = element->FirstChildElement("Envelope");
while (element != nullptr) {
EnvelopePointData env = {
.delay = (s16)element->IntAttribute("Delay"),
.arg = (s16)element->IntAttribute("Arg"),
};
envelopes.emplace_back(env);
element = element->NextSiblingElement("Envelope");
total++;
}
*count = total;
return envelopes;
}
std::shared_ptr<Ship::IResource> ResourceFactoryXMLSoundFontV0::ReadResource(std::shared_ptr<Ship::File> file) {
if (!FileHasValidFormatAndReader(file)) {
return nullptr;
}
auto audioSoundFont = std::make_shared<SoundFont>(file->InitData);
auto child = std::get<std::shared_ptr<tinyxml2::XMLDocument>>(file->Reader)->FirstChildElement();
// Header data
memset(&audioSoundFont->mFont, 0, sizeof(audioSoundFont->mFont));
auto shortData1 = child->IntAttribute("Data1");
auto shortData2 = child->IntAttribute("Data2");
audioSoundFont->mFont.numInstruments = (shortData2 >> 8) & 0xFFu;
audioSoundFont->mFont.numDrums = shortData2 & 0xFFu;
audioSoundFont->mFont.sampleBankId1 = (shortData1 >> 8) & 0xFFu;
audioSoundFont->mFont.sampleBankId2 = shortData1 & 0xFFu;
child = (tinyxml2::XMLElement*)child->FirstChildElement();
while (child != nullptr) {
const char* name = child->Name();
if (!strcmp(name, "Drums")) {
ParseDrums(audioSoundFont.get(), child);
} else if (!strcmp(name, "Instruments")) {
ParseInstruments(audioSoundFont.get(), child);
}
child = child->NextSiblingElement();
}
return audioSoundFont;
}
} // namespace LUS

View File

@ -1,11 +1,26 @@
#pragma once
#include "Resource.h"
#include "ResourceFactoryXML.h"
#include "ResourceFactoryBinary.h"
#include "port/resource/type/audio/SoundFont.h"
namespace SF64 {
class ResourceFactoryBinarySoundFontV0 : public Ship::ResourceFactoryBinary {
public:
std::shared_ptr<Ship::IResource> ReadResource(std::shared_ptr<Ship::File> file) override;
};
class ResourceFactoryXMLSoundFontV0 : public Ship::ResourceFactoryXML {
public:
std::shared_ptr<Ship::IResource> ReadResource(std::shared_ptr<Ship::File> file) override;
static int8_t MediumStrToInt(const char* str);
static int8_t CachePolicyToInt(const char* str);
private:
void ParseDrums(SoundFont* soundFont, tinyxml2::XMLElement* element);
void ParseInstruments(SoundFont* soundFont, tinyxml2::XMLElement* element);
std::vector<EnvelopePointData> ParseEnvelopes(SoundFont* soundFont, tinyxml2::XMLElement* element,
unsigned int* count);
};
}; // namespace LUS

@ -1 +1 @@
Subproject commit 053d97a433f3cfc9607b7cedb512d2e7ee1dc78a
Subproject commit 27af72331ceba7703f0382bb0316320baed377a3