mirror of
https://github.com/HarbourMasters/Starship.git
synced 2025-02-13 21:45:17 +03:00
We did partial success while loading this
This commit is contained in:
parent
5f0bd6e9f0
commit
93199b4c02
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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
|
Loading…
Reference in New Issue
Block a user