From f574ce152837cfe9e25d40b35414d44fb1ac4ec7 Mon Sep 17 00:00:00 2001 From: Jcw87 Date: Mon, 22 Jan 2024 07:43:44 -0800 Subject: [PATCH] JASBNKParser --- include/JSystem/JAudio/JASBNKParser.h | 78 +++++++++-- include/JSystem/JAudio/JASInst.h | 29 +++- src/JSystem/JAudio/JASBNKParser.cpp | 186 +++++++++++++++++++++++++- src/JSystem/JAudio/JASBasicInst.cpp | 4 +- src/JSystem/JAudio/JASDrumSet.cpp | 4 +- 5 files changed, 275 insertions(+), 26 deletions(-) diff --git a/include/JSystem/JAudio/JASBNKParser.h b/include/JSystem/JAudio/JASBNKParser.h index 91c5fbd92..bba4561ed 100644 --- a/include/JSystem/JAudio/JASBNKParser.h +++ b/include/JSystem/JAudio/JASBNKParser.h @@ -1,24 +1,78 @@ #ifndef JASBNKPARSER_H #define JASBNKPARSER_H -#include "dolphin/types.h" +#include "JSystem/JAudio/JASOscillator.h" namespace JASystem { class TBasicBank; namespace BNKParser { - struct THeader; - struct TInst; - struct TKeymap; - struct TOsc; - struct TPerc; - struct TPmap; - struct TRand; - struct TSense; - struct TVmap; + struct THeader { + /* 0x000 */ u8 field_0x0[0x24]; + /* 0x024 */ u32 mInstOffsets[0x80]; + /* 0x224 */ u8 field_0x224[0x190]; + /* 0x3B4 */ u32 mPercOffsets[12]; + }; + struct TInst { + /* 0x00 */ u8 field_0x0[8]; + /* 0x08 */ f32 field_0x8; + /* 0x0C */ f32 field_0xC; + /* 0x10 */ u32 mOscOffsets[2]; + /* 0x18 */ u32 mRandOffsets[2]; + /* 0x20 */ u32 mSenseOffsets[2]; + /* 0x28 */ u32 mKeyRegionCount; + /* 0x2C */ u32 mKeymapOffsets[2]; + }; + struct TKeymap { + /* 0x00 */ u8 field_0x0; + /* 0x04 */ u32 field_0x4; + /* 0x08 */ u32 mVmapOffsets[1]; + }; + struct TOsc { + /* 0x00 */ u8 field_0x0; + /* 0x04 */ f32 field_0x4; + /* 0x08 */ u32 field_0x8; + /* 0x0C */ u32 field_0xC; + /* 0x10 */ f32 field_0x10; + /* 0x14 */ f32 field_0x14; + }; + struct TPerc { + /* 0x000 */ u32 mMagic; + /* 0x004 */ u8 field_0x4[0x84]; + /* 0x088 */ u32 mPmapOffsets[0x80]; + /* 0x288 */ s8 field_0x288[0x80]; + /* 0x308 */ u16 field_0x308[0x80]; + }; + struct TPmap { + /* 0x00 */ f32 field_0x0; + /* 0x04 */ f32 field_0x4; + /* 0x08 */ u32 mRandOffsets[2]; + /* 0x10 */ u32 mVeloRegionCount; + /* 0x14 */ u32 mVeloRegionOffsets[1]; + }; + struct TRand { + /* 0x00 */ u8 field_0x0; + /* 0x04 */ f32 field_0x4; + /* 0x08 */ f32 field_0x8; + }; + struct TSense { + /* 0x00 */ u8 field_0x0; + /* 0x01 */ u8 field_0x1; + /* 0x02 */ u8 field_0x2; + /* 0x04 */ f32 field_0x4; + /* 0x08 */ f32 field_0x8; + }; + struct TVmap { + /* 0x00 */ u8 field_0x0; + /* 0x04 */ u32 field_0x4; + /* 0x08 */ f32 field_0x8; + /* 0x0C */ f32 field_0xC; + }; TBasicBank* createBasicBank(void*); - void findOscPtr(JASystem::TBasicBank*, JASystem::BNKParser::THeader*, JASystem::BNKParser::TOsc*); - void getOscTableEndPtr(s16*); + TOscillator::Osc_* findOscPtr(JASystem::TBasicBank*, JASystem::BNKParser::THeader*, JASystem::BNKParser::TOsc*); + s16* getOscTableEndPtr(s16*); + + extern u32 sUsedHeapSize; }; } diff --git a/include/JSystem/JAudio/JASInst.h b/include/JSystem/JAudio/JASInst.h index c41cd505e..167b687e8 100644 --- a/include/JSystem/JAudio/JASInst.h +++ b/include/JSystem/JAudio/JASInst.h @@ -6,22 +6,45 @@ namespace JASystem { struct TInstParam { + TInstParam() { + field_0x0 = 0; + field_0x4 = 0; + mOscData = NULL; + mOscCount = 0; + field_0x10 = 1.0f; + field_0x14 = 1.0f; + field_0x18 = 1.0f; + field_0x1c = 1.0f; + field_0x20 = 0.5f; + field_0x24 = 0.0f; + field_0x28 = 0.0f; + field_0x2c = 0.5f; + field_0x30 = 0.0f; + field_0x34 = 0.0f; + field_0x38 = 0; + field_0x3a = 0; + field_0x3c = 0; + field_0x40 = 0; + } + /* 0x00 */ u8 field_0x0; /* 0x04 */ int field_0x4; - /* 0x08 */ TOscillator::Osc_** field_0x8; - /* 0x0C */ int field_0xc; + /* 0x08 */ TOscillator::Osc_** mOscData; + /* 0x0C */ u32 mOscCount; /* 0x10 */ f32 field_0x10; /* 0x14 */ f32 field_0x14; /* 0x18 */ f32 field_0x18; /* 0x1C */ f32 field_0x1c; /* 0x20 */ f32 field_0x20; - /* 0x24 */ u8 field_0x24[0x2C - 0x24]; + /* 0x24 */ f32 field_0x24; + /* 0x28 */ f32 field_0x28; /* 0x2C */ f32 field_0x2c; /* 0x30 */ f32 field_0x30; /* 0x34 */ f32 field_0x34; /* 0x38 */ u8 field_0x38; /* 0x3A */ u16 field_0x3a; /* 0x3C */ int field_0x3c; + /* 0x40 */ int field_0x40; }; class TInst { public: diff --git a/src/JSystem/JAudio/JASBNKParser.cpp b/src/JSystem/JAudio/JASBNKParser.cpp index 223d63518..2cc995b04 100644 --- a/src/JSystem/JAudio/JASBNKParser.cpp +++ b/src/JSystem/JAudio/JASBNKParser.cpp @@ -4,19 +4,191 @@ // #include "JSystem/JAudio/JASBNKParser.h" -#include "dolphin/types.h" +#include "JSystem/JAudio/JASBasicBank.h" +#include "JSystem/JAudio/JASBasicInst.h" +#include "JSystem/JAudio/JASCalc.h" +#include "JSystem/JAudio/JASDrumSet.h" +#include "JSystem/JAudio/JASInstRand.h" +#include "JSystem/JAudio/JASInstSense.h" +#include "JSystem/JKernel/JKRHeap.h" +#include "JSystem/JSupport/JSupport.h" +#include "JSystem/JUtility/JUTAssert.h" + +u32 JASystem::BNKParser::sUsedHeapSize; /* 802870F0-802879A0 .text createBasicBank__Q28JASystem9BNKParserFPv */ -JASystem::TBasicBank* JASystem::BNKParser::createBasicBank(void*) { - /* Nonmatching */ +JASystem::TBasicBank* JASystem::BNKParser::createBasicBank(void* stream) { + JKRHeap* heap = TBank::getCurrentHeap(); + const u32 freeSize = heap->getFreeSize(); + THeader* header = (THeader*)stream; + TBasicBank* bank = new (heap, 0) TBasicBank(); + if (bank == NULL) { + return NULL; + } + bank->setInstCount(0x100); + + for (int i = 0; i < 0x80; i++) { + TInst* instRaw = JSUConvertOffsetToPtr(header, header->mInstOffsets[i]); + if (instRaw != NULL) { + TBasicInst* instp = new (heap, 0) TBasicInst(); + JUT_ASSERT(56, instp != 0); + instp->field_0x4 = instRaw->field_0x8; + instp->field_0x8 = instRaw->field_0xC; + + instp->setOscCount(2); + for (int oscIndex = 0, j = 0; j < 2; j++) { + TOsc* oscRaw = JSUConvertOffsetToPtr(header, instRaw->mOscOffsets[j]); + if (oscRaw != NULL) { + TOscillator::Osc_* osc = findOscPtr(bank, header, oscRaw); + if (osc == NULL) { + osc = new (heap, 0) TOscillator::Osc_(); + JUT_ASSERT(72, osc != 0); + osc->field_0x0 = oscRaw->field_0x0; + osc->field_0x4 = oscRaw->field_0x4; + s16* oscTable = JSUConvertOffsetToPtr(header, oscRaw->field_0x8); + if (oscTable != NULL) { + u32 tableLength = getOscTableEndPtr(oscTable) - oscTable; + osc->table = new (heap, 0) s16[tableLength]; + JUT_ASSERT(82, osc->table != 0); + Calc::bcopy(oscTable, osc->table, tableLength * sizeof(s16)); + } else { + osc->table = NULL; + } + oscTable = JSUConvertOffsetToPtr(header, oscRaw->field_0xC); + if (oscTable != NULL) { + u32 tableLength = getOscTableEndPtr(oscTable) - oscTable; + osc->rel_table = new (heap, 0) s16[tableLength]; + JUT_ASSERT(94, osc->rel_table != 0); + Calc::bcopy(oscTable, osc->rel_table, tableLength); + } else { + osc->rel_table = NULL; + } + osc->field_0x10 = oscRaw->field_0x10; + osc->field_0x14 = oscRaw->field_0x14; + } + instp->setOsc(oscIndex, osc); + oscIndex++; + } + } + + instp->setEffectCount(4); + for (int j = 0; j < 2; j++) { + TRand* randRaw = JSUConvertOffsetToPtr(header, instRaw->mRandOffsets[j]); + if (randRaw != NULL) { + TInstRand* randp = new (heap, 0) TInstRand(); + JUT_ASSERT(120, randp != 0); + randp->setTarget(randRaw->field_0x0); + randp->field_0x8 = randRaw->field_0x4; + randp->field_0xc = randRaw->field_0x8; + instp->setEffect(j, randp); + } + } + for (int j = 0; j < 2; j++) { + TSense* senseRaw = JSUConvertOffsetToPtr(header, instRaw->mSenseOffsets[j]); + if (senseRaw != NULL) { + TInstSense* sensep = new (heap, 0) TInstSense(); + JUT_ASSERT(133, sensep != 0); + sensep->setTarget(senseRaw->field_0x0); + sensep->setParams(senseRaw->field_0x1, senseRaw->field_0x2, senseRaw->field_0x4, senseRaw->field_0x8); + instp->setEffect(j + 2, sensep); + } + } + + instp->setKeyRegionCount(instRaw->mKeyRegionCount); + for (int j = 0; j < instRaw->mKeyRegionCount; j++) { + TBasicInst::TKeymap* instKeymap = instp->getKeyRegion(j); + TKeymap* keymapRaw = JSUConvertOffsetToPtr(header, instRaw->mKeymapOffsets[j]); + instKeymap->mBaseKey = keymapRaw->field_0x0; + instKeymap->setVeloRegionCount(keymapRaw->field_0x4); + for (int k = 0; k < keymapRaw->field_0x4; k++) { + TBasicInst::TVeloRegion* instVeloRegion = instKeymap->getVeloRegion(k); + TVmap* vmapRaw = JSUConvertOffsetToPtr(header, keymapRaw->mVmapOffsets[k]); + instVeloRegion->mBaseVel = vmapRaw->field_0x0; + instVeloRegion->field_0x04 = vmapRaw->field_0x4 & 0xFFFF; + instVeloRegion->field_0x08 = vmapRaw->field_0x8; + instVeloRegion->field_0x0c = vmapRaw->field_0xC; + } + } + bank->setInst(i, instp); + } + } + + for (int i = 0; i < 12; i++) { + TPerc* percRaw = JSUConvertOffsetToPtr(header, header->mPercOffsets[i]); + if (percRaw != NULL) { + TDrumSet* setp = new (heap, 0) TDrumSet(); + JUT_ASSERT(183, setp != 0); + for (int j = 0; j < 0x80; j++) { + TPmap* pmapRaw = JSUConvertOffsetToPtr(header, percRaw->mPmapOffsets[j]); + if (pmapRaw != NULL) { + TDrumSet::TPerc* drumSetPerc = setp->getPerc(j); + drumSetPerc->field_0x0 = pmapRaw->field_0x0; + drumSetPerc->field_0x4 = pmapRaw->field_0x4; + if (percRaw->mMagic == 'PER2') { + drumSetPerc->field_0x8 = percRaw->field_0x288[j] / 127.0f; + drumSetPerc->setRelease(percRaw->field_0x308[j]); + } + drumSetPerc->setEffectCount(2); + for (int effectIndex = 0, k = 0; k < 2; k++) { + TRand* randRaw = JSUConvertOffsetToPtr(header, pmapRaw->mRandOffsets[k]); + if (randRaw != NULL) { + TInstRand* randp = new (heap, 0) TInstRand(); + JUT_ASSERT(207, randp != 0); + randp->setTarget(randRaw->field_0x0); + randp->field_0x8 = randRaw->field_0x4; + randp->field_0xc = randRaw->field_0x8; + drumSetPerc->setEffect(effectIndex, randp); + effectIndex++; + } + } + drumSetPerc->setVeloRegionCount(pmapRaw->mVeloRegionCount); + for (int k = 0; k < pmapRaw->mVeloRegionCount; k++) { + TBasicInst::TVeloRegion* instVeloRegion = drumSetPerc->getVeloRegion(k); + TVmap* vmapRaw = JSUConvertOffsetToPtr(header, pmapRaw->mVeloRegionOffsets[k]); + instVeloRegion->mBaseVel = vmapRaw->field_0x0; + instVeloRegion->field_0x04 = vmapRaw->field_0x4 & 0xFFFF; + instVeloRegion->field_0x08 = vmapRaw->field_0x8; + instVeloRegion->field_0x0c = vmapRaw->field_0xC; + } + } + } + bank->setInst(i + 0xE4, setp); + } + } + sUsedHeapSize += freeSize - heap->getFreeSize(); + return bank; } /* 802879A0-80287AEC .text findOscPtr__Q28JASystem9BNKParserFPQ28JASystem10TBasicBankPQ38JASystem9BNKParser7THeaderPQ38JASystem9BNKParser4TOsc */ -void JASystem::BNKParser::findOscPtr(JASystem::TBasicBank*, JASystem::BNKParser::THeader*, JASystem::BNKParser::TOsc*) { - /* Nonmatching */ +JASystem::TOscillator::Osc_* JASystem::BNKParser::findOscPtr(JASystem::TBasicBank* bank, JASystem::BNKParser::THeader* header, JASystem::BNKParser::TOsc* oscPtr) { + u32* instOffsets = header->mInstOffsets - 1; + for (int i = 0; i < 128; i++) { + TInst* instRaw = JSUConvertOffsetToPtr(header, instOffsets[i + 1]); + if (instRaw != NULL) { + for (int j = 0; j < 2; j++) { + TOsc* oscRaw = JSUConvertOffsetToPtr(header, instRaw->mOscOffsets[j]); + if (oscRaw == oscPtr) { + JASystem::TInst* inst = bank->getInst(i); + if (inst != NULL) { + TInstParam param; + inst->getParam(60, 127, ¶m); + if (j < param.mOscCount) { + return param.mOscData[j]; + } + } + } + } + } + } + return NULL; } /* 80287AEC-80287B00 .text getOscTableEndPtr__Q28JASystem9BNKParserFPs */ -void JASystem::BNKParser::getOscTableEndPtr(s16*) { - /* Nonmatching */ +s16* JASystem::BNKParser::getOscTableEndPtr(s16* param_1) { + s16 v1; + do { + v1 = *param_1; + param_1 += 3; + } while (v1 <= 0xa); + return param_1; } diff --git a/src/JSystem/JAudio/JASBasicInst.cpp b/src/JSystem/JAudio/JASBasicInst.cpp index 1fe5be921..b09f7be60 100644 --- a/src/JSystem/JAudio/JASBasicInst.cpp +++ b/src/JSystem/JAudio/JASBasicInst.cpp @@ -33,8 +33,8 @@ JASystem::TBasicInst::~TBasicInst() { bool JASystem::TBasicInst::getParam(int key, int velo, TInstParam* param) const { param->field_0x0 = 0; param->field_0x38 = 0; - param->field_0x8 = mOsc; - param->field_0xc = mOscCount; + param->mOscData = mOsc; + param->mOscCount = mOscCount; param->field_0x10 *= field_0x4; param->field_0x14 *= field_0x8; for (int i = 0; i < mEffectCount; i++) { diff --git a/src/JSystem/JAudio/JASDrumSet.cpp b/src/JSystem/JAudio/JASDrumSet.cpp index 37561eeda..718a9d0aa 100644 --- a/src/JSystem/JAudio/JASDrumSet.cpp +++ b/src/JSystem/JAudio/JASDrumSet.cpp @@ -32,8 +32,8 @@ bool JASystem::TDrumSet::getParam(int key, int param_2, JASystem::TInstParam* pa osc.field_0x10 = 1.0f; osc.field_0x14 = 0.0f; static TOscillator::Osc_* oscp = &osc; - param_3->field_0x8 = &oscp; - param_3->field_0xc = 1; + param_3->mOscData = &oscp; + param_3->mOscCount = 1; for (int i = 0; i < perc->mEffectCount; i++) { TInstEffect* effect = perc->mEffect[i]; if (effect) {