diff --git a/configure.py b/configure.py index 42aec169b..bf78fd363 100755 --- a/configure.py +++ b/configure.py @@ -875,7 +875,7 @@ config.libs = [ Object(NonMatching, "JSystem/JAudio/JASBNKParser.cpp"), Object(Matching, "JSystem/JAudio/JASWaveArcLoader.cpp"), Object(Matching, "JSystem/JAudio/JASWaveBankMgr.cpp"), - Object(NonMatching, "JSystem/JAudio/JASBankMgr.cpp"), + Object(Matching, "JSystem/JAudio/JASBankMgr.cpp"), Object(Matching, "JSystem/JAudio/JASAudioThread.cpp"), Object(Matching, "JSystem/JAudio/JASDSPBuf.cpp"), Object(NonMatching, "JSystem/JAudio/JASDSPChannel.cpp"), @@ -884,7 +884,7 @@ config.libs = [ Object(Matching, "JSystem/JAudio/JASChGlobal.cpp"), Object(Matching, "JSystem/JAudio/JASChAllocQueue.cpp"), Object(Matching, "JSystem/JAudio/JASChannel.cpp"), - Object(NonMatching, "JSystem/JAudio/JASChannelMgr.cpp"), + Object(Matching, "JSystem/JAudio/JASChannelMgr.cpp"), Object(Matching, "JSystem/JAudio/JASOscillator.cpp"), Object(Matching, "JSystem/JAudio/JASDriverTables.cpp"), Object(Matching, "JSystem/JAudio/dspproc.c", extra_cflags=["-lang c++", "-O4", "-func_align 32"]), diff --git a/include/JSystem/JAudio/JASBank.h b/include/JSystem/JAudio/JASBank.h index 4a447c914..3d9b1b684 100644 --- a/include/JSystem/JAudio/JASBank.h +++ b/include/JSystem/JAudio/JASBank.h @@ -11,17 +11,19 @@ namespace JASystem { class TBank { public: TBank() { - field_0x4 = 0; + mWaveBank = 0; } virtual ~TBank() {} virtual TInst* getInst(int) const = 0; virtual u32 getType() const = 0; - static JKRHeap* getCurrentHeap(); + void assignWaveBank(const TWaveBank* waveBank) { mWaveBank = waveBank; } + const TWaveBank* getWaveBank() const { return mWaveBank; } + static JKRHeap* getCurrentHeap(); static JKRHeap* sCurrentHeap; - /* 0x04 */ TWaveBank* field_0x4; + /* 0x04 */ const TWaveBank* mWaveBank; }; } diff --git a/include/JSystem/JAudio/JASBasicWaveBank.h b/include/JSystem/JAudio/JASBasicWaveBank.h index 9cddfcfe1..806e1cd6c 100644 --- a/include/JSystem/JAudio/JASBasicWaveBank.h +++ b/include/JSystem/JAudio/JASBasicWaveBank.h @@ -15,12 +15,13 @@ namespace JASystem { const JASystem::TWaveInfo* getWaveInfo() const { return &mWaveInfo; } - const void* getWavePtr() const { + intptr_t getWavePtr() const { JUT_ASSERT(77, mHeap); - if (!mHeap->mBase) { + void* base = mHeap->getBase(); + if (base == NULL) { return NULL; } - return (u8*)mHeap->mBase + mWaveInfo.mWavePtrOffs; + return (intptr_t)base + mWaveInfo.mWavePtrOffs; } /* 0x04 */ JASystem::TWaveInfo mWaveInfo; diff --git a/include/JSystem/JAudio/JASChGlobal.h b/include/JSystem/JAudio/JASChGlobal.h index effe633de..7849c0ae8 100644 --- a/include/JSystem/JAudio/JASChGlobal.h +++ b/include/JSystem/JAudio/JASChGlobal.h @@ -11,7 +11,7 @@ namespace JASystem { namespace TGlobalChannel { TChannel* getChannelHandle(u32); void init(); - int alloc(TChannelMgr*, u32); + u32 alloc(TChannelMgr*, u32); int release(TChannel*); int releaseAll(TChannelMgr*); diff --git a/include/JSystem/JAudio/JASChannel.h b/include/JSystem/JAudio/JASChannel.h index 703247871..4c3c3b09c 100644 --- a/include/JSystem/JAudio/JASChannel.h +++ b/include/JSystem/JAudio/JASChannel.h @@ -31,7 +31,7 @@ namespace JASystem { } mParts; }; - TChannel() : field_0x4(NULL), field_0x8(NULL), field_0x20(NULL), field_0x24(NULL), field_0xd8(this) { + TChannel() : field_0x4(NULL), field_0x8(NULL), field_0x20(NULL), mNext(NULL), field_0xd8(this) { for (int i = 0; i < 4; i++) { osc[i] = NULL; } @@ -74,9 +74,7 @@ namespace JASystem { u8 getNoteOnPriority() const { return field_0x48; } u8 getReleasePriority() const { return field_0x48 >> 8; } u8 getLifeTimePriority() const { return field_0x48 >> 0x10; } - - // TODO - void setSkipSamples(u32) {} + void setSkipSamples(u32 samples) { mSkipSamples = samples; } /* 0x00 */ u8 field_0x0; /* 0x01 */ u8 field_0x1; @@ -86,11 +84,11 @@ namespace JASystem { /* 0x08 */ TChannel** field_0x8; /* 0x0C */ u8 field_0xc; /* 0x10 */ Driver::Wave_* field_0x10; - /* 0x14 */ int field_0x14; + /* 0x14 */ u32 field_0x14; // TODO: sometimes used as an intptr, sometimes not...? /* 0x18 */ int field_0x18; /* 0x1C */ int field_0x1c; /* 0x20 */ TDSPChannel* field_0x20; - /* 0x24 */ TChannel* field_0x24; + /* 0x24 */ TChannel* mNext; /* 0x28 */ BOOL (*field_0x28)(TChannel*, u32); /* 0x2C */ u32 (*field_0x2c)(TChannel*, u32); /* 0x30 */ int field_0x30; @@ -103,10 +101,7 @@ namespace JASystem { /* 0x58 */ f32 field_0x58; /* 0x5C */ f32 field_0x5c; /* 0x60 */ u8 mCalcTypes[3]; // Pan, FxMix, ? - /* 0x64 */ Driver::PanMatrix_ mPanPower; - /* 0x70 */ Driver::PanMatrix_ mPanVec; - /* 0x7C */ Driver::PanMatrix_ mFxmixVec; - /* 0x88 */ Driver::PanMatrix_ mDolbyVec; + /* 0x64 */ Driver::PanMatrix_ field_0x6c[4]; // PanPower, PanVec, FxmixVec, DolbyVec? /* 0x94 */ f32 field_0x94; /* 0x98 */ f32 field_0x98; /* 0x9C */ f32 field_0x9c; @@ -118,11 +113,11 @@ namespace JASystem { /* 0xB0 */ MixConfig mMixConfigs[6]; /* 0xBC */ u16 field_0xbc[6]; /* 0xC8 */ u16 field_0xc8; - /* 0xCC */ int field_0xcc; + /* 0xCC */ u32 field_0xcc; /* 0xD0 */ int field_0xd0; /* 0xD4 */ int field_0xd4; /* 0xD8 */ JSULink field_0xd8; - /* 0xE8 */ u32 field_0xe8; + /* 0xE8 */ u32 mSkipSamples; }; } diff --git a/include/JSystem/JAudio/JASChannelMgr.h b/include/JSystem/JAudio/JASChannelMgr.h index 0b599a9ff..ec060f4e9 100644 --- a/include/JSystem/JAudio/JASChannelMgr.h +++ b/include/JSystem/JAudio/JASChannelMgr.h @@ -19,11 +19,11 @@ namespace JASystem { void addListTail(TChannel*, u32); TChannel* getListHead(u32); int cutList(TChannel*); - void receiveAllChannels(TChannelMgr*); + int receiveAllChannels(TChannelMgr*); int checkLimitStart(u32); void checkLimitStop(TChannel*, u32); - /* 0x00 */ u32 field_0x0; + /* 0x00 */ u32 mManagedChannels; /* 0x04 */ u32 field_0x4; /* 0x08 */ TChannel* field_0x8; /* 0x0C */ TChannel* field_0xc; diff --git a/include/JSystem/JAudio/JASHeapCtrl.h b/include/JSystem/JAudio/JASHeapCtrl.h index f800f16be..922f39a05 100644 --- a/include/JSystem/JAudio/JASHeapCtrl.h +++ b/include/JSystem/JAudio/JASHeapCtrl.h @@ -27,8 +27,9 @@ namespace JASystem { JASystem::Kernel::THeap* getTailHeap(); u32 getTailOffset(); u32 getCurOffset(); - - bool isAllocated() { return mBase; } + + void* getBase() { return mBase; } + bool isAllocated() const { return mBase != NULL; } /* 0x00 */ JSUTree mTree; /* 0x1C */ OSMutex mMutex; diff --git a/include/JSystem/JAudio/JASSimpleWaveBank.h b/include/JSystem/JAudio/JASSimpleWaveBank.h index 6aacc958f..1d3c44b0a 100644 --- a/include/JSystem/JAudio/JASSimpleWaveBank.h +++ b/include/JSystem/JAudio/JASSimpleWaveBank.h @@ -13,11 +13,12 @@ namespace JASystem { TWaveHandle() { mHeap = NULL; } ~TWaveHandle(); const TWaveInfo* getWaveInfo() const { return &mWaveInfo; } - const void* getWavePtr() const { - if (mHeap->mBase == NULL) { + intptr_t getWavePtr() const { + void* base = mHeap->getBase(); + if (base == NULL) { return NULL; } - return (u8*)mHeap->mBase + mWaveInfo.mWavePtrOffs; + return (intptr_t)base + mWaveInfo.mWavePtrOffs; } /* 0x04 */ TWaveInfo mWaveInfo; diff --git a/include/JSystem/JAudio/JASWaveArcLoader.h b/include/JSystem/JAudio/JASWaveArcLoader.h index 0b738ca9d..d019ecae6 100644 --- a/include/JSystem/JAudio/JASWaveArcLoader.h +++ b/include/JSystem/JAudio/JASWaveArcLoader.h @@ -30,11 +30,19 @@ namespace JASystem { void setEntryNum(s32); void setFileName(const char*); + // fake struct name + struct loadToAramCallbackMsg { + JASystem::TWaveArc* mpWaveArc; + s32 mEntryNum; + uintptr_t mBase; + u32 field_0xc; + }; + /* 0x04 */ Kernel::THeap mHeap; /* 0x4C */ int field_0x4c; /* 0x50 */ OSMutex mMutex; /* 0x68 */ int field_0x68; - /* 0x6C */ int mFileNo; + /* 0x6C */ s32 mEntryNum; /* 0x70 */ int mSize; /* 0x74 */ int field_0x74; }; diff --git a/include/JSystem/JAudio/JASWaveBank.h b/include/JSystem/JAudio/JASWaveBank.h index 8653864fe..26b86d7c2 100644 --- a/include/JSystem/JAudio/JASWaveBank.h +++ b/include/JSystem/JAudio/JASWaveBank.h @@ -29,7 +29,7 @@ namespace JASystem { public: virtual ~TWaveHandle() {} virtual const TWaveInfo* getWaveInfo() const = 0; - virtual const void* getWavePtr() const = 0; + virtual intptr_t getWavePtr() const = 0; }; class TWaveBank { diff --git a/src/JSystem/JAudio/JASBankMgr.cpp b/src/JSystem/JAudio/JASBankMgr.cpp index 117d9a459..1d8d8380b 100644 --- a/src/JSystem/JAudio/JASBankMgr.cpp +++ b/src/JSystem/JAudio/JASBankMgr.cpp @@ -15,6 +15,9 @@ #include "JSystem/JAudio/JASRate.h" #include "JSystem/JAudio/JASSystemHeap.h" #include "JSystem/JAudio/JASWaveBankMgr.h" +#include "JSystem/JAudio/JASWaveBank.h" +#include "JSystem/JAudio/JASInst.h" +#include "JSystem/JAudio/JASDSPInterface.h" #include "JSystem/JKernel/JKRSolidHeap.h" #include "JSystem/JUtility/JUTAssert.h" @@ -95,7 +98,7 @@ bool JASystem::BankMgr::assignWaveBank(int param_1, int param_2) { if (!waveBank) { return false; } - bank->field_0x4 = waveBank; + bank->assignWaveBank(waveBank); return true; } @@ -111,13 +114,103 @@ f32 JASystem::BankMgr::clamp01(f32 param_1) { } /* 8028892C-80288CE8 .text noteOn__Q28JASystem7BankMgrFPQ28JASystem11TChannelMgriiUcUcUl */ -JASystem::TChannel* JASystem::BankMgr::noteOn(TChannelMgr*, int, int, u8, u8, u32) { - /* Nonmatching */ +JASystem::TChannel* JASystem::BankMgr::noteOn(TChannelMgr* param_1, int param_2, int param_3, u8 param_4, u8 param_5, u32 param_6) { + if (param_3 > 0xEF) + return noteOnOsc(param_1, param_3 - 0xF0, param_4, param_5, param_6); + + TBank* bank = getBank(param_2); + if (!bank) + return NULL; + + TInst* inst = bank->getInst(param_3); + if (!inst) + return NULL; + + TInstParam instParam; + if (!inst->getParam(param_4, param_5, &instParam)) + return NULL; + + const TWaveBank* waveBank = bank->getWaveBank(); + if (!waveBank) + return NULL; + + TWaveHandle* waveHndl = waveBank->getWaveHandle(instParam.field_0x4); + if (!waveHndl) + return NULL; + + const TWaveInfo* waveInfo = waveHndl->getWaveInfo(); + if (!waveInfo) + return NULL; + + intptr_t wave = waveHndl->getWavePtr(); + if (!wave) + return NULL; + + u32 chanKey = (instParam.field_0x40 << 0x18) | (param_2 << 8) | param_3; + switch (instParam.field_0x40 & 0xC0) { + case 0xC0: + chanKey |= 0xffffff; + break; + case 0x80: + chanKey |= 0xff; + break; + case 0x40: + chanKey |= instParam.field_0x3c << 0x10; + break; + } + + TChannel* chan = param_1->getLogicalChannel(chanKey); + if (!chan) + return NULL; + + // TODO: TWaveInfo and Driver::Wave_ appear to be the same struct, but have two different names in the maps? + chan->field_0x10 = (Driver::Wave_*)waveInfo; + chan->field_0x14 = wave; + chan->field_0xc = instParam.field_0x0; + chan->field_0x0 = param_5; + chan->field_0x1 = param_4; + chan->field_0x50 = instParam.field_0x14 * (waveInfo->field_0x4 / Kernel::getDacRate()); + chan->field_0x58 = chan->field_0x50 * instParam.field_0x1c; + if (instParam.field_0x38 == 0) { + int var = (param_4 + 0x3C) - waveInfo->field_0x2; + if (var < 0) + var = 0; + if (var > 0x7f) + var = 0x7f; + chan->field_0x58 *= Driver::C5BASE_PITCHTABLE[var]; + } + chan->field_0x54 = instParam.field_0x10; + chan->field_0x5c = chan->field_0x0 / 127.0f; + chan->field_0x5c = chan->field_0x54 * (chan->field_0x5c * chan->field_0x5c); + chan->field_0x5c *= instParam.field_0x18; + + chan->field_0x6c[1].mSound = instParam.field_0x20; + chan->field_0x6c[2].mSound = instParam.field_0x24; + chan->field_0x6c[3].mSound = instParam.field_0x28; + + for (int i = 1; i < 3; i++) { + chan->field_0x6c[i].mSound = clamp01(chan->field_0x6c[i].mSound); + } + + chan->field_0x6c[1].mEffect = instParam.field_0x2c; + chan->field_0x6c[2].mEffect = instParam.field_0x30; + chan->field_0x6c[3].mEffect = instParam.field_0x34; + + chan->field_0x94 = 1.0f; + chan->field_0x98 = 1.0f; + + for (u32 i = 0; i < instParam.mOscCount; ++i) + chan->setOscInit(i, instParam.mOscData[i]); + + chan->directReleaseOsc(0, instParam.field_0x3a); + if (!chan->play(param_6)) + return NULL; + + return chan; } /* 80288CE8-80288E44 .text noteOnOsc__Q28JASystem7BankMgrFPQ28JASystem11TChannelMgriUcUcUl */ JASystem::TChannel* JASystem::BankMgr::noteOnOsc(TChannelMgr* param_1, int param_2, u8 param_3, u8 param_4, u32 param_5) { - /* Nonmatching */ TChannel* channel = param_1->getLogicalChannel(0); if (!channel) { return NULL; @@ -139,12 +232,12 @@ JASystem::TChannel* JASystem::BankMgr::noteOnOsc(TChannelMgr* param_1, int param channel->field_0x54 = 1.0f; channel->field_0x5c = channel->field_0x0 / 127.0f; channel->field_0x5c = channel->field_0x54 * (channel->field_0x5c * channel->field_0x5c); - channel->mPanVec.mSound = 0.5f; - channel->mFxmixVec.mSound = 0.0f; - channel->mDolbyVec.mSound = 0.0f; - channel->mPanVec.mEffect = 0.5f; - channel->mFxmixVec.mEffect = 0.0f; - channel->mDolbyVec.mEffect = 0.0f; + channel->field_0x6c[1].mSound = 0.5f; + channel->field_0x6c[2].mSound = 0.0f; + channel->field_0x6c[3].mSound = 0.0f; + channel->field_0x6c[1].mEffect = 0.5f; + channel->field_0x6c[2].mEffect = 0.0f; + channel->field_0x6c[3].mEffect = 0.0f; channel->field_0x94 = 1.0f; channel->field_0x98 = 1.0f; channel->setOscInit(0, &OSC_ENV); @@ -156,6 +249,27 @@ JASystem::TChannel* JASystem::BankMgr::noteOnOsc(TChannelMgr* param_1, int param } /* 80288E44-80288F08 .text gateOn__Q28JASystem7BankMgrFPQ28JASystem8TChannelUcUcUl */ -void JASystem::BankMgr::gateOn(JASystem::TChannel*, u8, u8, u32) { - /* Nonmatching */ +void JASystem::BankMgr::gateOn(JASystem::TChannel* channel, u8 param_2, u8 param_3, u32 param_4) { + if (channel->field_0x30 != -1) + return; + + channel->field_0x30 = param_4; + channel->field_0x34 = channel->field_0x30; + s32 var; + if (channel->field_0xc == 2) + var = param_2; + else + var = (param_2 + 0x3C) - channel->field_0x10->field_0x2; + + if (var < 0) + var = 0; + if (var > 0x7F) + var = 0x7F; + + f32 pitch = Driver::C5BASE_PITCHTABLE[var]; + channel->field_0x0 = param_3; + channel->field_0x1 = param_2; + channel->field_0x58 = channel->field_0x50 * pitch; + channel->field_0x5c = channel->field_0x0 / 127.0f; + channel->field_0x5c = channel->field_0x54 * (channel->field_0x5c * channel->field_0x5c); } diff --git a/src/JSystem/JAudio/JASChGlobal.cpp b/src/JSystem/JAudio/JASChGlobal.cpp index 6d7181e08..7c2db46d2 100644 --- a/src/JSystem/JAudio/JASChGlobal.cpp +++ b/src/JSystem/JAudio/JASChGlobal.cpp @@ -41,13 +41,13 @@ void JASystem::TGlobalChannel::init() { mgr->addListHead(&sChannel[i], 0); sChannel[i].field_0x4 = mgr; } - mgr->field_0x0 = 256; + mgr->mManagedChannels = 256; OSReport("----- JASChannel size : %d\n", sizeof(TChannel)); } /* 8028AD50-8028ADE8 .text alloc__Q28JASystem14TGlobalChannelFPQ28JASystem11TChannelMgrUl */ -int JASystem::TGlobalChannel::alloc(TChannelMgr* param_1, u32 param_2) { - int i; +u32 JASystem::TGlobalChannel::alloc(TChannelMgr* param_1, u32 param_2) { + u32 i; for (i = 0; i < param_2; i++) { TChannel* channel = sChannelMgr->getListHead(0); if (!channel) { @@ -57,16 +57,16 @@ int JASystem::TGlobalChannel::alloc(TChannelMgr* param_1, u32 param_2) { channel->field_0x4 = param_1; channel->init(); } - param_1->field_0x0 += i; - sChannelMgr->field_0x0 -= i; + param_1->mManagedChannels += i; + sChannelMgr->mManagedChannels -= i; return i; } /* 8028ADE8-8028AE4C .text release__Q28JASystem14TGlobalChannelFPQ28JASystem8TChannel */ int JASystem::TGlobalChannel::release(TChannel* param_1) { sChannelMgr->addListHead(param_1, 0); - param_1->field_0x4->field_0x0--; - sChannelMgr->field_0x0++; + param_1->field_0x4->mManagedChannels--; + sChannelMgr->mManagedChannels++; param_1->field_0x4 = sChannelMgr; return 0; } @@ -112,7 +112,7 @@ int JASystem::TGlobalChannel::releaseAll(TChannelMgr* param_1) { } channel->field_0x4 = sChannelMgr; } - sChannelMgr->field_0x0 += param_1->field_0x0; - param_1->field_0x0 = 0; + sChannelMgr->mManagedChannels += param_1->mManagedChannels; + param_1->mManagedChannels = 0; return 0; } diff --git a/src/JSystem/JAudio/JASChannel.cpp b/src/JSystem/JAudio/JASChannel.cpp index 0693bf847..9403c3ba1 100644 --- a/src/JSystem/JAudio/JASChannel.cpp +++ b/src/JSystem/JAudio/JASChannel.cpp @@ -106,7 +106,7 @@ void TChannel::init() { if (s32(field_0xc8) == 0) { field_0xc8 = 1; } - field_0xe8 = 0; + mSkipSamples = 0; } /* 8028B5A4-8028B620 .text setOscillator__Q28JASystem8TChannelFUlPQ28JASystem11TOscillator */ @@ -160,16 +160,16 @@ void TChannel::effectOsc(u32 oscnum, f32 effect) { break; case 2: effect -= 0.5; // Must be double literal to match - mPanVec.mEffect += effect; - mPanVec.mEffect = Driver::Clamp01(mPanVec.mEffect); + field_0x6c[1].mEffect += effect; + field_0x6c[1].mEffect = Driver::Clamp01(field_0x6c[1].mEffect); break; case 3: - mFxmixVec.mEffect += effect; - mFxmixVec.mEffect = Driver::Clamp01(mFxmixVec.mEffect); + field_0x6c[2].mEffect += effect; + field_0x6c[2].mEffect = Driver::Clamp01(field_0x6c[2].mEffect); break; case 4: - mDolbyVec.mEffect += effect; - mDolbyVec.mEffect = Driver::Clamp01(mDolbyVec.mEffect); + field_0x6c[3].mEffect += effect; + field_0x6c[3].mEffect = Driver::Clamp01(field_0x6c[3].mEffect); break; } } @@ -248,9 +248,9 @@ void TChannel::setPanPower(f32 param_1, f32 param_2, f32 param_3, f32 param_4) { OSReport("----- JASChannel::setPanPower : px == 0.0\n"); px = 1.0f; } - mPanPower.mSound = param_1 / px; - mPanPower.mEffect = param_2 / px; - mPanPower.mChannel = param_3 / px; + field_0x6c[0].mSound = param_1 / px; + field_0x6c[0].mEffect = param_2 / px; + field_0x6c[0].mChannel = param_3 / px; } /* 8028BE64-8028BEB8 .text checkLogicalChannel__Q28JASystem8TChannelFv */ @@ -359,7 +359,7 @@ BOOL TChannel::playLogicalChannel() { switch (field_0xc) { case 0: - buf->setWaveInfo(field_0x10, field_0x14, field_0xe8); + buf->setWaveInfo(field_0x10, field_0x14, mSkipSamples); break; case 2: buf->setOscInfo(field_0x14); @@ -422,9 +422,9 @@ void TChannel::updateEffectorParam() { if (field_0xa4 == field_0x4) { field_0xa8 = field_0x4->field_0x1c; field_0xac = field_0x4->field_0x18; - mPanVec.mChannel = field_0x4->field_0x20; - mFxmixVec.mChannel = field_0x4->field_0x24; - mDolbyVec.mChannel = field_0x4->field_0x28; + field_0x6c[1].mChannel = field_0x4->field_0x20; + field_0x6c[2].mChannel = field_0x4->field_0x24; + field_0x6c[3].mChannel = field_0x4->field_0x28; for (int i = 0; i < 3; i++) { mCalcTypes[i] = field_0x4->mCalcTypes[i]; } @@ -434,17 +434,17 @@ void TChannel::updateEffectorParam() { case 0: pan = 0.5f; dolby = 0.0f; - fxmix = calcEffect(&mFxmixVec, &mPanPower, mCalcTypes[1]); + fxmix = calcEffect(&field_0x6c[2], &field_0x6c[0], mCalcTypes[1]); break; case 1: - pan = (mCalcTypes[0] == CALC_None) ? 0.5f : calcPan(&mPanVec, &mPanPower, mCalcTypes[0]); - fxmix = calcEffect(&mFxmixVec, &mPanPower, mCalcTypes[1]); + pan = (mCalcTypes[0] == CALC_None) ? 0.5f : calcPan(&field_0x6c[1], &field_0x6c[0], mCalcTypes[0]); + fxmix = calcEffect(&field_0x6c[2], &field_0x6c[0], mCalcTypes[1]); dolby = 0.0f; break; case 2: - pan = (mCalcTypes[0] == CALC_None) ? 0.5f : calcPan(&mPanVec, &mPanPower, mCalcTypes[0]); - fxmix = calcEffect(&mFxmixVec, &mPanPower, mCalcTypes[1]); - dolby = calcEffect(&mDolbyVec, &mPanPower, mCalcTypes[2]); + pan = (mCalcTypes[0] == CALC_None) ? 0.5f : calcPan(&field_0x6c[1], &field_0x6c[0], mCalcTypes[0]); + fxmix = calcEffect(&field_0x6c[2], &field_0x6c[0], mCalcTypes[1]); + dolby = calcEffect(&field_0x6c[3], &field_0x6c[0], mCalcTypes[2]); break; } @@ -546,9 +546,9 @@ int TChannel::updatecallDSPChannel(TDSPChannel* dspChannel, u32 param_2) { if (param_2 == 0) { channel->field_0x94 = 1.0f; channel->field_0x98 = 1.0f; - channel->mPanVec.mEffect = 0.5f; - channel->mFxmixVec.mEffect = 0.0f; - channel->mDolbyVec.mEffect = 0.0f; + channel->field_0x6c[1].mEffect = 0.5f; + channel->field_0x6c[2].mEffect = 0.0f; + channel->field_0x6c[3].mEffect = 0.0f; for (i = 0; i < 4; i++) { if (!channel->isOsc(i)) continue; diff --git a/src/JSystem/JAudio/JASChannelMgr.cpp b/src/JSystem/JAudio/JASChannelMgr.cpp index f3a0927e1..221ba3fd7 100644 --- a/src/JSystem/JAudio/JASChannelMgr.cpp +++ b/src/JSystem/JAudio/JASChannelMgr.cpp @@ -8,32 +8,40 @@ #include "JSystem/JAudio/JASChannelMgr.h" #include "JSystem/JAudio/JASChGlobal.h" #include "JSystem/JAudio/JASChannel.h" +#include "JSystem/JAudio/JASDSPChannel.h" +#include "JSystem/JAudio/JASChAllocQueue.h" #include "dolphin/os/OS.h" +namespace JASystem{ +namespace Driver { +const u8 polys_table[16] = { 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x8, 0xa, 0xc, 0xe, 0x10, 0x14, 0x18, 0x1c, 0x20 }; +} // namespace Driver +} // namespace JASystem + /* 8028D3C0-8028D4D0 .text init__Q28JASystem11TChannelMgrFv */ void JASystem::TChannelMgr::init() { - /* Nonmatching */ + int i; field_0x8 = NULL; field_0xc = NULL; field_0x10 = NULL; field_0x14 = NULL; field_0x4 = 0; - field_0x0 = 0; + mManagedChannels = 0; field_0x70 = 1; field_0x18 = 1.0f; field_0x1c = 1.0f; field_0x20 = 0.5f; field_0x24 = 0.0f; field_0x28 = 0.0f; - for (int i = 0; i < 8; i++) { + for (i = 0; i < 8; i++) { field_0x2c[i] = 0; } field_0x2c[0] = 0x7fff; field_0x4c = 0; - for (int i = 0; i < 4; i++) { + for (i = 0; i < 4; i++) { field_0x3c[i] = 0; } - for (int i = 0; i < 6; i++) { + for (i = 0; i < 6; i++) { field_0x5a[i] = 0; } field_0x60 = 0; @@ -56,7 +64,7 @@ void JASystem::TChannelMgr::init() { void JASystem::TChannelMgr::stopAll() { TChannel* channel = field_0xc; while (channel) { - TChannel* r31 = channel->field_0x24; + TChannel* r31 = channel->mNext; channel->stop(0); channel = r31; } @@ -64,15 +72,15 @@ void JASystem::TChannelMgr::stopAll() { /* 8028D514-8028D558 .text stopAllRelease__Q28JASystem11TChannelMgrFv */ void JASystem::TChannelMgr::stopAllRelease() { - for (TChannel* channel = field_0x10; channel; channel = channel->field_0x24) { + for (TChannel* channel = field_0x10; channel; channel = channel->mNext) { channel->forceStopOsc(0); } } /* 8028D558-8028D5D0 .text initAllocChannel__Q28JASystem11TChannelMgrFUl */ void JASystem::TChannelMgr::initAllocChannel(u32 param_1) { - if (field_0x0) { - OSReport("----- Warning JCSにボイスが %d 残っているのでグローバルに返却します\n", field_0x0); + if (mManagedChannels) { + OSReport("----- Warning JCSにボイスが %d 残っているのでグローバルに返却します\n", mManagedChannels); TGlobalChannel::releaseAll(this); } init(); @@ -81,8 +89,55 @@ void JASystem::TChannelMgr::initAllocChannel(u32 param_1) { } /* 8028D5D0-8028D778 .text getLogicalChannel__Q28JASystem11TChannelMgrFUl */ -JASystem::TChannel* JASystem::TChannelMgr::getLogicalChannel(u32) { - /* Nonmatching */ +JASystem::TChannel* JASystem::TChannelMgr::getLogicalChannel(u32 param) { + BOOL bVar1 = false; + if (!checkLimitStart(param)) { + if ((param >> 0x18) & 0x10) + return NULL; + bVar1 = true; + } + + TChannel* head = getListHead(0); + if (head == NULL) { + if (!TGlobalChannel::alloc(this, 1)) { + OSReport("----- getLC グローバル論理チャンネルの残りがない\n"); + return NULL; + } + + field_0x4++; + head = getListHead(0); + if (field_0x70 == TRUE) { + TChannel* chan = getListHead(2); + if (chan == NULL) { + chan = getListHead(1); + if (chan == NULL) { + OSReport("----- getLC Error ----- fjc is NULL again\n"); + } + } + if (chan != NULL) { + chan->forceStopOsc(0); + addListHead(chan, 3); + if (chan->field_0x20 != NULL) { + chan->field_0x20->forceStop(); + } else { + OSReport("----- getLC -----does not have DSP CH\n"); + } + } else { + OSReport("cannot FORCESTOP (thisの論理ボイスが飽和?)\n"); + } + } + } + + head->init(); + if (bVar1) { + head->mPauseFlag = 1; + head->field_0x3 = 1; + } + + head->field_0xcc = param; + head->field_0x18 = 0; + head->setPanPower(1.0f, 1.0f, 1.0f, 1.0f); + return head; } /* 8028D778-8028D7D8 .text moveListHead__Q28JASystem11TChannelMgrFPQ28JASystem8TChannelUl */ @@ -105,7 +160,6 @@ BOOL JASystem::TChannelMgr::moveListTail(TChannel* param_1, u32 param_2) { /* 8028D838-8028D8E4 .text addListHead__Q28JASystem11TChannelMgrFPQ28JASystem8TChannelUl */ void JASystem::TChannelMgr::addListHead(TChannel* param_1, u32 param_2) { - /* Nonmatching */ TChannel** r31; switch (param_2) { case 0: @@ -130,12 +184,11 @@ void JASystem::TChannelMgr::addListHead(TChannel* param_1, u32 param_2) { } param_1->field_0x8 = r31; *r31 = param_1; - param_1->field_0x24 = r30; + param_1->mNext = r30; } /* 8028D8E4-8028D9C4 .text addListTail__Q28JASystem11TChannelMgrFPQ28JASystem8TChannelUl */ -void JASystem::TChannelMgr::addListTail(TChannel*param_1, u32 param_2) { - /* Nonmatching */ +void JASystem::TChannelMgr::addListTail(TChannel* param_1, u32 param_2) { TChannel** r31; switch (param_2) { case 0: @@ -161,14 +214,14 @@ void JASystem::TChannelMgr::addListTail(TChannel*param_1, u32 param_2) { param_1->field_0x8 = r31; if (!r30) { *r31 = param_1; - param_1->field_0x24 = NULL; + param_1->mNext = NULL; return; } while (true) { - TChannel* tmp = r30->field_0x24; + TChannel* tmp = r30->mNext; if (!tmp) { - r30->field_0x24 = param_1; - param_1->field_0x24 = NULL; + r30->mNext = param_1; + param_1->mNext = NULL; break; } r30 = tmp; @@ -199,27 +252,194 @@ JASystem::TChannel* JASystem::TChannelMgr::getListHead(u32 param_1) { if (!r30) { return NULL; } - *r31 = r30->field_0x24; + *r31 = r30->mNext; r30->field_0x8 = NULL; return r30; } /* 8028DA38-8028DAF0 .text cutList__Q28JASystem11TChannelMgrFPQ28JASystem8TChannel */ -int JASystem::TChannelMgr::cutList(TChannel*) { - /* Nonmatching */ +int JASystem::TChannelMgr::cutList(TChannel* channel) { + int n = 0; + + TChannel* head = *channel->field_0x8; + + if (!head) { + OSReport("cutChList Error: No Member\n"); + return -1; + } + + if (head == channel) { + *channel->field_0x8 = channel->mNext; + channel->field_0x8 = NULL; + return 0; + } + + for (;;) { + n++; + if (head == NULL) { + OSReport("cutChList Error: Not Member\n"); + return -1; + } + if (head->mNext == channel) + break; + head = head->mNext; + } + + head->mNext = channel->mNext; + channel->field_0x8 = NULL; + return n; } /* 8028DAF0-8028DC34 .text receiveAllChannels__Q28JASystem11TChannelMgrFPQ28JASystem11TChannelMgr */ -void JASystem::TChannelMgr::receiveAllChannels(TChannelMgr*) { - /* Nonmatching */ +int JASystem::TChannelMgr::receiveAllChannels(TChannelMgr* other) { + TChannel* stolen; + for (;;) { + stolen = other->getListHead(0); + if (!stolen) + break; + addListHead(stolen, 0); + stolen->field_0x4 = this; + } + for (;;) { + stolen = other->getListHead(1); + if (!stolen) + break; + addListHead(stolen, 1); + stolen->field_0x4 = this; + stolen->field_0xd4 = 1; + } + for (;;) { + stolen = other->getListHead(2); + if (!stolen) + break; + addListHead(stolen, 2); + stolen->field_0x4 = this; + stolen->field_0xd4 = 1; + } + for (;;) { + stolen = other->getListHead(3); + if (!stolen) + break; + if (TDSPQueue::deleteQueue(stolen)) + addListHead(stolen, 0); + else + addListHead(stolen, 3); + stolen->field_0x4 = this; + } + mManagedChannels += other->mManagedChannels; + other->mManagedChannels = 0; + field_0x4 += other->field_0x4; + other->field_0x4 = 0; + + return 0; } /* 8028DC34-8028DDD0 .text checkLimitStart__Q28JASystem11TChannelMgrFUl */ -int JASystem::TChannelMgr::checkLimitStart(u32) { - /* Nonmatching */ +int JASystem::TChannelMgr::checkLimitStart(u32 param) { + u8 r5 = Driver::polys_table[(param >> 0x18) & 0xF]; + if (!r5) + return true; + + u32 chNum = 0; + + TChannel* head = field_0x10; + if (((param >> 0x18) & 0x20)) { + for (;;) { + if (!head) + break; + + if (head->field_0xcc == param && head->mPauseFlag == 0) + chNum++; + } + + head = field_0xc; + for (;;) { + if (!head) + break; + + if (head->field_0xcc == param && head->mPauseFlag == 0) + chNum++; + } + + if (chNum == r5) + return false; + else if (chNum > r5) { + OSReport("----- checkLimitStart Why? chNum is over\n"); + return false; + } + + return true; + } else { + TChannel* found = NULL; + for (;;) { + if (!head) + break; + + if (head->field_0xcc == param && head->mPauseFlag == 0) { + if (found == NULL) + found = head; + if (chNum == r5) { + found->forceStopLogicalChannel(); + return 1; + } + chNum++; + } + } + + head = field_0xc; + for (;;) { + if (!head) + break; + + if (head->field_0xcc == param && head->mPauseFlag == 0) { + if (found == NULL) + found = head; + if (chNum == r5) { + if ((param >> 0x18) & 0x10) + found->forceStopLogicalChannel(); + else + head->setPauseFlagReq(1); + + return 1; + } + chNum++; + } + } + return true; + } } /* 8028DDD0-8028DE94 .text checkLimitStop__Q28JASystem11TChannelMgrFPQ28JASystem8TChannelUl */ -void JASystem::TChannelMgr::checkLimitStop(TChannel*, u32) { - /* Nonmatching */ +void JASystem::TChannelMgr::checkLimitStop(TChannel* channel, u32 param) { + TChannel* chan = field_0xc; + u8 thing = Driver::polys_table[(param >> 0x18) & 0xF]; + + if (param == 0) + return; + if (thing == 0) + return; + + if ((param >> 0x18) & 0x20) { + for (;;) { + if (!chan) + break; + if (chan->field_0xcc == param && chan->mPauseFlag == 1) { + chan->setPauseFlagReq(0); + return; + } + chan = chan->mNext; + } + } else { + TChannel* found = NULL; + for (;;) { + if (!chan) + break; + if (chan->field_0xcc == param && chan->mPauseFlag == 1) + found = chan; + chan = chan->mNext; + } + + if (found) + found->setPauseFlagReq(0); + } } diff --git a/src/JSystem/JAudio/JASSeqParser.cpp b/src/JSystem/JAudio/JASSeqParser.cpp index fc621fbd2..273dcc5e0 100644 --- a/src/JSystem/JAudio/JASSeqParser.cpp +++ b/src/JSystem/JAudio/JASSeqParser.cpp @@ -859,7 +859,7 @@ int JASystem::TSeqParser::cmdNoteOn(TTrack* track, u8 note) { } u8 r23; u8 noteid = r27 & 0x7; - int r22 = 0; + u32 skipSamples = 0; if (!noteid) { r23 = track->getSeq()->readByte(); if (r23 & 0x80) { @@ -881,7 +881,7 @@ int JASystem::TSeqParser::cmdNoteOn(TTrack* track, u8 note) { JUT_ASSERT(0x4FE, noteid < 8); } if (r26 & 1) { - r22 = track->exchangeRegisterValue(track->getSeq()->readByte()); + skipSamples = track->exchangeRegisterValue(track->getSeq()->readByte()); r26 ^= 1; } @@ -912,7 +912,7 @@ int JASystem::TSeqParser::cmdNoteOn(TTrack* track, u8 note) { } if (!track->mIsPaused || !(track->mPauseStatus & 0x10)) { - track->noteOn(noteid, note, r25, time, r22); + track->noteOn(noteid, note, r25, time, skipSamples); } } diff --git a/src/JSystem/JAudio/JASTrack.cpp b/src/JSystem/JAudio/JASTrack.cpp index 0a7f20644..4c58c3800 100644 --- a/src/JSystem/JAudio/JASTrack.cpp +++ b/src/JSystem/JAudio/JASTrack.cpp @@ -136,13 +136,13 @@ s8 JASystem::TTrack::mainProc() { } field_0x364 -= 1.0f; } - if (mParent && mChannelUpdater.field_0x0) { + if (mParent && mChannelUpdater.mManagedChannels) { TChannel* channel = mChannelUpdater.getListHead(0); if (channel) { mParent->mChannelUpdater.addListHead(channel, 0); channel->field_0x4 = &mParent->mChannelUpdater; - mChannelUpdater.field_0x0--; - mParent->mChannelUpdater.field_0x0++; + mChannelUpdater.mManagedChannels--; + mParent->mChannelUpdater.mManagedChannels++; } } mIntrMgr.request(REQUEST_UNK_7); @@ -225,21 +225,21 @@ void JASystem::TTrack::flushAll() { /* 80281088-80281138 .text moveFreeChannel__Q28JASystem6TTrackFPQ28JASystem11TChannelMgrPQ28JASystem11TChannelMgri */ int JASystem::TTrack::moveFreeChannel(TChannelMgr* param_1, TChannelMgr* param_2, int param_3) { if (param_3 < 0) { - u32 r31 = param_1->field_0x0; + u32 r31 = param_1->mManagedChannels; param_2->receiveAllChannels(param_1); return r31; } for (int i = 0; i < param_3; i++) { - if (!param_1->field_0x0) { + if (!param_1->mManagedChannels) { break; } TChannel* channel = param_1->getListHead(0); if (!channel) { break; } - param_1->field_0x0--; + param_1->mManagedChannels--; param_2->addListHead(channel, 0); - param_2->field_0x0++; + param_2->mManagedChannels++; } return 0; } @@ -283,14 +283,14 @@ void JASystem::TTrack::connectBus(int line, int param_2) { } /* 80281258-802814AC .text noteOn__Q28JASystem6TTrackFUclllUl */ -int JASystem::TTrack::noteOn(u8 param_1, s32 param_2, s32 param_3, s32 param_4, u32 param_5) { +int JASystem::TTrack::noteOn(u8 param_1, s32 param_2, s32 param_3, s32 param_4, u32 skipSamples) { if (field_0x386 && (mPauseStatus & 0x40)) { return -1; } noteOff(param_1, 0); TChannelMgr* r31 = &mChannelUpdater; TTrack* parent = mParent; - while (r31->field_0x0 == 0 || r31->field_0x8 == 0) { + while (r31->mManagedChannels == 0 || r31->field_0x8 == 0) { if (!parent) { r31 = &mChannelUpdater; break; @@ -302,13 +302,13 @@ int JASystem::TTrack::noteOn(u8 param_1, s32 param_2, s32 param_3, s32 param_4, JUT_ASSERT(527, mParent != NULL); if (r31 != &mParent->mChannelUpdater) { if (moveFreeChannel(r31, &mParent->mChannelUpdater, 1) != 1) { - OSReport("in Player (NOTE-MODE) ... ボイス借用に失敗しました!! (%d)\n", r31->field_0x0); + OSReport("in Player (NOTE-MODE) ... ボイス借用に失敗しました!! (%d)\n", r31->mManagedChannels); } r31 = &mParent->mChannelUpdater; } } else if (r31 != &mChannelUpdater) { if (moveFreeChannel(r31, &mChannelUpdater, 1) != 1) { - OSReport("in Player ボイス借用に失敗しました!! (%d)\n", r31->field_0x0); + OSReport("in Player ボイス借用に失敗しました!! (%d)\n", r31->mManagedChannels); } r31 = &mChannelUpdater; } @@ -320,7 +320,7 @@ int JASystem::TTrack::noteOn(u8 param_1, s32 param_2, s32 param_3, s32 param_4, return -1; } mNoteMgr.setChannel(param_1, channel); - channel->field_0xe8 = param_5; + channel->setSkipSamples(skipSamples); channel->setPanPower(mRegisterParam.getPanPowerBank(), mRegisterParam.getPanPowerExt(), mRegisterParam.getPanPowerOsc(), 0.0f); overwriteOsc(channel); if (field_0x374) { diff --git a/src/JSystem/JAudio/JASWaveArcLoader.cpp b/src/JSystem/JAudio/JASWaveArcLoader.cpp index e500a7c62..bc460e235 100644 --- a/src/JSystem/JAudio/JASWaveArcLoader.cpp +++ b/src/JSystem/JAudio/JASWaveArcLoader.cpp @@ -56,7 +56,7 @@ char* JASystem::WaveArcLoader::getCurrentDir() { JASystem::TWaveArc::TWaveArc() : mHeap(this) { field_0x4c = 0; field_0x68 = 0; - mFileNo = -1; + mEntryNum = -1; mSize = 0; field_0x74 = 0; OSInitMutex(&mMutex); @@ -97,17 +97,10 @@ bool JASystem::TWaveArc::eraseSetup() { return true; } -struct unk_message { - JASystem::TWaveArc* mpWaveArc; - int mFileNo; - void* field_0x8; - u32 field_0xc; -}; - /* 80287EB8-80287F48 .text loadToAramCallback__Q28JASystem8TWaveArcFPv */ s32 JASystem::TWaveArc::loadToAramCallback(void* param_1) { - unk_message* msg = (unk_message*)param_1; - if (JKRDvdAramRipper::loadToAram(msg->mFileNo, u32(msg->field_0x8), EXPAND_SWITCH_UNKNOWN0, 0, 0) == 0) { + loadToAramCallbackMsg* msg = (loadToAramCallbackMsg*)param_1; + if (JKRDvdAramRipper::loadToAram(msg->mEntryNum, msg->mBase, EXPAND_SWITCH_UNKNOWN0, 0, 0) == 0) { return -1; } TWaveArc* waveArc = msg->mpWaveArc; @@ -123,10 +116,10 @@ bool JASystem::TWaveArc::sendLoadCmd() { OSLockMutex(&mMutex); field_0x4c = 0; field_0x68 = 1; - unk_message msg; + loadToAramCallbackMsg msg; msg.mpWaveArc = this; - msg.mFileNo = mFileNo; - msg.field_0x8 = mHeap.mBase; + msg.mEntryNum = mEntryNum; + msg.mBase = (uintptr_t)mHeap.getBase(); msg.field_0xc = ++field_0x74; OSUnlockMutex(&mMutex); if (!Dvd::sendCmdMsg(loadToAramCallback, &msg, sizeof(msg))) { @@ -138,7 +131,7 @@ bool JASystem::TWaveArc::sendLoadCmd() { /* 80287FE4-802880A0 .text load__Q28JASystem8TWaveArcFPQ38JASystem6Kernel5THeap */ bool JASystem::TWaveArc::load(Kernel::THeap* heap) { - if (mFileNo < 0) + if (mEntryNum < 0) return false; OSLockMutex(&mMutex); @@ -178,7 +171,7 @@ void JASystem::TWaveArc::setEntryNum(s32 entryNum) { if (entryNum >= 0 && DVDFastOpen(entryNum, &file)) { mSize = file.length; DVDClose(&file); - mFileNo = entryNum; + mEntryNum = entryNum; } }