Fixed ocarina loop points

This commit is contained in:
Kevin Alexis Contreras 2022-06-13 21:53:26 -05:00
commit 9cf537eaff
8 changed files with 62 additions and 31 deletions

View File

@ -10,19 +10,16 @@ void OTRExporter_Audio::WriteSampleEntryReference(ZAudio* audio, SampleEntry* en
{ {
writer->Write((uint8_t)(entry != nullptr ? 1 : 0)); writer->Write((uint8_t)(entry != nullptr ? 1 : 0));
for (auto pair : samples)
{
if (pair.second == entry)
{
break;
}
}
if (entry != nullptr) if (entry != nullptr)
{ {
if (audio->sampleOffsets[entry->bankId].find(entry->sampleDataOffset) != audio->sampleOffsets[entry->bankId].end()) if (audio->sampleOffsets[entry->bankId].find(entry->sampleLoopOffset) != audio->sampleOffsets[entry->bankId].end())
{ {
writer->Write(StringHelper::Sprintf("audio/samples/%s", audio->sampleOffsets[entry->bankId][entry->sampleDataOffset].c_str())); if (audio->sampleOffsets[entry->bankId][entry->sampleLoopOffset].find(entry->sampleDataOffset) != audio->sampleOffsets[entry->bankId][entry->sampleLoopOffset].end())
{
writer->Write(StringHelper::Sprintf("audio/samples/%s", audio->sampleOffsets[entry->bankId][entry->sampleLoopOffset][entry->sampleDataOffset].c_str()));
}
else
writer->Write(entry->fileName);
} }
else else
writer->Write(entry->fileName); writer->Write(entry->fileName);
@ -98,8 +95,13 @@ void OTRExporter_Audio::Save(ZResource* res, const fs::path& outPath, BinaryWrit
std::string basePath = ""; std::string basePath = "";
if (audio->sampleOffsets[pair.second->bankId].find(pair.second->sampleDataOffset) != audio->sampleOffsets[pair.second->bankId].end()) if (audio->sampleOffsets[pair.second->bankId].find(pair.second->sampleLoopOffset) != audio->sampleOffsets[pair.second->bankId].end())
basePath = StringHelper::Sprintf("samples/%s", audio->sampleOffsets[pair.second->bankId][pair.second->sampleDataOffset].c_str()); {
if (audio->sampleOffsets[pair.second->bankId][pair.second->sampleLoopOffset].find(pair.second->sampleDataOffset) != audio->sampleOffsets[pair.second->bankId][pair.second->sampleLoopOffset].end())
basePath = StringHelper::Sprintf("samples/%s", audio->sampleOffsets[pair.second->bankId][pair.second->sampleLoopOffset][pair.second->sampleDataOffset].c_str());
else
basePath = StringHelper::Sprintf("samples/sample_%08X", pair.first);
}
else else
basePath = StringHelper::Sprintf("samples/sample_%08X", pair.first); basePath = StringHelper::Sprintf("samples/sample_%08X", pair.first);

View File

@ -26,7 +26,6 @@ void ZAudio::ParseXML(tinyxml2::XMLElement* reader)
while (child != nullptr) while (child != nullptr)
{ {
int bp = 0;
if (std::string(child->Value()) == "Sequences") if (std::string(child->Value()) == "Sequences")
{ {
auto seqChild = child->FirstChildElement(); auto seqChild = child->FirstChildElement();
@ -52,7 +51,17 @@ void ZAudio::ParseXML(tinyxml2::XMLElement* reader)
if (std::string(sampChild->Value()) == "Sample") if (std::string(sampChild->Value()) == "Sample")
{ {
auto atStr = sampChild->FirstChildElement()->Attribute("At"); auto atStr = sampChild->FirstChildElement()->Attribute("At");
sampleOffsets[bankId][StringHelper::StrToL(atStr, 16)] = sampChild->Attribute("Name"); auto loopStr = sampChild->FirstChildElement()->Attribute("LoopOffset");
uint32_t loopOffset = 0xFFFFFFFF;
uint32_t atOffset = StringHelper::StrToL(atStr, 16);
if (loopStr != NULL)
{
loopOffset = StringHelper::StrToL(loopStr, 16);
specialLoopSamples[loopOffset] = atOffset;
}
sampleOffsets[bankId][loopOffset][atOffset] = sampChild->Attribute("Name");
} }
sampChild = sampChild->NextSiblingElement(); sampChild = sampChild->NextSiblingElement();
@ -140,11 +149,20 @@ SampleEntry* ZAudio::ParseSampleEntry(std::vector<uint8_t> audioBank,
sample->loop.end = BitConverter::ToInt32BE(audioBank, loopOffset + 4); sample->loop.end = BitConverter::ToInt32BE(audioBank, loopOffset + 4);
sample->loop.count = BitConverter::ToInt32BE(audioBank, loopOffset + 8); sample->loop.count = BitConverter::ToInt32BE(audioBank, loopOffset + 8);
if (sample->loop.count != 0xFFFFFFFF) if (sample->loop.start == 0x3ADB)
{ {
for (int i = 0; i < sample->loop.count; i++) int bp = 0;
}
if (/* sample->loop.count != 0xFFFFFFFF && */ sample->loop.count != 0)
{ {
int16_t state = BitConverter::ToInt16BE(sample->data, loopOffset + 16 + (i * 2)); //for (int i = 0; i < sample->loop.count; i++)
for (int i = 0; i < 16; i++)
{
//if ((loopOffset + 16 + (i * 2)) >= audioBank.size())
//break;
int16_t state = BitConverter::ToInt16BE(audioBank, loopOffset + 16 + (i * 2));
sample->loop.states.push_back(state); sample->loop.states.push_back(state);
} }
} }
@ -159,6 +177,10 @@ SampleEntry* ZAudio::ParseSampleEntry(std::vector<uint8_t> audioBank,
} }
sample->sampleDataOffset = sampleDataOffset; sample->sampleDataOffset = sampleDataOffset;
if (specialLoopSamples.find(loopOffset) != specialLoopSamples.end())
sample->sampleLoopOffset = loopOffset;
sample->fileName = StringHelper::Sprintf("audio/samples/sample_%08X", sampleOffset); sample->fileName = StringHelper::Sprintf("audio/samples/sample_%08X", sampleOffset);
samples[sampleOffset] = sample; samples[sampleOffset] = sample;

View File

@ -29,6 +29,7 @@ struct SampleEntry
std::string fileName; std::string fileName;
uint8_t bankId; uint8_t bankId;
uint32_t sampleDataOffset; uint32_t sampleDataOffset;
uint32_t sampleLoopOffset = 0xFFFFFFFF;
uint8_t codec; uint8_t codec;
uint8_t medium; uint8_t medium;
uint8_t unk_bit26; uint8_t unk_bit26;
@ -94,7 +95,12 @@ public:
std::map<uint32_t, SampleEntry*> samples; std::map<uint32_t, SampleEntry*> samples;
std::vector<std::vector<uint32_t>> fontIndices; std::vector<std::vector<uint32_t>> fontIndices;
std::vector<std::string> seqNames; std::vector<std::string> seqNames;
std::map<uint32_t, std::map<uint32_t, std::string>> sampleOffsets;
// First Key = Bank ID, Sec Key = LoopDataOffset, Third Key = Sample Data Offset
std::map<uint32_t, std::map<uint32_t, std::map<uint32_t, std::string>>> sampleOffsets;
// Key = Loop Offset, Value = Sample Offset
std::map<uint32_t, uint32_t> specialLoopSamples;
ZAudio(ZFile* nParent); ZAudio(ZFile* nParent);

View File

@ -73,11 +73,11 @@ namespace Ship
{ {
InstrumentEntry entry; InstrumentEntry entry;
entry.isValidEntry = reader->ReadByte(); entry.isValidEntry = reader->ReadUByte();
entry.loaded = reader->ReadByte(); entry.loaded = reader->ReadUByte();
entry.normalRangeLo = reader->ReadByte(); entry.normalRangeLo = reader->ReadUByte();
entry.normalRangeHi = reader->ReadByte(); entry.normalRangeHi = reader->ReadUByte();
entry.releaseRate = reader->ReadByte(); entry.releaseRate = reader->ReadUByte();
entry.env = ReadEnvelopeData(reader); entry.env = ReadEnvelopeData(reader);

View File

@ -461,8 +461,11 @@
<Sample Name="Person Whistling"> <Sample Name="Person Whistling">
<Offset Version="MQDebug" At="0xF72A0"/> <Offset Version="MQDebug" At="0xF72A0"/>
</Sample> </Sample>
<Sample Name="Ocarina"> <Sample Name="Ocarina_Looped">
<Offset Version="MQDebug" At="0xFAD40"/> <Offset Version="MQDebug" At="0xFAD40" LoopOffset="0x1550"/>
</Sample>
<Sample Name="Ocarina_NoLooped">
<Offset Version="MQDebug" At="0xFAD40" LoopOffset="0x77C0"/>
</Sample> </Sample>
<Sample Name="Accordion"> <Sample Name="Accordion">
<Offset Version="MQDebug" At="0xFDFC0"/> <Offset Version="MQDebug" At="0xFDFC0"/>

View File

@ -687,7 +687,6 @@ typedef struct {
union{ union{
u32 opArgs; u32 opArgs;
struct { struct {
// OTRTODO: struct members swapped for quick audio
u8 arg2; u8 arg2;
u8 arg1; u8 arg1;
u8 arg0; u8 arg0;

View File

@ -70,7 +70,6 @@ ReverbSettings D_80133420[][3] = {
}, },
}; };
// OTRTODO
AudioSpec gAudioSpecs[18] = { AudioSpec gAudioSpecs[18] = {
{ 44100, 1, 24, 4, 0, 0, 2, D_80133420[0], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x4000, 0x2880, 0, 0, 0 }, { 44100, 1, 24, 4, 0, 0, 2, D_80133420[0], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x4000, 0x2880, 0, 0, 0 },
{ 44100, 1, 24, 4, 0, 0, 2, D_80133420[1], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x3800, 0x2880, 0, 0, 0 }, { 44100, 1, 24, 4, 0, 0, 2, D_80133420[1], 0x300, 0x200, 0x7FFF, 0x7F0, 0xE00, 0, 0x3800, 0x2880, 0, 0, 0 },

View File

@ -561,8 +561,8 @@ Acmd* AudioSynth_DoOneAudioUpdate(s16* aiBuf, s32 aiBufLen, Acmd* cmd, s32 updat
NoteSubEu* noteSubEu2; NoteSubEu* noteSubEu2;
s32 unk14; s32 unk14;
if (aiBufLen == 0) //if (aiBufLen == 0)
return; //return;
t = gAudioContext.numNotes * updateIndex; t = gAudioContext.numNotes * updateIndex;
count = 0; count = 0;