mirror of
https://github.com/HarbourMasters/Shipwright.git
synced 2025-08-20 21:33:40 -07:00
Add audio sound font XML importer & exporter
This commit is contained in:
parent
fa6f45bde5
commit
f3908c3968
5 changed files with 334 additions and 0 deletions
|
@ -1,7 +1,9 @@
|
|||
#include "soh/resource/importer/AudioSoundFontFactory.h"
|
||||
#include "soh/resource/type/AudioSoundFont.h"
|
||||
#include "soh/resource/logging/AudioSoundFontLogger.h"
|
||||
#include "spdlog/spdlog.h"
|
||||
#include "libultraship/libultraship.h"
|
||||
#include <tinyxml2.h>
|
||||
|
||||
namespace SOH {
|
||||
std::shared_ptr<Ship::IResource>
|
||||
|
@ -72,6 +74,7 @@ ResourceFactoryBinaryAudioSoundFontV2::ReadResource(std::shared_ptr<Ship::File>
|
|||
auto res = Ship::Context::GetInstance()->GetResourceManager()->LoadResourceProcess(sampleFileName.c_str());
|
||||
drum.sound.sample = static_cast<Sample*>(res ? res->GetRawPointer() : nullptr);
|
||||
}
|
||||
audioSoundFont->drumFileNames.push_back(sampleFileName);
|
||||
|
||||
audioSoundFont->drums.push_back(drum);
|
||||
audioSoundFont->drumAddresses.push_back(&audioSoundFont->drums.back());
|
||||
|
@ -115,9 +118,11 @@ ResourceFactoryBinaryAudioSoundFontV2::ReadResource(std::shared_ptr<Ship::File>
|
|||
instrument.lowNotesSound.tuning = reader->ReadFloat();
|
||||
auto res = Ship::Context::GetInstance()->GetResourceManager()->LoadResourceProcess(sampleFileName.c_str());
|
||||
instrument.lowNotesSound.sample = static_cast<Sample*>(res ? res->GetRawPointer() : nullptr);
|
||||
audioSoundFont->lowInstrumentFileNames.push_back(sampleFileName);
|
||||
} else {
|
||||
instrument.lowNotesSound.sample = nullptr;
|
||||
instrument.lowNotesSound.tuning = 0;
|
||||
audioSoundFont->lowInstrumentFileNames.push_back("");
|
||||
}
|
||||
|
||||
bool hasNormalNoteSoundFontEntry = reader->ReadInt8();
|
||||
|
@ -127,9 +132,11 @@ ResourceFactoryBinaryAudioSoundFontV2::ReadResource(std::shared_ptr<Ship::File>
|
|||
instrument.normalNotesSound.tuning = reader->ReadFloat();
|
||||
auto res = Ship::Context::GetInstance()->GetResourceManager()->LoadResourceProcess(sampleFileName.c_str());
|
||||
instrument.normalNotesSound.sample = static_cast<Sample*>(res ? res->GetRawPointer() : nullptr);
|
||||
audioSoundFont->normalInstrumentFileNames.push_back(sampleFileName);
|
||||
} else {
|
||||
instrument.normalNotesSound.sample = nullptr;
|
||||
instrument.normalNotesSound.tuning = 0;
|
||||
audioSoundFont->normalInstrumentFileNames.push_back("");
|
||||
}
|
||||
|
||||
bool hasHighNoteSoundFontEntry = reader->ReadInt8();
|
||||
|
@ -139,9 +146,11 @@ ResourceFactoryBinaryAudioSoundFontV2::ReadResource(std::shared_ptr<Ship::File>
|
|||
instrument.highNotesSound.tuning = reader->ReadFloat();
|
||||
auto res = Ship::Context::GetInstance()->GetResourceManager()->LoadResourceProcess(sampleFileName.c_str());
|
||||
instrument.highNotesSound.sample = static_cast<Sample*>(res ? res->GetRawPointer() : nullptr);
|
||||
audioSoundFont->highInstrumentFileNames.push_back(sampleFileName);
|
||||
} else {
|
||||
instrument.highNotesSound.sample = nullptr;
|
||||
instrument.highNotesSound.tuning = 0;
|
||||
audioSoundFont->highInstrumentFileNames.push_back("");
|
||||
}
|
||||
|
||||
audioSoundFont->instruments.push_back(instrument);
|
||||
|
@ -161,12 +170,216 @@ ResourceFactoryBinaryAudioSoundFontV2::ReadResource(std::shared_ptr<Ship::File>
|
|||
soundEffect.tuning = reader->ReadFloat();
|
||||
auto res = Ship::Context::GetInstance()->GetResourceManager()->LoadResourceProcess(sampleFileName.c_str());
|
||||
soundEffect.sample = static_cast<Sample*>(res ? res->GetRawPointer() : nullptr);
|
||||
audioSoundFont->soundEffectFileNames.push_back(sampleFileName);
|
||||
}
|
||||
|
||||
audioSoundFont->soundEffects.push_back(soundEffect);
|
||||
}
|
||||
audioSoundFont->soundFont.soundEffects = audioSoundFont->soundEffects.data();
|
||||
|
||||
if (CVarGetInteger(CVAR_DEVELOPER_TOOLS("ResourceLogging"), 0)) {
|
||||
LogAudioSoundFontAsXML(initData, audioSoundFont);
|
||||
}
|
||||
|
||||
return audioSoundFont;
|
||||
}
|
||||
|
||||
std::shared_ptr<Ship::IResource>
|
||||
ResourceFactoryXMLAudioSoundFontV2::ReadResource(std::shared_ptr<Ship::File> file,
|
||||
std::shared_ptr<Ship::ResourceInitData> initData) {
|
||||
if (!FileHasValidFormatAndReader(file, initData)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::shared_ptr<SOH::AudioSoundFont> audioSoundFont = std::make_shared<AudioSoundFont>(initData);
|
||||
std::shared_ptr<tinyxml2::XMLDocument> reader = std::get<std::shared_ptr<tinyxml2::XMLDocument>>(file->Reader);
|
||||
|
||||
tinyxml2::XMLElement* root = reader->RootElement();
|
||||
|
||||
if (root->Name() != "SoundFont") {
|
||||
LUSLOG_ERROR("Tried to load malformed sound font");
|
||||
assert(false);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
audioSoundFont->soundFont.fntIndex = root->IntAttribute("FntIndex");
|
||||
audioSoundFont->medium = root->IntAttribute("Medium");
|
||||
audioSoundFont->cachePolicy = root->IntAttribute("CachePolicy");
|
||||
|
||||
audioSoundFont->soundFont.sampleBankId1 = root->IntAttribute("SampleBankId1");
|
||||
audioSoundFont->soundFont.sampleBankId2 = root->IntAttribute("SampleBankId2");
|
||||
audioSoundFont->data1 = (audioSoundFont->soundFont.sampleBankId1 << 8) & audioSoundFont->soundFont.sampleBankId2;
|
||||
|
||||
audioSoundFont->data2 = root->IntAttribute("Data2");
|
||||
audioSoundFont->data3 = root->IntAttribute("Data3");
|
||||
|
||||
tinyxml2::XMLElement* rootChild = root->FirstChildElement();
|
||||
|
||||
while (rootChild != nullptr) {
|
||||
if (rootChild->Name() == "Drum") { // 🥁 DRUMS 🥁
|
||||
Drum drum;
|
||||
drum.releaseRate = rootChild->IntAttribute("ReleaseRate");
|
||||
drum.pan = rootChild->IntAttribute("Pan");
|
||||
|
||||
// this was always getting set to zero in ResourceMgr_LoadAudioSoundFont
|
||||
// drum.loaded = rootChild->IntAttribute("Loaded");
|
||||
drum.loaded = 0;
|
||||
|
||||
std::vector<AdsrEnvelope> drumEnvelopes;
|
||||
tinyxml2::XMLElement* drumChild = rootChild->FirstChildElement();
|
||||
|
||||
while (drumChild != nullptr) {
|
||||
if (drumChild->Name() != "Envelope") {
|
||||
LUSLOG_ERROR("Tried to load malformed sound font drum envelope");
|
||||
assert(false);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
AdsrEnvelope env;
|
||||
|
||||
int16_t delay = drumChild->IntAttribute("Delay");
|
||||
int16_t arg = drumChild->IntAttribute("Arg");
|
||||
|
||||
env.delay = BE16SWAP(delay);
|
||||
env.arg = BE16SWAP(arg);
|
||||
|
||||
drumEnvelopes.push_back(env);
|
||||
|
||||
drumChild = drumChild->NextSiblingElement();
|
||||
}
|
||||
|
||||
audioSoundFont->drumEnvelopeArrays.push_back(drumEnvelopes);
|
||||
drum.envelope = audioSoundFont->drumEnvelopeArrays.back().data();
|
||||
audioSoundFont->drumEnvelopeCounts.push_back(drumEnvelopes.size());
|
||||
|
||||
std::string sampleFileName = std::string(rootChild->Attribute("SampleFileName"));
|
||||
drum.sound.tuning = rootChild->FloatAttribute("Tuning");
|
||||
|
||||
if (sampleFileName.empty()) {
|
||||
drum.sound.sample = nullptr;
|
||||
} else {
|
||||
std::shared_ptr<Ship::IResource> res =
|
||||
Ship::Context::GetInstance()->GetResourceManager()->LoadResourceProcess(sampleFileName.c_str());
|
||||
drum.sound.sample = static_cast<Sample*>(res ? res->GetRawPointer() : nullptr);
|
||||
}
|
||||
audioSoundFont->drumFileNames.push_back(sampleFileName);
|
||||
|
||||
audioSoundFont->drums.push_back(drum);
|
||||
audioSoundFont->drumAddresses.push_back(&audioSoundFont->drums.back());
|
||||
} else if (rootChild->Name() == "Instrument") { // 🎺🎻🎷🎸🎹 INSTRUMENTS 🎹🎸🎷🎻🎺
|
||||
Instrument instrument;
|
||||
|
||||
uint8_t isValidEntry = rootChild->IntAttribute("IsValidEntry");
|
||||
// this was always getting set to zero in ResourceMgr_LoadAudioSoundFont
|
||||
// instrument.loaded = rootChild->IntAttribute("Loaded");
|
||||
instrument.loaded = 0;
|
||||
|
||||
instrument.normalRangeLo = rootChild->IntAttribute("NormalRangeLo");
|
||||
instrument.normalRangeHi = rootChild->IntAttribute("NormalRangeHi");
|
||||
instrument.releaseRate = rootChild->IntAttribute("ReleaseRate");
|
||||
|
||||
std::vector<AdsrEnvelope> instrumentEnvelopes;
|
||||
tinyxml2::XMLElement* instrumentChild = rootChild->FirstChildElement();
|
||||
|
||||
while (instrumentChild != nullptr) {
|
||||
if (instrumentChild->Name() != "Envelope") {
|
||||
LUSLOG_ERROR("Tried to load malformed sound font drum envelope");
|
||||
assert(false);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
AdsrEnvelope env;
|
||||
|
||||
int16_t delay = instrumentChild->IntAttribute("Delay");
|
||||
int16_t arg = instrumentChild->IntAttribute("Arg");
|
||||
|
||||
env.delay = BE16SWAP(delay);
|
||||
env.arg = BE16SWAP(arg);
|
||||
|
||||
instrumentEnvelopes.push_back(env);
|
||||
|
||||
instrumentChild = instrumentChild->NextSiblingElement();
|
||||
}
|
||||
|
||||
audioSoundFont->instrumentEnvelopeCounts.push_back(instrumentEnvelopes.size());
|
||||
audioSoundFont->instrumentEnvelopeArrays.push_back(instrumentEnvelopes);
|
||||
instrument.envelope = audioSoundFont->instrumentEnvelopeArrays.back().data();
|
||||
|
||||
const char* lowNoteSampleFileName = rootChild->Attribute("LowNoteSampleFileName");
|
||||
if (lowNoteSampleFileName != nullptr) {
|
||||
instrument.lowNotesSound.tuning = rootChild->FloatAttribute("Tuning");
|
||||
std::string sampleFileName = std::string(lowNoteSampleFileName);
|
||||
std::shared_ptr<Ship::IResource> res =
|
||||
Ship::Context::GetInstance()->GetResourceManager()->LoadResourceProcess(sampleFileName.c_str());
|
||||
instrument.lowNotesSound.sample = static_cast<Sample*>(res ? res->GetRawPointer() : nullptr);
|
||||
audioSoundFont->lowInstrumentFileNames.push_back(sampleFileName);
|
||||
} else {
|
||||
instrument.lowNotesSound.tuning = 0;
|
||||
instrument.lowNotesSound.sample = nullptr;
|
||||
audioSoundFont->lowInstrumentFileNames.push_back("");
|
||||
}
|
||||
|
||||
const char* normalNoteSampleFileName = rootChild->Attribute("NormalNoteSampleFileName");
|
||||
if (normalNoteSampleFileName != nullptr) {
|
||||
instrument.normalNotesSound.tuning = rootChild->FloatAttribute("Tuning");
|
||||
std::string sampleFileName = std::string(normalNoteSampleFileName);
|
||||
std::shared_ptr<Ship::IResource> res =
|
||||
Ship::Context::GetInstance()->GetResourceManager()->LoadResourceProcess(sampleFileName.c_str());
|
||||
instrument.normalNotesSound.sample = static_cast<Sample*>(res ? res->GetRawPointer() : nullptr);
|
||||
audioSoundFont->normalInstrumentFileNames.push_back(sampleFileName);
|
||||
} else {
|
||||
instrument.normalNotesSound.tuning = 0;
|
||||
instrument.normalNotesSound.sample = nullptr;
|
||||
audioSoundFont->normalInstrumentFileNames.push_back("");
|
||||
}
|
||||
|
||||
const char* highNoteSampleFileName = rootChild->Attribute("HighNoteSampleFileName");
|
||||
if (normalNoteSampleFileName != nullptr) {
|
||||
instrument.highNotesSound.tuning = rootChild->FloatAttribute("Tuning");
|
||||
std::string sampleFileName = std::string(normalNoteSampleFileName);
|
||||
std::shared_ptr<Ship::IResource> res =
|
||||
Ship::Context::GetInstance()->GetResourceManager()->LoadResourceProcess(sampleFileName.c_str());
|
||||
instrument.highNotesSound.sample = static_cast<Sample*>(res ? res->GetRawPointer() : nullptr);
|
||||
audioSoundFont->highInstrumentFileNames.push_back(sampleFileName);
|
||||
} else {
|
||||
instrument.highNotesSound.tuning = 0;
|
||||
instrument.highNotesSound.sample = nullptr;
|
||||
audioSoundFont->highInstrumentFileNames.push_back("");
|
||||
}
|
||||
|
||||
audioSoundFont->instruments.push_back(instrument);
|
||||
audioSoundFont->instrumentAddresses.push_back(isValidEntry ? &audioSoundFont->instruments.back() : nullptr);
|
||||
} else if (rootChild->Name() == "Sfx") { // 🔊 SOUND EFFECTS 🔊
|
||||
SoundFontSound soundEffect;
|
||||
|
||||
soundEffect.tuning = rootChild->FloatAttribute("Tuning");
|
||||
std::string sampleFileName = std::string(rootChild->Attribute("SampleFileName"));
|
||||
std::shared_ptr<Ship::IResource> res =
|
||||
Ship::Context::GetInstance()->GetResourceManager()->LoadResourceProcess(sampleFileName.c_str());
|
||||
soundEffect.sample = static_cast<Sample*>(res ? res->GetRawPointer() : nullptr);
|
||||
audioSoundFont->soundEffectFileNames.push_back(sampleFileName);
|
||||
|
||||
audioSoundFont->soundEffects.push_back(soundEffect);
|
||||
} else {
|
||||
LUSLOG_ERROR("Tried to load sound font element of unknown type: %s (valid types are \"Drum\", "
|
||||
"\"Instrument\" & \"Sfx\")",
|
||||
rootChild->Name());
|
||||
assert(false);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
rootChild = rootChild->NextSiblingElement();
|
||||
}
|
||||
|
||||
audioSoundFont->soundFont.numDrums = audioSoundFont->drumAddresses.size();
|
||||
audioSoundFont->soundFont.drums = audioSoundFont->drumAddresses.data();
|
||||
|
||||
audioSoundFont->soundFont.numInstruments = audioSoundFont->instrumentAddresses.size();
|
||||
audioSoundFont->soundFont.instruments = audioSoundFont->instrumentAddresses.data();
|
||||
|
||||
audioSoundFont->soundFont.numSfx = audioSoundFont->soundEffects.size();
|
||||
audioSoundFont->soundFont.soundEffects = audioSoundFont->soundEffects.data();
|
||||
|
||||
return audioSoundFont;
|
||||
}
|
||||
} // namespace SOH
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
#include "Resource.h"
|
||||
#include "ResourceFactoryBinary.h"
|
||||
#include "ResourceFactoryXML.h"
|
||||
|
||||
namespace SOH {
|
||||
class ResourceFactoryBinaryAudioSoundFontV2 final : public Ship::ResourceFactoryBinary {
|
||||
|
@ -9,4 +10,10 @@ class ResourceFactoryBinaryAudioSoundFontV2 final : public Ship::ResourceFactory
|
|||
std::shared_ptr<Ship::IResource> ReadResource(std::shared_ptr<Ship::File> file,
|
||||
std::shared_ptr<Ship::ResourceInitData> initData) override;
|
||||
};
|
||||
|
||||
class ResourceFactoryXMLAudioSoundFontV2 : public Ship::ResourceFactoryXML {
|
||||
public:
|
||||
std::shared_ptr<Ship::IResource> ReadResource(std::shared_ptr<Ship::File> file,
|
||||
std::shared_ptr<Ship::ResourceInitData> initData) override;
|
||||
};
|
||||
} // namespace SOH
|
||||
|
|
100
soh/soh/resource/logging/AudioSoundFontLogger.cpp
Normal file
100
soh/soh/resource/logging/AudioSoundFontLogger.cpp
Normal file
|
@ -0,0 +1,100 @@
|
|||
#include "soh/resource/type/AudioSoundFont.h"
|
||||
#include "spdlog/spdlog.h"
|
||||
#include <tinyxml2.h>
|
||||
|
||||
namespace SOH {
|
||||
void LogAudioSoundFontAsXML(std::shared_ptr<Ship::ResourceInitData> initData,
|
||||
std::shared_ptr<SOH::AudioSoundFont> audioSoundFont) {
|
||||
tinyxml2::XMLDocument doc;
|
||||
tinyxml2::XMLElement* root = doc.NewElement("SoundFont");
|
||||
doc.InsertFirstChild(root);
|
||||
|
||||
for (size_t i = 0; i < audioSoundFont->soundFont.numDrums; i += 1) {
|
||||
tinyxml2::XMLElement* drumElement = doc.NewElement("Drum");
|
||||
Drum* drum = audioSoundFont->soundFont.drums[i];
|
||||
|
||||
drumElement->SetAttribute("ReleaseRate", drum->releaseRate);
|
||||
drumElement->SetAttribute("Pan", drum->pan);
|
||||
drumElement->SetAttribute("Loaded", drum->loaded);
|
||||
drumElement->SetAttribute("Tuning", drum->sound.tuning);
|
||||
|
||||
if (drum->sound.sample != nullptr) {
|
||||
drumElement->SetAttribute("SampleFileName", audioSoundFont->drumFileNames[i].c_str());
|
||||
}
|
||||
|
||||
std::vector<AdsrEnvelope> envelopes = audioSoundFont->drumEnvelopeArrays[i];
|
||||
|
||||
for (AdsrEnvelope envelope : envelopes) {
|
||||
tinyxml2::XMLElement* drumEnvelopeElement = doc.NewElement("Envelope");
|
||||
|
||||
drumEnvelopeElement->SetAttribute("Delay", BE16SWAP(envelope.delay));
|
||||
drumEnvelopeElement->SetAttribute("Arg", BE16SWAP(envelope.arg));
|
||||
|
||||
drumElement->InsertEndChild(drumEnvelopeElement);
|
||||
}
|
||||
|
||||
root->InsertEndChild(drumElement);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < audioSoundFont->soundFont.numInstruments; i += 1) {
|
||||
tinyxml2::XMLElement* instrumentElement = doc.NewElement("Instrument");
|
||||
Instrument* instrument = audioSoundFont->soundFont.instruments[i];
|
||||
|
||||
if (instrument == nullptr) {
|
||||
SPDLOG_INFO("[LogAudioSoundFontAsXML]: Instrument was nullptr (i={})", i);
|
||||
instrumentElement->SetAttribute("IsValidEntry", 0);
|
||||
root->InsertEndChild(instrumentElement);
|
||||
continue;
|
||||
}
|
||||
|
||||
instrumentElement->SetAttribute("IsValidEntry", "1");
|
||||
instrumentElement->SetAttribute("Loaded", instrument->loaded);
|
||||
instrumentElement->SetAttribute("NormalRangeLo", instrument->normalRangeLo);
|
||||
instrumentElement->SetAttribute("NormalRangeHi", instrument->normalRangeHi);
|
||||
instrumentElement->SetAttribute("ReleaseRate", instrument->releaseRate);
|
||||
|
||||
std::vector<AdsrEnvelope> envelopes = audioSoundFont->instrumentEnvelopeArrays[i];
|
||||
|
||||
for (AdsrEnvelope envelope : envelopes) {
|
||||
tinyxml2::XMLElement* instrumentEnvelopeElement = doc.NewElement("Envelope");
|
||||
|
||||
instrumentEnvelopeElement->SetAttribute("Delay", BE16SWAP(envelope.delay));
|
||||
instrumentEnvelopeElement->SetAttribute("Arg", BE16SWAP(envelope.arg));
|
||||
|
||||
instrumentElement->InsertEndChild(instrumentEnvelopeElement);
|
||||
}
|
||||
|
||||
if (instrument->lowNotesSound.sample != nullptr) {
|
||||
instrumentElement->SetAttribute("LowNoteSampleFileName", audioSoundFont->lowInstrumentFileNames[i].c_str());
|
||||
}
|
||||
|
||||
if (instrument->lowNotesSound.sample != nullptr) {
|
||||
instrumentElement->SetAttribute("NormalNoteSampleFileName",
|
||||
audioSoundFont->normalInstrumentFileNames[i].c_str());
|
||||
}
|
||||
|
||||
if (instrument->lowNotesSound.sample != nullptr) {
|
||||
instrumentElement->SetAttribute("HighNoteSampleFileName",
|
||||
audioSoundFont->highInstrumentFileNames[i].c_str());
|
||||
}
|
||||
|
||||
root->InsertEndChild(instrumentElement);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < audioSoundFont->soundFont.numSfx; i += 1) {
|
||||
tinyxml2::XMLElement* sfxElement = doc.NewElement("Sfx");
|
||||
SoundFontSound sfx = audioSoundFont->soundFont.soundEffects[i];
|
||||
|
||||
sfxElement->SetAttribute("Tuning", sfx.tuning);
|
||||
|
||||
sfxElement->SetAttribute("SampleFileName", audioSoundFont->soundEffectFileNames[i].c_str());
|
||||
|
||||
root->InsertEndChild(sfxElement);
|
||||
}
|
||||
|
||||
tinyxml2::XMLPrinter printer;
|
||||
doc.Accept(&printer);
|
||||
|
||||
SPDLOG_INFO("{}: {}", initData->Path, printer.CStr());
|
||||
}
|
||||
} // namespace SOH
|
8
soh/soh/resource/logging/AudioSoundFontLogger.h
Normal file
8
soh/soh/resource/logging/AudioSoundFontLogger.h
Normal file
|
@ -0,0 +1,8 @@
|
|||
#include "Resource.h"
|
||||
#include "soh/OTRGlobals.h"
|
||||
#include "soh/cvar_prefixes.h"
|
||||
|
||||
namespace SOH {
|
||||
void LogAudioSoundFontAsXML(std::shared_ptr<Ship::ResourceInitData> initData,
|
||||
std::shared_ptr<SOH::AudioSoundFont> audioSoundFont);
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "Resource.h"
|
||||
#include "soh/resource/type/AudioSample.h"
|
||||
|
@ -69,16 +70,21 @@ class AudioSoundFont : public Ship::Resource<SoundFont> {
|
|||
uint16_t data3;
|
||||
|
||||
std::vector<Drum> drums;
|
||||
std::vector<std::string> drumFileNames;
|
||||
std::vector<Drum*> drumAddresses;
|
||||
std::vector<uint32_t> drumEnvelopeCounts;
|
||||
std::vector<std::vector<AdsrEnvelope>> drumEnvelopeArrays;
|
||||
|
||||
std::vector<Instrument> instruments;
|
||||
std::vector<std::string> lowInstrumentFileNames;
|
||||
std::vector<std::string> normalInstrumentFileNames;
|
||||
std::vector<std::string> highInstrumentFileNames;
|
||||
std::vector<Instrument*> instrumentAddresses;
|
||||
std::vector<uint32_t> instrumentEnvelopeCounts;
|
||||
std::vector<std::vector<AdsrEnvelope>> instrumentEnvelopeArrays;
|
||||
|
||||
std::vector<SoundFontSound> soundEffects;
|
||||
std::vector<std::string> soundEffectFileNames;
|
||||
|
||||
SoundFont soundFont;
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue